blob: fabf7aef7f2bee07031cbd0e65787c513e516904 [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);
mmenked1205bd3972015-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);
bnc7dc7e1b42015-07-28 14:43:127867 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:227868 http_server_properties->SetAlternativeService(
bnc7dc7e1b42015-07-28 14:43:127869 HostPortPair("host.with.alternate", 80), alternative_service, 1.0,
7870 expiration);
[email protected]2d731a32010-04-29 01:04:067871
7872 return session;
7873}
7874
7875int GroupNameTransactionHelper(
7876 const std::string& url,
7877 const scoped_refptr<HttpNetworkSession>& session) {
[email protected]2d731a32010-04-29 01:04:067878 HttpRequestInfo request;
7879 request.method = "GET";
7880 request.url = GURL(url);
7881 request.load_flags = 0;
7882
[email protected]262eec82013-03-19 21:01:367883 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507884 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277885
[email protected]49639fa2011-12-20 23:22:417886 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:067887
7888 // We do not complete this request, the dtor will clean the transaction up.
[email protected]49639fa2011-12-20 23:22:417889 return trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d731a32010-04-29 01:04:067890}
7891
[email protected]448d4ca52012-03-04 04:12:237892} // namespace
7893
[email protected]23e482282013-06-14 16:08:027894TEST_P(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:067895 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:237896 {
7897 "", // unused
7898 "http://www.example.org/direct",
7899 "www.example.org:80",
7900 false,
7901 },
7902 {
7903 "", // unused
7904 "http://[2001:1418:13:1::25]/direct",
7905 "[2001:1418:13:1::25]:80",
7906 false,
7907 },
[email protected]04e5be32009-06-26 20:00:317908
bncce36dca22015-04-21 22:11:237909 // SSL Tests
7910 {
7911 "", // unused
7912 "https://www.example.org/direct_ssl",
7913 "ssl/www.example.org:443",
7914 true,
7915 },
7916 {
7917 "", // unused
7918 "https://[2001:1418:13:1::25]/direct",
7919 "ssl/[2001:1418:13:1::25]:443",
7920 true,
7921 },
7922 {
7923 "", // unused
7924 "http://host.with.alternate/direct",
7925 "ssl/host.with.alternate:443",
7926 true,
7927 },
[email protected]2d731a32010-04-29 01:04:067928 };
[email protected]2ff8b312010-04-26 22:20:547929
[email protected]d7599122014-05-24 03:37:237930 session_deps_.use_alternate_protocols = true;
[email protected]2d731a32010-04-29 01:04:067931
viettrungluue4a8b882014-10-16 06:17:387932 for (size_t i = 0; i < arraysize(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:077933 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:027934 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:067935 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:437936 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:067937
7938 HttpNetworkSessionPeer peer(session);
[email protected]ab739042011-04-07 15:22:287939 CaptureGroupNameTransportSocketPool* transport_conn_pool =
7940 new CaptureGroupNameTransportSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:137941 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347942 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]831e4a32013-11-14 02:14:447943 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
7944 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:027945 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
7946 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
dchenge3d1ddc2014-10-15 19:30:517947 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]2d731a32010-04-29 01:04:067948
7949 EXPECT_EQ(ERR_IO_PENDING,
7950 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:187951 if (tests[i].ssl)
7952 EXPECT_EQ(tests[i].expected_group_name,
7953 ssl_conn_pool->last_group_name_received());
7954 else
7955 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:287956 transport_conn_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:067957 }
7958
[email protected]2d731a32010-04-29 01:04:067959}
7960
[email protected]23e482282013-06-14 16:08:027961TEST_P(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:067962 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:237963 {
7964 "http_proxy",
7965 "http://www.example.org/http_proxy_normal",
7966 "www.example.org:80",
7967 false,
7968 },
[email protected]2d731a32010-04-29 01:04:067969
bncce36dca22015-04-21 22:11:237970 // SSL Tests
7971 {
7972 "http_proxy",
7973 "https://www.example.org/http_connect_ssl",
7974 "ssl/www.example.org:443",
7975 true,
7976 },
[email protected]af3490e2010-10-16 21:02:297977
bncce36dca22015-04-21 22:11:237978 {
7979 "http_proxy",
7980 "http://host.with.alternate/direct",
7981 "ssl/host.with.alternate:443",
7982 true,
7983 },
[email protected]45499252013-01-23 17:12:567984
bncce36dca22015-04-21 22:11:237985 {
7986 "http_proxy",
7987 "ftp://ftp.google.com/http_proxy_normal",
7988 "ftp/ftp.google.com:21",
7989 false,
7990 },
[email protected]2d731a32010-04-29 01:04:067991 };
7992
[email protected]d7599122014-05-24 03:37:237993 session_deps_.use_alternate_protocols = true;
[email protected]2d731a32010-04-29 01:04:067994
viettrungluue4a8b882014-10-16 06:17:387995 for (size_t i = 0; i < arraysize(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:077996 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:027997 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:067998 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:437999 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:068000
8001 HttpNetworkSessionPeer peer(session);
8002
[email protected]e60e47a2010-07-14 03:37:188003 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:138004 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:348005 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:138006 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:348007 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:028008
[email protected]831e4a32013-11-14 02:14:448009 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
8010 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:028011 mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool);
8012 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
dchenge3d1ddc2014-10-15 19:30:518013 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]2d731a32010-04-29 01:04:068014
8015 EXPECT_EQ(ERR_IO_PENDING,
8016 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:188017 if (tests[i].ssl)
8018 EXPECT_EQ(tests[i].expected_group_name,
8019 ssl_conn_pool->last_group_name_received());
8020 else
8021 EXPECT_EQ(tests[i].expected_group_name,
8022 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:068023 }
[email protected]2d731a32010-04-29 01:04:068024}
8025
[email protected]23e482282013-06-14 16:08:028026TEST_P(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:068027 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:238028 {
8029 "socks4://socks_proxy:1080",
8030 "http://www.example.org/socks4_direct",
8031 "socks4/www.example.org:80",
8032 false,
8033 },
8034 {
8035 "socks5://socks_proxy:1080",
8036 "http://www.example.org/socks5_direct",
8037 "socks5/www.example.org:80",
8038 false,
8039 },
[email protected]2d731a32010-04-29 01:04:068040
bncce36dca22015-04-21 22:11:238041 // SSL Tests
8042 {
8043 "socks4://socks_proxy:1080",
8044 "https://www.example.org/socks4_ssl",
8045 "socks4/ssl/www.example.org:443",
8046 true,
8047 },
8048 {
8049 "socks5://socks_proxy:1080",
8050 "https://www.example.org/socks5_ssl",
8051 "socks5/ssl/www.example.org:443",
8052 true,
8053 },
[email protected]af3490e2010-10-16 21:02:298054
bncce36dca22015-04-21 22:11:238055 {
8056 "socks4://socks_proxy:1080",
8057 "http://host.with.alternate/direct",
8058 "socks4/ssl/host.with.alternate:443",
8059 true,
8060 },
[email protected]04e5be32009-06-26 20:00:318061 };
8062
[email protected]d7599122014-05-24 03:37:238063 session_deps_.use_alternate_protocols = true;
[email protected]2ff8b312010-04-26 22:20:548064
viettrungluue4a8b882014-10-16 06:17:388065 for (size_t i = 0; i < arraysize(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:078066 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:028067 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:068068 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:438069 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]8b114dd72011-03-25 05:33:028070
[email protected]2d731a32010-04-29 01:04:068071 HttpNetworkSessionPeer peer(session);
[email protected]04e5be32009-06-26 20:00:318072
[email protected]e60e47a2010-07-14 03:37:188073 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:138074 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:348075 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:138076 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:348077 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:028078
[email protected]831e4a32013-11-14 02:14:448079 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
8080 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:028081 mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_conn_pool);
8082 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
dchenge3d1ddc2014-10-15 19:30:518083 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]04e5be32009-06-26 20:00:318084
[email protected]262eec82013-03-19 21:01:368085 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508086 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]04e5be32009-06-26 20:00:318087
[email protected]2d731a32010-04-29 01:04:068088 EXPECT_EQ(ERR_IO_PENDING,
8089 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:188090 if (tests[i].ssl)
8091 EXPECT_EQ(tests[i].expected_group_name,
8092 ssl_conn_pool->last_group_name_received());
8093 else
8094 EXPECT_EQ(tests[i].expected_group_name,
8095 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:318096 }
8097}
8098
[email protected]23e482282013-06-14 16:08:028099TEST_P(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:278100 HttpRequestInfo request;
8101 request.method = "GET";
bncce36dca22015-04-21 22:11:238102 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278103
[email protected]bb88e1d32013-05-03 23:11:078104 session_deps_.proxy_service.reset(
[email protected]81cdfcd2010-10-16 00:49:008105 ProxyService::CreateFixed("myproxy:70;foobar:80"));
[email protected]b59ff372009-07-15 22:04:328106
[email protected]69719062010-01-05 20:09:218107 // This simulates failure resolving all hostnames; that means we will fail
8108 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:078109 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:328110
[email protected]3fe8d2f82013-10-17 08:56:078111 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]9172a982009-06-06 00:30:258112 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418113 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]9172a982009-06-06 00:30:258114
[email protected]49639fa2011-12-20 23:22:418115 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:258116
[email protected]49639fa2011-12-20 23:22:418117 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9172a982009-06-06 00:30:258118 EXPECT_EQ(ERR_IO_PENDING, rv);
8119
[email protected]9172a982009-06-06 00:30:258120 rv = callback.WaitForResult();
[email protected]f7fccee2010-09-16 20:53:018121 EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
[email protected]9172a982009-06-06 00:30:258122}
8123
[email protected]685af592010-05-11 19:31:248124// Base test to make sure that when the load flags for a request specify to
8125// bypass the cache, the DNS cache is not used.
[email protected]23e482282013-06-14 16:08:028126void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
[email protected]bb88e1d32013-05-03 23:11:078127 int load_flags) {
[email protected]cb9bf6ca2011-01-28 13:15:278128 // Issue a request, asking to bypass the cache(s).
8129 HttpRequestInfo request;
8130 request.method = "GET";
8131 request.load_flags = load_flags;
bncce36dca22015-04-21 22:11:238132 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278133
[email protected]a2c2fb92009-07-18 07:31:048134 // Select a host resolver that does caching.
[email protected]bb88e1d32013-05-03 23:11:078135 session_deps_.host_resolver.reset(new MockCachingHostResolver);
[email protected]b59ff372009-07-15 22:04:328136
[email protected]3fe8d2f82013-10-17 08:56:078137 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8138 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418139 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3b9cca42009-06-16 01:08:288140
bncce36dca22015-04-21 22:11:238141 // Warm up the host cache so it has an entry for "www.example.org".
[email protected]3b9cca42009-06-16 01:08:288142 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:298143 TestCompletionCallback callback;
[email protected]bb88e1d32013-05-03 23:11:078144 int rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:238145 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
8146 DEFAULT_PRIORITY, &addrlist, callback.callback(), NULL, BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:478147 EXPECT_EQ(ERR_IO_PENDING, rv);
8148 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:288149 EXPECT_EQ(OK, rv);
8150
8151 // Verify that it was added to host cache, by doing a subsequent async lookup
8152 // and confirming it completes synchronously.
[email protected]bb88e1d32013-05-03 23:11:078153 rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:238154 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
8155 DEFAULT_PRIORITY, &addrlist, callback.callback(), NULL, BoundNetLog());
[email protected]b59ff372009-07-15 22:04:328156 ASSERT_EQ(OK, rv);
[email protected]3b9cca42009-06-16 01:08:288157
bncce36dca22015-04-21 22:11:238158 // Inject a failure the next time that "www.example.org" is resolved. This way
[email protected]3b9cca42009-06-16 01:08:288159 // we can tell if the next lookup hit the cache, or the "network".
8160 // (cache --> success, "network" --> failure).
bncce36dca22015-04-21 22:11:238161 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.example.org");
[email protected]3b9cca42009-06-16 01:08:288162
8163 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
8164 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:068165 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
[email protected]31a2bfe2010-02-09 08:03:398166 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078167 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:288168
[email protected]3b9cca42009-06-16 01:08:288169 // Run the request.
[email protected]49639fa2011-12-20 23:22:418170 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3b9cca42009-06-16 01:08:288171 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:418172 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:288173
8174 // If we bypassed the cache, we would have gotten a failure while resolving
bncce36dca22015-04-21 22:11:238175 // "www.example.org".
[email protected]3b9cca42009-06-16 01:08:288176 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
8177}
8178
[email protected]685af592010-05-11 19:31:248179// There are multiple load flags that should trigger the host cache bypass.
8180// Test each in isolation:
[email protected]23e482282013-06-14 16:08:028181TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
[email protected]685af592010-05-11 19:31:248182 BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
8183}
8184
[email protected]23e482282013-06-14 16:08:028185TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
[email protected]685af592010-05-11 19:31:248186 BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
8187}
8188
[email protected]23e482282013-06-14 16:08:028189TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
[email protected]685af592010-05-11 19:31:248190 BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
8191}
8192
[email protected]0877e3d2009-10-17 22:29:578193// Make sure we can handle an error when writing the request.
[email protected]23e482282013-06-14 16:08:028194TEST_P(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:578195 HttpRequestInfo request;
8196 request.method = "GET";
8197 request.url = GURL("http://www.foo.com/");
8198 request.load_flags = 0;
8199
8200 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:068201 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:578202 };
[email protected]31a2bfe2010-02-09 08:03:398203 StaticSocketDataProvider data(NULL, 0,
8204 write_failure, arraysize(write_failure));
[email protected]bb88e1d32013-05-03 23:11:078205 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3fe8d2f82013-10-17 08:56:078206 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578207
[email protected]49639fa2011-12-20 23:22:418208 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:578209
8210 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418211 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:578212
[email protected]49639fa2011-12-20 23:22:418213 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578214 EXPECT_EQ(ERR_IO_PENDING, rv);
8215
8216 rv = callback.WaitForResult();
8217 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
8218}
8219
8220// Check that a connection closed after the start of the headers finishes ok.
[email protected]23e482282013-06-14 16:08:028221TEST_P(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:578222 HttpRequestInfo request;
8223 request.method = "GET";
8224 request.url = GURL("http://www.foo.com/");
8225 request.load_flags = 0;
8226
8227 MockRead data_reads[] = {
8228 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:068229 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:578230 };
8231
[email protected]31a2bfe2010-02-09 08:03:398232 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078233 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3fe8d2f82013-10-17 08:56:078234 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578235
[email protected]49639fa2011-12-20 23:22:418236 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:578237
8238 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418239 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:578240
[email protected]49639fa2011-12-20 23:22:418241 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578242 EXPECT_EQ(ERR_IO_PENDING, rv);
8243
8244 rv = callback.WaitForResult();
8245 EXPECT_EQ(OK, rv);
8246
8247 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508248 ASSERT_TRUE(response != NULL);
[email protected]0877e3d2009-10-17 22:29:578249
[email protected]90499482013-06-01 00:39:508250 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]0877e3d2009-10-17 22:29:578251 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
8252
8253 std::string response_data;
8254 rv = ReadTransaction(trans.get(), &response_data);
8255 EXPECT_EQ(OK, rv);
8256 EXPECT_EQ("", response_data);
8257}
8258
8259// Make sure that a dropped connection while draining the body for auth
8260// restart does the right thing.
[email protected]23e482282013-06-14 16:08:028261TEST_P(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:578262 HttpRequestInfo request;
8263 request.method = "GET";
bncce36dca22015-04-21 22:11:238264 request.url = GURL("http://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:578265 request.load_flags = 0;
8266
8267 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238268 MockWrite(
8269 "GET / HTTP/1.1\r\n"
8270 "Host: www.example.org\r\n"
8271 "Connection: keep-alive\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:578272 };
8273
8274 MockRead data_reads1[] = {
8275 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
8276 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8277 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8278 MockRead("Content-Length: 14\r\n\r\n"),
8279 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:068280 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:578281 };
8282
[email protected]31a2bfe2010-02-09 08:03:398283 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8284 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:078285 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:578286
8287 // After calling trans->RestartWithAuth(), this is the request we should
8288 // be issuing -- the final header line contains the credentials.
8289 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238290 MockWrite(
8291 "GET / HTTP/1.1\r\n"
8292 "Host: www.example.org\r\n"
8293 "Connection: keep-alive\r\n"
8294 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:578295 };
8296
8297 // Lastly, the server responds with the actual content.
8298 MockRead data_reads2[] = {
8299 MockRead("HTTP/1.1 200 OK\r\n"),
8300 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8301 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068302 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:578303 };
8304
[email protected]31a2bfe2010-02-09 08:03:398305 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8306 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:078307 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3fe8d2f82013-10-17 08:56:078308 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578309
[email protected]49639fa2011-12-20 23:22:418310 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:578311
[email protected]262eec82013-03-19 21:01:368312 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508313 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:508314
[email protected]49639fa2011-12-20 23:22:418315 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578316 EXPECT_EQ(ERR_IO_PENDING, rv);
8317
8318 rv = callback1.WaitForResult();
8319 EXPECT_EQ(OK, rv);
8320
8321 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508322 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048323 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:578324
[email protected]49639fa2011-12-20 23:22:418325 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:578326
[email protected]49639fa2011-12-20 23:22:418327 rv = trans->RestartWithAuth(
8328 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]0877e3d2009-10-17 22:29:578329 EXPECT_EQ(ERR_IO_PENDING, rv);
8330
8331 rv = callback2.WaitForResult();
8332 EXPECT_EQ(OK, rv);
8333
8334 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508335 ASSERT_TRUE(response != NULL);
[email protected]0877e3d2009-10-17 22:29:578336 EXPECT_TRUE(response->auth_challenge.get() == NULL);
8337 EXPECT_EQ(100, response->headers->GetContentLength());
8338}
8339
8340// Test HTTPS connections going through a proxy that sends extra data.
[email protected]23e482282013-06-14 16:08:028341TEST_P(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
[email protected]bb88e1d32013-05-03 23:11:078342 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]0877e3d2009-10-17 22:29:578343
8344 HttpRequestInfo request;
8345 request.method = "GET";
bncce36dca22015-04-21 22:11:238346 request.url = GURL("https://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:578347 request.load_flags = 0;
8348
8349 MockRead proxy_reads[] = {
8350 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:068351 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:578352 };
8353
[email protected]31a2bfe2010-02-09 08:03:398354 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
[email protected]8ddf8322012-02-23 18:08:068355 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:578356
[email protected]bb88e1d32013-05-03 23:11:078357 session_deps_.socket_factory->AddSocketDataProvider(&data);
8358 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:578359
[email protected]49639fa2011-12-20 23:22:418360 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:578361
[email protected]bb88e1d32013-05-03 23:11:078362 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:578363
[email protected]3fe8d2f82013-10-17 08:56:078364 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578365 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418366 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:578367
[email protected]49639fa2011-12-20 23:22:418368 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578369 EXPECT_EQ(ERR_IO_PENDING, rv);
8370
8371 rv = callback.WaitForResult();
8372 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
8373}
8374
[email protected]23e482282013-06-14 16:08:028375TEST_P(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:468376 HttpRequestInfo request;
8377 request.method = "GET";
bncce36dca22015-04-21 22:11:238378 request.url = GURL("http://www.example.org/");
[email protected]9492e4a2010-02-24 00:58:468379 request.load_flags = 0;
8380
[email protected]3fe8d2f82013-10-17 08:56:078381 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:278382 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418383 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278384
[email protected]e22e1362009-11-23 21:31:128385 MockRead data_reads[] = {
8386 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068387 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:128388 };
[email protected]9492e4a2010-02-24 00:58:468389
8390 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078391 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:468392
[email protected]49639fa2011-12-20 23:22:418393 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:468394
[email protected]49639fa2011-12-20 23:22:418395 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9492e4a2010-02-24 00:58:468396 EXPECT_EQ(ERR_IO_PENDING, rv);
8397
8398 EXPECT_EQ(OK, callback.WaitForResult());
8399
8400 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508401 ASSERT_TRUE(response != NULL);
[email protected]9492e4a2010-02-24 00:58:468402
[email protected]90499482013-06-01 00:39:508403 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]9492e4a2010-02-24 00:58:468404 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
8405
8406 std::string response_data;
8407 rv = ReadTransaction(trans.get(), &response_data);
[email protected]5543cbb2012-04-20 16:35:238408 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
[email protected]e22e1362009-11-23 21:31:128409}
8410
[email protected]23e482282013-06-14 16:08:028411TEST_P(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:158412 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:528413 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
[email protected]95d88ffe2010-02-04 21:25:338414 const uint64 kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:218415 UploadFileElementReader::ScopedOverridingContentLengthForTests
8416 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:338417
[email protected]b2d26cfd2012-12-11 10:36:068418 ScopedVector<UploadElementReader> element_readers;
8419 element_readers.push_back(
skyostil4891b25b2015-06-11 11:43:458420 new UploadFileElementReader(base::ThreadTaskRunnerHandle::Get().get(),
8421 temp_file_path, 0, kuint64max, base::Time()));
mmenkecbc2b712014-10-09 20:29:078422 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:278423
8424 HttpRequestInfo request;
8425 request.method = "POST";
bncce36dca22015-04-21 22:11:238426 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:278427 request.upload_data_stream = &upload_data_stream;
8428 request.load_flags = 0;
8429
[email protected]3fe8d2f82013-10-17 08:56:078430 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]329b68b2012-11-14 17:54:278431 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418432 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]95d88ffe2010-02-04 21:25:338433
8434 MockRead data_reads[] = {
8435 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
8436 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068437 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:338438 };
[email protected]31a2bfe2010-02-09 08:03:398439 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078440 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:338441
[email protected]49639fa2011-12-20 23:22:418442 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:338443
[email protected]49639fa2011-12-20 23:22:418444 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]95d88ffe2010-02-04 21:25:338445 EXPECT_EQ(ERR_IO_PENDING, rv);
8446
8447 rv = callback.WaitForResult();
8448 EXPECT_EQ(OK, rv);
8449
8450 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508451 ASSERT_TRUE(response != NULL);
[email protected]95d88ffe2010-02-04 21:25:338452
[email protected]90499482013-06-01 00:39:508453 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]95d88ffe2010-02-04 21:25:338454 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
8455
8456 std::string response_data;
8457 rv = ReadTransaction(trans.get(), &response_data);
8458 EXPECT_EQ(OK, rv);
8459 EXPECT_EQ("hello world", response_data);
8460
[email protected]dd3aa792013-07-16 19:10:238461 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:338462}
8463
[email protected]23e482282013-06-14 16:08:028464TEST_P(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:158465 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:528466 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:368467 std::string temp_file_content("Unreadable file.");
[email protected]e5c2a22e2014-03-06 20:42:308468 ASSERT_TRUE(base::WriteFile(temp_file, temp_file_content.c_str(),
[email protected]6624b4622010-03-29 19:58:368469 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:118470 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:368471
[email protected]b2d26cfd2012-12-11 10:36:068472 ScopedVector<UploadElementReader> element_readers;
8473 element_readers.push_back(
skyostil4891b25b2015-06-11 11:43:458474 new UploadFileElementReader(base::ThreadTaskRunnerHandle::Get().get(),
8475 temp_file, 0, kuint64max, base::Time()));
mmenkecbc2b712014-10-09 20:29:078476 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:278477
8478 HttpRequestInfo request;
8479 request.method = "POST";
bncce36dca22015-04-21 22:11:238480 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:278481 request.upload_data_stream = &upload_data_stream;
8482 request.load_flags = 0;
8483
[email protected]999dd8c2013-11-12 06:45:548484 // If we try to upload an unreadable file, the transaction should fail.
[email protected]3fe8d2f82013-10-17 08:56:078485 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]329b68b2012-11-14 17:54:278486 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418487 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]6624b4622010-03-29 19:58:368488
[email protected]999dd8c2013-11-12 06:45:548489 StaticSocketDataProvider data(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078490 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:368491
[email protected]49639fa2011-12-20 23:22:418492 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:368493
[email protected]49639fa2011-12-20 23:22:418494 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]6624b4622010-03-29 19:58:368495 EXPECT_EQ(ERR_IO_PENDING, rv);
8496
8497 rv = callback.WaitForResult();
[email protected]999dd8c2013-11-12 06:45:548498 EXPECT_EQ(ERR_ACCESS_DENIED, rv);
[email protected]6624b4622010-03-29 19:58:368499
[email protected]dd3aa792013-07-16 19:10:238500 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:368501}
8502
[email protected]02cad5d2013-10-02 08:14:038503TEST_P(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
8504 class FakeUploadElementReader : public UploadElementReader {
8505 public:
8506 FakeUploadElementReader() {}
dchengb03027d2014-10-21 12:00:208507 ~FakeUploadElementReader() override {}
[email protected]02cad5d2013-10-02 08:14:038508
8509 const CompletionCallback& callback() const { return callback_; }
8510
8511 // UploadElementReader overrides:
dchengb03027d2014-10-21 12:00:208512 int Init(const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:038513 callback_ = callback;
8514 return ERR_IO_PENDING;
8515 }
dchengb03027d2014-10-21 12:00:208516 uint64 GetContentLength() const override { return 0; }
8517 uint64 BytesRemaining() const override { return 0; }
8518 int Read(IOBuffer* buf,
8519 int buf_length,
8520 const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:038521 return ERR_FAILED;
8522 }
8523
8524 private:
8525 CompletionCallback callback_;
8526 };
8527
8528 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
8529 ScopedVector<UploadElementReader> element_readers;
8530 element_readers.push_back(fake_reader);
mmenkecbc2b712014-10-09 20:29:078531 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02cad5d2013-10-02 08:14:038532
8533 HttpRequestInfo request;
8534 request.method = "POST";
bncce36dca22015-04-21 22:11:238535 request.url = GURL("http://www.example.org/upload");
[email protected]02cad5d2013-10-02 08:14:038536 request.upload_data_stream = &upload_data_stream;
8537 request.load_flags = 0;
8538
[email protected]3fe8d2f82013-10-17 08:56:078539 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02cad5d2013-10-02 08:14:038540 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418541 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02cad5d2013-10-02 08:14:038542
8543 StaticSocketDataProvider data;
8544 session_deps_.socket_factory->AddSocketDataProvider(&data);
8545
8546 TestCompletionCallback callback;
8547 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8548 EXPECT_EQ(ERR_IO_PENDING, rv);
8549 base::MessageLoop::current()->RunUntilIdle();
8550
8551 // Transaction is pending on request body initialization.
8552 ASSERT_FALSE(fake_reader->callback().is_null());
8553
8554 // Return Init()'s result after the transaction gets destroyed.
8555 trans.reset();
8556 fake_reader->callback().Run(OK); // Should not crash.
8557}
8558
[email protected]aeefc9e82010-02-19 16:18:278559// Tests that changes to Auth realms are treated like auth rejections.
[email protected]23e482282013-06-14 16:08:028560TEST_P(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:278561
8562 HttpRequestInfo request;
8563 request.method = "GET";
bncce36dca22015-04-21 22:11:238564 request.url = GURL("http://www.example.org/");
[email protected]aeefc9e82010-02-19 16:18:278565 request.load_flags = 0;
8566
8567 // First transaction will request a resource and receive a Basic challenge
8568 // with realm="first_realm".
8569 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238570 MockWrite(
8571 "GET / HTTP/1.1\r\n"
8572 "Host: www.example.org\r\n"
8573 "Connection: keep-alive\r\n"
8574 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:278575 };
8576 MockRead data_reads1[] = {
8577 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8578 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
8579 "\r\n"),
8580 };
8581
8582 // After calling trans->RestartWithAuth(), provide an Authentication header
8583 // for first_realm. The server will reject and provide a challenge with
8584 // second_realm.
8585 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238586 MockWrite(
8587 "GET / HTTP/1.1\r\n"
8588 "Host: www.example.org\r\n"
8589 "Connection: keep-alive\r\n"
8590 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
8591 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:278592 };
8593 MockRead data_reads2[] = {
8594 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8595 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
8596 "\r\n"),
8597 };
8598
8599 // This again fails, and goes back to first_realm. Make sure that the
8600 // entry is removed from cache.
8601 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:238602 MockWrite(
8603 "GET / HTTP/1.1\r\n"
8604 "Host: www.example.org\r\n"
8605 "Connection: keep-alive\r\n"
8606 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
8607 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:278608 };
8609 MockRead data_reads3[] = {
8610 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8611 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
8612 "\r\n"),
8613 };
8614
8615 // Try one last time (with the correct password) and get the resource.
8616 MockWrite data_writes4[] = {
bncce36dca22015-04-21 22:11:238617 MockWrite(
8618 "GET / HTTP/1.1\r\n"
8619 "Host: www.example.org\r\n"
8620 "Connection: keep-alive\r\n"
8621 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
8622 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:278623 };
8624 MockRead data_reads4[] = {
8625 MockRead("HTTP/1.1 200 OK\r\n"
8626 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:508627 "Content-Length: 5\r\n"
8628 "\r\n"
8629 "hello"),
[email protected]aeefc9e82010-02-19 16:18:278630 };
8631
8632 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8633 data_writes1, arraysize(data_writes1));
8634 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8635 data_writes2, arraysize(data_writes2));
8636 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
8637 data_writes3, arraysize(data_writes3));
8638 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
8639 data_writes4, arraysize(data_writes4));
[email protected]bb88e1d32013-05-03 23:11:078640 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8641 session_deps_.socket_factory->AddSocketDataProvider(&data2);
8642 session_deps_.socket_factory->AddSocketDataProvider(&data3);
8643 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:278644
[email protected]49639fa2011-12-20 23:22:418645 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:278646
[email protected]3fe8d2f82013-10-17 08:56:078647 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0b0bf032010-09-21 18:08:508648 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418649 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:508650
[email protected]aeefc9e82010-02-19 16:18:278651 // Issue the first request with Authorize headers. There should be a
8652 // password prompt for first_realm waiting to be filled in after the
8653 // transaction completes.
[email protected]49639fa2011-12-20 23:22:418654 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]aeefc9e82010-02-19 16:18:278655 EXPECT_EQ(ERR_IO_PENDING, rv);
8656 rv = callback1.WaitForResult();
8657 EXPECT_EQ(OK, rv);
8658 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508659 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048660 const AuthChallengeInfo* challenge = response->auth_challenge.get();
8661 ASSERT_FALSE(challenge == NULL);
8662 EXPECT_FALSE(challenge->is_proxy);
bncce36dca22015-04-21 22:11:238663 EXPECT_EQ("www.example.org:80", challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:048664 EXPECT_EQ("first_realm", challenge->realm);
8665 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278666
8667 // Issue the second request with an incorrect password. There should be a
8668 // password prompt for second_realm waiting to be filled in after the
8669 // transaction completes.
[email protected]49639fa2011-12-20 23:22:418670 TestCompletionCallback callback2;
8671 rv = trans->RestartWithAuth(
8672 AuthCredentials(kFirst, kBaz), callback2.callback());
[email protected]aeefc9e82010-02-19 16:18:278673 EXPECT_EQ(ERR_IO_PENDING, rv);
8674 rv = callback2.WaitForResult();
8675 EXPECT_EQ(OK, rv);
8676 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508677 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048678 challenge = response->auth_challenge.get();
8679 ASSERT_FALSE(challenge == NULL);
8680 EXPECT_FALSE(challenge->is_proxy);
bncce36dca22015-04-21 22:11:238681 EXPECT_EQ("www.example.org:80", challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:048682 EXPECT_EQ("second_realm", challenge->realm);
8683 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278684
8685 // Issue the third request with another incorrect password. There should be
8686 // a password prompt for first_realm waiting to be filled in. If the password
8687 // prompt is not present, it indicates that the HttpAuthCacheEntry for
8688 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:418689 TestCompletionCallback callback3;
8690 rv = trans->RestartWithAuth(
8691 AuthCredentials(kSecond, kFou), callback3.callback());
[email protected]aeefc9e82010-02-19 16:18:278692 EXPECT_EQ(ERR_IO_PENDING, rv);
8693 rv = callback3.WaitForResult();
8694 EXPECT_EQ(OK, rv);
8695 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508696 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048697 challenge = response->auth_challenge.get();
8698 ASSERT_FALSE(challenge == NULL);
8699 EXPECT_FALSE(challenge->is_proxy);
bncce36dca22015-04-21 22:11:238700 EXPECT_EQ("www.example.org:80", challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:048701 EXPECT_EQ("first_realm", challenge->realm);
8702 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278703
8704 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:418705 TestCompletionCallback callback4;
8706 rv = trans->RestartWithAuth(
8707 AuthCredentials(kFirst, kBar), callback4.callback());
[email protected]aeefc9e82010-02-19 16:18:278708 EXPECT_EQ(ERR_IO_PENDING, rv);
8709 rv = callback4.WaitForResult();
8710 EXPECT_EQ(OK, rv);
8711 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508712 ASSERT_TRUE(response != NULL);
[email protected]aeefc9e82010-02-19 16:18:278713 EXPECT_TRUE(response->auth_challenge.get() == NULL);
8714}
8715
[email protected]23e482282013-06-14 16:08:028716TEST_P(HttpNetworkTransactionTest, HonorAlternateProtocolHeader) {
[email protected]d7599122014-05-24 03:37:238717 session_deps_.next_protos = SpdyNextProtos();
8718 session_deps_.use_alternate_protocols = true;
[email protected]a2cb8122010-03-10 17:22:428719
[email protected]8a0fc822013-06-27 20:52:438720 std::string alternate_protocol_http_header =
8721 GetAlternateProtocolHttpHeader();
8722
[email protected]564b4912010-03-09 16:30:428723 MockRead data_reads[] = {
8724 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438725 MockRead(alternate_protocol_http_header.c_str()),
[email protected]564b4912010-03-09 16:30:428726 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068727 MockRead(SYNCHRONOUS, OK),
[email protected]564b4912010-03-09 16:30:428728 };
8729
8730 HttpRequestInfo request;
8731 request.method = "GET";
bncce36dca22015-04-21 22:11:238732 request.url = GURL("http://www.example.org/");
[email protected]564b4912010-03-09 16:30:428733 request.load_flags = 0;
8734
8735 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
8736
[email protected]bb88e1d32013-05-03 23:11:078737 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]564b4912010-03-09 16:30:428738
[email protected]49639fa2011-12-20 23:22:418739 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:428740
[email protected]bb88e1d32013-05-03 23:11:078741 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:368742 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508743 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]564b4912010-03-09 16:30:428744
[email protected]49639fa2011-12-20 23:22:418745 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:428746 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]9e743cd2010-03-16 07:03:538747
bncce36dca22015-04-21 22:11:238748 HostPortPair http_host_port_pair("www.example.org", 80);
[email protected]9801e3702014-03-07 09:33:558749 HttpServerProperties& http_server_properties =
[email protected]17291a022011-10-10 07:32:538750 *session->http_server_properties();
bncd9b132e2015-07-08 05:16:108751 AlternativeServiceVector alternative_service_vector =
8752 http_server_properties.GetAlternativeServices(http_host_port_pair);
8753 EXPECT_TRUE(alternative_service_vector.empty());
[email protected]564b4912010-03-09 16:30:428754
8755 EXPECT_EQ(OK, callback.WaitForResult());
8756
8757 const HttpResponseInfo* response = trans->GetResponseInfo();
8758 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508759 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:428760 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:538761 EXPECT_FALSE(response->was_fetched_via_spdy);
8762 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]564b4912010-03-09 16:30:428763
8764 std::string response_data;
8765 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8766 EXPECT_EQ("hello world", response_data);
8767
bncd9b132e2015-07-08 05:16:108768 alternative_service_vector =
8769 http_server_properties.GetAlternativeServices(http_host_port_pair);
8770 ASSERT_EQ(1u, alternative_service_vector.size());
8771 EXPECT_EQ(443, alternative_service_vector[0].port);
bnc181b39a2015-03-17 21:36:478772 EXPECT_EQ(AlternateProtocolFromNextProto(GetParam()),
bncd9b132e2015-07-08 05:16:108773 alternative_service_vector[0].protocol);
[email protected]564b4912010-03-09 16:30:428774}
8775
rch89c6e102015-03-18 18:56:528776TEST_P(HttpNetworkTransactionTest, EmptyAlternateProtocolHeader) {
8777 session_deps_.next_protos = SpdyNextProtos();
8778 session_deps_.use_alternate_protocols = true;
8779
8780 MockRead data_reads[] = {
8781 MockRead("HTTP/1.1 200 OK\r\n"),
8782 MockRead("Alternate-Protocol: \r\n\r\n"),
8783 MockRead("hello world"),
8784 MockRead(SYNCHRONOUS, OK),
8785 };
8786
8787 HttpRequestInfo request;
8788 request.method = "GET";
bncce36dca22015-04-21 22:11:238789 request.url = GURL("http://www.example.org/");
rch89c6e102015-03-18 18:56:528790 request.load_flags = 0;
8791
8792 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
8793
8794 session_deps_.socket_factory->AddSocketDataProvider(&data);
8795
8796 TestCompletionCallback callback;
8797
8798 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8799
bncce36dca22015-04-21 22:11:238800 HostPortPair http_host_port_pair("www.example.org", 80);
rch89c6e102015-03-18 18:56:528801 HttpServerProperties& http_server_properties =
8802 *session->http_server_properties();
bnccacc0992015-03-20 20:22:228803 AlternativeService alternative_service(QUIC, "", 80);
bnc7dc7e1b42015-07-28 14:43:128804 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
8805 http_server_properties.SetAlternativeService(
8806 http_host_port_pair, alternative_service, 1.0, expiration);
bnccacc0992015-03-20 20:22:228807
bncd9b132e2015-07-08 05:16:108808 AlternativeServiceVector alternative_service_vector =
8809 http_server_properties.GetAlternativeServices(http_host_port_pair);
8810 ASSERT_EQ(1u, alternative_service_vector.size());
8811 EXPECT_EQ(QUIC, alternative_service_vector[0].protocol);
rch89c6e102015-03-18 18:56:528812
8813 scoped_ptr<HttpTransaction> trans(
8814 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8815
8816 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8817 EXPECT_EQ(ERR_IO_PENDING, rv);
8818
8819 EXPECT_EQ(OK, callback.WaitForResult());
8820
8821 const HttpResponseInfo* response = trans->GetResponseInfo();
8822 ASSERT_TRUE(response != NULL);
8823 ASSERT_TRUE(response->headers.get() != NULL);
8824 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8825 EXPECT_FALSE(response->was_fetched_via_spdy);
8826 EXPECT_FALSE(response->was_npn_negotiated);
8827
8828 std::string response_data;
8829 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8830 EXPECT_EQ("hello world", response_data);
8831
bncd9b132e2015-07-08 05:16:108832 alternative_service_vector =
8833 http_server_properties.GetAlternativeServices(http_host_port_pair);
8834 EXPECT_TRUE(alternative_service_vector.empty());
rch89c6e102015-03-18 18:56:528835}
8836
[email protected]23e482282013-06-14 16:08:028837TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238838 MarkBrokenAlternateProtocolAndFallback) {
[email protected]d7599122014-05-24 03:37:238839 session_deps_.use_alternate_protocols = true;
[email protected]564b4912010-03-09 16:30:428840
8841 HttpRequestInfo request;
8842 request.method = "GET";
bncce36dca22015-04-21 22:11:238843 request.url = GURL("http://www.example.org/");
[email protected]564b4912010-03-09 16:30:428844 request.load_flags = 0;
8845
[email protected]d973e99a2012-02-17 21:02:368846 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:428847 StaticSocketDataProvider first_data;
8848 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078849 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]564b4912010-03-09 16:30:428850
8851 MockRead data_reads[] = {
8852 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8853 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068854 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:428855 };
8856 StaticSocketDataProvider second_data(
8857 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078858 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:428859
[email protected]bb88e1d32013-05-03 23:11:078860 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:428861
[email protected]30d4c022013-07-18 22:58:168862 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538863 session->http_server_properties();
bnc8445b3002015-03-13 01:57:098864 const HostPortPair host_port_pair = HostPortPair::FromURL(request.url);
[email protected]3912662a32011-10-04 00:51:118865 // Port must be < 1024, or the header will be ignored (since initial port was
8866 // port 80 (another restricted port).
bncd9b132e2015-07-08 05:16:108867 const AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:238868 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bncd9b132e2015-07-08 05:16:108869 666); // Port is ignored by MockConnect anyway.
bnc7dc7e1b42015-07-28 14:43:128870 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
8871 http_server_properties->SetAlternativeService(
8872 host_port_pair, alternative_service, 1.0, expiration);
[email protected]564b4912010-03-09 16:30:428873
[email protected]262eec82013-03-19 21:01:368874 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508875 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418876 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:428877
[email protected]49639fa2011-12-20 23:22:418878 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:428879 EXPECT_EQ(ERR_IO_PENDING, rv);
8880 EXPECT_EQ(OK, callback.WaitForResult());
8881
8882 const HttpResponseInfo* response = trans->GetResponseInfo();
8883 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508884 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:428885 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8886
8887 std::string response_data;
8888 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8889 EXPECT_EQ("hello world", response_data);
8890
bncd9b132e2015-07-08 05:16:108891 const AlternativeServiceVector alternative_service_vector =
8892 http_server_properties->GetAlternativeServices(host_port_pair);
8893 ASSERT_EQ(1u, alternative_service_vector.size());
8894 EXPECT_EQ(alternative_service, alternative_service_vector[0]);
8895 EXPECT_TRUE(http_server_properties->IsAlternativeServiceBroken(
8896 alternative_service_vector[0]));
[email protected]564b4912010-03-09 16:30:428897}
8898
[email protected]23e482282013-06-14 16:08:028899TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238900 AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:118901 // Ensure that we're not allowed to redirect traffic via an alternate
8902 // protocol to an unrestricted (port >= 1024) when the original traffic was
8903 // on a restricted port (port < 1024). Ensure that we can redirect in all
8904 // other cases.
[email protected]d7599122014-05-24 03:37:238905 session_deps_.use_alternate_protocols = true;
[email protected]3912662a32011-10-04 00:51:118906
8907 HttpRequestInfo restricted_port_request;
8908 restricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:238909 restricted_port_request.url = GURL("http://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:118910 restricted_port_request.load_flags = 0;
8911
[email protected]d973e99a2012-02-17 21:02:368912 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118913 StaticSocketDataProvider first_data;
8914 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078915 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118916
8917 MockRead data_reads[] = {
8918 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8919 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068920 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118921 };
8922 StaticSocketDataProvider second_data(
8923 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078924 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118925
[email protected]bb88e1d32013-05-03 23:11:078926 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118927
[email protected]30d4c022013-07-18 22:58:168928 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538929 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118930 const int kUnrestrictedAlternatePort = 1024;
bnccacc0992015-03-20 20:22:228931 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:238932 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:228933 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:128934 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:228935 http_server_properties->SetAlternativeService(
8936 HostPortPair::FromURL(restricted_port_request.url), alternative_service,
bnc7dc7e1b42015-07-28 14:43:128937 1.0, expiration);
[email protected]3912662a32011-10-04 00:51:118938
[email protected]262eec82013-03-19 21:01:368939 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508940 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418941 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118942
[email protected]49639fa2011-12-20 23:22:418943 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:368944 &restricted_port_request,
8945 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118946 EXPECT_EQ(ERR_IO_PENDING, rv);
8947 // Invalid change to unrestricted port should fail.
8948 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.WaitForResult());
[email protected]c54c6962013-02-01 04:53:198949}
[email protected]3912662a32011-10-04 00:51:118950
[email protected]23e482282013-06-14 16:08:028951TEST_P(HttpNetworkTransactionTest,
[email protected]c54c6962013-02-01 04:53:198952 AlternateProtocolPortRestrictedPermitted) {
8953 // Ensure that we're allowed to redirect traffic via an alternate
8954 // protocol to an unrestricted (port >= 1024) when the original traffic was
8955 // on a restricted port (port < 1024) if we set
8956 // enable_user_alternate_protocol_ports.
8957
[email protected]d7599122014-05-24 03:37:238958 session_deps_.use_alternate_protocols = true;
[email protected]bb88e1d32013-05-03 23:11:078959 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:198960
8961 HttpRequestInfo restricted_port_request;
8962 restricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:238963 restricted_port_request.url = GURL("http://www.example.org:1023/");
[email protected]c54c6962013-02-01 04:53:198964 restricted_port_request.load_flags = 0;
8965
8966 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
8967 StaticSocketDataProvider first_data;
8968 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078969 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:198970
8971 MockRead data_reads[] = {
8972 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8973 MockRead("hello world"),
8974 MockRead(ASYNC, OK),
8975 };
8976 StaticSocketDataProvider second_data(
8977 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078978 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]c54c6962013-02-01 04:53:198979
[email protected]bb88e1d32013-05-03 23:11:078980 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:198981
[email protected]30d4c022013-07-18 22:58:168982 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]c54c6962013-02-01 04:53:198983 session->http_server_properties();
8984 const int kUnrestrictedAlternatePort = 1024;
bnccacc0992015-03-20 20:22:228985 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:238986 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:228987 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:128988 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:228989 http_server_properties->SetAlternativeService(
8990 HostPortPair::FromURL(restricted_port_request.url), alternative_service,
bnc7dc7e1b42015-07-28 14:43:128991 1.0, expiration);
[email protected]c54c6962013-02-01 04:53:198992
[email protected]262eec82013-03-19 21:01:368993 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508994 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]c54c6962013-02-01 04:53:198995 TestCompletionCallback callback;
8996
8997 EXPECT_EQ(ERR_IO_PENDING, trans->Start(
[email protected]262eec82013-03-19 21:01:368998 &restricted_port_request,
8999 callback.callback(), BoundNetLog()));
[email protected]c54c6962013-02-01 04:53:199000 // Change to unrestricted port should succeed.
9001 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:119002}
9003
[email protected]23e482282013-06-14 16:08:029004TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239005 AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:119006 // Ensure that we're not allowed to redirect traffic via an alternate
9007 // protocol to an unrestricted (port >= 1024) when the original traffic was
9008 // on a restricted port (port < 1024). Ensure that we can redirect in all
9009 // other cases.
[email protected]d7599122014-05-24 03:37:239010 session_deps_.use_alternate_protocols = true;
[email protected]3912662a32011-10-04 00:51:119011
9012 HttpRequestInfo restricted_port_request;
9013 restricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:239014 restricted_port_request.url = GURL("http://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:119015 restricted_port_request.load_flags = 0;
9016
[email protected]d973e99a2012-02-17 21:02:369017 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:119018 StaticSocketDataProvider first_data;
9019 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079020 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:119021
9022 MockRead data_reads[] = {
9023 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9024 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069025 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:119026 };
9027 StaticSocketDataProvider second_data(
9028 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079029 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:119030
[email protected]bb88e1d32013-05-03 23:11:079031 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:119032
[email protected]30d4c022013-07-18 22:58:169033 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:539034 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:119035 const int kRestrictedAlternatePort = 80;
bnccacc0992015-03-20 20:22:229036 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239037 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229038 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:129039 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:229040 http_server_properties->SetAlternativeService(
9041 HostPortPair::FromURL(restricted_port_request.url), alternative_service,
bnc7dc7e1b42015-07-28 14:43:129042 1.0, expiration);
[email protected]3912662a32011-10-04 00:51:119043
[email protected]262eec82013-03-19 21:01:369044 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509045 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419046 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:119047
[email protected]49639fa2011-12-20 23:22:419048 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:369049 &restricted_port_request,
9050 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:119051 EXPECT_EQ(ERR_IO_PENDING, rv);
9052 // Valid change to restricted port should pass.
9053 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:119054}
9055
[email protected]23e482282013-06-14 16:08:029056TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239057 AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:119058 // Ensure that we're not allowed to redirect traffic via an alternate
9059 // protocol to an unrestricted (port >= 1024) when the original traffic was
9060 // on a restricted port (port < 1024). Ensure that we can redirect in all
9061 // other cases.
[email protected]d7599122014-05-24 03:37:239062 session_deps_.use_alternate_protocols = true;
[email protected]3912662a32011-10-04 00:51:119063
9064 HttpRequestInfo unrestricted_port_request;
9065 unrestricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:239066 unrestricted_port_request.url = GURL("http://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:119067 unrestricted_port_request.load_flags = 0;
9068
[email protected]d973e99a2012-02-17 21:02:369069 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:119070 StaticSocketDataProvider first_data;
9071 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079072 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:119073
9074 MockRead data_reads[] = {
9075 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9076 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069077 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:119078 };
9079 StaticSocketDataProvider second_data(
9080 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079081 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:119082
[email protected]bb88e1d32013-05-03 23:11:079083 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:119084
[email protected]30d4c022013-07-18 22:58:169085 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:539086 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:119087 const int kRestrictedAlternatePort = 80;
bnccacc0992015-03-20 20:22:229088 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239089 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229090 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:129091 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:229092 http_server_properties->SetAlternativeService(
9093 HostPortPair::FromURL(unrestricted_port_request.url), alternative_service,
bnc7dc7e1b42015-07-28 14:43:129094 1.0, expiration);
[email protected]3912662a32011-10-04 00:51:119095
[email protected]262eec82013-03-19 21:01:369096 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509097 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419098 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:119099
[email protected]49639fa2011-12-20 23:22:419100 int rv = trans->Start(
9101 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:119102 EXPECT_EQ(ERR_IO_PENDING, rv);
9103 // Valid change to restricted port should pass.
9104 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:119105}
9106
[email protected]23e482282013-06-14 16:08:029107TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239108 AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:119109 // Ensure that we're not allowed to redirect traffic via an alternate
9110 // protocol to an unrestricted (port >= 1024) when the original traffic was
9111 // on a restricted port (port < 1024). Ensure that we can redirect in all
9112 // other cases.
[email protected]d7599122014-05-24 03:37:239113 session_deps_.use_alternate_protocols = true;
[email protected]3912662a32011-10-04 00:51:119114
9115 HttpRequestInfo unrestricted_port_request;
9116 unrestricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:239117 unrestricted_port_request.url = GURL("http://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:119118 unrestricted_port_request.load_flags = 0;
9119
[email protected]d973e99a2012-02-17 21:02:369120 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:119121 StaticSocketDataProvider first_data;
9122 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079123 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:119124
9125 MockRead data_reads[] = {
9126 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9127 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069128 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:119129 };
9130 StaticSocketDataProvider second_data(
9131 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079132 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:119133
[email protected]bb88e1d32013-05-03 23:11:079134 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:119135
[email protected]30d4c022013-07-18 22:58:169136 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:539137 session->http_server_properties();
bnc0bbb02622015-07-23 10:06:229138 const int kUnrestrictedAlternatePort = 1025;
bnccacc0992015-03-20 20:22:229139 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239140 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229141 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:129142 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:229143 http_server_properties->SetAlternativeService(
9144 HostPortPair::FromURL(unrestricted_port_request.url), alternative_service,
bnc7dc7e1b42015-07-28 14:43:129145 1.0, expiration);
[email protected]3912662a32011-10-04 00:51:119146
[email protected]262eec82013-03-19 21:01:369147 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509148 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419149 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:119150
[email protected]49639fa2011-12-20 23:22:419151 int rv = trans->Start(
9152 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:119153 EXPECT_EQ(ERR_IO_PENDING, rv);
9154 // Valid change to an unrestricted port should pass.
9155 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:119156}
9157
[email protected]d7599122014-05-24 03:37:239158TEST_P(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:029159 // Ensure that we're not allowed to redirect traffic via an alternate
9160 // protocol to an unsafe port, and that we resume the second
9161 // HttpStreamFactoryImpl::Job once the alternate protocol request fails.
[email protected]d7599122014-05-24 03:37:239162 session_deps_.use_alternate_protocols = true;
[email protected]eb6234e2012-01-19 01:50:029163
9164 HttpRequestInfo request;
9165 request.method = "GET";
bncce36dca22015-04-21 22:11:239166 request.url = GURL("http://www.example.org/");
[email protected]eb6234e2012-01-19 01:50:029167 request.load_flags = 0;
9168
9169 // The alternate protocol request will error out before we attempt to connect,
9170 // so only the standard HTTP request will try to connect.
9171 MockRead data_reads[] = {
9172 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9173 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069174 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:029175 };
9176 StaticSocketDataProvider data(
9177 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079178 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:029179
[email protected]bb88e1d32013-05-03 23:11:079180 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:029181
[email protected]30d4c022013-07-18 22:58:169182 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]eb6234e2012-01-19 01:50:029183 session->http_server_properties();
9184 const int kUnsafePort = 7;
bnccacc0992015-03-20 20:22:229185 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239186 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229187 kUnsafePort);
bnc7dc7e1b42015-07-28 14:43:129188 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:229189 http_server_properties->SetAlternativeService(
bnc7dc7e1b42015-07-28 14:43:129190 HostPortPair::FromURL(request.url), alternative_service, 1.0, expiration);
[email protected]eb6234e2012-01-19 01:50:029191
[email protected]262eec82013-03-19 21:01:369192 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509193 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]eb6234e2012-01-19 01:50:029194 TestCompletionCallback callback;
9195
9196 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9197 EXPECT_EQ(ERR_IO_PENDING, rv);
9198 // The HTTP request should succeed.
9199 EXPECT_EQ(OK, callback.WaitForResult());
9200
9201 // Disable alternate protocol before the asserts.
[email protected]d7599122014-05-24 03:37:239202 // HttpStreamFactory::set_use_alternate_protocols(false);
[email protected]eb6234e2012-01-19 01:50:029203
9204 const HttpResponseInfo* response = trans->GetResponseInfo();
9205 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509206 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]eb6234e2012-01-19 01:50:029207 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9208
9209 std::string response_data;
9210 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9211 EXPECT_EQ("hello world", response_data);
9212}
9213
[email protected]23e482282013-06-14 16:08:029214TEST_P(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]d7599122014-05-24 03:37:239215 session_deps_.use_alternate_protocols = true;
9216 session_deps_.next_protos = SpdyNextProtos();
[email protected]2ff8b312010-04-26 22:20:549217
9218 HttpRequestInfo request;
9219 request.method = "GET";
bncce36dca22015-04-21 22:11:239220 request.url = GURL("http://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:549221 request.load_flags = 0;
9222
[email protected]8a0fc822013-06-27 20:52:439223 std::string alternate_protocol_http_header =
9224 GetAlternateProtocolHttpHeader();
9225
[email protected]2ff8b312010-04-26 22:20:549226 MockRead data_reads[] = {
9227 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439228 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2ff8b312010-04-26 22:20:549229 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:179230 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
9231 MockRead(ASYNC, OK)
[email protected]2ff8b312010-04-26 22:20:549232 };
9233
9234 StaticSocketDataProvider first_transaction(
9235 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079236 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:549237
[email protected]8ddf8322012-02-23 18:08:069238 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029239 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:239240 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
9241 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:079242 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:549243
[email protected]cdf8f7e72013-05-23 10:56:469244 scoped_ptr<SpdyFrame> req(
9245 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
rch8e6c6c42015-05-01 14:05:139246 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]2ff8b312010-04-26 22:20:549247
[email protected]23e482282013-06-14 16:08:029248 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9249 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:549250 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:139251 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:549252 };
9253
rch8e6c6c42015-05-01 14:05:139254 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9255 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079256 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:549257
[email protected]d973e99a2012-02-17 21:02:369258 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559259 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
9260 NULL, 0, NULL, 0);
9261 hanging_non_alternate_protocol_socket.set_connect_data(
9262 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:079263 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:559264 &hanging_non_alternate_protocol_socket);
9265
[email protected]49639fa2011-12-20 23:22:419266 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:549267
[email protected]bb88e1d32013-05-03 23:11:079268 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369269 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509270 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:549271
[email protected]49639fa2011-12-20 23:22:419272 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:549273 EXPECT_EQ(ERR_IO_PENDING, rv);
9274 EXPECT_EQ(OK, callback.WaitForResult());
9275
9276 const HttpResponseInfo* response = trans->GetResponseInfo();
9277 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509278 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:549279 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9280
9281 std::string response_data;
9282 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9283 EXPECT_EQ("hello world", response_data);
9284
[email protected]90499482013-06-01 00:39:509285 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:549286
[email protected]49639fa2011-12-20 23:22:419287 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:549288 EXPECT_EQ(ERR_IO_PENDING, rv);
9289 EXPECT_EQ(OK, callback.WaitForResult());
9290
9291 response = trans->GetResponseInfo();
9292 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509293 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:549294 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539295 EXPECT_TRUE(response->was_fetched_via_spdy);
9296 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:549297
9298 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9299 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:549300}
9301
[email protected]23e482282013-06-14 16:08:029302TEST_P(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]d7599122014-05-24 03:37:239303 session_deps_.use_alternate_protocols = true;
9304 session_deps_.next_protos = SpdyNextProtos();
[email protected]2d6728692011-03-12 01:39:559305
9306 HttpRequestInfo request;
9307 request.method = "GET";
bncce36dca22015-04-21 22:11:239308 request.url = GURL("http://www.example.org/");
[email protected]2d6728692011-03-12 01:39:559309 request.load_flags = 0;
9310
[email protected]8a0fc822013-06-27 20:52:439311 std::string alternate_protocol_http_header =
9312 GetAlternateProtocolHttpHeader();
9313
[email protected]2d6728692011-03-12 01:39:559314 MockRead data_reads[] = {
9315 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439316 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2d6728692011-03-12 01:39:559317 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:179318 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:069319 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:559320 };
9321
9322 StaticSocketDataProvider first_transaction(
9323 data_reads, arraysize(data_reads), NULL, 0);
9324 // Socket 1 is the HTTP transaction with the Alternate-Protocol header.
[email protected]bb88e1d32013-05-03 23:11:079325 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:559326
[email protected]d973e99a2012-02-17 21:02:369327 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559328 StaticSocketDataProvider hanging_socket(
9329 NULL, 0, NULL, 0);
9330 hanging_socket.set_connect_data(never_finishing_connect);
9331 // Socket 2 and 3 are the hanging Alternate-Protocol and
9332 // non-Alternate-Protocol jobs from the 2nd transaction.
[email protected]bb88e1d32013-05-03 23:11:079333 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
9334 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
[email protected]2d6728692011-03-12 01:39:559335
[email protected]8ddf8322012-02-23 18:08:069336 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029337 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:239338 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
9339 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:079340 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:559341
[email protected]cdf8f7e72013-05-23 10:56:469342 scoped_ptr<SpdyFrame> req1(
9343 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
9344 scoped_ptr<SpdyFrame> req2(
9345 spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
[email protected]2d6728692011-03-12 01:39:559346 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:139347 CreateMockWrite(*req1, 0), CreateMockWrite(*req2, 1),
[email protected]2d6728692011-03-12 01:39:559348 };
[email protected]23e482282013-06-14 16:08:029349 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9350 scoped_ptr<SpdyFrame> data1(spdy_util_.ConstructSpdyBodyFrame(1, true));
9351 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
9352 scoped_ptr<SpdyFrame> data2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]2d6728692011-03-12 01:39:559353 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:139354 CreateMockRead(*resp1, 2),
9355 CreateMockRead(*data1, 3),
9356 CreateMockRead(*resp2, 4),
9357 CreateMockRead(*data2, 5),
9358 MockRead(ASYNC, 0, 6),
[email protected]2d6728692011-03-12 01:39:559359 };
9360
rch8e6c6c42015-05-01 14:05:139361 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9362 arraysize(spdy_writes));
[email protected]2d6728692011-03-12 01:39:559363 // Socket 4 is the successful Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:079364 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:559365
9366 // Socket 5 is the unsuccessful non-Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:079367 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
[email protected]2d6728692011-03-12 01:39:559368
[email protected]bb88e1d32013-05-03 23:11:079369 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:419370 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:509371 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:559372
[email protected]49639fa2011-12-20 23:22:419373 int rv = trans1.Start(&request, callback1.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559374 EXPECT_EQ(ERR_IO_PENDING, rv);
9375 EXPECT_EQ(OK, callback1.WaitForResult());
9376
9377 const HttpResponseInfo* response = trans1.GetResponseInfo();
9378 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509379 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559380 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9381
9382 std::string response_data;
9383 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
9384 EXPECT_EQ("hello world", response_data);
9385
[email protected]49639fa2011-12-20 23:22:419386 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:509387 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:419388 rv = trans2.Start(&request, callback2.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559389 EXPECT_EQ(ERR_IO_PENDING, rv);
9390
[email protected]49639fa2011-12-20 23:22:419391 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:509392 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:419393 rv = trans3.Start(&request, callback3.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559394 EXPECT_EQ(ERR_IO_PENDING, rv);
9395
9396 EXPECT_EQ(OK, callback2.WaitForResult());
9397 EXPECT_EQ(OK, callback3.WaitForResult());
9398
9399 response = trans2.GetResponseInfo();
9400 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509401 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559402 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9403 EXPECT_TRUE(response->was_fetched_via_spdy);
9404 EXPECT_TRUE(response->was_npn_negotiated);
9405 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
9406 EXPECT_EQ("hello!", response_data);
9407
9408 response = trans3.GetResponseInfo();
9409 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509410 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559411 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9412 EXPECT_TRUE(response->was_fetched_via_spdy);
9413 EXPECT_TRUE(response->was_npn_negotiated);
9414 ASSERT_EQ(OK, ReadTransaction(&trans3, &response_data));
9415 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:559416}
9417
[email protected]23e482282013-06-14 16:08:029418TEST_P(HttpNetworkTransactionTest, StallAlternateProtocolForNpnSpdy) {
[email protected]d7599122014-05-24 03:37:239419 session_deps_.use_alternate_protocols = true;
9420 session_deps_.next_protos = SpdyNextProtos();
[email protected]2d6728692011-03-12 01:39:559421
9422 HttpRequestInfo request;
9423 request.method = "GET";
bncce36dca22015-04-21 22:11:239424 request.url = GURL("http://www.example.org/");
[email protected]2d6728692011-03-12 01:39:559425 request.load_flags = 0;
9426
[email protected]8a0fc822013-06-27 20:52:439427 std::string alternate_protocol_http_header =
9428 GetAlternateProtocolHttpHeader();
9429
[email protected]2d6728692011-03-12 01:39:559430 MockRead data_reads[] = {
9431 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439432 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2d6728692011-03-12 01:39:559433 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:179434 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:069435 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:559436 };
9437
9438 StaticSocketDataProvider first_transaction(
9439 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079440 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:559441
[email protected]8ddf8322012-02-23 18:08:069442 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029443 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:079444 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:559445
[email protected]d973e99a2012-02-17 21:02:369446 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559447 StaticSocketDataProvider hanging_alternate_protocol_socket(
9448 NULL, 0, NULL, 0);
9449 hanging_alternate_protocol_socket.set_connect_data(
9450 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:079451 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:559452 &hanging_alternate_protocol_socket);
9453
9454 // 2nd request is just a copy of the first one, over HTTP again.
[email protected]bb88e1d32013-05-03 23:11:079455 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:559456
[email protected]49639fa2011-12-20 23:22:419457 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:559458
[email protected]bb88e1d32013-05-03 23:11:079459 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369460 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509461 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:559462
[email protected]49639fa2011-12-20 23:22:419463 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559464 EXPECT_EQ(ERR_IO_PENDING, rv);
9465 EXPECT_EQ(OK, callback.WaitForResult());
9466
9467 const HttpResponseInfo* response = trans->GetResponseInfo();
9468 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509469 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559470 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9471
9472 std::string response_data;
9473 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9474 EXPECT_EQ("hello world", response_data);
9475
[email protected]90499482013-06-01 00:39:509476 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:559477
[email protected]49639fa2011-12-20 23:22:419478 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559479 EXPECT_EQ(ERR_IO_PENDING, rv);
9480 EXPECT_EQ(OK, callback.WaitForResult());
9481
9482 response = trans->GetResponseInfo();
9483 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509484 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559485 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9486 EXPECT_FALSE(response->was_fetched_via_spdy);
9487 EXPECT_FALSE(response->was_npn_negotiated);
9488
9489 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9490 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:559491}
9492
[email protected]631f1322010-04-30 17:59:119493class CapturingProxyResolver : public ProxyResolver {
9494 public:
sammce90c9212015-05-27 23:43:359495 CapturingProxyResolver() {}
dchengb03027d2014-10-21 12:00:209496 ~CapturingProxyResolver() override {}
[email protected]631f1322010-04-30 17:59:119497
dchengb03027d2014-10-21 12:00:209498 int GetProxyForURL(const GURL& url,
9499 ProxyInfo* results,
9500 const CompletionCallback& callback,
9501 RequestHandle* request,
9502 const BoundNetLog& net_log) override {
[email protected]fae7669f2010-08-02 21:49:409503 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
9504 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:429505 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:119506 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:429507 return OK;
[email protected]631f1322010-04-30 17:59:119508 }
9509
dchengb03027d2014-10-21 12:00:209510 void CancelRequest(RequestHandle request) override { NOTREACHED(); }
[email protected]631f1322010-04-30 17:59:119511
dchengb03027d2014-10-21 12:00:209512 LoadState GetLoadState(RequestHandle request) const override {
[email protected]f2c971f2011-11-08 00:33:179513 NOTREACHED();
9514 return LOAD_STATE_IDLE;
9515 }
9516
[email protected]24476402010-07-20 20:55:179517 const std::vector<GURL>& resolved() const { return resolved_; }
9518
9519 private:
[email protected]631f1322010-04-30 17:59:119520 std::vector<GURL> resolved_;
9521
9522 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
9523};
9524
sammce64b2362015-04-29 03:50:239525class CapturingProxyResolverFactory : public ProxyResolverFactory {
9526 public:
9527 explicit CapturingProxyResolverFactory(CapturingProxyResolver* resolver)
9528 : ProxyResolverFactory(false), resolver_(resolver) {}
9529
9530 int CreateProxyResolver(
9531 const scoped_refptr<ProxyResolverScriptData>& pac_script,
9532 scoped_ptr<ProxyResolver>* resolver,
9533 const net::CompletionCallback& callback,
9534 scoped_ptr<Request>* request) override {
9535 resolver->reset(new ForwardingProxyResolver(resolver_));
9536 return OK;
9537 }
9538
9539 private:
9540 ProxyResolver* resolver_;
9541};
9542
[email protected]23e482282013-06-14 16:08:029543TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239544 UseAlternateProtocolForTunneledNpnSpdy) {
[email protected]d7599122014-05-24 03:37:239545 session_deps_.use_alternate_protocols = true;
9546 session_deps_.next_protos = SpdyNextProtos();
[email protected]631f1322010-04-30 17:59:119547
9548 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:429549 proxy_config.set_auto_detect(true);
9550 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:119551
sammc5dd160c2015-04-02 02:43:139552 CapturingProxyResolver capturing_proxy_resolver;
[email protected]bb88e1d32013-05-03 23:11:079553 session_deps_.proxy_service.reset(new ProxyService(
sammc5dd160c2015-04-02 02:43:139554 new ProxyConfigServiceFixed(proxy_config),
9555 make_scoped_ptr(
sammce64b2362015-04-29 03:50:239556 new CapturingProxyResolverFactory(&capturing_proxy_resolver)),
[email protected]66761b952010-06-25 21:30:389557 NULL));
vishal.b62985ca92015-04-17 08:45:519558 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079559 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:119560
9561 HttpRequestInfo request;
9562 request.method = "GET";
bncce36dca22015-04-21 22:11:239563 request.url = GURL("http://www.example.org/");
[email protected]631f1322010-04-30 17:59:119564 request.load_flags = 0;
9565
[email protected]8a0fc822013-06-27 20:52:439566 std::string alternate_protocol_http_header =
9567 GetAlternateProtocolHttpHeader();
9568
[email protected]631f1322010-04-30 17:59:119569 MockRead data_reads[] = {
9570 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439571 MockRead(alternate_protocol_http_header.c_str()),
[email protected]631f1322010-04-30 17:59:119572 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:179573 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:069574 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:119575 };
9576
9577 StaticSocketDataProvider first_transaction(
9578 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079579 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]631f1322010-04-30 17:59:119580
[email protected]8ddf8322012-02-23 18:08:069581 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029582 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:239583 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
9584 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:079585 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]631f1322010-04-30 17:59:119586
[email protected]cdf8f7e72013-05-23 10:56:469587 scoped_ptr<SpdyFrame> req(
9588 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]631f1322010-04-30 17:59:119589 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:139590 MockWrite(ASYNC, 0,
9591 "CONNECT www.example.org:443 HTTP/1.1\r\n"
9592 "Host: www.example.org\r\n"
9593 "Proxy-Connection: keep-alive\r\n\r\n"),
9594 CreateMockWrite(*req, 2),
[email protected]631f1322010-04-30 17:59:119595 };
9596
[email protected]d911f1b2010-05-05 22:39:429597 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
9598
[email protected]23e482282013-06-14 16:08:029599 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9600 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]631f1322010-04-30 17:59:119601 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:139602 MockRead(ASYNC, 1, kCONNECTResponse),
9603 CreateMockRead(*resp.get(), 3),
9604 CreateMockRead(*data.get(), 4),
9605 MockRead(ASYNC, ERR_IO_PENDING, 5),
[email protected]631f1322010-04-30 17:59:119606 };
9607
rch8e6c6c42015-05-01 14:05:139608 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9609 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079610 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:119611
[email protected]d973e99a2012-02-17 21:02:369612 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559613 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
9614 NULL, 0, NULL, 0);
9615 hanging_non_alternate_protocol_socket.set_connect_data(
9616 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:079617 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:559618 &hanging_non_alternate_protocol_socket);
9619
[email protected]49639fa2011-12-20 23:22:419620 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:119621
[email protected]bb88e1d32013-05-03 23:11:079622 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369623 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509624 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:119625
[email protected]49639fa2011-12-20 23:22:419626 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:119627 EXPECT_EQ(ERR_IO_PENDING, rv);
9628 EXPECT_EQ(OK, callback.WaitForResult());
9629
9630 const HttpResponseInfo* response = trans->GetResponseInfo();
9631 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509632 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]631f1322010-04-30 17:59:119633 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539634 EXPECT_FALSE(response->was_fetched_via_spdy);
9635 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:119636
9637 std::string response_data;
9638 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9639 EXPECT_EQ("hello world", response_data);
9640
[email protected]90499482013-06-01 00:39:509641 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:119642
[email protected]49639fa2011-12-20 23:22:419643 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:119644 EXPECT_EQ(ERR_IO_PENDING, rv);
9645 EXPECT_EQ(OK, callback.WaitForResult());
9646
9647 response = trans->GetResponseInfo();
9648 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509649 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]631f1322010-04-30 17:59:119650 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539651 EXPECT_TRUE(response->was_fetched_via_spdy);
9652 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:119653
9654 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9655 EXPECT_EQ("hello!", response_data);
sammc5dd160c2015-04-02 02:43:139656 ASSERT_EQ(3u, capturing_proxy_resolver.resolved().size());
bncce36dca22015-04-21 22:11:239657 EXPECT_EQ("http://www.example.org/",
sammc5dd160c2015-04-02 02:43:139658 capturing_proxy_resolver.resolved()[0].spec());
bncce36dca22015-04-21 22:11:239659 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:139660 capturing_proxy_resolver.resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:119661
[email protected]029c83b62013-01-24 05:28:209662 LoadTimingInfo load_timing_info;
9663 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
9664 TestLoadTimingNotReusedWithPac(load_timing_info,
9665 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:119666}
[email protected]631f1322010-04-30 17:59:119667
[email protected]23e482282013-06-14 16:08:029668TEST_P(HttpNetworkTransactionTest,
[email protected]2ff8b312010-04-26 22:20:549669 UseAlternateProtocolForNpnSpdyWithExistingSpdySession) {
[email protected]d7599122014-05-24 03:37:239670 session_deps_.use_alternate_protocols = true;
9671 session_deps_.next_protos = SpdyNextProtos();
[email protected]2ff8b312010-04-26 22:20:549672
9673 HttpRequestInfo request;
9674 request.method = "GET";
bncce36dca22015-04-21 22:11:239675 request.url = GURL("http://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:549676 request.load_flags = 0;
9677
[email protected]8a0fc822013-06-27 20:52:439678 std::string alternate_protocol_http_header =
9679 GetAlternateProtocolHttpHeader();
9680
[email protected]2ff8b312010-04-26 22:20:549681 MockRead data_reads[] = {
9682 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439683 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2ff8b312010-04-26 22:20:549684 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069685 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:549686 };
9687
9688 StaticSocketDataProvider first_transaction(
9689 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079690 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:549691
[email protected]8ddf8322012-02-23 18:08:069692 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029693 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:239694 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
9695 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:079696 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:549697
[email protected]cdf8f7e72013-05-23 10:56:469698 scoped_ptr<SpdyFrame> req(
9699 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
rch8e6c6c42015-05-01 14:05:139700 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]2ff8b312010-04-26 22:20:549701
[email protected]23e482282013-06-14 16:08:029702 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9703 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:549704 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:139705 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:549706 };
9707
rch8e6c6c42015-05-01 14:05:139708 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9709 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079710 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:549711
[email protected]83039bb2011-12-09 18:43:559712 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:549713
[email protected]bb88e1d32013-05-03 23:11:079714 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:549715
[email protected]262eec82013-03-19 21:01:369716 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509717 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:549718
[email protected]49639fa2011-12-20 23:22:419719 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:549720 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:419721 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:549722
9723 const HttpResponseInfo* response = trans->GetResponseInfo();
9724 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509725 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:549726 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9727
9728 std::string response_data;
9729 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9730 EXPECT_EQ("hello world", response_data);
9731
9732 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:239733 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:409734 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:539735 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:279736 base::WeakPtr<SpdySession> spdy_session =
[email protected]41d64e82013-07-03 22:44:269737 CreateSecureSpdySession(session, key, BoundNetLog());
[email protected]02b0c342010-09-25 21:09:389738
[email protected]90499482013-06-01 00:39:509739 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:549740
[email protected]49639fa2011-12-20 23:22:419741 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:549742 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:419743 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:549744
9745 response = trans->GetResponseInfo();
9746 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509747 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:549748 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539749 EXPECT_TRUE(response->was_fetched_via_spdy);
9750 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:549751
9752 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9753 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:429754}
9755
[email protected]044de0642010-06-17 10:42:159756// GenerateAuthToken is a mighty big test.
9757// It tests all permutation of GenerateAuthToken behavior:
9758// - Synchronous and Asynchronous completion.
9759// - OK or error on completion.
9760// - Direct connection, non-authenticating proxy, and authenticating proxy.
9761// - HTTP or HTTPS backend (to include proxy tunneling).
9762// - Non-authenticating and authenticating backend.
9763//
[email protected]fe3b7dc2012-02-03 19:52:099764// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:159765// problems generating an auth token for an authenticating proxy, we don't
9766// need to test all permutations of the backend server).
9767//
9768// The test proceeds by going over each of the configuration cases, and
9769// potentially running up to three rounds in each of the tests. The TestConfig
9770// specifies both the configuration for the test as well as the expectations
9771// for the results.
[email protected]23e482282013-06-14 16:08:029772TEST_P(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:509773 static const char kServer[] = "http://www.example.com";
9774 static const char kSecureServer[] = "https://www.example.com";
9775 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:159776 const int kAuthErr = ERR_INVALID_AUTH_CREDENTIALS;
9777
9778 enum AuthTiming {
9779 AUTH_NONE,
9780 AUTH_SYNC,
9781 AUTH_ASYNC,
9782 };
9783
9784 const MockWrite kGet(
9785 "GET / HTTP/1.1\r\n"
9786 "Host: www.example.com\r\n"
9787 "Connection: keep-alive\r\n\r\n");
9788 const MockWrite kGetProxy(
9789 "GET http://www.example.com/ HTTP/1.1\r\n"
9790 "Host: www.example.com\r\n"
9791 "Proxy-Connection: keep-alive\r\n\r\n");
9792 const MockWrite kGetAuth(
9793 "GET / HTTP/1.1\r\n"
9794 "Host: www.example.com\r\n"
9795 "Connection: keep-alive\r\n"
9796 "Authorization: auth_token\r\n\r\n");
9797 const MockWrite kGetProxyAuth(
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\r\n");
9802 const MockWrite kGetAuthThroughProxy(
9803 "GET http://www.example.com/ HTTP/1.1\r\n"
9804 "Host: www.example.com\r\n"
9805 "Proxy-Connection: keep-alive\r\n"
9806 "Authorization: auth_token\r\n\r\n");
9807 const MockWrite kGetAuthWithProxyAuth(
9808 "GET http://www.example.com/ 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"
9812 "Authorization: auth_token\r\n\r\n");
9813 const MockWrite kConnect(
9814 "CONNECT www.example.com:443 HTTP/1.1\r\n"
9815 "Host: www.example.com\r\n"
9816 "Proxy-Connection: keep-alive\r\n\r\n");
9817 const MockWrite kConnectProxyAuth(
9818 "CONNECT www.example.com:443 HTTP/1.1\r\n"
9819 "Host: www.example.com\r\n"
9820 "Proxy-Connection: keep-alive\r\n"
9821 "Proxy-Authorization: auth_token\r\n\r\n");
9822
9823 const MockRead kSuccess(
9824 "HTTP/1.1 200 OK\r\n"
9825 "Content-Type: text/html; charset=iso-8859-1\r\n"
9826 "Content-Length: 3\r\n\r\n"
9827 "Yes");
9828 const MockRead kFailure(
9829 "Should not be called.");
9830 const MockRead kServerChallenge(
9831 "HTTP/1.1 401 Unauthorized\r\n"
9832 "WWW-Authenticate: Mock realm=server\r\n"
9833 "Content-Type: text/html; charset=iso-8859-1\r\n"
9834 "Content-Length: 14\r\n\r\n"
9835 "Unauthorized\r\n");
9836 const MockRead kProxyChallenge(
9837 "HTTP/1.1 407 Unauthorized\r\n"
9838 "Proxy-Authenticate: Mock realm=proxy\r\n"
9839 "Proxy-Connection: close\r\n"
9840 "Content-Type: text/html; charset=iso-8859-1\r\n"
9841 "Content-Length: 14\r\n\r\n"
9842 "Unauthorized\r\n");
9843 const MockRead kProxyConnected(
9844 "HTTP/1.1 200 Connection Established\r\n\r\n");
9845
9846 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
9847 // no constructors, but the C++ compiler on Windows warns about
9848 // unspecified data in compound literals. So, moved to using constructors,
9849 // and TestRound's created with the default constructor should not be used.
9850 struct TestRound {
9851 TestRound()
9852 : expected_rv(ERR_UNEXPECTED),
9853 extra_write(NULL),
9854 extra_read(NULL) {
9855 }
9856 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
9857 int expected_rv_arg)
9858 : write(write_arg),
9859 read(read_arg),
9860 expected_rv(expected_rv_arg),
9861 extra_write(NULL),
9862 extra_read(NULL) {
9863 }
9864 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
9865 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:019866 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:159867 : write(write_arg),
9868 read(read_arg),
9869 expected_rv(expected_rv_arg),
9870 extra_write(extra_write_arg),
9871 extra_read(extra_read_arg) {
9872 }
9873 MockWrite write;
9874 MockRead read;
9875 int expected_rv;
9876 const MockWrite* extra_write;
9877 const MockRead* extra_read;
9878 };
9879
9880 static const int kNoSSL = 500;
9881
9882 struct TestConfig {
thestig9d3bb0c2015-01-24 00:49:519883 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:159884 AuthTiming proxy_auth_timing;
9885 int proxy_auth_rv;
thestig9d3bb0c2015-01-24 00:49:519886 const char* const server_url;
[email protected]044de0642010-06-17 10:42:159887 AuthTiming server_auth_timing;
9888 int server_auth_rv;
9889 int num_auth_rounds;
9890 int first_ssl_round;
9891 TestRound rounds[3];
9892 } test_configs[] = {
9893 // Non-authenticating HTTP server with a direct connection.
9894 { NULL, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
9895 { TestRound(kGet, kSuccess, OK)}},
9896 // Authenticating HTTP server with a direct connection.
9897 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
9898 { TestRound(kGet, kServerChallenge, OK),
9899 TestRound(kGetAuth, kSuccess, OK)}},
9900 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
9901 { TestRound(kGet, kServerChallenge, OK),
9902 TestRound(kGetAuth, kFailure, kAuthErr)}},
9903 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
9904 { TestRound(kGet, kServerChallenge, OK),
9905 TestRound(kGetAuth, kSuccess, OK)}},
9906 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
9907 { TestRound(kGet, kServerChallenge, OK),
9908 TestRound(kGetAuth, kFailure, kAuthErr)}},
9909 // Non-authenticating HTTP server through a non-authenticating proxy.
9910 { kProxy, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
9911 { TestRound(kGetProxy, kSuccess, OK)}},
9912 // Authenticating HTTP server through a non-authenticating proxy.
9913 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
9914 { TestRound(kGetProxy, kServerChallenge, OK),
9915 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
9916 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
9917 { TestRound(kGetProxy, kServerChallenge, OK),
9918 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
9919 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
9920 { TestRound(kGetProxy, kServerChallenge, OK),
9921 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
9922 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
9923 { TestRound(kGetProxy, kServerChallenge, OK),
9924 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
9925 // Non-authenticating HTTP server through an authenticating proxy.
9926 { kProxy, AUTH_SYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
9927 { TestRound(kGetProxy, kProxyChallenge, OK),
9928 TestRound(kGetProxyAuth, kSuccess, OK)}},
9929 { kProxy, AUTH_SYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
9930 { TestRound(kGetProxy, kProxyChallenge, OK),
9931 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
9932 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
9933 { TestRound(kGetProxy, kProxyChallenge, OK),
9934 TestRound(kGetProxyAuth, kSuccess, OK)}},
9935 { kProxy, AUTH_ASYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
9936 { TestRound(kGetProxy, kProxyChallenge, OK),
9937 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
9938 // Authenticating HTTP server through an authenticating proxy.
9939 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
9940 { TestRound(kGetProxy, kProxyChallenge, OK),
9941 TestRound(kGetProxyAuth, kServerChallenge, OK),
9942 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9943 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
9944 { TestRound(kGetProxy, kProxyChallenge, OK),
9945 TestRound(kGetProxyAuth, kServerChallenge, OK),
9946 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9947 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
9948 { TestRound(kGetProxy, kProxyChallenge, OK),
9949 TestRound(kGetProxyAuth, kServerChallenge, OK),
9950 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9951 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
9952 { TestRound(kGetProxy, kProxyChallenge, OK),
9953 TestRound(kGetProxyAuth, kServerChallenge, OK),
9954 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9955 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
9956 { TestRound(kGetProxy, kProxyChallenge, OK),
9957 TestRound(kGetProxyAuth, kServerChallenge, OK),
9958 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9959 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
9960 { TestRound(kGetProxy, kProxyChallenge, OK),
9961 TestRound(kGetProxyAuth, kServerChallenge, OK),
9962 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9963 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
9964 { TestRound(kGetProxy, kProxyChallenge, OK),
9965 TestRound(kGetProxyAuth, kServerChallenge, OK),
9966 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9967 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
9968 { TestRound(kGetProxy, kProxyChallenge, OK),
9969 TestRound(kGetProxyAuth, kServerChallenge, OK),
9970 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9971 // Non-authenticating HTTPS server with a direct connection.
9972 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
9973 { TestRound(kGet, kSuccess, OK)}},
9974 // Authenticating HTTPS server with a direct connection.
9975 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
9976 { TestRound(kGet, kServerChallenge, OK),
9977 TestRound(kGetAuth, kSuccess, OK)}},
9978 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
9979 { TestRound(kGet, kServerChallenge, OK),
9980 TestRound(kGetAuth, kFailure, kAuthErr)}},
9981 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
9982 { TestRound(kGet, kServerChallenge, OK),
9983 TestRound(kGetAuth, kSuccess, OK)}},
9984 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
9985 { TestRound(kGet, kServerChallenge, OK),
9986 TestRound(kGetAuth, kFailure, kAuthErr)}},
9987 // Non-authenticating HTTPS server with a non-authenticating proxy.
9988 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
9989 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
9990 // Authenticating HTTPS server through a non-authenticating proxy.
9991 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
9992 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9993 TestRound(kGetAuth, kSuccess, OK)}},
9994 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
9995 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9996 TestRound(kGetAuth, kFailure, kAuthErr)}},
9997 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
9998 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9999 TestRound(kGetAuth, kSuccess, OK)}},
10000 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
10001 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
10002 TestRound(kGetAuth, kFailure, kAuthErr)}},
10003 // Non-Authenticating HTTPS server through an authenticating proxy.
10004 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
10005 { TestRound(kConnect, kProxyChallenge, OK),
10006 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
10007 { kProxy, AUTH_SYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
10008 { TestRound(kConnect, kProxyChallenge, OK),
10009 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
10010 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
10011 { TestRound(kConnect, kProxyChallenge, OK),
10012 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
10013 { kProxy, AUTH_ASYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
10014 { TestRound(kConnect, kProxyChallenge, OK),
10015 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
10016 // Authenticating HTTPS server through an authenticating proxy.
10017 { kProxy, AUTH_SYNC, 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_SYNC, 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_ASYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
10028 { TestRound(kConnect, kProxyChallenge, OK),
10029 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10030 &kGet, &kServerChallenge),
10031 TestRound(kGetAuth, kSuccess, OK)}},
10032 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
10033 { TestRound(kConnect, kProxyChallenge, OK),
10034 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10035 &kGet, &kServerChallenge),
10036 TestRound(kGetAuth, kFailure, kAuthErr)}},
10037 { kProxy, AUTH_SYNC, 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_SYNC, 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 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
10048 { TestRound(kConnect, kProxyChallenge, OK),
10049 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10050 &kGet, &kServerChallenge),
10051 TestRound(kGetAuth, kSuccess, OK)}},
10052 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
10053 { TestRound(kConnect, kProxyChallenge, OK),
10054 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10055 &kGet, &kServerChallenge),
10056 TestRound(kGetAuth, kFailure, kAuthErr)}},
10057 };
10058
viettrungluue4a8b882014-10-16 06:17:3810059 for (size_t i = 0; i < arraysize(test_configs); ++i) {
[email protected]2d01c262011-08-11 23:07:0810060 HttpAuthHandlerMock::Factory* auth_factory(
10061 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0710062 session_deps_.http_auth_handler_factory.reset(auth_factory);
[email protected]044de0642010-06-17 10:42:1510063 const TestConfig& test_config = test_configs[i];
[email protected]65d34382010-07-01 18:12:2610064
10065 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:1510066 if (test_config.proxy_auth_timing != AUTH_NONE) {
[email protected]2d01c262011-08-11 23:07:0810067 for (int n = 0; n < 2; n++) {
10068 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
10069 std::string auth_challenge = "Mock realm=proxy";
10070 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:2410071 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
10072 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:0810073 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
10074 origin, BoundNetLog());
10075 auth_handler->SetGenerateExpectation(
10076 test_config.proxy_auth_timing == AUTH_ASYNC,
10077 test_config.proxy_auth_rv);
10078 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
10079 }
[email protected]044de0642010-06-17 10:42:1510080 }
10081 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:0010082 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:1510083 std::string auth_challenge = "Mock realm=server";
10084 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:2410085 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
10086 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:1510087 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
10088 origin, BoundNetLog());
10089 auth_handler->SetGenerateExpectation(
10090 test_config.server_auth_timing == AUTH_ASYNC,
10091 test_config.server_auth_rv);
[email protected]2d01c262011-08-11 23:07:0810092 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:1510093 }
10094 if (test_config.proxy_url) {
[email protected]bb88e1d32013-05-03 23:11:0710095 session_deps_.proxy_service.reset(
[email protected]6104ea5d2011-04-27 21:37:1210096 ProxyService::CreateFixed(test_config.proxy_url));
[email protected]044de0642010-06-17 10:42:1510097 } else {
[email protected]bb88e1d32013-05-03 23:11:0710098 session_deps_.proxy_service.reset(ProxyService::CreateDirect());
[email protected]044de0642010-06-17 10:42:1510099 }
10100
10101 HttpRequestInfo request;
10102 request.method = "GET";
10103 request.url = GURL(test_config.server_url);
10104 request.load_flags = 0;
10105
[email protected]bb88e1d32013-05-03 23:11:0710106 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
dcheng48459ac22014-08-26 00:46:4110107 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]044de0642010-06-17 10:42:1510108
rchcb68dc62015-05-21 04:45:3610109 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
10110
10111 std::vector<std::vector<MockRead>> mock_reads(1);
10112 std::vector<std::vector<MockWrite>> mock_writes(1);
[email protected]044de0642010-06-17 10:42:1510113 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
10114 const TestRound& read_write_round = test_config.rounds[round];
10115
10116 // Set up expected reads and writes.
rchcb68dc62015-05-21 04:45:3610117 mock_reads.back().push_back(read_write_round.read);
10118 mock_writes.back().push_back(read_write_round.write);
10119
10120 // kProxyChallenge uses Proxy-Connection: close which means that the
10121 // socket is closed and a new one will be created for the next request.
10122 if (read_write_round.read.data == kProxyChallenge.data &&
10123 read_write_round.write.data != kConnect.data) {
10124 mock_reads.push_back(std::vector<MockRead>());
10125 mock_writes.push_back(std::vector<MockWrite>());
[email protected]044de0642010-06-17 10:42:1510126 }
10127
rchcb68dc62015-05-21 04:45:3610128 if (read_write_round.extra_read) {
10129 mock_reads.back().push_back(*read_write_round.extra_read);
[email protected]044de0642010-06-17 10:42:1510130 }
rchcb68dc62015-05-21 04:45:3610131 if (read_write_round.extra_write) {
10132 mock_writes.back().push_back(*read_write_round.extra_write);
10133 }
[email protected]044de0642010-06-17 10:42:1510134
10135 // Add an SSL sequence if necessary.
[email protected]044de0642010-06-17 10:42:1510136 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0710137 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1510138 &ssl_socket_data_provider);
rchcb68dc62015-05-21 04:45:3610139 }
[email protected]044de0642010-06-17 10:42:1510140
rchcb68dc62015-05-21 04:45:3610141 ScopedVector<StaticSocketDataProvider> data_providers;
10142 for (size_t i = 0; i < mock_reads.size(); ++i) {
10143 data_providers.push_back(new StaticSocketDataProvider(
10144 vector_as_array(&mock_reads[i]), mock_reads[i].size(),
10145 vector_as_array(&mock_writes[i]), mock_writes[i].size()));
10146 session_deps_.socket_factory->AddSocketDataProvider(
10147 data_providers.back());
10148 }
10149
10150 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
10151 const TestRound& read_write_round = test_config.rounds[round];
[email protected]044de0642010-06-17 10:42:1510152 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4110153 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1510154 int rv;
10155 if (round == 0) {
[email protected]49639fa2011-12-20 23:22:4110156 rv = trans.Start(&request, callback.callback(), BoundNetLog());
[email protected]044de0642010-06-17 10:42:1510157 } else {
[email protected]49639fa2011-12-20 23:22:4110158 rv = trans.RestartWithAuth(
10159 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1510160 }
10161 if (rv == ERR_IO_PENDING)
10162 rv = callback.WaitForResult();
10163
10164 // Compare results with expected data.
10165 EXPECT_EQ(read_write_round.expected_rv, rv);
[email protected]0b0bf032010-09-21 18:08:5010166 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttlec0c828492015-05-15 01:25:5510167 if (read_write_round.expected_rv != OK) {
[email protected]044de0642010-06-17 10:42:1510168 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
10169 continue;
10170 }
10171 if (round + 1 < test_config.num_auth_rounds) {
10172 EXPECT_FALSE(response->auth_challenge.get() == NULL);
10173 } else {
10174 EXPECT_TRUE(response->auth_challenge.get() == NULL);
10175 }
10176 }
[email protected]e5ae96a2010-04-14 20:12:4510177 }
10178}
10179
[email protected]23e482282013-06-14 16:08:0210180TEST_P(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1410181 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1410182 HttpAuthHandlerMock::Factory* auth_factory(
10183 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0710184 session_deps_.http_auth_handler_factory.reset(auth_factory);
10185 session_deps_.proxy_service.reset(ProxyService::CreateDirect());
10186 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
10187 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:1410188
10189 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
10190 auth_handler->set_connection_based(true);
10191 std::string auth_challenge = "Mock realm=server";
10192 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2410193 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
10194 auth_challenge.end());
[email protected]c871bce92010-07-15 21:51:1410195 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
10196 origin, BoundNetLog());
[email protected]2d01c262011-08-11 23:07:0810197 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1410198
[email protected]c871bce92010-07-15 21:51:1410199 int rv = OK;
10200 const HttpResponseInfo* response = NULL;
10201 HttpRequestInfo request;
10202 request.method = "GET";
10203 request.url = origin;
10204 request.load_flags = 0;
[email protected]cb9bf6ca2011-01-28 13:15:2710205
[email protected]bb88e1d32013-05-03 23:11:0710206 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1010207
10208 // Use a TCP Socket Pool with only one connection per group. This is used
10209 // to validate that the TCP socket is not released to the pool between
10210 // each round of multi-round authentication.
10211 HttpNetworkSessionPeer session_peer(session);
[email protected]ab739042011-04-07 15:22:2810212 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:1010213 50, // Max sockets for pool
10214 1, // Max sockets per group
[email protected]bb88e1d32013-05-03 23:11:0710215 session_deps_.host_resolver.get(),
10216 session_deps_.socket_factory.get(),
10217 session_deps_.net_log);
[email protected]831e4a32013-11-14 02:14:4410218 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
10219 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:0210220 mock_pool_manager->SetTransportSocketPool(transport_pool);
dchenge3d1ddc2014-10-15 19:30:5110221 session_peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]7ef4cbbb2011-02-06 11:19:1010222
[email protected]262eec82013-03-19 21:01:3610223 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010224 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110225 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1410226
10227 const MockWrite kGet(
10228 "GET / HTTP/1.1\r\n"
10229 "Host: www.example.com\r\n"
10230 "Connection: keep-alive\r\n\r\n");
10231 const MockWrite kGetAuth(
10232 "GET / HTTP/1.1\r\n"
10233 "Host: www.example.com\r\n"
10234 "Connection: keep-alive\r\n"
10235 "Authorization: auth_token\r\n\r\n");
10236
10237 const MockRead kServerChallenge(
10238 "HTTP/1.1 401 Unauthorized\r\n"
10239 "WWW-Authenticate: Mock realm=server\r\n"
10240 "Content-Type: text/html; charset=iso-8859-1\r\n"
10241 "Content-Length: 14\r\n\r\n"
10242 "Unauthorized\r\n");
10243 const MockRead kSuccess(
10244 "HTTP/1.1 200 OK\r\n"
10245 "Content-Type: text/html; charset=iso-8859-1\r\n"
10246 "Content-Length: 3\r\n\r\n"
10247 "Yes");
10248
10249 MockWrite writes[] = {
10250 // First round
10251 kGet,
10252 // Second round
10253 kGetAuth,
10254 // Third round
10255 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3010256 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1010257 kGetAuth,
10258 // Competing request
10259 kGet,
[email protected]c871bce92010-07-15 21:51:1410260 };
10261 MockRead reads[] = {
10262 // First round
10263 kServerChallenge,
10264 // Second round
10265 kServerChallenge,
10266 // Third round
[email protected]eca50e122010-09-11 14:03:3010267 kServerChallenge,
10268 // Fourth round
[email protected]c871bce92010-07-15 21:51:1410269 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1010270 // Competing response
10271 kSuccess,
[email protected]c871bce92010-07-15 21:51:1410272 };
10273 StaticSocketDataProvider data_provider(reads, arraysize(reads),
10274 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:0710275 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1410276
thestig9d3bb0c2015-01-24 00:49:5110277 const char kSocketGroup[] = "www.example.com:80";
[email protected]7ef4cbbb2011-02-06 11:19:1010278
10279 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1410280 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4110281 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]c871bce92010-07-15 21:51:1410282 if (rv == ERR_IO_PENDING)
10283 rv = callback.WaitForResult();
10284 EXPECT_EQ(OK, rv);
10285 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010286 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:1410287 EXPECT_FALSE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2810288 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1410289
[email protected]7ef4cbbb2011-02-06 11:19:1010290 // In between rounds, another request comes in for the same domain.
10291 // It should not be able to grab the TCP socket that trans has already
10292 // claimed.
10293 scoped_ptr<HttpTransaction> trans_compete(
[email protected]90499482013-06-01 00:39:5010294 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110295 TestCompletionCallback callback_compete;
10296 rv = trans_compete->Start(
10297 &request, callback_compete.callback(), BoundNetLog());
[email protected]7ef4cbbb2011-02-06 11:19:1010298 EXPECT_EQ(ERR_IO_PENDING, rv);
10299 // callback_compete.WaitForResult at this point would stall forever,
10300 // since the HttpNetworkTransaction does not release the request back to
10301 // the pool until after authentication completes.
10302
10303 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1410304 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4110305 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1410306 if (rv == ERR_IO_PENDING)
10307 rv = callback.WaitForResult();
10308 EXPECT_EQ(OK, rv);
10309 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010310 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:1410311 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2810312 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1410313
[email protected]7ef4cbbb2011-02-06 11:19:1010314 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1410315 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4110316 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1410317 if (rv == ERR_IO_PENDING)
10318 rv = callback.WaitForResult();
10319 EXPECT_EQ(OK, rv);
10320 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010321 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:1410322 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2810323 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]eca50e122010-09-11 14:03:3010324
[email protected]7ef4cbbb2011-02-06 11:19:1010325 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3010326 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4110327 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3010328 if (rv == ERR_IO_PENDING)
10329 rv = callback.WaitForResult();
10330 EXPECT_EQ(OK, rv);
10331 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010332 ASSERT_TRUE(response != NULL);
[email protected]eca50e122010-09-11 14:03:3010333 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2810334 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1010335
10336 // Read the body since the fourth round was successful. This will also
10337 // release the socket back to the pool.
10338 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
[email protected]90499482013-06-01 00:39:5010339 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1010340 if (rv == ERR_IO_PENDING)
10341 rv = callback.WaitForResult();
10342 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:5010343 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1010344 EXPECT_EQ(0, rv);
10345 // There are still 0 idle sockets, since the trans_compete transaction
10346 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:2810347 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1010348
10349 // The competing request can now finish. Wait for the headers and then
10350 // read the body.
10351 rv = callback_compete.WaitForResult();
10352 EXPECT_EQ(OK, rv);
[email protected]90499482013-06-01 00:39:5010353 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1010354 if (rv == ERR_IO_PENDING)
10355 rv = callback.WaitForResult();
10356 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:5010357 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1010358 EXPECT_EQ(0, rv);
10359
10360 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:2810361 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1410362}
10363
[email protected]65041fa2010-05-21 06:56:5310364// This tests the case that a request is issued via http instead of spdy after
10365// npn is negotiated.
[email protected]23e482282013-06-14 16:08:0210366TEST_P(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]d7599122014-05-24 03:37:2310367 session_deps_.use_alternate_protocols = true;
10368 NextProtoVector next_protos;
[email protected]0ce3af82013-07-22 16:17:1610369 next_protos.push_back(kProtoHTTP11);
[email protected]d7599122014-05-24 03:37:2310370 session_deps_.next_protos = next_protos;
10371
[email protected]65041fa2010-05-21 06:56:5310372 HttpRequestInfo request;
10373 request.method = "GET";
bncce36dca22015-04-21 22:11:2310374 request.url = GURL("https://www.example.org/");
[email protected]65041fa2010-05-21 06:56:5310375 request.load_flags = 0;
10376
10377 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310378 MockWrite(
10379 "GET / HTTP/1.1\r\n"
10380 "Host: www.example.org\r\n"
10381 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5310382 };
10383
[email protected]8a0fc822013-06-27 20:52:4310384 std::string alternate_protocol_http_header =
10385 GetAlternateProtocolHttpHeader();
10386
[email protected]65041fa2010-05-21 06:56:5310387 MockRead data_reads[] = {
10388 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:4310389 MockRead(alternate_protocol_http_header.c_str()),
[email protected]65041fa2010-05-21 06:56:5310390 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610391 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5310392 };
10393
[email protected]8ddf8322012-02-23 18:08:0610394 SSLSocketDataProvider ssl(ASYNC, OK);
davidben6974bf72015-04-27 17:52:4810395 ssl.SetNextProto(kProtoHTTP11);
[email protected]65041fa2010-05-21 06:56:5310396
[email protected]bb88e1d32013-05-03 23:11:0710397 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5310398
10399 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
10400 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0710401 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5310402
[email protected]49639fa2011-12-20 23:22:4110403 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5310404
[email protected]bb88e1d32013-05-03 23:11:0710405 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610406 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010407 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]65041fa2010-05-21 06:56:5310408
[email protected]49639fa2011-12-20 23:22:4110409 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]65041fa2010-05-21 06:56:5310410
10411 EXPECT_EQ(ERR_IO_PENDING, rv);
10412 EXPECT_EQ(OK, callback.WaitForResult());
10413
10414 const HttpResponseInfo* response = trans->GetResponseInfo();
10415 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010416 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]65041fa2010-05-21 06:56:5310417 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10418
10419 std::string response_data;
10420 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10421 EXPECT_EQ("hello world", response_data);
10422
10423 EXPECT_FALSE(response->was_fetched_via_spdy);
10424 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]65041fa2010-05-21 06:56:5310425}
[email protected]26ef6582010-06-24 02:30:4710426
[email protected]23e482282013-06-14 16:08:0210427TEST_P(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:4710428 // Simulate the SSL handshake completing with an NPN negotiation
10429 // followed by an immediate server closing of the socket.
10430 // Fix crash: http://crbug.com/46369
[email protected]d7599122014-05-24 03:37:2310431 session_deps_.use_alternate_protocols = true;
10432 session_deps_.next_protos = SpdyNextProtos();
[email protected]26ef6582010-06-24 02:30:4710433
10434 HttpRequestInfo request;
10435 request.method = "GET";
bncce36dca22015-04-21 22:11:2310436 request.url = GURL("https://www.example.org/");
[email protected]26ef6582010-06-24 02:30:4710437 request.load_flags = 0;
10438
[email protected]8ddf8322012-02-23 18:08:0610439 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210440 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710441 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4710442
[email protected]cdf8f7e72013-05-23 10:56:4610443 scoped_ptr<SpdyFrame> req(
10444 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
rch8e6c6c42015-05-01 14:05:1310445 MockWrite spdy_writes[] = {CreateMockWrite(*req, 1)};
[email protected]26ef6582010-06-24 02:30:4710446
10447 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0610448 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4710449 };
10450
rch8e6c6c42015-05-01 14:05:1310451 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10452 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710453 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4710454
[email protected]49639fa2011-12-20 23:22:4110455 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4710456
[email protected]bb88e1d32013-05-03 23:11:0710457 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610458 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010459 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]26ef6582010-06-24 02:30:4710460
[email protected]49639fa2011-12-20 23:22:4110461 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]26ef6582010-06-24 02:30:4710462 EXPECT_EQ(ERR_IO_PENDING, rv);
10463 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult());
[email protected]26ef6582010-06-24 02:30:4710464}
[email protected]65d34382010-07-01 18:12:2610465
[email protected]795cbf82013-07-22 09:37:2710466// A subclass of HttpAuthHandlerMock that records the request URL when
10467// it gets it. This is needed since the auth handler may get destroyed
10468// before we get a chance to query it.
10469class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
10470 public:
10471 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
10472
dchengb03027d2014-10-21 12:00:2010473 ~UrlRecordingHttpAuthHandlerMock() override {}
[email protected]795cbf82013-07-22 09:37:2710474
10475 protected:
dchengb03027d2014-10-21 12:00:2010476 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
10477 const HttpRequestInfo* request,
10478 const CompletionCallback& callback,
10479 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2710480 *url_ = request->url;
10481 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
10482 credentials, request, callback, auth_token);
10483 }
10484
10485 private:
10486 GURL* url_;
10487};
10488
[email protected]23e482282013-06-14 16:08:0210489TEST_P(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) {
[email protected]f45c1ee2010-08-03 00:54:3010490 // This test ensures that the URL passed into the proxy is upgraded
10491 // to https when doing an Alternate Protocol upgrade.
[email protected]d7599122014-05-24 03:37:2310492 session_deps_.use_alternate_protocols = true;
10493 session_deps_.next_protos = SpdyNextProtos();
[email protected]f45c1ee2010-08-03 00:54:3010494
[email protected]bb88e1d32013-05-03 23:11:0710495 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:2010496 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
vishal.b62985ca92015-04-17 08:45:5110497 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710498 session_deps_.net_log = &net_log;
[email protected]795cbf82013-07-22 09:37:2710499 GURL request_url;
10500 {
10501 HttpAuthHandlerMock::Factory* auth_factory =
10502 new HttpAuthHandlerMock::Factory();
10503 UrlRecordingHttpAuthHandlerMock* auth_handler =
10504 new UrlRecordingHttpAuthHandlerMock(&request_url);
10505 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
10506 auth_factory->set_do_init_from_challenge(true);
10507 session_deps_.http_auth_handler_factory.reset(auth_factory);
10508 }
[email protected]f45c1ee2010-08-03 00:54:3010509
10510 HttpRequestInfo request;
10511 request.method = "GET";
bncce36dca22015-04-21 22:11:2310512 request.url = GURL("http://www.example.org");
[email protected]f45c1ee2010-08-03 00:54:3010513 request.load_flags = 0;
10514
10515 // First round goes unauthenticated through the proxy.
10516 MockWrite data_writes_1[] = {
bncce36dca22015-04-21 22:11:2310517 MockWrite(
10518 "GET http://www.example.org/ HTTP/1.1\r\n"
10519 "Host: www.example.org\r\n"
10520 "Proxy-Connection: keep-alive\r\n"
10521 "\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3010522 };
10523 MockRead data_reads_1[] = {
[email protected]8ddf8322012-02-23 18:08:0610524 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
bnc33b8cef42014-11-19 17:30:3810525 MockRead("HTTP/1.1 200 OK\r\n"),
10526 MockRead("Alternate-Protocol: 443:"),
10527 MockRead(GetAlternateProtocolFromParam()),
10528 MockRead("\r\n"),
10529 MockRead("Proxy-Connection: close\r\n"),
10530 MockRead("\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3010531 };
10532 StaticSocketDataProvider data_1(data_reads_1, arraysize(data_reads_1),
10533 data_writes_1, arraysize(data_writes_1));
10534
bncce36dca22015-04-21 22:11:2310535 // Second round tries to tunnel to www.example.org due to the
[email protected]f45c1ee2010-08-03 00:54:3010536 // Alternate-Protocol announcement in the first round. It fails due
10537 // to a proxy authentication challenge.
bncce36dca22015-04-21 22:11:2310538 // After the failure, a tunnel is established to www.example.org using
[email protected]394816e92010-08-03 07:38:5910539 // Proxy-Authorization headers. There is then a SPDY request round.
10540 //
[email protected]fe3b7dc2012-02-03 19:52:0910541 // NOTE: Despite the "Proxy-Connection: Close", these are done on the
10542 // same MockTCPClientSocket since the underlying HttpNetworkClientSocket
10543 // does a Disconnect and Connect on the same socket, rather than trying
10544 // to obtain a new one.
10545 //
[email protected]394816e92010-08-03 07:38:5910546 // NOTE: Originally, the proxy response to the second CONNECT request
10547 // simply returned another 407 so the unit test could skip the SSL connection
10548 // establishment and SPDY framing issues. Alas, the
10549 // retry-http-when-alternate-protocol fails logic kicks in, which was more
[email protected]f45c1ee2010-08-03 00:54:3010550 // complicated to set up expectations for than the SPDY session.
[email protected]394816e92010-08-03 07:38:5910551
[email protected]cdf8f7e72013-05-23 10:56:4610552 scoped_ptr<SpdyFrame> req(
10553 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]23e482282013-06-14 16:08:0210554 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10555 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]f45c1ee2010-08-03 00:54:3010556
[email protected]394816e92010-08-03 07:38:5910557 MockWrite data_writes_2[] = {
bncce36dca22015-04-21 22:11:2310558 // First connection attempt without Proxy-Authorization.
rch8e6c6c42015-05-01 14:05:1310559 MockWrite(ASYNC, 0,
10560 "CONNECT www.example.org:443 HTTP/1.1\r\n"
10561 "Host: www.example.org\r\n"
10562 "Proxy-Connection: keep-alive\r\n"
10563 "\r\n"),
[email protected]394816e92010-08-03 07:38:5910564
bncce36dca22015-04-21 22:11:2310565 // Second connection attempt with Proxy-Authorization.
rch8e6c6c42015-05-01 14:05:1310566 MockWrite(ASYNC, 2,
10567 "CONNECT www.example.org:443 HTTP/1.1\r\n"
10568 "Host: www.example.org\r\n"
10569 "Proxy-Connection: keep-alive\r\n"
10570 "Proxy-Authorization: auth_token\r\n"
10571 "\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3010572
bncce36dca22015-04-21 22:11:2310573 // SPDY request
rch8e6c6c42015-05-01 14:05:1310574 CreateMockWrite(*req, 4),
[email protected]f45c1ee2010-08-03 00:54:3010575 };
[email protected]394816e92010-08-03 07:38:5910576 const char kRejectConnectResponse[] = ("HTTP/1.1 407 Unauthorized\r\n"
10577 "Proxy-Authenticate: Mock\r\n"
10578 "Proxy-Connection: close\r\n"
10579 "\r\n");
10580 const char kAcceptConnectResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
10581 MockRead data_reads_2[] = {
rch8e6c6c42015-05-01 14:05:1310582 // First connection attempt fails
10583 MockRead(ASYNC, kRejectConnectResponse,
10584 arraysize(kRejectConnectResponse) - 1, 1),
[email protected]394816e92010-08-03 07:38:5910585
rch8e6c6c42015-05-01 14:05:1310586 // Second connection attempt passes
10587 MockRead(ASYNC, kAcceptConnectResponse,
10588 arraysize(kAcceptConnectResponse) - 1, 3),
[email protected]394816e92010-08-03 07:38:5910589
rch8e6c6c42015-05-01 14:05:1310590 // SPDY response
10591 CreateMockRead(*resp.get(), 5),
10592 CreateMockRead(*data.get(), 6),
10593 MockRead(ASYNC, 0, 0, 7),
[email protected]394816e92010-08-03 07:38:5910594 };
rch8e6c6c42015-05-01 14:05:1310595 SequencedSocketData data_2(data_reads_2, arraysize(data_reads_2),
10596 data_writes_2, arraysize(data_writes_2));
[email protected]f45c1ee2010-08-03 00:54:3010597
[email protected]8ddf8322012-02-23 18:08:0610598 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210599 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:2310600 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
10601 ASSERT_TRUE(ssl.cert.get());
[email protected]f45c1ee2010-08-03 00:54:3010602
[email protected]d973e99a2012-02-17 21:02:3610603 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5510604 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
10605 NULL, 0, NULL, 0);
10606 hanging_non_alternate_protocol_socket.set_connect_data(
10607 never_finishing_connect);
10608
[email protected]bb88e1d32013-05-03 23:11:0710609 session_deps_.socket_factory->AddSocketDataProvider(&data_1);
10610 session_deps_.socket_factory->AddSocketDataProvider(&data_2);
10611 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10612 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5510613 &hanging_non_alternate_protocol_socket);
[email protected]bb88e1d32013-05-03 23:11:0710614 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f45c1ee2010-08-03 00:54:3010615
10616 // First round should work and provide the Alternate-Protocol state.
[email protected]49639fa2011-12-20 23:22:4110617 TestCompletionCallback callback_1;
[email protected]262eec82013-03-19 21:01:3610618 scoped_ptr<HttpTransaction> trans_1(
[email protected]90499482013-06-01 00:39:5010619 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110620 int rv = trans_1->Start(&request, callback_1.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:3010621 EXPECT_EQ(ERR_IO_PENDING, rv);
10622 EXPECT_EQ(OK, callback_1.WaitForResult());
10623
10624 // Second round should attempt a tunnel connect and get an auth challenge.
[email protected]49639fa2011-12-20 23:22:4110625 TestCompletionCallback callback_2;
[email protected]262eec82013-03-19 21:01:3610626 scoped_ptr<HttpTransaction> trans_2(
[email protected]90499482013-06-01 00:39:5010627 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110628 rv = trans_2->Start(&request, callback_2.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:3010629 EXPECT_EQ(ERR_IO_PENDING, rv);
10630 EXPECT_EQ(OK, callback_2.WaitForResult());
10631 const HttpResponseInfo* response = trans_2->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010632 ASSERT_TRUE(response != NULL);
[email protected]f45c1ee2010-08-03 00:54:3010633 ASSERT_FALSE(response->auth_challenge.get() == NULL);
10634
10635 // Restart with auth. Tunnel should work and response received.
[email protected]49639fa2011-12-20 23:22:4110636 TestCompletionCallback callback_3;
10637 rv = trans_2->RestartWithAuth(
10638 AuthCredentials(kFoo, kBar), callback_3.callback());
[email protected]f45c1ee2010-08-03 00:54:3010639 EXPECT_EQ(ERR_IO_PENDING, rv);
10640 EXPECT_EQ(OK, callback_3.WaitForResult());
10641
10642 // After all that work, these two lines (or actually, just the scheme) are
10643 // what this test is all about. Make sure it happens correctly.
[email protected]f45c1ee2010-08-03 00:54:3010644 EXPECT_EQ("https", request_url.scheme());
bncce36dca22015-04-21 22:11:2310645 EXPECT_EQ("www.example.org", request_url.host());
[email protected]f45c1ee2010-08-03 00:54:3010646
[email protected]029c83b62013-01-24 05:28:2010647 LoadTimingInfo load_timing_info;
10648 EXPECT_TRUE(trans_2->GetLoadTimingInfo(&load_timing_info));
10649 TestLoadTimingNotReusedWithPac(load_timing_info,
10650 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]8e6441ca2010-08-19 05:56:3810651}
10652
10653// Test that if we cancel the transaction as the connection is completing, that
10654// everything tears down correctly.
[email protected]23e482282013-06-14 16:08:0210655TEST_P(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3810656 // Setup everything about the connection to complete synchronously, so that
10657 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
10658 // for is the callback from the HttpStreamRequest.
10659 // Then cancel the transaction.
10660 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3610661 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3810662 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0610663 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
10664 MockRead(SYNCHRONOUS, "hello world"),
10665 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3810666 };
10667
[email protected]8e6441ca2010-08-19 05:56:3810668 HttpRequestInfo request;
10669 request.method = "GET";
bncce36dca22015-04-21 22:11:2310670 request.url = GURL("http://www.example.org/");
[email protected]8e6441ca2010-08-19 05:56:3810671 request.load_flags = 0;
10672
[email protected]bb88e1d32013-05-03 23:11:0710673 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]3fe8d2f82013-10-17 08:56:0710674 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:2710675 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4110676 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:2710677
[email protected]8e6441ca2010-08-19 05:56:3810678 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10679 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710680 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3810681
[email protected]49639fa2011-12-20 23:22:4110682 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3810683
vishal.b62985ca92015-04-17 08:45:5110684 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4110685 int rv = trans->Start(&request, callback.callback(), log.bound());
[email protected]8e6441ca2010-08-19 05:56:3810686 EXPECT_EQ(ERR_IO_PENDING, rv);
10687 trans.reset(); // Cancel the transaction here.
10688
[email protected]2da659e2013-05-23 20:51:3410689 base::MessageLoop::current()->RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3010690}
10691
[email protected]ecab6e052014-05-16 14:58:1210692// Test that if a transaction is cancelled after receiving the headers, the
10693// stream is drained properly and added back to the socket pool. The main
10694// purpose of this test is to make sure that an HttpStreamParser can be read
10695// from after the HttpNetworkTransaction and the objects it owns have been
10696// deleted.
10697// See http://crbug.com/368418
10698TEST_P(HttpNetworkTransactionTest, CancelAfterHeaders) {
10699 MockRead data_reads[] = {
10700 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
10701 MockRead(ASYNC, "Content-Length: 2\r\n"),
10702 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
10703 MockRead(ASYNC, "1"),
10704 // 2 async reads are necessary to trigger a ReadResponseBody call after the
10705 // HttpNetworkTransaction has been deleted.
10706 MockRead(ASYNC, "2"),
10707 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
10708 };
10709 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10710 session_deps_.socket_factory->AddSocketDataProvider(&data);
10711
10712 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10713
10714 {
10715 HttpRequestInfo request;
10716 request.method = "GET";
bncce36dca22015-04-21 22:11:2310717 request.url = GURL("http://www.example.org/");
[email protected]ecab6e052014-05-16 14:58:1210718 request.load_flags = 0;
10719
dcheng48459ac22014-08-26 00:46:4110720 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1210721 TestCompletionCallback callback;
10722
10723 int rv = trans.Start(&request, callback.callback(), BoundNetLog());
10724 EXPECT_EQ(ERR_IO_PENDING, rv);
10725 callback.WaitForResult();
10726
10727 const HttpResponseInfo* response = trans.GetResponseInfo();
10728 ASSERT_TRUE(response != NULL);
10729 EXPECT_TRUE(response->headers.get() != NULL);
10730 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10731
10732 // The transaction and HttpRequestInfo are deleted.
10733 }
10734
10735 // Let the HttpResponseBodyDrainer drain the socket.
10736 base::MessageLoop::current()->RunUntilIdle();
10737
10738 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4110739 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1210740}
10741
[email protected]76a505b2010-08-25 06:23:0010742// Test a basic GET request through a proxy.
[email protected]23e482282013-06-14 16:08:0210743TEST_P(HttpNetworkTransactionTest, ProxyGet) {
[email protected]bb88e1d32013-05-03 23:11:0710744 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:2010745 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
vishal.b62985ca92015-04-17 08:45:5110746 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710747 session_deps_.net_log = log.bound().net_log();
10748 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0010749
[email protected]76a505b2010-08-25 06:23:0010750 HttpRequestInfo request;
10751 request.method = "GET";
bncce36dca22015-04-21 22:11:2310752 request.url = GURL("http://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0010753
10754 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2310755 MockWrite(
10756 "GET http://www.example.org/ HTTP/1.1\r\n"
10757 "Host: www.example.org\r\n"
10758 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0010759 };
10760
10761 MockRead data_reads1[] = {
10762 MockRead("HTTP/1.1 200 OK\r\n"),
10763 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10764 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610765 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0010766 };
10767
10768 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10769 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710770 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0010771
[email protected]49639fa2011-12-20 23:22:4110772 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0010773
[email protected]262eec82013-03-19 21:01:3610774 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010775 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]597a1ab2014-06-26 08:12:2710776 BeforeProxyHeadersSentHandler proxy_headers_handler;
10777 trans->SetBeforeProxyHeadersSentCallback(
10778 base::Bind(&BeforeProxyHeadersSentHandler::OnBeforeProxyHeadersSent,
10779 base::Unretained(&proxy_headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5010780
[email protected]49639fa2011-12-20 23:22:4110781 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0010782 EXPECT_EQ(ERR_IO_PENDING, rv);
10783
10784 rv = callback1.WaitForResult();
10785 EXPECT_EQ(OK, rv);
10786
10787 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010788 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:0010789
10790 EXPECT_TRUE(response->headers->IsKeepAlive());
10791 EXPECT_EQ(200, response->headers->response_code());
10792 EXPECT_EQ(100, response->headers->GetContentLength());
10793 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]d8fc4722014-06-13 13:17:1510794 EXPECT_TRUE(
10795 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
[email protected]597a1ab2014-06-26 08:12:2710796 EXPECT_TRUE(proxy_headers_handler.observed_before_proxy_headers_sent());
10797 EXPECT_EQ("myproxy:70", proxy_headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0010798 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2010799
10800 LoadTimingInfo load_timing_info;
10801 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10802 TestLoadTimingNotReusedWithPac(load_timing_info,
10803 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0010804}
10805
10806// Test a basic HTTPS GET request through a proxy.
[email protected]23e482282013-06-14 16:08:0210807TEST_P(HttpNetworkTransactionTest, ProxyTunnelGet) {
[email protected]bb88e1d32013-05-03 23:11:0710808 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:2010809 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
vishal.b62985ca92015-04-17 08:45:5110810 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710811 session_deps_.net_log = log.bound().net_log();
10812 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0010813
[email protected]76a505b2010-08-25 06:23:0010814 HttpRequestInfo request;
10815 request.method = "GET";
bncce36dca22015-04-21 22:11:2310816 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0010817
10818 // Since we have proxy, should try to establish tunnel.
10819 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2310820 MockWrite(
10821 "CONNECT www.example.org:443 HTTP/1.1\r\n"
10822 "Host: www.example.org\r\n"
10823 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0010824
bncce36dca22015-04-21 22:11:2310825 MockWrite(
10826 "GET / HTTP/1.1\r\n"
10827 "Host: www.example.org\r\n"
10828 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0010829 };
10830
10831 MockRead data_reads1[] = {
10832 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
10833
10834 MockRead("HTTP/1.1 200 OK\r\n"),
10835 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10836 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610837 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0010838 };
10839
10840 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10841 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710842 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0610843 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710844 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0010845
[email protected]49639fa2011-12-20 23:22:4110846 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0010847
[email protected]262eec82013-03-19 21:01:3610848 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010849 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5010850
[email protected]49639fa2011-12-20 23:22:4110851 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0010852 EXPECT_EQ(ERR_IO_PENDING, rv);
10853
10854 rv = callback1.WaitForResult();
10855 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:4610856 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4010857 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0010858 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010859 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0010860 NetLog::PHASE_NONE);
10861 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010862 entries, pos,
[email protected]76a505b2010-08-25 06:23:0010863 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
10864 NetLog::PHASE_NONE);
10865
10866 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010867 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:0010868
10869 EXPECT_TRUE(response->headers->IsKeepAlive());
10870 EXPECT_EQ(200, response->headers->response_code());
10871 EXPECT_EQ(100, response->headers->GetContentLength());
10872 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10873 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]d8fc4722014-06-13 13:17:1510874 EXPECT_TRUE(
10875 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
[email protected]029c83b62013-01-24 05:28:2010876
10877 LoadTimingInfo load_timing_info;
10878 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10879 TestLoadTimingNotReusedWithPac(load_timing_info,
10880 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0010881}
10882
10883// Test a basic HTTPS GET request through a proxy, but the server hangs up
10884// while establishing the tunnel.
[email protected]23e482282013-06-14 16:08:0210885TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
[email protected]bb88e1d32013-05-03 23:11:0710886 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
vishal.b62985ca92015-04-17 08:45:5110887 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710888 session_deps_.net_log = log.bound().net_log();
10889 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0010890
[email protected]76a505b2010-08-25 06:23:0010891 HttpRequestInfo request;
10892 request.method = "GET";
bncce36dca22015-04-21 22:11:2310893 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0010894
10895 // Since we have proxy, should try to establish tunnel.
10896 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2310897 MockWrite(
10898 "CONNECT www.example.org:443 HTTP/1.1\r\n"
10899 "Host: www.example.org\r\n"
10900 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0010901
bncce36dca22015-04-21 22:11:2310902 MockWrite(
10903 "GET / HTTP/1.1\r\n"
10904 "Host: www.example.org\r\n"
10905 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0010906 };
10907
10908 MockRead data_reads1[] = {
[email protected]8ddf8322012-02-23 18:08:0610909 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:0010910 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610911 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0010912 };
10913
10914 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10915 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710916 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0610917 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710918 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0010919
[email protected]49639fa2011-12-20 23:22:4110920 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0010921
[email protected]262eec82013-03-19 21:01:3610922 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010923 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5010924
[email protected]49639fa2011-12-20 23:22:4110925 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0010926 EXPECT_EQ(ERR_IO_PENDING, rv);
10927
10928 rv = callback1.WaitForResult();
10929 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
mmenke43758e62015-05-04 21:09:4610930 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4010931 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0010932 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010933 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0010934 NetLog::PHASE_NONE);
10935 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010936 entries, pos,
[email protected]76a505b2010-08-25 06:23:0010937 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
10938 NetLog::PHASE_NONE);
10939}
10940
[email protected]749eefa82010-09-13 22:14:0310941// Test for crbug.com/55424.
[email protected]23e482282013-06-14 16:08:0210942TEST_P(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
[email protected]cdf8f7e72013-05-23 10:56:4610943 scoped_ptr<SpdyFrame> req(
bncce36dca22015-04-21 22:11:2310944 spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
rch8e6c6c42015-05-01 14:05:1310945 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]749eefa82010-09-13 22:14:0310946
[email protected]23e482282013-06-14 16:08:0210947 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10948 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0310949 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1310950 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0310951 };
10952
rch8e6c6c42015-05-01 14:05:1310953 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10954 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710955 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0310956
[email protected]8ddf8322012-02-23 18:08:0610957 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210958 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710959 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0310960
[email protected]bb88e1d32013-05-03 23:11:0710961 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0310962
10963 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2310964 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4010965 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5310966 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2710967 base::WeakPtr<SpdySession> spdy_session =
[email protected]41d64e82013-07-03 22:44:2610968 CreateInsecureSpdySession(session, key, BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0310969
10970 HttpRequestInfo request;
10971 request.method = "GET";
bncce36dca22015-04-21 22:11:2310972 request.url = GURL("https://www.example.org/");
[email protected]749eefa82010-09-13 22:14:0310973 request.load_flags = 0;
10974
10975 // This is the important line that marks this as a preconnect.
10976 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
10977
[email protected]262eec82013-03-19 21:01:3610978 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010979 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]749eefa82010-09-13 22:14:0310980
[email protected]41d64e82013-07-03 22:44:2610981 TestCompletionCallback callback;
[email protected]49639fa2011-12-20 23:22:4110982 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0310983 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110984 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]749eefa82010-09-13 22:14:0310985}
10986
[email protected]73b8dd222010-11-11 19:55:2410987// Given a net error, cause that error to be returned from the first Write()
10988// call and verify that the HttpTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0210989void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0710990 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2910991 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2710992 request_info.url = GURL("https://www.example.com/");
10993 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2910994 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2710995
[email protected]8ddf8322012-02-23 18:08:0610996 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2910997 MockWrite data_writes[] = {
10998 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2410999 };
ttuttle859dc7a2015-04-23 19:42:2911000 StaticSocketDataProvider data(NULL, 0, data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0711001 session_deps_.socket_factory->AddSocketDataProvider(&data);
11002 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2411003
[email protected]bb88e1d32013-05-03 23:11:0711004 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3611005 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011006 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]73b8dd222010-11-11 19:55:2411007
[email protected]49639fa2011-12-20 23:22:4111008 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2911009 int rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
11010 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2411011 rv = callback.WaitForResult();
11012 ASSERT_EQ(error, rv);
11013}
11014
[email protected]23e482282013-06-14 16:08:0211015TEST_P(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2411016 // Just check a grab bag of cert errors.
11017 static const int kErrors[] = {
11018 ERR_CERT_COMMON_NAME_INVALID,
11019 ERR_CERT_AUTHORITY_INVALID,
11020 ERR_CERT_DATE_INVALID,
11021 };
11022 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0611023 CheckErrorIsPassedBack(kErrors[i], ASYNC);
11024 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2411025 }
11026}
11027
[email protected]bd0b6772011-01-11 19:59:3011028// Ensure that a client certificate is removed from the SSL client auth
11029// cache when:
11030// 1) No proxy is involved.
11031// 2) TLS False Start is disabled.
11032// 3) The initial TLS handshake requests a client certificate.
11033// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0211034TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2311035 ClientAuthCertCache_Direct_NoFalseStart) {
ttuttle859dc7a2015-04-23 19:42:2911036 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2711037 request_info.url = GURL("https://www.example.com/");
11038 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2911039 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2711040
[email protected]bd0b6772011-01-11 19:59:3011041 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4111042 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3011043
11044 // [ssl_]data1 contains the data for the first SSL handshake. When a
11045 // CertificateRequest is received for the first time, the handshake will
11046 // be aborted to allow the caller to provide a certificate.
ttuttle859dc7a2015-04-23 19:42:2911047 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3011048 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711049 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2911050 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711051 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3011052
11053 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
11054 // False Start is not being used, the result of the SSL handshake will be
11055 // returned as part of the SSLClientSocket::Connect() call. This test
11056 // matches the result of a server sending a handshake_failure alert,
11057 // rather than a Finished message, because it requires a client
11058 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2911059 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3011060 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711061 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2911062 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711063 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3011064
11065 // [ssl_]data3 contains the data for the third SSL handshake. When a
11066 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4211067 // HttpNetworkTransaction will attempt to fallback to TLSv1.1 if the previous
11068 // connection was attempted with TLSv1.2. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3011069 // of the HttpNetworkTransaction. Because this test failure is due to
11070 // requiring a client certificate, this fallback handshake should also
11071 // fail.
ttuttle859dc7a2015-04-23 19:42:2911072 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3011073 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711074 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2911075 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711076 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3011077
[email protected]80c75f682012-05-26 16:22:1711078 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
11079 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4211080 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
11081 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]80c75f682012-05-26 16:22:1711082 // of the HttpNetworkTransaction. Because this test failure is due to
11083 // requiring a client certificate, this fallback handshake should also
11084 // fail.
ttuttle859dc7a2015-04-23 19:42:2911085 SSLSocketDataProvider ssl_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1711086 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711087 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2911088 StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711089 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1711090
[email protected]bb88e1d32013-05-03 23:11:0711091 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3611092 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011093 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3011094
[email protected]bd0b6772011-01-11 19:59:3011095 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4111096 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2911097 int rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
11098 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3011099
11100 // Complete the SSL handshake, which should abort due to requiring a
11101 // client certificate.
11102 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911103 ASSERT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
[email protected]bd0b6772011-01-11 19:59:3011104
11105 // Indicate that no certificate should be supplied. From the perspective
11106 // of SSLClientCertCache, NULL is just as meaningful as a real
11107 // certificate, so this is the same as supply a
11108 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4111109 rv = trans->RestartWithCertificate(NULL, callback.callback());
ttuttle859dc7a2015-04-23 19:42:2911110 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3011111
11112 // Ensure the certificate was added to the client auth cache before
11113 // allowing the connection to continue restarting.
11114 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4111115 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
11116 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3011117 ASSERT_EQ(NULL, client_cert.get());
11118
11119 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1711120 // then consume ssl_data3 and ssl_data4, both of which should also fail.
11121 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3011122 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911123 ASSERT_EQ(ERR_SSL_PROTOCOL_ERROR, rv);
[email protected]bd0b6772011-01-11 19:59:3011124
11125 // Ensure that the client certificate is removed from the cache on a
11126 // handshake failure.
[email protected]791879c2013-12-17 07:22:4111127 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11128 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3011129}
11130
11131// Ensure that a client certificate is removed from the SSL client auth
11132// cache when:
11133// 1) No proxy is involved.
11134// 2) TLS False Start is enabled.
11135// 3) The initial TLS handshake requests a client certificate.
11136// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0211137TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2311138 ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2911139 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2711140 request_info.url = GURL("https://www.example.com/");
11141 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2911142 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2711143
[email protected]bd0b6772011-01-11 19:59:3011144 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4111145 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3011146
11147 // When TLS False Start is used, SSLClientSocket::Connect() calls will
11148 // return successfully after reading up to the peer's Certificate message.
11149 // This is to allow the caller to call SSLClientSocket::Write(), which can
11150 // enqueue application data to be sent in the same packet as the
11151 // ChangeCipherSpec and Finished messages.
11152 // The actual handshake will be finished when SSLClientSocket::Read() is
11153 // called, which expects to process the peer's ChangeCipherSpec and
11154 // Finished messages. If there was an error negotiating with the peer,
11155 // such as due to the peer requiring a client certificate when none was
11156 // supplied, the alert sent by the peer won't be processed until Read() is
11157 // called.
11158
11159 // Like the non-False Start case, when a client certificate is requested by
11160 // the peer, the handshake is aborted during the Connect() call.
11161 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2911162 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3011163 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711164 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2911165 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711166 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3011167
11168 // When a client certificate is supplied, Connect() will not be aborted
11169 // when the peer requests the certificate. Instead, the handshake will
11170 // artificially succeed, allowing the caller to write the HTTP request to
11171 // the socket. The handshake messages are not processed until Read() is
11172 // called, which then detects that the handshake was aborted, due to the
11173 // peer sending a handshake_failure because it requires a client
11174 // certificate.
ttuttle859dc7a2015-04-23 19:42:2911175 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3011176 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711177 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2911178 MockRead data2_reads[] = {
11179 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3011180 };
ttuttle859dc7a2015-04-23 19:42:2911181 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711182 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3011183
11184 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1711185 // the data for the SSL handshake once the TLSv1.1 connection falls back to
11186 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2911187 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3011188 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711189 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2911190 StaticSocketDataProvider data3(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711191 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3011192
[email protected]80c75f682012-05-26 16:22:1711193 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
11194 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2911195 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1711196 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711197 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2911198 StaticSocketDataProvider data4(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711199 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1711200
[email protected]7799de12013-05-30 05:52:5111201 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2911202 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5111203 ssl_data5.cert_request_info = cert_request.get();
11204 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
ttuttle859dc7a2015-04-23 19:42:2911205 StaticSocketDataProvider data5(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]7799de12013-05-30 05:52:5111206 session_deps_.socket_factory->AddSocketDataProvider(&data5);
11207
[email protected]bb88e1d32013-05-03 23:11:0711208 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3611209 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011210 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3011211
[email protected]bd0b6772011-01-11 19:59:3011212 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4111213 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2911214 int rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
11215 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3011216
11217 // Complete the SSL handshake, which should abort due to requiring a
11218 // client certificate.
11219 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911220 ASSERT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
[email protected]bd0b6772011-01-11 19:59:3011221
11222 // Indicate that no certificate should be supplied. From the perspective
11223 // of SSLClientCertCache, NULL is just as meaningful as a real
11224 // certificate, so this is the same as supply a
11225 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4111226 rv = trans->RestartWithCertificate(NULL, callback.callback());
ttuttle859dc7a2015-04-23 19:42:2911227 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3011228
11229 // Ensure the certificate was added to the client auth cache before
11230 // allowing the connection to continue restarting.
11231 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4111232 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
11233 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3011234 ASSERT_EQ(NULL, client_cert.get());
11235
[email protected]bd0b6772011-01-11 19:59:3011236 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1711237 // then consume ssl_data3 and ssl_data4, both of which should also fail.
11238 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3011239 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911240 ASSERT_EQ(ERR_SSL_PROTOCOL_ERROR, rv);
[email protected]bd0b6772011-01-11 19:59:3011241
11242 // Ensure that the client certificate is removed from the cache on a
11243 // handshake failure.
[email protected]791879c2013-12-17 07:22:4111244 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11245 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3011246}
11247
[email protected]8c405132011-01-11 22:03:1811248// Ensure that a client certificate is removed from the SSL client auth
11249// cache when:
11250// 1) An HTTPS proxy is involved.
11251// 3) The HTTPS proxy requests a client certificate.
11252// 4) The client supplies an invalid/unacceptable certificate for the
11253// proxy.
11254// The test is repeated twice, first for connecting to an HTTPS endpoint,
11255// then for connecting to an HTTP endpoint.
[email protected]23e482282013-06-14 16:08:0211256TEST_P(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
[email protected]bb88e1d32013-05-03 23:11:0711257 session_deps_.proxy_service.reset(
[email protected]8c405132011-01-11 22:03:1811258 ProxyService::CreateFixed("https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:5111259 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0711260 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1811261
11262 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4111263 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1811264
11265 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
11266 // [ssl_]data[1-3]. Rather than represending the endpoint
11267 // (www.example.com:443), they represent failures with the HTTPS proxy
11268 // (proxy:70).
ttuttle859dc7a2015-04-23 19:42:2911269 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1811270 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711271 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2911272 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711273 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1811274
ttuttle859dc7a2015-04-23 19:42:2911275 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1811276 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711277 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2911278 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711279 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1811280
[email protected]80c75f682012-05-26 16:22:1711281 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
11282#if 0
ttuttle859dc7a2015-04-23 19:42:2911283 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1811284 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711285 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2911286 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711287 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1711288#endif
[email protected]8c405132011-01-11 22:03:1811289
ttuttle859dc7a2015-04-23 19:42:2911290 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1811291 requests[0].url = GURL("https://www.example.com/");
11292 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2911293 requests[0].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1811294
11295 requests[1].url = GURL("http://www.example.com/");
11296 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2911297 requests[1].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1811298
11299 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0711300 session_deps_.socket_factory->ResetNextMockIndexes();
11301 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c405132011-01-11 22:03:1811302 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5011303 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c405132011-01-11 22:03:1811304
11305 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4111306 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2911307 int rv = trans->Start(&requests[i], callback.callback(), BoundNetLog());
11308 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]8c405132011-01-11 22:03:1811309
11310 // Complete the SSL handshake, which should abort due to requiring a
11311 // client certificate.
11312 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911313 ASSERT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
[email protected]8c405132011-01-11 22:03:1811314
11315 // Indicate that no certificate should be supplied. From the perspective
11316 // of SSLClientCertCache, NULL is just as meaningful as a real
11317 // certificate, so this is the same as supply a
11318 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4111319 rv = trans->RestartWithCertificate(NULL, callback.callback());
ttuttle859dc7a2015-04-23 19:42:2911320 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]8c405132011-01-11 22:03:1811321
11322 // Ensure the certificate was added to the client auth cache before
11323 // allowing the connection to continue restarting.
11324 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4111325 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
11326 HostPortPair("proxy", 70), &client_cert));
[email protected]8c405132011-01-11 22:03:1811327 ASSERT_EQ(NULL, client_cert.get());
11328 // Ensure the certificate was NOT cached for the endpoint. This only
11329 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4111330 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11331 HostPortPair("www.example.com", 443), &client_cert));
[email protected]8c405132011-01-11 22:03:1811332
11333 // Restart the handshake. This will consume ssl_data2, which fails, and
11334 // then consume ssl_data3, which should also fail. The result code is
11335 // checked against what ssl_data3 should return.
11336 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911337 ASSERT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
[email protected]8c405132011-01-11 22:03:1811338
11339 // Now that the new handshake has failed, ensure that the client
11340 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4111341 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11342 HostPortPair("proxy", 70), &client_cert));
11343 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11344 HostPortPair("www.example.com", 443), &client_cert));
[email protected]8c405132011-01-11 22:03:1811345 }
11346}
11347
mmenke5c642132015-06-02 16:05:1311348TEST_P(HttpNetworkTransactionTest, UseIPConnectionPooling) {
[email protected]d7599122014-05-24 03:37:2311349 session_deps_.use_alternate_protocols = true;
11350 session_deps_.next_protos = SpdyNextProtos();
[email protected]e3ceb682011-06-28 23:55:4611351
11352 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0711353 session_deps_.host_resolver.reset(new MockCachingHostResolver());
11354 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2611355 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
11356 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4611357
[email protected]8ddf8322012-02-23 18:08:0611358 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211359 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711360 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4611361
[email protected]cdf8f7e72013-05-23 10:56:4611362 scoped_ptr<SpdyFrame> host1_req(
bncce36dca22015-04-21 22:11:2311363 spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
[email protected]cdf8f7e72013-05-23 10:56:4611364 scoped_ptr<SpdyFrame> host2_req(
11365 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4611366 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1311367 CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4611368 };
[email protected]23e482282013-06-14 16:08:0211369 scoped_ptr<SpdyFrame> host1_resp(
11370 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11371 scoped_ptr<SpdyFrame> host1_resp_body(
11372 spdy_util_.ConstructSpdyBodyFrame(1, true));
11373 scoped_ptr<SpdyFrame> host2_resp(
11374 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11375 scoped_ptr<SpdyFrame> host2_resp_body(
11376 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4611377 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1311378 CreateMockRead(*host1_resp, 1),
11379 CreateMockRead(*host1_resp_body, 2),
11380 CreateMockRead(*host2_resp, 4),
11381 CreateMockRead(*host2_resp_body, 5),
11382 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4611383 };
11384
[email protected]d2b5f092012-06-08 23:55:0211385 IPAddressNumber ip;
11386 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
11387 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11388 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1311389 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
11390 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711391 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4611392
[email protected]aa22b242011-11-16 18:58:2911393 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4611394 HttpRequestInfo request1;
11395 request1.method = "GET";
bncce36dca22015-04-21 22:11:2311396 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4611397 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011398 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611399
[email protected]49639fa2011-12-20 23:22:4111400 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611401 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111402 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611403
11404 const HttpResponseInfo* response = trans1.GetResponseInfo();
11405 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011406 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611407 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11408
11409 std::string response_data;
11410 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
11411 EXPECT_EQ("hello!", response_data);
11412
11413 // Preload www.gmail.com into HostCache.
11414 HostPortPair host_port("www.gmail.com", 443);
[email protected]5109c1952013-08-20 18:44:1011415 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4611416 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1011417 rv = session_deps_.host_resolver->Resolve(resolve_info,
11418 DEFAULT_PRIORITY,
11419 &ignored,
11420 callback.callback(),
11421 NULL,
11422 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4711423 EXPECT_EQ(ERR_IO_PENDING, rv);
11424 rv = callback.WaitForResult();
11425 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4611426
11427 HttpRequestInfo request2;
11428 request2.method = "GET";
11429 request2.url = GURL("https://www.gmail.com/");
11430 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011431 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611432
[email protected]49639fa2011-12-20 23:22:4111433 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611434 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111435 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611436
11437 response = trans2.GetResponseInfo();
11438 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011439 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611440 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11441 EXPECT_TRUE(response->was_fetched_via_spdy);
11442 EXPECT_TRUE(response->was_npn_negotiated);
11443 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
11444 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4611445}
11446
[email protected]23e482282013-06-14 16:08:0211447TEST_P(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d7599122014-05-24 03:37:2311448 session_deps_.use_alternate_protocols = true;
11449 session_deps_.next_protos = SpdyNextProtos();
[email protected]d2b5f092012-06-08 23:55:0211450
11451 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0711452 session_deps_.host_resolver.reset(new MockCachingHostResolver());
11453 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0211454 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
11455 pool_peer.DisableDomainAuthenticationVerification();
11456
11457 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211458 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711459 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]d2b5f092012-06-08 23:55:0211460
[email protected]cdf8f7e72013-05-23 10:56:4611461 scoped_ptr<SpdyFrame> host1_req(
bncce36dca22015-04-21 22:11:2311462 spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
[email protected]cdf8f7e72013-05-23 10:56:4611463 scoped_ptr<SpdyFrame> host2_req(
11464 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0211465 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1311466 CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0211467 };
[email protected]23e482282013-06-14 16:08:0211468 scoped_ptr<SpdyFrame> host1_resp(
11469 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11470 scoped_ptr<SpdyFrame> host1_resp_body(
11471 spdy_util_.ConstructSpdyBodyFrame(1, true));
11472 scoped_ptr<SpdyFrame> host2_resp(
11473 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11474 scoped_ptr<SpdyFrame> host2_resp_body(
11475 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0211476 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1311477 CreateMockRead(*host1_resp, 1),
11478 CreateMockRead(*host1_resp_body, 2),
11479 CreateMockRead(*host2_resp, 4),
11480 CreateMockRead(*host2_resp_body, 5),
11481 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0211482 };
11483
11484 IPAddressNumber ip;
11485 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
11486 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11487 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1311488 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
11489 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711490 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0211491
11492 TestCompletionCallback callback;
11493 HttpRequestInfo request1;
11494 request1.method = "GET";
bncce36dca22015-04-21 22:11:2311495 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0211496 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011497 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0211498
11499 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
11500 EXPECT_EQ(ERR_IO_PENDING, rv);
11501 EXPECT_EQ(OK, callback.WaitForResult());
11502
11503 const HttpResponseInfo* response = trans1.GetResponseInfo();
11504 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011505 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d2b5f092012-06-08 23:55:0211506 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11507
11508 std::string response_data;
11509 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
11510 EXPECT_EQ("hello!", response_data);
11511
11512 HttpRequestInfo request2;
11513 request2.method = "GET";
11514 request2.url = GURL("https://www.gmail.com/");
11515 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011516 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0211517
11518 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
11519 EXPECT_EQ(ERR_IO_PENDING, rv);
11520 EXPECT_EQ(OK, callback.WaitForResult());
11521
11522 response = trans2.GetResponseInfo();
11523 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011524 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d2b5f092012-06-08 23:55:0211525 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11526 EXPECT_TRUE(response->was_fetched_via_spdy);
11527 EXPECT_TRUE(response->was_npn_negotiated);
11528 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
11529 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0211530}
11531
ttuttle859dc7a2015-04-23 19:42:2911532class OneTimeCachingHostResolver : public HostResolver {
[email protected]e3ceb682011-06-28 23:55:4611533 public:
11534 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
11535 : host_port_(host_port) {}
dchengb03027d2014-10-21 12:00:2011536 ~OneTimeCachingHostResolver() override {}
[email protected]e3ceb682011-06-28 23:55:4611537
11538 RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); }
11539
11540 // HostResolver methods:
dchengb03027d2014-10-21 12:00:2011541 int Resolve(const RequestInfo& info,
11542 RequestPriority priority,
11543 AddressList* addresses,
11544 const CompletionCallback& callback,
11545 RequestHandle* out_req,
11546 const BoundNetLog& net_log) override {
[email protected]95a214c2011-08-04 21:50:4011547 return host_resolver_.Resolve(
[email protected]5109c1952013-08-20 18:44:1011548 info, priority, addresses, callback, out_req, net_log);
[email protected]95a214c2011-08-04 21:50:4011549 }
11550
dchengb03027d2014-10-21 12:00:2011551 int ResolveFromCache(const RequestInfo& info,
11552 AddressList* addresses,
11553 const BoundNetLog& net_log) override {
[email protected]95a214c2011-08-04 21:50:4011554 int rv = host_resolver_.ResolveFromCache(info, addresses, net_log);
11555 if (rv == OK && info.host_port_pair().Equals(host_port_))
[email protected]98e1cd012011-11-08 15:33:0911556 host_resolver_.GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4611557 return rv;
11558 }
11559
dchengb03027d2014-10-21 12:00:2011560 void CancelRequest(RequestHandle req) override {
[email protected]e3ceb682011-06-28 23:55:4611561 host_resolver_.CancelRequest(req);
11562 }
11563
[email protected]46da33be2011-07-19 21:58:0411564 MockCachingHostResolver* GetMockHostResolver() {
11565 return &host_resolver_;
11566 }
11567
[email protected]e3ceb682011-06-28 23:55:4611568 private:
11569 MockCachingHostResolver host_resolver_;
11570 const HostPortPair host_port_;
11571};
11572
mmenke5c642132015-06-02 16:05:1311573TEST_P(HttpNetworkTransactionTest,
11574 UseIPConnectionPoolingWithHostCacheExpiration) {
[email protected]d7599122014-05-24 03:37:2311575 session_deps_.use_alternate_protocols = true;
11576 session_deps_.next_protos = SpdyNextProtos();
[email protected]e3ceb682011-06-28 23:55:4611577
11578 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
[email protected]e3ceb682011-06-28 23:55:4611579 OneTimeCachingHostResolver host_resolver(HostPortPair("www.gmail.com", 443));
[email protected]c6bf8152012-12-02 07:43:3411580 HttpNetworkSession::Params params =
[email protected]bb88e1d32013-05-03 23:11:0711581 SpdySessionDependencies::CreateSessionParams(&session_deps_);
[email protected]e3ceb682011-06-28 23:55:4611582 params.host_resolver = &host_resolver;
[email protected]bb88e1d32013-05-03 23:11:0711583 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2611584 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
11585 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4611586
[email protected]8ddf8322012-02-23 18:08:0611587 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211588 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711589 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4611590
[email protected]cdf8f7e72013-05-23 10:56:4611591 scoped_ptr<SpdyFrame> host1_req(
bncce36dca22015-04-21 22:11:2311592 spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
[email protected]cdf8f7e72013-05-23 10:56:4611593 scoped_ptr<SpdyFrame> host2_req(
11594 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4611595 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1311596 CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4611597 };
[email protected]23e482282013-06-14 16:08:0211598 scoped_ptr<SpdyFrame> host1_resp(
11599 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11600 scoped_ptr<SpdyFrame> host1_resp_body(
11601 spdy_util_.ConstructSpdyBodyFrame(1, true));
11602 scoped_ptr<SpdyFrame> host2_resp(
11603 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11604 scoped_ptr<SpdyFrame> host2_resp_body(
11605 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4611606 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1311607 CreateMockRead(*host1_resp, 1),
11608 CreateMockRead(*host1_resp_body, 2),
11609 CreateMockRead(*host2_resp, 4),
11610 CreateMockRead(*host2_resp_body, 5),
11611 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4611612 };
11613
[email protected]d2b5f092012-06-08 23:55:0211614 IPAddressNumber ip;
11615 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
11616 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11617 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1311618 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
11619 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711620 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4611621
[email protected]aa22b242011-11-16 18:58:2911622 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4611623 HttpRequestInfo request1;
11624 request1.method = "GET";
bncce36dca22015-04-21 22:11:2311625 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4611626 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011627 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611628
[email protected]49639fa2011-12-20 23:22:4111629 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611630 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111631 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611632
11633 const HttpResponseInfo* response = trans1.GetResponseInfo();
11634 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011635 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611636 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11637
11638 std::string response_data;
11639 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
11640 EXPECT_EQ("hello!", response_data);
11641
11642 // Preload cache entries into HostCache.
[email protected]5109c1952013-08-20 18:44:1011643 HostResolver::RequestInfo resolve_info(HostPortPair("www.gmail.com", 443));
[email protected]e3ceb682011-06-28 23:55:4611644 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1011645 rv = host_resolver.Resolve(resolve_info,
11646 DEFAULT_PRIORITY,
11647 &ignored,
11648 callback.callback(),
11649 NULL,
11650 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4711651 EXPECT_EQ(ERR_IO_PENDING, rv);
11652 rv = callback.WaitForResult();
11653 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4611654
11655 HttpRequestInfo request2;
11656 request2.method = "GET";
11657 request2.url = GURL("https://www.gmail.com/");
11658 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011659 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611660
[email protected]49639fa2011-12-20 23:22:4111661 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611662 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111663 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611664
11665 response = trans2.GetResponseInfo();
11666 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011667 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611668 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11669 EXPECT_TRUE(response->was_fetched_via_spdy);
11670 EXPECT_TRUE(response->was_npn_negotiated);
11671 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
11672 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4611673}
11674
[email protected]23e482282013-06-14 16:08:0211675TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2311676 const std::string https_url = "https://www.example.org:8080/";
11677 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0411678
11679 // SPDY GET for HTTPS URL
[email protected]cdf8f7e72013-05-23 10:56:4611680 scoped_ptr<SpdyFrame> req1(
11681 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0411682
11683 MockWrite writes1[] = {
11684 CreateMockWrite(*req1, 0),
11685 };
11686
[email protected]23e482282013-06-14 16:08:0211687 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11688 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8450d722012-07-02 19:14:0411689 MockRead reads1[] = {
11690 CreateMockRead(*resp1, 1),
11691 CreateMockRead(*body1, 2),
11692 MockRead(ASYNC, ERR_IO_PENDING, 3)
11693 };
11694
rch8e6c6c42015-05-01 14:05:1311695 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
11696 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0411697 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5711698 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0411699
11700 // HTTP GET for the HTTP URL
11701 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1311702 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3411703 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2311704 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3411705 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0411706 };
11707
11708 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1311709 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
11710 MockRead(ASYNC, 2, "hello"),
11711 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0411712 };
11713
rch8e6c6c42015-05-01 14:05:1311714 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
11715 arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0411716
[email protected]8450d722012-07-02 19:14:0411717 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211718 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711719 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11720 session_deps_.socket_factory->AddSocketDataProvider(&data1);
11721 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0411722
[email protected]bb88e1d32013-05-03 23:11:0711723 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0411724
11725 // Start the first transaction to set up the SpdySession
11726 HttpRequestInfo request1;
11727 request1.method = "GET";
11728 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0411729 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011730 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0411731 TestCompletionCallback callback1;
11732 EXPECT_EQ(ERR_IO_PENDING,
11733 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411734 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411735
11736 EXPECT_EQ(OK, callback1.WaitForResult());
11737 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11738
11739 // Now, start the HTTP request
11740 HttpRequestInfo request2;
11741 request2.method = "GET";
11742 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0411743 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011744 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0411745 TestCompletionCallback callback2;
11746 EXPECT_EQ(ERR_IO_PENDING,
11747 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411748 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411749
11750 EXPECT_EQ(OK, callback2.WaitForResult());
11751 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11752}
11753
bnc1b0e36852015-04-28 15:32:5911754class AltSvcCertificateVerificationTest : public HttpNetworkTransactionTest {
11755 public:
11756 void Run(bool pooling, bool valid) {
11757 HostPortPair origin(valid ? "mail.example.org" : "invalid.example.org",
11758 443);
11759 HostPortPair alternative("www.example.org", 443);
11760
11761 base::FilePath certs_dir = GetTestCertsDirectory();
11762 scoped_refptr<X509Certificate> cert(
11763 ImportCertFromFile(certs_dir, "spdy_pooling.pem"));
11764 ASSERT_TRUE(cert.get());
11765 bool common_name_fallback_used;
11766 EXPECT_EQ(valid,
11767 cert->VerifyNameMatch(origin.host(), &common_name_fallback_used));
11768 EXPECT_TRUE(
11769 cert->VerifyNameMatch(alternative.host(), &common_name_fallback_used));
11770 SSLSocketDataProvider ssl(ASYNC, OK);
11771 ssl.SetNextProto(GetParam());
11772 ssl.cert = cert;
11773 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11774
11775 // If pooling, then start a request to alternative first to create a
11776 // SpdySession.
11777 std::string url0 = "https://www.example.org:443";
11778 // Second request to origin, which has an alternative service, and could
11779 // open a connection to the alternative host or pool to the existing one.
11780 std::string url1("https://");
11781 url1.append(origin.host());
11782 url1.append(":443");
11783
11784 scoped_ptr<SpdyFrame> req0;
11785 scoped_ptr<SpdyFrame> req1;
11786 scoped_ptr<SpdyFrame> resp0;
11787 scoped_ptr<SpdyFrame> body0;
11788 scoped_ptr<SpdyFrame> resp1;
11789 scoped_ptr<SpdyFrame> body1;
11790 std::vector<MockWrite> writes;
11791 std::vector<MockRead> reads;
11792
11793 if (pooling) {
11794 req0.reset(spdy_util_.ConstructSpdyGet(url0.c_str(), false, 1, LOWEST));
11795 req1.reset(spdy_util_.ConstructSpdyGet(url1.c_str(), false, 3, LOWEST));
11796
11797 writes.push_back(CreateMockWrite(*req0, 0));
11798 writes.push_back(CreateMockWrite(*req1, 3));
11799
11800 resp0.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11801 body0.reset(spdy_util_.ConstructSpdyBodyFrame(1, true));
11802 resp1.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11803 body1.reset(spdy_util_.ConstructSpdyBodyFrame(3, true));
11804
11805 reads.push_back(CreateMockRead(*resp0, 1));
11806 reads.push_back(CreateMockRead(*body0, 2));
11807 reads.push_back(MockRead(ASYNC, ERR_IO_PENDING, 4));
11808 reads.push_back(CreateMockRead(*resp1, 5));
11809 reads.push_back(CreateMockRead(*body1, 6));
11810 reads.push_back(MockRead(ASYNC, OK, 7));
11811 } else {
11812 req1.reset(spdy_util_.ConstructSpdyGet(url1.c_str(), false, 1, LOWEST));
11813
11814 writes.push_back(CreateMockWrite(*req1, 0));
11815
11816 resp1.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11817 body1.reset(spdy_util_.ConstructSpdyBodyFrame(1, true));
11818
11819 reads.push_back(CreateMockRead(*resp1, 1));
11820 reads.push_back(CreateMockRead(*body1, 2));
11821 reads.push_back(MockRead(ASYNC, OK, 3));
11822 }
11823
rch32320842015-05-16 15:57:0911824 SequencedSocketData data(vector_as_array(&reads), reads.size(),
11825 vector_as_array(&writes), writes.size());
bnc1b0e36852015-04-28 15:32:5911826 session_deps_.socket_factory->AddSocketDataProvider(&data);
11827
11828 // Connection to the origin fails.
11829 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11830 StaticSocketDataProvider data_refused;
11831 data_refused.set_connect_data(mock_connect);
11832 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
11833
11834 session_deps_.use_alternate_protocols = true;
11835 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11836 base::WeakPtr<HttpServerProperties> http_server_properties =
11837 session->http_server_properties();
11838 AlternativeService alternative_service(
11839 AlternateProtocolFromNextProto(GetParam()), alternative);
bnc7dc7e1b42015-07-28 14:43:1211840 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnc1b0e36852015-04-28 15:32:5911841 http_server_properties->SetAlternativeService(origin, alternative_service,
bnc7dc7e1b42015-07-28 14:43:1211842 1.0, expiration);
bnc1b0e36852015-04-28 15:32:5911843
11844 // First request to alternative.
11845 if (pooling) {
11846 scoped_ptr<HttpTransaction> trans0(
11847 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
11848 HttpRequestInfo request0;
11849 request0.method = "GET";
11850 request0.url = GURL(url0);
11851 request0.load_flags = 0;
11852 TestCompletionCallback callback0;
11853
11854 int rv = trans0->Start(&request0, callback0.callback(), BoundNetLog());
11855 EXPECT_EQ(ERR_IO_PENDING, rv);
11856 rv = callback0.WaitForResult();
11857 EXPECT_EQ(OK, rv);
11858 }
11859
11860 // Second request to origin.
11861 scoped_ptr<HttpTransaction> trans1(
11862 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
11863 HttpRequestInfo request1;
11864 request1.method = "GET";
11865 request1.url = GURL(url1);
11866 request1.load_flags = 0;
11867 TestCompletionCallback callback1;
11868
11869 int rv = trans1->Start(&request1, callback1.callback(), BoundNetLog());
11870 EXPECT_EQ(ERR_IO_PENDING, rv);
rch32320842015-05-16 15:57:0911871 base::MessageLoop::current()->RunUntilIdle();
11872 if (data.IsReadPaused()) {
11873 data.CompleteRead();
11874 }
bnc1b0e36852015-04-28 15:32:5911875 rv = callback1.WaitForResult();
11876 if (valid) {
11877 EXPECT_EQ(OK, rv);
11878 } else {
11879 if (pooling) {
11880 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
11881 } else {
11882 EXPECT_EQ(ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN, rv);
11883 }
11884 }
11885 }
11886};
11887
11888INSTANTIATE_TEST_CASE_P(NextProto,
11889 AltSvcCertificateVerificationTest,
11890 testing::Values(kProtoSPDY31,
bnc06d22432015-06-29 12:39:4311891 kProtoHTTP2_14,
11892 kProtoHTTP2));
bnc1b0e36852015-04-28 15:32:5911893
11894// The alternative service host must exhibit a certificate that is valid for the
11895// origin host. Test that this is enforced when pooling to an existing
11896// connection.
11897TEST_P(AltSvcCertificateVerificationTest, PoolingValid) {
11898 Run(true, true);
11899}
11900
11901TEST_P(AltSvcCertificateVerificationTest, PoolingInvalid) {
11902 Run(true, false);
11903}
11904
11905// The alternative service host must exhibit a certificate that is valid for the
11906// origin host. Test that this is enforced when opening a new connection.
11907TEST_P(AltSvcCertificateVerificationTest, NewConnectionValid) {
11908 Run(false, true);
11909}
11910
11911TEST_P(AltSvcCertificateVerificationTest, NewConnectionInvalid) {
11912 Run(false, false);
11913}
11914
bnc5452e2a2015-05-08 16:27:4211915// Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
11916// with the alternative server. That connection should not be used.
11917TEST_P(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
11918 HostPortPair origin("origin.example.org", 443);
11919 HostPortPair alternative("alternative.example.org", 443);
11920
11921 // Negotiate HTTP/1.1 with alternative.example.org.
11922 SSLSocketDataProvider ssl(ASYNC, OK);
11923 ssl.SetNextProto(kProtoHTTP11);
11924 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11925
11926 // No data should be read from the alternative, because HTTP/1.1 is
11927 // negotiated.
11928 StaticSocketDataProvider data;
11929 session_deps_.socket_factory->AddSocketDataProvider(&data);
11930
11931 // This test documents that an alternate Job should not be used if HTTP/1.1 is
11932 // negotiated. In order to test this, a failed connection to the origin is
11933 // mocked. This way the request relies on the alternate Job.
11934 StaticSocketDataProvider data_refused;
11935 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
11936 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
11937
11938 // Set up alternative service for origin.
11939 session_deps_.use_alternate_protocols = true;
11940 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11941 base::WeakPtr<HttpServerProperties> http_server_properties =
11942 session->http_server_properties();
11943 AlternativeService alternative_service(
11944 AlternateProtocolFromNextProto(GetParam()), alternative);
bnc7dc7e1b42015-07-28 14:43:1211945 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnc5452e2a2015-05-08 16:27:4211946 http_server_properties->SetAlternativeService(origin, alternative_service,
bnc7dc7e1b42015-07-28 14:43:1211947 1.0, expiration);
bnc5452e2a2015-05-08 16:27:4211948
11949 scoped_ptr<HttpTransaction> trans(
11950 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
11951 HttpRequestInfo request;
11952 request.method = "GET";
11953 request.url = GURL("https://origin.example.org:443");
11954 request.load_flags = 0;
11955 TestCompletionCallback callback;
11956
11957 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
11958 // negotiated, the alternate Job should fail with ERR_NPN_NEGOTIATION_FAILED.
11959 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11960 EXPECT_EQ(ERR_NPN_NEGOTIATION_FAILED, callback.GetResult(rv));
11961}
11962
bnc40448a532015-05-11 19:13:1411963// A request to a server with an alternative service fires two Jobs: one to the
11964// origin, and an alternate one to the alternative server. If the former
11965// succeeds, the request should succeed, even if the latter fails because
11966// HTTP/1.1 is negotiated which is insufficient for alternative service.
11967TEST_P(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
11968 HostPortPair origin("origin.example.org", 443);
11969 HostPortPair alternative("alternative.example.org", 443);
11970
11971 // Negotiate HTTP/1.1 with alternative.
11972 SSLSocketDataProvider alternative_ssl(ASYNC, OK);
11973 alternative_ssl.SetNextProto(kProtoHTTP11);
11974 session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
11975
11976 // No data should be read from the alternative, because HTTP/1.1 is
11977 // negotiated.
11978 StaticSocketDataProvider data;
11979 session_deps_.socket_factory->AddSocketDataProvider(&data);
11980
11981 // Negotiate HTTP/1.1 with origin.
11982 SSLSocketDataProvider origin_ssl(ASYNC, OK);
11983 origin_ssl.SetNextProto(kProtoHTTP11);
11984 session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
11985
11986 MockWrite http_writes[] = {
11987 MockWrite(
11988 "GET / HTTP/1.1\r\n"
11989 "Host: origin.example.org\r\n"
11990 "Connection: keep-alive\r\n\r\n"),
11991 MockWrite(
11992 "GET /second HTTP/1.1\r\n"
11993 "Host: origin.example.org\r\n"
11994 "Connection: keep-alive\r\n\r\n"),
11995 };
11996
11997 MockRead http_reads[] = {
11998 MockRead("HTTP/1.1 200 OK\r\n"),
11999 MockRead("Content-Type: text/html\r\n"),
12000 MockRead("Content-Length: 6\r\n\r\n"),
12001 MockRead("foobar"),
12002 MockRead("HTTP/1.1 200 OK\r\n"),
12003 MockRead("Content-Type: text/html\r\n"),
12004 MockRead("Content-Length: 7\r\n\r\n"),
12005 MockRead("another"),
12006 };
12007 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
12008 http_writes, arraysize(http_writes));
12009 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12010
12011 // Set up alternative service for origin.
12012 session_deps_.use_alternate_protocols = true;
12013 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12014 base::WeakPtr<HttpServerProperties> http_server_properties =
12015 session->http_server_properties();
12016 AlternativeService alternative_service(
12017 AlternateProtocolFromNextProto(GetParam()), alternative);
bnc7dc7e1b42015-07-28 14:43:1212018 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnc40448a532015-05-11 19:13:1412019 http_server_properties->SetAlternativeService(origin, alternative_service,
bnc7dc7e1b42015-07-28 14:43:1212020 1.0, expiration);
bnc40448a532015-05-11 19:13:1412021
12022 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
12023 HttpRequestInfo request1;
12024 request1.method = "GET";
12025 request1.url = GURL("https://origin.example.org:443");
12026 request1.load_flags = 0;
12027 TestCompletionCallback callback1;
12028
12029 int rv = trans1.Start(&request1, callback1.callback(), BoundNetLog());
12030 rv = callback1.GetResult(rv);
12031 EXPECT_EQ(OK, rv);
12032
12033 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
12034 ASSERT_TRUE(response1 != nullptr);
12035 ASSERT_TRUE(response1->headers.get() != nullptr);
12036 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
12037
12038 std::string response_data1;
12039 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data1));
12040 EXPECT_EQ("foobar", response_data1);
12041
12042 // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
12043 // for alternative service.
12044 EXPECT_TRUE(
12045 http_server_properties->IsAlternativeServiceBroken(alternative_service));
12046
12047 // Since |alternative_service| is broken, a second transaction to origin
12048 // should not start an alternate Job. It should pool to existing connection
12049 // to origin.
12050 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
12051 HttpRequestInfo request2;
12052 request2.method = "GET";
12053 request2.url = GURL("https://origin.example.org:443/second");
12054 request2.load_flags = 0;
12055 TestCompletionCallback callback2;
12056
12057 rv = trans2.Start(&request2, callback2.callback(), BoundNetLog());
12058 rv = callback2.GetResult(rv);
12059 EXPECT_EQ(OK, rv);
12060
12061 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
12062 ASSERT_TRUE(response2 != nullptr);
12063 ASSERT_TRUE(response2->headers.get() != nullptr);
12064 EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
12065
12066 std::string response_data2;
12067 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data2));
12068 EXPECT_EQ("another", response_data2);
12069}
12070
bnc5452e2a2015-05-08 16:27:4212071// Alternative service requires HTTP/2 (or SPDY), but there is already a
12072// HTTP/1.1 socket open to the alternative server. That socket should not be
12073// used.
12074TEST_P(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
12075 HostPortPair origin("origin.example.org", 443);
12076 HostPortPair alternative("alternative.example.org", 443);
12077 std::string origin_url = "https://origin.example.org:443";
12078 std::string alternative_url = "https://alternative.example.org:443";
12079
12080 // Negotiate HTTP/1.1 with alternative.example.org.
12081 SSLSocketDataProvider ssl(ASYNC, OK);
12082 ssl.SetNextProto(kProtoHTTP11);
12083 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12084
12085 // HTTP/1.1 data for |request1| and |request2|.
12086 MockWrite http_writes[] = {
12087 MockWrite(
12088 "GET / HTTP/1.1\r\n"
12089 "Host: alternative.example.org\r\n"
12090 "Connection: keep-alive\r\n\r\n"),
12091 MockWrite(
12092 "GET / HTTP/1.1\r\n"
12093 "Host: alternative.example.org\r\n"
12094 "Connection: keep-alive\r\n\r\n"),
12095 };
12096
12097 MockRead http_reads[] = {
12098 MockRead(
12099 "HTTP/1.1 200 OK\r\n"
12100 "Content-Type: text/html; charset=iso-8859-1\r\n"
12101 "Content-Length: 40\r\n\r\n"
12102 "first HTTP/1.1 response from alternative"),
12103 MockRead(
12104 "HTTP/1.1 200 OK\r\n"
12105 "Content-Type: text/html; charset=iso-8859-1\r\n"
12106 "Content-Length: 41\r\n\r\n"
12107 "second HTTP/1.1 response from alternative"),
12108 };
12109 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
12110 http_writes, arraysize(http_writes));
12111 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12112
12113 // This test documents that an alternate Job should not pool to an already
12114 // existing HTTP/1.1 connection. In order to test this, a failed connection
12115 // to the origin is mocked. This way |request2| relies on the alternate Job.
12116 StaticSocketDataProvider data_refused;
12117 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
12118 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
12119
12120 // Set up alternative service for origin.
12121 session_deps_.use_alternate_protocols = true;
12122 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12123 base::WeakPtr<HttpServerProperties> http_server_properties =
12124 session->http_server_properties();
12125 AlternativeService alternative_service(
12126 AlternateProtocolFromNextProto(GetParam()), alternative);
bnc7dc7e1b42015-07-28 14:43:1212127 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnc5452e2a2015-05-08 16:27:4212128 http_server_properties->SetAlternativeService(origin, alternative_service,
bnc7dc7e1b42015-07-28 14:43:1212129 1.0, expiration);
bnc5452e2a2015-05-08 16:27:4212130
12131 // First transaction to alternative to open an HTTP/1.1 socket.
12132 scoped_ptr<HttpTransaction> trans1(
12133 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12134 HttpRequestInfo request1;
12135 request1.method = "GET";
12136 request1.url = GURL(alternative_url);
12137 request1.load_flags = 0;
12138 TestCompletionCallback callback1;
12139
12140 int rv = trans1->Start(&request1, callback1.callback(), BoundNetLog());
12141 EXPECT_EQ(OK, callback1.GetResult(rv));
12142 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
12143 ASSERT_TRUE(response1);
12144 ASSERT_TRUE(response1->headers.get());
12145 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
12146 EXPECT_TRUE(response1->was_npn_negotiated);
12147 EXPECT_FALSE(response1->was_fetched_via_spdy);
12148 std::string response_data1;
12149 ASSERT_EQ(OK, ReadTransaction(trans1.get(), &response_data1));
12150 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
12151
12152 // Request for origin.example.org, which has an alternative service. This
12153 // will start two Jobs: the alternative looks for connections to pool to,
12154 // finds one which is HTTP/1.1, and should ignore it, and should not try to
12155 // open other connections to alternative server. The Job to origin fails, so
12156 // this request fails.
12157 scoped_ptr<HttpTransaction> trans2(
12158 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12159 HttpRequestInfo request2;
12160 request2.method = "GET";
12161 request2.url = GURL(origin_url);
12162 request2.load_flags = 0;
12163 TestCompletionCallback callback2;
12164
12165 rv = trans2->Start(&request2, callback2.callback(), BoundNetLog());
12166 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback2.GetResult(rv));
12167
12168 // Another transaction to alternative. This is to test that the HTTP/1.1
12169 // socket is still open and in the pool.
12170 scoped_ptr<HttpTransaction> trans3(
12171 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12172 HttpRequestInfo request3;
12173 request3.method = "GET";
12174 request3.url = GURL(alternative_url);
12175 request3.load_flags = 0;
12176 TestCompletionCallback callback3;
12177
12178 rv = trans3->Start(&request3, callback3.callback(), BoundNetLog());
12179 EXPECT_EQ(OK, callback3.GetResult(rv));
12180 const HttpResponseInfo* response3 = trans3->GetResponseInfo();
12181 ASSERT_TRUE(response3);
12182 ASSERT_TRUE(response3->headers.get());
12183 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
12184 EXPECT_TRUE(response3->was_npn_negotiated);
12185 EXPECT_FALSE(response3->was_fetched_via_spdy);
12186 std::string response_data3;
12187 ASSERT_EQ(OK, ReadTransaction(trans3.get(), &response_data3));
12188 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
12189}
12190
[email protected]23e482282013-06-14 16:08:0212191TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2312192 const std::string https_url = "https://www.example.org:8080/";
12193 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0412194
12195 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2312196 const HostPortPair host_port_pair("www.example.org", 8080);
lgarrona91df87f2014-12-05 00:51:3412197 scoped_ptr<SpdyFrame> connect(
12198 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
[email protected]cdf8f7e72013-05-23 10:56:4612199 scoped_ptr<SpdyFrame> req1(
12200 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]23e482282013-06-14 16:08:0212201 scoped_ptr<SpdyFrame> wrapped_req1(
12202 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3912203
12204 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
[email protected]745aa9c2014-06-27 02:21:2912205 SpdyHeaderBlock req2_block;
12206 req2_block[spdy_util_.GetMethodKey()] = "GET";
bnc33b8cef42014-11-19 17:30:3812207 req2_block[spdy_util_.GetPathKey()] = "/";
bncce36dca22015-04-21 22:11:2312208 req2_block[spdy_util_.GetHostKey()] = "www.example.org:8080";
[email protected]745aa9c2014-06-27 02:21:2912209 req2_block[spdy_util_.GetSchemeKey()] = "http";
12210 spdy_util_.MaybeAddVersionHeader(&req2_block);
[email protected]601e03f12014-04-06 16:26:3912211 scoped_ptr<SpdyFrame> req2(
[email protected]745aa9c2014-06-27 02:21:2912212 spdy_util_.ConstructSpdySyn(3, req2_block, MEDIUM, false, true));
[email protected]8450d722012-07-02 19:14:0412213
12214 MockWrite writes1[] = {
12215 CreateMockWrite(*connect, 0),
12216 CreateMockWrite(*wrapped_req1, 2),
12217 CreateMockWrite(*req2, 5),
12218 };
12219
[email protected]23e482282013-06-14 16:08:0212220 scoped_ptr<SpdyFrame> conn_resp(
12221 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12222 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12223 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
12224 scoped_ptr<SpdyFrame> wrapped_resp1(
12225 spdy_util_.ConstructWrappedSpdyFrame(resp1, 1));
12226 scoped_ptr<SpdyFrame> wrapped_body1(
12227 spdy_util_.ConstructWrappedSpdyFrame(body1, 1));
12228 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
12229 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]8450d722012-07-02 19:14:0412230 MockRead reads1[] = {
12231 CreateMockRead(*conn_resp, 1),
12232 CreateMockRead(*wrapped_resp1, 3),
12233 CreateMockRead(*wrapped_body1, 4),
12234 CreateMockRead(*resp2, 6),
12235 CreateMockRead(*body2, 7),
12236 MockRead(ASYNC, ERR_IO_PENDING, 8)
12237 };
12238
[email protected]dd54bd82012-07-19 23:44:5712239 DeterministicSocketData data1(reads1, arraysize(reads1),
12240 writes1, arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0412241 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5712242 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0412243
[email protected]bb88e1d32013-05-03 23:11:0712244 session_deps_.proxy_service.reset(
[email protected]f6c63db52013-02-02 00:35:2212245 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
vishal.b62985ca92015-04-17 08:45:5112246 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712247 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0412248 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
[email protected]23e482282013-06-14 16:08:0212249 ssl1.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0712250 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0412251 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
[email protected]23e482282013-06-14 16:08:0212252 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0712253 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
12254 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0412255
12256 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0712257 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]8450d722012-07-02 19:14:0412258
12259 // Start the first transaction to set up the SpdySession
12260 HttpRequestInfo request1;
12261 request1.method = "GET";
12262 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0412263 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012264 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0412265 TestCompletionCallback callback1;
12266 EXPECT_EQ(ERR_IO_PENDING,
12267 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412268 base::MessageLoop::current()->RunUntilIdle();
[email protected]dd54bd82012-07-19 23:44:5712269 data1.RunFor(4);
[email protected]8450d722012-07-02 19:14:0412270
12271 EXPECT_EQ(OK, callback1.WaitForResult());
12272 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
12273
[email protected]f6c63db52013-02-02 00:35:2212274 LoadTimingInfo load_timing_info1;
12275 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
12276 TestLoadTimingNotReusedWithPac(load_timing_info1,
12277 CONNECT_TIMING_HAS_SSL_TIMES);
12278
[email protected]8450d722012-07-02 19:14:0412279 // Now, start the HTTP request
12280 HttpRequestInfo request2;
12281 request2.method = "GET";
12282 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0412283 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012284 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0412285 TestCompletionCallback callback2;
12286 EXPECT_EQ(ERR_IO_PENDING,
12287 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412288 base::MessageLoop::current()->RunUntilIdle();
[email protected]dd54bd82012-07-19 23:44:5712289 data1.RunFor(3);
[email protected]8450d722012-07-02 19:14:0412290
12291 EXPECT_EQ(OK, callback2.WaitForResult());
12292 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2212293
12294 LoadTimingInfo load_timing_info2;
12295 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
12296 // The established SPDY sessions is considered reused by the HTTP request.
12297 TestLoadTimingReusedWithPac(load_timing_info2);
12298 // HTTP requests over a SPDY session should have a different connection
12299 // socket_log_id than requests over a tunnel.
12300 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0412301}
12302
[email protected]2d88e7d2012-07-19 17:55:1712303// Test that in the case where we have a SPDY session to a SPDY proxy
12304// that we do not pool other origins that resolve to the same IP when
12305// the certificate does not match the new origin.
12306// http://crbug.com/134690
[email protected]23e482282013-06-14 16:08:0212307TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2312308 const std::string url1 = "http://www.example.org/";
12309 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1712310 const std::string ip_addr = "1.2.3.4";
12311
12312 // SPDY GET for HTTP URL (through SPDY proxy)
[email protected]23e482282013-06-14 16:08:0212313 scoped_ptr<SpdyHeaderBlock> headers(
bncce36dca22015-04-21 22:11:2312314 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
[email protected]745aa9c2014-06-27 02:21:2912315 scoped_ptr<SpdyFrame> req1(
12316 spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, false, true));
[email protected]2d88e7d2012-07-19 17:55:1712317
12318 MockWrite writes1[] = {
12319 CreateMockWrite(*req1, 0),
12320 };
12321
[email protected]23e482282013-06-14 16:08:0212322 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12323 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1712324 MockRead reads1[] = {
12325 CreateMockRead(*resp1, 1),
12326 CreateMockRead(*body1, 2),
12327 MockRead(ASYNC, OK, 3) // EOF
12328 };
12329
12330 scoped_ptr<DeterministicSocketData> data1(
12331 new DeterministicSocketData(reads1, arraysize(reads1),
12332 writes1, arraysize(writes1)));
12333 IPAddressNumber ip;
12334 ASSERT_TRUE(ParseIPLiteralToNumber(ip_addr, &ip));
12335 IPEndPoint peer_addr = IPEndPoint(ip, 443);
12336 MockConnect connect_data1(ASYNC, OK, peer_addr);
12337 data1->set_connect_data(connect_data1);
12338
12339 // SPDY GET for HTTPS URL (direct)
[email protected]cdf8f7e72013-05-23 10:56:4612340 scoped_ptr<SpdyFrame> req2(
12341 spdy_util_.ConstructSpdyGet(url2.c_str(), false, 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1712342
12343 MockWrite writes2[] = {
12344 CreateMockWrite(*req2, 0),
12345 };
12346
[email protected]23e482282013-06-14 16:08:0212347 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12348 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1712349 MockRead reads2[] = {
12350 CreateMockRead(*resp2, 1),
12351 CreateMockRead(*body2, 2),
12352 MockRead(ASYNC, OK, 3) // EOF
12353 };
12354
12355 scoped_ptr<DeterministicSocketData> data2(
12356 new DeterministicSocketData(reads2, arraysize(reads2),
12357 writes2, arraysize(writes2)));
12358 MockConnect connect_data2(ASYNC, OK);
12359 data2->set_connect_data(connect_data2);
12360
12361 // Set up a proxy config that sends HTTP requests to a proxy, and
12362 // all others direct.
12363 ProxyConfig proxy_config;
12364 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
[email protected]bb88e1d32013-05-03 23:11:0712365 session_deps_.proxy_service.reset(new ProxyService(
sammc5dd160c2015-04-02 02:43:1312366 new ProxyConfigServiceFixed(proxy_config), nullptr, NULL));
[email protected]2d88e7d2012-07-19 17:55:1712367
bncce36dca22015-04-21 22:11:2312368 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
12369 ssl1.SetNextProto(GetParam());
[email protected]2d88e7d2012-07-19 17:55:1712370 // Load a valid cert. Note, that this does not need to
12371 // be valid for proxy because the MockSSLClientSocket does
12372 // not actually verify it. But SpdySession will use this
12373 // to see if it is valid for the new origin
bncce36dca22015-04-21 22:11:2312374 ssl1.cert = ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
12375 ASSERT_TRUE(ssl1.cert.get());
[email protected]bb88e1d32013-05-03 23:11:0712376 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
12377 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
12378 data1.get());
[email protected]2d88e7d2012-07-19 17:55:1712379
12380 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
[email protected]23e482282013-06-14 16:08:0212381 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0712382 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
12383 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
12384 data2.get());
[email protected]2d88e7d2012-07-19 17:55:1712385
[email protected]bb88e1d32013-05-03 23:11:0712386 session_deps_.host_resolver.reset(new MockCachingHostResolver());
bncce36dca22015-04-21 22:11:2312387 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0712388 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1712389
12390 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0712391 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]2d88e7d2012-07-19 17:55:1712392
12393 // Start the first transaction to set up the SpdySession
12394 HttpRequestInfo request1;
12395 request1.method = "GET";
12396 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1712397 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012398 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1712399 TestCompletionCallback callback1;
12400 ASSERT_EQ(ERR_IO_PENDING,
12401 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
12402 data1->RunFor(3);
12403
12404 ASSERT_TRUE(callback1.have_result());
12405 EXPECT_EQ(OK, callback1.WaitForResult());
12406 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
12407
12408 // Now, start the HTTP request
12409 HttpRequestInfo request2;
12410 request2.method = "GET";
12411 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1712412 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012413 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1712414 TestCompletionCallback callback2;
12415 EXPECT_EQ(ERR_IO_PENDING,
12416 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412417 base::MessageLoop::current()->RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1712418 data2->RunFor(3);
12419
12420 ASSERT_TRUE(callback2.have_result());
12421 EXPECT_EQ(OK, callback2.WaitForResult());
12422 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
12423}
12424
[email protected]85f97342013-04-17 06:12:2412425// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
12426// error) in SPDY session, removes the socket from pool and closes the SPDY
12427// session. Verify that new url's from the same HttpNetworkSession (and a new
12428// SpdySession) do work. http://crbug.com/224701
[email protected]23e482282013-06-14 16:08:0212429TEST_P(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2312430 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2412431
12432 MockRead reads1[] = {
12433 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
12434 };
12435
mmenke11eb5152015-06-09 14:50:5012436 SequencedSocketData data1(reads1, arraysize(reads1), NULL, 0);
[email protected]85f97342013-04-17 06:12:2412437
[email protected]cdf8f7e72013-05-23 10:56:4612438 scoped_ptr<SpdyFrame> req2(
12439 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2412440 MockWrite writes2[] = {
12441 CreateMockWrite(*req2, 0),
12442 };
12443
[email protected]23e482282013-06-14 16:08:0212444 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12445 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]85f97342013-04-17 06:12:2412446 MockRead reads2[] = {
12447 CreateMockRead(*resp2, 1),
12448 CreateMockRead(*body2, 2),
12449 MockRead(ASYNC, OK, 3) // EOF
12450 };
12451
mmenke11eb5152015-06-09 14:50:5012452 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
12453 arraysize(writes2));
[email protected]85f97342013-04-17 06:12:2412454
[email protected]85f97342013-04-17 06:12:2412455 SSLSocketDataProvider ssl1(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212456 ssl1.SetNextProto(GetParam());
mmenke11eb5152015-06-09 14:50:5012457 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
12458 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]85f97342013-04-17 06:12:2412459
12460 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212461 ssl2.SetNextProto(GetParam());
mmenke11eb5152015-06-09 14:50:5012462 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
12463 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]85f97342013-04-17 06:12:2412464
12465 scoped_refptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:5012466 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]85f97342013-04-17 06:12:2412467
12468 // Start the first transaction to set up the SpdySession and verify that
12469 // connection was closed.
12470 HttpRequestInfo request1;
12471 request1.method = "GET";
12472 request1.url = GURL(https_url);
12473 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012474 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2412475 TestCompletionCallback callback1;
12476 EXPECT_EQ(ERR_IO_PENDING,
12477 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]85f97342013-04-17 06:12:2412478 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback1.WaitForResult());
12479
12480 // Now, start the second request and make sure it succeeds.
12481 HttpRequestInfo request2;
12482 request2.method = "GET";
12483 request2.url = GURL(https_url);
12484 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012485 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2412486 TestCompletionCallback callback2;
12487 EXPECT_EQ(ERR_IO_PENDING,
12488 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]85f97342013-04-17 06:12:2412489
mmenke11eb5152015-06-09 14:50:5012490 ASSERT_EQ(OK, callback2.WaitForResult());
[email protected]85f97342013-04-17 06:12:2412491 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
12492}
12493
[email protected]23e482282013-06-14 16:08:0212494TEST_P(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]d7599122014-05-24 03:37:2312495 session_deps_.next_protos = SpdyNextProtos();
[email protected]483fa202013-05-14 01:07:0312496 ClientSocketPoolManager::set_max_sockets_per_group(
12497 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12498 ClientSocketPoolManager::set_max_sockets_per_pool(
12499 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12500
12501 // Use two different hosts with different IPs so they don't get pooled.
12502 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
12503 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
12504 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12505
12506 SSLSocketDataProvider ssl1(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212507 ssl1.SetNextProto(GetParam());
[email protected]483fa202013-05-14 01:07:0312508 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212509 ssl2.SetNextProto(GetParam());
[email protected]483fa202013-05-14 01:07:0312510 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
12511 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
12512
[email protected]cdf8f7e72013-05-23 10:56:4612513 scoped_ptr<SpdyFrame> host1_req(spdy_util_.ConstructSpdyGet(
[email protected]483fa202013-05-14 01:07:0312514 "https://www.a.com", false, 1, DEFAULT_PRIORITY));
12515 MockWrite spdy1_writes[] = {
rch8e6c6c42015-05-01 14:05:1312516 CreateMockWrite(*host1_req, 0),
[email protected]483fa202013-05-14 01:07:0312517 };
[email protected]23e482282013-06-14 16:08:0212518 scoped_ptr<SpdyFrame> host1_resp(
12519 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12520 scoped_ptr<SpdyFrame> host1_resp_body(
12521 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0312522 MockRead spdy1_reads[] = {
rch8e6c6c42015-05-01 14:05:1312523 CreateMockRead(*host1_resp, 1),
12524 CreateMockRead(*host1_resp_body, 2),
12525 MockRead(ASYNC, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0312526 };
12527
rch8e6c6c42015-05-01 14:05:1312528 scoped_ptr<SequencedSocketData> spdy1_data(
12529 new SequencedSocketData(spdy1_reads, arraysize(spdy1_reads), spdy1_writes,
12530 arraysize(spdy1_writes)));
[email protected]483fa202013-05-14 01:07:0312531 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
12532
[email protected]cdf8f7e72013-05-23 10:56:4612533 scoped_ptr<SpdyFrame> host2_req(spdy_util_.ConstructSpdyGet(
[email protected]483fa202013-05-14 01:07:0312534 "https://www.b.com", false, 1, DEFAULT_PRIORITY));
12535 MockWrite spdy2_writes[] = {
rch8e6c6c42015-05-01 14:05:1312536 CreateMockWrite(*host2_req, 0),
[email protected]483fa202013-05-14 01:07:0312537 };
[email protected]23e482282013-06-14 16:08:0212538 scoped_ptr<SpdyFrame> host2_resp(
12539 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12540 scoped_ptr<SpdyFrame> host2_resp_body(
12541 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0312542 MockRead spdy2_reads[] = {
rch8e6c6c42015-05-01 14:05:1312543 CreateMockRead(*host2_resp, 1),
12544 CreateMockRead(*host2_resp_body, 2),
12545 MockRead(ASYNC, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0312546 };
12547
rch8e6c6c42015-05-01 14:05:1312548 scoped_ptr<SequencedSocketData> spdy2_data(
12549 new SequencedSocketData(spdy2_reads, arraysize(spdy2_reads), spdy2_writes,
12550 arraysize(spdy2_writes)));
[email protected]483fa202013-05-14 01:07:0312551 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
12552
12553 MockWrite http_write[] = {
12554 MockWrite("GET / HTTP/1.1\r\n"
12555 "Host: www.a.com\r\n"
12556 "Connection: keep-alive\r\n\r\n"),
12557 };
12558
12559 MockRead http_read[] = {
12560 MockRead("HTTP/1.1 200 OK\r\n"),
12561 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12562 MockRead("Content-Length: 6\r\n\r\n"),
12563 MockRead("hello!"),
12564 };
12565 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
12566 http_write, arraysize(http_write));
12567 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12568
12569 HostPortPair host_port_pair_a("www.a.com", 443);
[email protected]e6d017652013-05-17 18:01:4012570 SpdySessionKey spdy_session_key_a(
[email protected]314b03992014-04-01 01:28:5312571 host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0312572 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2612573 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0312574
12575 TestCompletionCallback callback;
12576 HttpRequestInfo request1;
12577 request1.method = "GET";
12578 request1.url = GURL("https://www.a.com/");
12579 request1.load_flags = 0;
12580 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5012581 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0312582
12583 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
12584 EXPECT_EQ(ERR_IO_PENDING, rv);
12585 EXPECT_EQ(OK, callback.WaitForResult());
12586
12587 const HttpResponseInfo* response = trans->GetResponseInfo();
12588 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5012589 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0312590 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12591 EXPECT_TRUE(response->was_fetched_via_spdy);
12592 EXPECT_TRUE(response->was_npn_negotiated);
12593
12594 std::string response_data;
12595 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
12596 EXPECT_EQ("hello!", response_data);
12597 trans.reset();
12598 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2612599 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0312600
12601 HostPortPair host_port_pair_b("www.b.com", 443);
[email protected]e6d017652013-05-17 18:01:4012602 SpdySessionKey spdy_session_key_b(
[email protected]314b03992014-04-01 01:28:5312603 host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0312604 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2612605 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0312606 HttpRequestInfo request2;
12607 request2.method = "GET";
12608 request2.url = GURL("https://www.b.com/");
12609 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012610 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0312611
12612 rv = trans->Start(&request2, callback.callback(), BoundNetLog());
12613 EXPECT_EQ(ERR_IO_PENDING, rv);
12614 EXPECT_EQ(OK, callback.WaitForResult());
12615
12616 response = trans->GetResponseInfo();
12617 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5012618 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0312619 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12620 EXPECT_TRUE(response->was_fetched_via_spdy);
12621 EXPECT_TRUE(response->was_npn_negotiated);
12622 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
12623 EXPECT_EQ("hello!", response_data);
12624 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2612625 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0312626 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2612627 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0312628
12629 HostPortPair host_port_pair_a1("www.a.com", 80);
[email protected]e6d017652013-05-17 18:01:4012630 SpdySessionKey spdy_session_key_a1(
[email protected]314b03992014-04-01 01:28:5312631 host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0312632 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2612633 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0312634 HttpRequestInfo request3;
12635 request3.method = "GET";
12636 request3.url = GURL("http://www.a.com/");
12637 request3.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012638 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0312639
12640 rv = trans->Start(&request3, callback.callback(), BoundNetLog());
12641 EXPECT_EQ(ERR_IO_PENDING, rv);
12642 EXPECT_EQ(OK, callback.WaitForResult());
12643
12644 response = trans->GetResponseInfo();
12645 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5012646 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0312647 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12648 EXPECT_FALSE(response->was_fetched_via_spdy);
12649 EXPECT_FALSE(response->was_npn_negotiated);
12650 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
12651 EXPECT_EQ("hello!", response_data);
12652 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2612653 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0312654 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2612655 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0312656}
12657
[email protected]79e1fd62013-06-20 06:50:0412658TEST_P(HttpNetworkTransactionTest, HttpSyncConnectError) {
12659 HttpRequestInfo request;
12660 request.method = "GET";
bncce36dca22015-04-21 22:11:2312661 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0412662 request.load_flags = 0;
12663
[email protected]3fe8d2f82013-10-17 08:56:0712664 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412665 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112666 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412667
12668 MockConnect mock_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
12669 StaticSocketDataProvider data;
12670 data.set_connect_data(mock_connect);
12671 session_deps_.socket_factory->AddSocketDataProvider(&data);
12672
12673 TestCompletionCallback callback;
12674
12675 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12676 EXPECT_EQ(ERR_IO_PENDING, rv);
12677
12678 rv = callback.WaitForResult();
12679 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
12680
[email protected]79e1fd62013-06-20 06:50:0412681 // We don't care whether this succeeds or fails, but it shouldn't crash.
12682 HttpRequestHeaders request_headers;
12683 trans->GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4712684
12685 ConnectionAttempts attempts;
12686 trans->GetConnectionAttempts(&attempts);
12687 ASSERT_EQ(1u, attempts.size());
12688 EXPECT_EQ(ERR_CONNECTION_REFUSED, attempts[0].result);
[email protected]79e1fd62013-06-20 06:50:0412689}
12690
12691TEST_P(HttpNetworkTransactionTest, HttpAsyncConnectError) {
12692 HttpRequestInfo request;
12693 request.method = "GET";
bncce36dca22015-04-21 22:11:2312694 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0412695 request.load_flags = 0;
12696
[email protected]3fe8d2f82013-10-17 08:56:0712697 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412698 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112699 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412700
12701 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
12702 StaticSocketDataProvider data;
12703 data.set_connect_data(mock_connect);
12704 session_deps_.socket_factory->AddSocketDataProvider(&data);
12705
12706 TestCompletionCallback callback;
12707
12708 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12709 EXPECT_EQ(ERR_IO_PENDING, rv);
12710
12711 rv = callback.WaitForResult();
12712 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
12713
[email protected]79e1fd62013-06-20 06:50:0412714 // We don't care whether this succeeds or fails, but it shouldn't crash.
12715 HttpRequestHeaders request_headers;
12716 trans->GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4712717
12718 ConnectionAttempts attempts;
12719 trans->GetConnectionAttempts(&attempts);
12720 ASSERT_EQ(1u, attempts.size());
12721 EXPECT_EQ(ERR_CONNECTION_REFUSED, attempts[0].result);
[email protected]79e1fd62013-06-20 06:50:0412722}
12723
12724TEST_P(HttpNetworkTransactionTest, HttpSyncWriteError) {
12725 HttpRequestInfo request;
12726 request.method = "GET";
bncce36dca22015-04-21 22:11:2312727 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0412728 request.load_flags = 0;
12729
[email protected]3fe8d2f82013-10-17 08:56:0712730 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412731 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112732 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412733
12734 MockWrite data_writes[] = {
12735 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
12736 };
12737 MockRead data_reads[] = {
12738 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
12739 };
12740
12741 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12742 data_writes, arraysize(data_writes));
12743 session_deps_.socket_factory->AddSocketDataProvider(&data);
12744
12745 TestCompletionCallback callback;
12746
12747 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12748 EXPECT_EQ(ERR_IO_PENDING, rv);
12749
12750 rv = callback.WaitForResult();
12751 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12752
[email protected]79e1fd62013-06-20 06:50:0412753 HttpRequestHeaders request_headers;
12754 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12755 EXPECT_TRUE(request_headers.HasHeader("Host"));
12756}
12757
12758TEST_P(HttpNetworkTransactionTest, HttpAsyncWriteError) {
12759 HttpRequestInfo request;
12760 request.method = "GET";
bncce36dca22015-04-21 22:11:2312761 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0412762 request.load_flags = 0;
12763
[email protected]3fe8d2f82013-10-17 08:56:0712764 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412765 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112766 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412767
12768 MockWrite data_writes[] = {
12769 MockWrite(ASYNC, ERR_CONNECTION_RESET),
12770 };
12771 MockRead data_reads[] = {
12772 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
12773 };
12774
12775 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12776 data_writes, arraysize(data_writes));
12777 session_deps_.socket_factory->AddSocketDataProvider(&data);
12778
12779 TestCompletionCallback callback;
12780
12781 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12782 EXPECT_EQ(ERR_IO_PENDING, rv);
12783
12784 rv = callback.WaitForResult();
12785 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12786
[email protected]79e1fd62013-06-20 06:50:0412787 HttpRequestHeaders request_headers;
12788 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12789 EXPECT_TRUE(request_headers.HasHeader("Host"));
12790}
12791
12792TEST_P(HttpNetworkTransactionTest, HttpSyncReadError) {
12793 HttpRequestInfo request;
12794 request.method = "GET";
bncce36dca22015-04-21 22:11:2312795 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0412796 request.load_flags = 0;
12797
[email protected]3fe8d2f82013-10-17 08:56:0712798 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412799 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112800 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412801
12802 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2312803 MockWrite(
12804 "GET / HTTP/1.1\r\n"
12805 "Host: www.example.org\r\n"
12806 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0412807 };
12808 MockRead data_reads[] = {
12809 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
12810 };
12811
12812 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12813 data_writes, arraysize(data_writes));
12814 session_deps_.socket_factory->AddSocketDataProvider(&data);
12815
12816 TestCompletionCallback callback;
12817
12818 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12819 EXPECT_EQ(ERR_IO_PENDING, rv);
12820
12821 rv = callback.WaitForResult();
12822 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12823
[email protected]79e1fd62013-06-20 06:50:0412824 HttpRequestHeaders request_headers;
12825 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12826 EXPECT_TRUE(request_headers.HasHeader("Host"));
12827}
12828
12829TEST_P(HttpNetworkTransactionTest, HttpAsyncReadError) {
12830 HttpRequestInfo request;
12831 request.method = "GET";
bncce36dca22015-04-21 22:11:2312832 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0412833 request.load_flags = 0;
12834
[email protected]3fe8d2f82013-10-17 08:56:0712835 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412836 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112837 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412838
12839 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2312840 MockWrite(
12841 "GET / HTTP/1.1\r\n"
12842 "Host: www.example.org\r\n"
12843 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0412844 };
12845 MockRead data_reads[] = {
12846 MockRead(ASYNC, ERR_CONNECTION_RESET),
12847 };
12848
12849 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12850 data_writes, arraysize(data_writes));
12851 session_deps_.socket_factory->AddSocketDataProvider(&data);
12852
12853 TestCompletionCallback callback;
12854
12855 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12856 EXPECT_EQ(ERR_IO_PENDING, rv);
12857
12858 rv = callback.WaitForResult();
12859 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12860
[email protected]79e1fd62013-06-20 06:50:0412861 HttpRequestHeaders request_headers;
12862 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12863 EXPECT_TRUE(request_headers.HasHeader("Host"));
12864}
12865
12866TEST_P(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
12867 HttpRequestInfo request;
12868 request.method = "GET";
bncce36dca22015-04-21 22:11:2312869 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0412870 request.load_flags = 0;
12871 request.extra_headers.SetHeader("X-Foo", "bar");
12872
[email protected]3fe8d2f82013-10-17 08:56:0712873 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412874 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112875 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412876
12877 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2312878 MockWrite(
12879 "GET / HTTP/1.1\r\n"
12880 "Host: www.example.org\r\n"
12881 "Connection: keep-alive\r\n"
12882 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0412883 };
12884 MockRead data_reads[] = {
12885 MockRead("HTTP/1.1 200 OK\r\n"
12886 "Content-Length: 5\r\n\r\n"
12887 "hello"),
12888 MockRead(ASYNC, ERR_UNEXPECTED),
12889 };
12890
12891 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12892 data_writes, arraysize(data_writes));
12893 session_deps_.socket_factory->AddSocketDataProvider(&data);
12894
12895 TestCompletionCallback callback;
12896
12897 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12898 EXPECT_EQ(ERR_IO_PENDING, rv);
12899
12900 rv = callback.WaitForResult();
12901 EXPECT_EQ(OK, rv);
12902
12903 HttpRequestHeaders request_headers;
12904 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12905 std::string foo;
12906 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
12907 EXPECT_EQ("bar", foo);
12908}
12909
[email protected]bf828982013-08-14 18:01:4712910namespace {
12911
yhiranoa7e05bb2014-11-06 05:40:3912912// Fake HttpStream that simply records calls to SetPriority().
12913class FakeStream : public HttpStream,
[email protected]e86839fd2013-08-14 18:29:0312914 public base::SupportsWeakPtr<FakeStream> {
12915 public:
12916 explicit FakeStream(RequestPriority priority) : priority_(priority) {}
dchengb03027d2014-10-21 12:00:2012917 ~FakeStream() override {}
[email protected]e86839fd2013-08-14 18:29:0312918
12919 RequestPriority priority() const { return priority_; }
12920
dchengb03027d2014-10-21 12:00:2012921 int InitializeStream(const HttpRequestInfo* request_info,
12922 RequestPriority priority,
12923 const BoundNetLog& net_log,
12924 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0312925 return ERR_IO_PENDING;
12926 }
12927
dchengb03027d2014-10-21 12:00:2012928 int SendRequest(const HttpRequestHeaders& request_headers,
12929 HttpResponseInfo* response,
12930 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0312931 ADD_FAILURE();
12932 return ERR_UNEXPECTED;
12933 }
12934
dchengb03027d2014-10-21 12:00:2012935 int ReadResponseHeaders(const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0312936 ADD_FAILURE();
12937 return ERR_UNEXPECTED;
12938 }
12939
dchengb03027d2014-10-21 12:00:2012940 int ReadResponseBody(IOBuffer* buf,
12941 int buf_len,
12942 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0312943 ADD_FAILURE();
12944 return ERR_UNEXPECTED;
12945 }
12946
dchengb03027d2014-10-21 12:00:2012947 void Close(bool not_reusable) override {}
[email protected]e86839fd2013-08-14 18:29:0312948
dchengb03027d2014-10-21 12:00:2012949 bool IsResponseBodyComplete() const override {
[email protected]e86839fd2013-08-14 18:29:0312950 ADD_FAILURE();
12951 return false;
12952 }
12953
dchengb03027d2014-10-21 12:00:2012954 bool CanFindEndOfResponse() const override { return false; }
[email protected]e86839fd2013-08-14 18:29:0312955
dchengb03027d2014-10-21 12:00:2012956 bool IsConnectionReused() const override {
[email protected]e86839fd2013-08-14 18:29:0312957 ADD_FAILURE();
12958 return false;
12959 }
12960
dchengb03027d2014-10-21 12:00:2012961 void SetConnectionReused() override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0312962
dchengb03027d2014-10-21 12:00:2012963 bool IsConnectionReusable() const override {
[email protected]e86839fd2013-08-14 18:29:0312964 ADD_FAILURE();
12965 return false;
12966 }
12967
dchengb03027d2014-10-21 12:00:2012968 int64 GetTotalReceivedBytes() const override {
[email protected]bc92bc972013-12-13 08:32:5912969 ADD_FAILURE();
12970 return 0;
12971 }
12972
dchengb03027d2014-10-21 12:00:2012973 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
[email protected]e86839fd2013-08-14 18:29:0312974 ADD_FAILURE();
12975 return false;
12976 }
12977
dchengb03027d2014-10-21 12:00:2012978 void GetSSLInfo(SSLInfo* ssl_info) override { ADD_FAILURE(); }
12979
12980 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
[email protected]e86839fd2013-08-14 18:29:0312981 ADD_FAILURE();
12982 }
12983
dchengb03027d2014-10-21 12:00:2012984 bool IsSpdyHttpStream() const override {
[email protected]e86839fd2013-08-14 18:29:0312985 ADD_FAILURE();
12986 return false;
12987 }
12988
dchengb03027d2014-10-21 12:00:2012989 void Drain(HttpNetworkSession* session) override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0312990
dchengb03027d2014-10-21 12:00:2012991 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]e86839fd2013-08-14 18:29:0312992
yhiranoa7e05bb2014-11-06 05:40:3912993 UploadProgress GetUploadProgress() const override { return UploadProgress(); }
12994
12995 HttpStream* RenewStreamForAuth() override { return NULL; }
12996
[email protected]e86839fd2013-08-14 18:29:0312997 private:
12998 RequestPriority priority_;
12999
13000 DISALLOW_COPY_AND_ASSIGN(FakeStream);
13001};
13002
13003// Fake HttpStreamRequest that simply records calls to SetPriority()
13004// and vends FakeStreams with its current priority.
[email protected]bf828982013-08-14 18:01:4713005class FakeStreamRequest : public HttpStreamRequest,
13006 public base::SupportsWeakPtr<FakeStreamRequest> {
13007 public:
[email protected]e86839fd2013-08-14 18:29:0313008 FakeStreamRequest(RequestPriority priority,
13009 HttpStreamRequest::Delegate* delegate)
13010 : priority_(priority),
[email protected]831e4a32013-11-14 02:14:4413011 delegate_(delegate),
13012 websocket_stream_create_helper_(NULL) {}
13013
13014 FakeStreamRequest(RequestPriority priority,
13015 HttpStreamRequest::Delegate* delegate,
13016 WebSocketHandshakeStreamBase::CreateHelper* create_helper)
13017 : priority_(priority),
13018 delegate_(delegate),
13019 websocket_stream_create_helper_(create_helper) {}
[email protected]e86839fd2013-08-14 18:29:0313020
dchengb03027d2014-10-21 12:00:2013021 ~FakeStreamRequest() override {}
[email protected]bf828982013-08-14 18:01:4713022
13023 RequestPriority priority() const { return priority_; }
13024
[email protected]831e4a32013-11-14 02:14:4413025 const WebSocketHandshakeStreamBase::CreateHelper*
13026 websocket_stream_create_helper() const {
13027 return websocket_stream_create_helper_;
13028 }
13029
[email protected]e86839fd2013-08-14 18:29:0313030 // Create a new FakeStream and pass it to the request's
13031 // delegate. Returns a weak pointer to the FakeStream.
13032 base::WeakPtr<FakeStream> FinishStreamRequest() {
13033 FakeStream* fake_stream = new FakeStream(priority_);
13034 // Do this before calling OnStreamReady() as OnStreamReady() may
13035 // immediately delete |fake_stream|.
13036 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
13037 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), fake_stream);
13038 return weak_stream;
13039 }
13040
dchengb03027d2014-10-21 12:00:2013041 int RestartTunnelWithProxyAuth(const AuthCredentials& credentials) override {
[email protected]bf828982013-08-14 18:01:4713042 ADD_FAILURE();
13043 return ERR_UNEXPECTED;
13044 }
13045
dchengb03027d2014-10-21 12:00:2013046 LoadState GetLoadState() const override {
[email protected]bf828982013-08-14 18:01:4713047 ADD_FAILURE();
13048 return LoadState();
13049 }
13050
dchengb03027d2014-10-21 12:00:2013051 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]bf828982013-08-14 18:01:4713052
dchengb03027d2014-10-21 12:00:2013053 bool was_npn_negotiated() const override { return false; }
[email protected]bf828982013-08-14 18:01:4713054
dchengb03027d2014-10-21 12:00:2013055 NextProto protocol_negotiated() const override { return kProtoUnknown; }
[email protected]bf828982013-08-14 18:01:4713056
dchengb03027d2014-10-21 12:00:2013057 bool using_spdy() const override { return false; }
[email protected]bf828982013-08-14 18:01:4713058
ttuttle1f2d7e92015-04-28 16:17:4713059 const ConnectionAttempts& connection_attempts() const override {
13060 static ConnectionAttempts no_attempts;
13061 return no_attempts;
13062 }
13063
[email protected]bf828982013-08-14 18:01:4713064 private:
13065 RequestPriority priority_;
[email protected]e86839fd2013-08-14 18:29:0313066 HttpStreamRequest::Delegate* const delegate_;
[email protected]831e4a32013-11-14 02:14:4413067 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
[email protected]bf828982013-08-14 18:01:4713068
13069 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
13070};
13071
13072// Fake HttpStreamFactory that vends FakeStreamRequests.
13073class FakeStreamFactory : public HttpStreamFactory {
13074 public:
13075 FakeStreamFactory() {}
dchengb03027d2014-10-21 12:00:2013076 ~FakeStreamFactory() override {}
[email protected]bf828982013-08-14 18:01:4713077
13078 // Returns a WeakPtr<> to the last HttpStreamRequest returned by
13079 // RequestStream() (which may be NULL if it was destroyed already).
13080 base::WeakPtr<FakeStreamRequest> last_stream_request() {
13081 return last_stream_request_;
13082 }
13083
dchengb03027d2014-10-21 12:00:2013084 HttpStreamRequest* RequestStream(const HttpRequestInfo& info,
13085 RequestPriority priority,
13086 const SSLConfig& server_ssl_config,
13087 const SSLConfig& proxy_ssl_config,
13088 HttpStreamRequest::Delegate* delegate,
13089 const BoundNetLog& net_log) override {
[email protected]e86839fd2013-08-14 18:29:0313090 FakeStreamRequest* fake_request = new FakeStreamRequest(priority, delegate);
[email protected]bf828982013-08-14 18:01:4713091 last_stream_request_ = fake_request->AsWeakPtr();
13092 return fake_request;
13093 }
13094
dchengb03027d2014-10-21 12:00:2013095 HttpStreamRequest* RequestWebSocketHandshakeStream(
[email protected]bf828982013-08-14 18:01:4713096 const HttpRequestInfo& info,
13097 RequestPriority priority,
13098 const SSLConfig& server_ssl_config,
13099 const SSLConfig& proxy_ssl_config,
13100 HttpStreamRequest::Delegate* delegate,
[email protected]467086b2013-11-12 08:19:4613101 WebSocketHandshakeStreamBase::CreateHelper* create_helper,
mostynbba063d6032014-10-09 11:01:1313102 const BoundNetLog& net_log) override {
[email protected]831e4a32013-11-14 02:14:4413103 FakeStreamRequest* fake_request =
13104 new FakeStreamRequest(priority, delegate, create_helper);
13105 last_stream_request_ = fake_request->AsWeakPtr();
13106 return fake_request;
[email protected]bf828982013-08-14 18:01:4713107 }
13108
dchengb03027d2014-10-21 12:00:2013109 void PreconnectStreams(int num_streams,
13110 const HttpRequestInfo& info,
dchengb03027d2014-10-21 12:00:2013111 const SSLConfig& server_ssl_config,
13112 const SSLConfig& proxy_ssl_config) override {
[email protected]bf828982013-08-14 18:01:4713113 ADD_FAILURE();
13114 }
13115
dchengb03027d2014-10-21 12:00:2013116 const HostMappingRules* GetHostMappingRules() const override {
[email protected]bf828982013-08-14 18:01:4713117 ADD_FAILURE();
13118 return NULL;
13119 }
13120
13121 private:
13122 base::WeakPtr<FakeStreamRequest> last_stream_request_;
13123
13124 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
13125};
13126
Adam Rice425cf122015-01-19 06:18:2413127// TODO(ricea): Maybe unify this with the one in
13128// url_request_http_job_unittest.cc ?
13129class FakeWebSocketBasicHandshakeStream : public WebSocketHandshakeStreamBase {
13130 public:
13131 FakeWebSocketBasicHandshakeStream(scoped_ptr<ClientSocketHandle> connection,
13132 bool using_proxy)
13133 : state_(connection.release(), using_proxy) {}
13134
13135 // Fake implementation of HttpStreamBase methods.
13136 // This ends up being quite "real" because this object has to really send data
13137 // on the mock socket. It might be easier to use the real implementation, but
13138 // the fact that the WebSocket code is not compiled on iOS makes that
13139 // difficult.
13140 int InitializeStream(const HttpRequestInfo* request_info,
13141 RequestPriority priority,
13142 const BoundNetLog& net_log,
13143 const CompletionCallback& callback) override {
13144 state_.Initialize(request_info, priority, net_log, callback);
13145 return OK;
13146 }
13147
13148 int SendRequest(const HttpRequestHeaders& request_headers,
13149 HttpResponseInfo* response,
13150 const CompletionCallback& callback) override {
13151 return parser()->SendRequest(state_.GenerateRequestLine(), request_headers,
13152 response, callback);
13153 }
13154
13155 int ReadResponseHeaders(const CompletionCallback& callback) override {
13156 return parser()->ReadResponseHeaders(callback);
13157 }
13158
13159 int ReadResponseBody(IOBuffer* buf,
13160 int buf_len,
13161 const CompletionCallback& callback) override {
13162 NOTREACHED();
13163 return ERR_IO_PENDING;
13164 }
13165
13166 void Close(bool not_reusable) override {
13167 if (parser())
13168 parser()->Close(true);
13169 }
13170
13171 bool IsResponseBodyComplete() const override {
13172 NOTREACHED();
13173 return false;
13174 }
13175
13176 bool CanFindEndOfResponse() const override {
13177 return parser()->CanFindEndOfResponse();
13178 }
13179
13180 bool IsConnectionReused() const override {
13181 NOTREACHED();
13182 return false;
13183 }
13184 void SetConnectionReused() override { NOTREACHED(); }
13185
13186 bool IsConnectionReusable() const override {
13187 NOTREACHED();
13188 return false;
13189 }
13190
13191 int64 GetTotalReceivedBytes() const override {
13192 NOTREACHED();
13193 return 0;
13194 }
13195
13196 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
13197 NOTREACHED();
13198 return false;
13199 }
13200
Adam Ricecb76ac62015-02-20 05:33:2513201 void GetSSLInfo(SSLInfo* ssl_info) override {}
Adam Rice425cf122015-01-19 06:18:2413202
13203 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
13204 NOTREACHED();
13205 }
13206
13207 bool IsSpdyHttpStream() const override {
13208 NOTREACHED();
13209 return false;
13210 }
13211
13212 void Drain(HttpNetworkSession* session) override { NOTREACHED(); }
13213
13214 void SetPriority(RequestPriority priority) override { NOTREACHED(); }
13215
13216 UploadProgress GetUploadProgress() const override {
13217 NOTREACHED();
13218 return UploadProgress();
13219 }
13220
13221 HttpStream* RenewStreamForAuth() override {
13222 NOTREACHED();
13223 return nullptr;
13224 }
13225
13226 // Fake implementation of WebSocketHandshakeStreamBase method(s)
13227 scoped_ptr<WebSocketStream> Upgrade() override {
13228 NOTREACHED();
13229 return scoped_ptr<WebSocketStream>();
13230 }
13231
13232 private:
13233 HttpStreamParser* parser() const { return state_.parser(); }
13234 HttpBasicState state_;
13235
13236 DISALLOW_COPY_AND_ASSIGN(FakeWebSocketBasicHandshakeStream);
13237};
13238
[email protected]831e4a32013-11-14 02:14:4413239// TODO(yhirano): Split this class out into a net/websockets file, if it is
13240// worth doing.
13241class FakeWebSocketStreamCreateHelper :
13242 public WebSocketHandshakeStreamBase::CreateHelper {
13243 public:
dchengb03027d2014-10-21 12:00:2013244 WebSocketHandshakeStreamBase* CreateBasicStream(
[email protected]7e841a52013-11-22 09:04:2113245 scoped_ptr<ClientSocketHandle> connection,
mostynbba063d6032014-10-09 11:01:1313246 bool using_proxy) override {
Adam Rice425cf122015-01-19 06:18:2413247 return new FakeWebSocketBasicHandshakeStream(connection.Pass(),
13248 using_proxy);
[email protected]831e4a32013-11-14 02:14:4413249 }
13250
dchengb03027d2014-10-21 12:00:2013251 WebSocketHandshakeStreamBase* CreateSpdyStream(
[email protected]831e4a32013-11-14 02:14:4413252 const base::WeakPtr<SpdySession>& session,
mostynbba063d6032014-10-09 11:01:1313253 bool use_relative_url) override {
[email protected]831e4a32013-11-14 02:14:4413254 NOTREACHED();
13255 return NULL;
13256 };
13257
dchengb03027d2014-10-21 12:00:2013258 ~FakeWebSocketStreamCreateHelper() override {}
[email protected]831e4a32013-11-14 02:14:4413259
13260 virtual scoped_ptr<WebSocketStream> Upgrade() {
13261 NOTREACHED();
13262 return scoped_ptr<WebSocketStream>();
13263 }
13264};
13265
[email protected]bf828982013-08-14 18:01:4713266} // namespace
13267
13268// Make sure that HttpNetworkTransaction passes on its priority to its
13269// stream request on start.
13270TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
13271 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13272 HttpNetworkSessionPeer peer(session);
13273 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4413274 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4713275
dcheng48459ac22014-08-26 00:46:4113276 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4713277
13278 ASSERT_TRUE(fake_factory->last_stream_request() == NULL);
13279
13280 HttpRequestInfo request;
13281 TestCompletionCallback callback;
13282 EXPECT_EQ(ERR_IO_PENDING,
13283 trans.Start(&request, callback.callback(), BoundNetLog()));
13284
13285 base::WeakPtr<FakeStreamRequest> fake_request =
13286 fake_factory->last_stream_request();
13287 ASSERT_TRUE(fake_request != NULL);
13288 EXPECT_EQ(LOW, fake_request->priority());
13289}
13290
13291// Make sure that HttpNetworkTransaction passes on its priority
13292// updates to its stream request.
13293TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriority) {
13294 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13295 HttpNetworkSessionPeer peer(session);
13296 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4413297 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4713298
dcheng48459ac22014-08-26 00:46:4113299 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4713300
13301 HttpRequestInfo request;
13302 TestCompletionCallback callback;
13303 EXPECT_EQ(ERR_IO_PENDING,
13304 trans.Start(&request, callback.callback(), BoundNetLog()));
13305
13306 base::WeakPtr<FakeStreamRequest> fake_request =
13307 fake_factory->last_stream_request();
13308 ASSERT_TRUE(fake_request != NULL);
13309 EXPECT_EQ(LOW, fake_request->priority());
13310
13311 trans.SetPriority(LOWEST);
13312 ASSERT_TRUE(fake_request != NULL);
13313 EXPECT_EQ(LOWEST, fake_request->priority());
13314}
13315
[email protected]e86839fd2013-08-14 18:29:0313316// Make sure that HttpNetworkTransaction passes on its priority
13317// updates to its stream.
13318TEST_P(HttpNetworkTransactionTest, SetStreamPriority) {
13319 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13320 HttpNetworkSessionPeer peer(session);
13321 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4413322 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]e86839fd2013-08-14 18:29:0313323
dcheng48459ac22014-08-26 00:46:4113324 HttpNetworkTransaction trans(LOW, session.get());
[email protected]e86839fd2013-08-14 18:29:0313325
13326 HttpRequestInfo request;
13327 TestCompletionCallback callback;
13328 EXPECT_EQ(ERR_IO_PENDING,
13329 trans.Start(&request, callback.callback(), BoundNetLog()));
13330
13331 base::WeakPtr<FakeStreamRequest> fake_request =
13332 fake_factory->last_stream_request();
13333 ASSERT_TRUE(fake_request != NULL);
13334 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
13335 ASSERT_TRUE(fake_stream != NULL);
13336 EXPECT_EQ(LOW, fake_stream->priority());
13337
13338 trans.SetPriority(LOWEST);
13339 EXPECT_EQ(LOWEST, fake_stream->priority());
13340}
13341
[email protected]831e4a32013-11-14 02:14:4413342TEST_P(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
13343 // The same logic needs to be tested for both ws: and wss: schemes, but this
13344 // test is already parameterised on NextProto, so it uses a loop to verify
13345 // that the different schemes work.
bncce36dca22015-04-21 22:11:2313346 std::string test_cases[] = {"ws://www.example.org/",
13347 "wss://www.example.org/"};
[email protected]831e4a32013-11-14 02:14:4413348 for (size_t i = 0; i < arraysize(test_cases); ++i) {
13349 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13350 HttpNetworkSessionPeer peer(session);
13351 FakeStreamFactory* fake_factory = new FakeStreamFactory();
13352 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
[email protected]0191b51c2013-11-18 10:55:2313353 peer.SetHttpStreamFactoryForWebSocket(
[email protected]831e4a32013-11-14 02:14:4413354 scoped_ptr<HttpStreamFactory>(fake_factory));
13355
dcheng48459ac22014-08-26 00:46:4113356 HttpNetworkTransaction trans(LOW, session.get());
[email protected]831e4a32013-11-14 02:14:4413357 trans.SetWebSocketHandshakeStreamCreateHelper(
13358 &websocket_stream_create_helper);
13359
13360 HttpRequestInfo request;
13361 TestCompletionCallback callback;
13362 request.method = "GET";
13363 request.url = GURL(test_cases[i]);
13364
13365 EXPECT_EQ(ERR_IO_PENDING,
13366 trans.Start(&request, callback.callback(), BoundNetLog()));
13367
13368 base::WeakPtr<FakeStreamRequest> fake_request =
13369 fake_factory->last_stream_request();
13370 ASSERT_TRUE(fake_request != NULL);
13371 EXPECT_EQ(&websocket_stream_create_helper,
13372 fake_request->websocket_stream_create_helper());
13373 }
13374}
13375
[email protected]043b68c82013-08-22 23:41:5213376// Tests that when a used socket is returned to the SSL socket pool, it's closed
13377// if the transport socket pool is stalled on the global socket limit.
13378TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
13379 ClientSocketPoolManager::set_max_sockets_per_group(
13380 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13381 ClientSocketPoolManager::set_max_sockets_per_pool(
13382 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13383
13384 // Set up SSL request.
13385
13386 HttpRequestInfo ssl_request;
13387 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2313388 ssl_request.url = GURL("https://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5213389
13390 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2313391 MockWrite(
13392 "GET / HTTP/1.1\r\n"
13393 "Host: www.example.org\r\n"
13394 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5213395 };
13396 MockRead ssl_reads[] = {
13397 MockRead("HTTP/1.1 200 OK\r\n"),
13398 MockRead("Content-Length: 11\r\n\r\n"),
13399 MockRead("hello world"),
13400 MockRead(SYNCHRONOUS, OK),
13401 };
13402 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
13403 ssl_writes, arraysize(ssl_writes));
13404 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
13405
13406 SSLSocketDataProvider ssl(ASYNC, OK);
13407 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13408
13409 // Set up HTTP request.
13410
13411 HttpRequestInfo http_request;
13412 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2313413 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5213414
13415 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2313416 MockWrite(
13417 "GET / HTTP/1.1\r\n"
13418 "Host: www.example.org\r\n"
13419 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5213420 };
13421 MockRead http_reads[] = {
13422 MockRead("HTTP/1.1 200 OK\r\n"),
13423 MockRead("Content-Length: 7\r\n\r\n"),
13424 MockRead("falafel"),
13425 MockRead(SYNCHRONOUS, OK),
13426 };
13427 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
13428 http_writes, arraysize(http_writes));
13429 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13430
13431 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13432
13433 // Start the SSL request.
13434 TestCompletionCallback ssl_callback;
13435 scoped_ptr<HttpTransaction> ssl_trans(
13436 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13437 ASSERT_EQ(ERR_IO_PENDING,
13438 ssl_trans->Start(&ssl_request, ssl_callback.callback(),
13439 BoundNetLog()));
13440
13441 // Start the HTTP request. Pool should stall.
13442 TestCompletionCallback http_callback;
13443 scoped_ptr<HttpTransaction> http_trans(
13444 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13445 ASSERT_EQ(ERR_IO_PENDING,
13446 http_trans->Start(&http_request, http_callback.callback(),
13447 BoundNetLog()));
dcheng48459ac22014-08-26 00:46:4113448 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5213449
13450 // Wait for response from SSL request.
13451 ASSERT_EQ(OK, ssl_callback.WaitForResult());
13452 std::string response_data;
13453 ASSERT_EQ(OK, ReadTransaction(ssl_trans.get(), &response_data));
13454 EXPECT_EQ("hello world", response_data);
13455
13456 // The SSL socket should automatically be closed, so the HTTP request can
13457 // start.
dcheng48459ac22014-08-26 00:46:4113458 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
13459 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5213460
13461 // The HTTP request can now complete.
13462 ASSERT_EQ(OK, http_callback.WaitForResult());
13463 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
13464 EXPECT_EQ("falafel", response_data);
13465
dcheng48459ac22014-08-26 00:46:4113466 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5213467}
13468
13469// Tests that when a SSL connection is established but there's no corresponding
13470// request that needs it, the new socket is closed if the transport socket pool
13471// is stalled on the global socket limit.
13472TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
13473 ClientSocketPoolManager::set_max_sockets_per_group(
13474 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13475 ClientSocketPoolManager::set_max_sockets_per_pool(
13476 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13477
13478 // Set up an ssl request.
13479
13480 HttpRequestInfo ssl_request;
13481 ssl_request.method = "GET";
13482 ssl_request.url = GURL("https://www.foopy.com/");
13483
13484 // No data will be sent on the SSL socket.
13485 StaticSocketDataProvider ssl_data;
13486 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
13487
13488 SSLSocketDataProvider ssl(ASYNC, OK);
13489 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13490
13491 // Set up HTTP request.
13492
13493 HttpRequestInfo http_request;
13494 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2313495 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5213496
13497 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2313498 MockWrite(
13499 "GET / HTTP/1.1\r\n"
13500 "Host: www.example.org\r\n"
13501 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5213502 };
13503 MockRead http_reads[] = {
13504 MockRead("HTTP/1.1 200 OK\r\n"),
13505 MockRead("Content-Length: 7\r\n\r\n"),
13506 MockRead("falafel"),
13507 MockRead(SYNCHRONOUS, OK),
13508 };
13509 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
13510 http_writes, arraysize(http_writes));
13511 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13512
13513 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13514
13515 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
13516 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2913517 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
13518 SSLConfig ssl_config;
[email protected]043b68c82013-08-22 23:41:5213519 session->ssl_config_service()->GetSSLConfig(&ssl_config);
mmenked1205bd3972015-07-15 22:26:3513520 http_stream_factory->PreconnectStreams(1, ssl_request, ssl_config,
13521 ssl_config);
dcheng48459ac22014-08-26 00:46:4113522 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5213523
13524 // Start the HTTP request. Pool should stall.
13525 TestCompletionCallback http_callback;
13526 scoped_ptr<HttpTransaction> http_trans(
13527 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13528 ASSERT_EQ(ERR_IO_PENDING,
13529 http_trans->Start(&http_request, http_callback.callback(),
13530 BoundNetLog()));
dcheng48459ac22014-08-26 00:46:4113531 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5213532
13533 // The SSL connection will automatically be closed once the connection is
13534 // established, to let the HTTP request start.
13535 ASSERT_EQ(OK, http_callback.WaitForResult());
13536 std::string response_data;
13537 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
13538 EXPECT_EQ("falafel", response_data);
13539
dcheng48459ac22014-08-26 00:46:4113540 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5213541}
13542
[email protected]02d74a02014-04-23 18:10:5413543TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
13544 ScopedVector<UploadElementReader> element_readers;
13545 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713546 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413547
13548 HttpRequestInfo request;
13549 request.method = "POST";
13550 request.url = GURL("http://www.foo.com/");
13551 request.upload_data_stream = &upload_data_stream;
13552 request.load_flags = 0;
13553
13554 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13555 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113556 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413557 // Send headers successfully, but get an error while sending the body.
13558 MockWrite data_writes[] = {
13559 MockWrite("POST / HTTP/1.1\r\n"
13560 "Host: www.foo.com\r\n"
13561 "Connection: keep-alive\r\n"
13562 "Content-Length: 3\r\n\r\n"),
13563 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13564 };
13565
13566 MockRead data_reads[] = {
13567 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
13568 MockRead("hello world"),
13569 MockRead(SYNCHRONOUS, OK),
13570 };
13571 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13572 arraysize(data_writes));
13573 session_deps_.socket_factory->AddSocketDataProvider(&data);
13574
13575 TestCompletionCallback callback;
13576
13577 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13578 EXPECT_EQ(ERR_IO_PENDING, rv);
13579
13580 rv = callback.WaitForResult();
13581 EXPECT_EQ(OK, rv);
13582
13583 const HttpResponseInfo* response = trans->GetResponseInfo();
13584 ASSERT_TRUE(response != NULL);
13585
13586 EXPECT_TRUE(response->headers.get() != NULL);
13587 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
13588
13589 std::string response_data;
13590 rv = ReadTransaction(trans.get(), &response_data);
13591 EXPECT_EQ(OK, rv);
13592 EXPECT_EQ("hello world", response_data);
13593}
13594
13595// This test makes sure the retry logic doesn't trigger when reading an error
13596// response from a server that rejected a POST with a CONNECTION_RESET.
13597TEST_P(HttpNetworkTransactionTest,
13598 PostReadsErrorResponseAfterResetOnReusedSocket) {
13599 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13600 MockWrite data_writes[] = {
13601 MockWrite("GET / HTTP/1.1\r\n"
13602 "Host: www.foo.com\r\n"
13603 "Connection: keep-alive\r\n\r\n"),
13604 MockWrite("POST / HTTP/1.1\r\n"
13605 "Host: www.foo.com\r\n"
13606 "Connection: keep-alive\r\n"
13607 "Content-Length: 3\r\n\r\n"),
13608 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13609 };
13610
13611 MockRead data_reads[] = {
13612 MockRead("HTTP/1.1 200 Peachy\r\n"
13613 "Content-Length: 14\r\n\r\n"),
13614 MockRead("first response"),
13615 MockRead("HTTP/1.1 400 Not OK\r\n"
13616 "Content-Length: 15\r\n\r\n"),
13617 MockRead("second response"),
13618 MockRead(SYNCHRONOUS, OK),
13619 };
13620 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13621 arraysize(data_writes));
13622 session_deps_.socket_factory->AddSocketDataProvider(&data);
13623
13624 TestCompletionCallback callback;
13625 HttpRequestInfo request1;
13626 request1.method = "GET";
13627 request1.url = GURL("http://www.foo.com/");
13628 request1.load_flags = 0;
13629
13630 scoped_ptr<HttpTransaction> trans1(
dcheng48459ac22014-08-26 00:46:4113631 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413632 int rv = trans1->Start(&request1, callback.callback(), BoundNetLog());
13633 EXPECT_EQ(ERR_IO_PENDING, rv);
13634
13635 rv = callback.WaitForResult();
13636 EXPECT_EQ(OK, rv);
13637
13638 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
13639 ASSERT_TRUE(response1 != NULL);
13640
13641 EXPECT_TRUE(response1->headers.get() != NULL);
13642 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
13643
13644 std::string response_data1;
13645 rv = ReadTransaction(trans1.get(), &response_data1);
13646 EXPECT_EQ(OK, rv);
13647 EXPECT_EQ("first response", response_data1);
13648 // Delete the transaction to release the socket back into the socket pool.
13649 trans1.reset();
13650
13651 ScopedVector<UploadElementReader> element_readers;
13652 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713653 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413654
13655 HttpRequestInfo request2;
13656 request2.method = "POST";
13657 request2.url = GURL("http://www.foo.com/");
13658 request2.upload_data_stream = &upload_data_stream;
13659 request2.load_flags = 0;
13660
13661 scoped_ptr<HttpTransaction> trans2(
dcheng48459ac22014-08-26 00:46:4113662 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413663 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
13664 EXPECT_EQ(ERR_IO_PENDING, rv);
13665
13666 rv = callback.WaitForResult();
13667 EXPECT_EQ(OK, rv);
13668
13669 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
13670 ASSERT_TRUE(response2 != NULL);
13671
13672 EXPECT_TRUE(response2->headers.get() != NULL);
13673 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
13674
13675 std::string response_data2;
13676 rv = ReadTransaction(trans2.get(), &response_data2);
13677 EXPECT_EQ(OK, rv);
13678 EXPECT_EQ("second response", response_data2);
13679}
13680
13681TEST_P(HttpNetworkTransactionTest,
13682 PostReadsErrorResponseAfterResetPartialBodySent) {
13683 ScopedVector<UploadElementReader> element_readers;
13684 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713685 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413686
13687 HttpRequestInfo request;
13688 request.method = "POST";
13689 request.url = GURL("http://www.foo.com/");
13690 request.upload_data_stream = &upload_data_stream;
13691 request.load_flags = 0;
13692
13693 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13694 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113695 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413696 // Send headers successfully, but get an error while sending the body.
13697 MockWrite data_writes[] = {
13698 MockWrite("POST / HTTP/1.1\r\n"
13699 "Host: www.foo.com\r\n"
13700 "Connection: keep-alive\r\n"
13701 "Content-Length: 3\r\n\r\n"
13702 "fo"),
13703 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13704 };
13705
13706 MockRead data_reads[] = {
13707 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
13708 MockRead("hello world"),
13709 MockRead(SYNCHRONOUS, OK),
13710 };
13711 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13712 arraysize(data_writes));
13713 session_deps_.socket_factory->AddSocketDataProvider(&data);
13714
13715 TestCompletionCallback callback;
13716
13717 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13718 EXPECT_EQ(ERR_IO_PENDING, rv);
13719
13720 rv = callback.WaitForResult();
13721 EXPECT_EQ(OK, rv);
13722
13723 const HttpResponseInfo* response = trans->GetResponseInfo();
13724 ASSERT_TRUE(response != NULL);
13725
13726 EXPECT_TRUE(response->headers.get() != NULL);
13727 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
13728
13729 std::string response_data;
13730 rv = ReadTransaction(trans.get(), &response_data);
13731 EXPECT_EQ(OK, rv);
13732 EXPECT_EQ("hello world", response_data);
13733}
13734
13735// This tests the more common case than the previous test, where headers and
13736// body are not merged into a single request.
13737TEST_P(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
13738 ScopedVector<UploadElementReader> element_readers;
13739 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713740 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5413741
13742 HttpRequestInfo request;
13743 request.method = "POST";
13744 request.url = GURL("http://www.foo.com/");
13745 request.upload_data_stream = &upload_data_stream;
13746 request.load_flags = 0;
13747
13748 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13749 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113750 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413751 // Send headers successfully, but get an error while sending the body.
13752 MockWrite data_writes[] = {
13753 MockWrite("POST / HTTP/1.1\r\n"
13754 "Host: www.foo.com\r\n"
13755 "Connection: keep-alive\r\n"
13756 "Transfer-Encoding: chunked\r\n\r\n"),
13757 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13758 };
13759
13760 MockRead data_reads[] = {
13761 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
13762 MockRead("hello world"),
13763 MockRead(SYNCHRONOUS, OK),
13764 };
13765 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13766 arraysize(data_writes));
13767 session_deps_.socket_factory->AddSocketDataProvider(&data);
13768
13769 TestCompletionCallback callback;
13770
13771 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13772 EXPECT_EQ(ERR_IO_PENDING, rv);
13773 // Make sure the headers are sent before adding a chunk. This ensures that
13774 // they can't be merged with the body in a single send. Not currently
13775 // necessary since a chunked body is never merged with headers, but this makes
13776 // the test more future proof.
13777 base::RunLoop().RunUntilIdle();
13778
mmenkecbc2b712014-10-09 20:29:0713779 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5413780
13781 rv = callback.WaitForResult();
13782 EXPECT_EQ(OK, rv);
13783
13784 const HttpResponseInfo* response = trans->GetResponseInfo();
13785 ASSERT_TRUE(response != NULL);
13786
13787 EXPECT_TRUE(response->headers.get() != NULL);
13788 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
13789
13790 std::string response_data;
13791 rv = ReadTransaction(trans.get(), &response_data);
13792 EXPECT_EQ(OK, rv);
13793 EXPECT_EQ("hello world", response_data);
13794}
13795
13796TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
13797 ScopedVector<UploadElementReader> element_readers;
13798 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713799 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413800
13801 HttpRequestInfo request;
13802 request.method = "POST";
13803 request.url = GURL("http://www.foo.com/");
13804 request.upload_data_stream = &upload_data_stream;
13805 request.load_flags = 0;
13806
13807 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13808 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113809 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413810
13811 MockWrite data_writes[] = {
13812 MockWrite("POST / HTTP/1.1\r\n"
13813 "Host: www.foo.com\r\n"
13814 "Connection: keep-alive\r\n"
13815 "Content-Length: 3\r\n\r\n"),
13816 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13817 };
13818
13819 MockRead data_reads[] = {
13820 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
13821 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
13822 MockRead("hello world"),
13823 MockRead(SYNCHRONOUS, OK),
13824 };
13825 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13826 arraysize(data_writes));
13827 session_deps_.socket_factory->AddSocketDataProvider(&data);
13828
13829 TestCompletionCallback callback;
13830
13831 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13832 EXPECT_EQ(ERR_IO_PENDING, rv);
13833
13834 rv = callback.WaitForResult();
13835 EXPECT_EQ(OK, rv);
13836
13837 const HttpResponseInfo* response = trans->GetResponseInfo();
13838 ASSERT_TRUE(response != NULL);
13839
13840 EXPECT_TRUE(response->headers.get() != NULL);
13841 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
13842
13843 std::string response_data;
13844 rv = ReadTransaction(trans.get(), &response_data);
13845 EXPECT_EQ(OK, rv);
13846 EXPECT_EQ("hello world", response_data);
13847}
13848
13849TEST_P(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
13850 ScopedVector<UploadElementReader> element_readers;
13851 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713852 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413853
13854 HttpRequestInfo request;
13855 request.method = "POST";
13856 request.url = GURL("http://www.foo.com/");
13857 request.upload_data_stream = &upload_data_stream;
13858 request.load_flags = 0;
13859
13860 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13861 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113862 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413863 // Send headers successfully, but get an error while sending the body.
13864 MockWrite data_writes[] = {
13865 MockWrite("POST / HTTP/1.1\r\n"
13866 "Host: www.foo.com\r\n"
13867 "Connection: keep-alive\r\n"
13868 "Content-Length: 3\r\n\r\n"),
13869 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13870 };
13871
13872 MockRead data_reads[] = {
13873 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
13874 MockRead("hello world"),
13875 MockRead(SYNCHRONOUS, OK),
13876 };
13877 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13878 arraysize(data_writes));
13879 session_deps_.socket_factory->AddSocketDataProvider(&data);
13880
13881 TestCompletionCallback callback;
13882
13883 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13884 EXPECT_EQ(ERR_IO_PENDING, rv);
13885
13886 rv = callback.WaitForResult();
13887 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5413888}
13889
13890TEST_P(HttpNetworkTransactionTest,
13891 PostIgnoresNonErrorResponseAfterResetAnd100) {
13892 ScopedVector<UploadElementReader> element_readers;
13893 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713894 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413895
13896 HttpRequestInfo request;
13897 request.method = "POST";
13898 request.url = GURL("http://www.foo.com/");
13899 request.upload_data_stream = &upload_data_stream;
13900 request.load_flags = 0;
13901
13902 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13903 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113904 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413905 // Send headers successfully, but get an error while sending the body.
13906 MockWrite data_writes[] = {
13907 MockWrite("POST / HTTP/1.1\r\n"
13908 "Host: www.foo.com\r\n"
13909 "Connection: keep-alive\r\n"
13910 "Content-Length: 3\r\n\r\n"),
13911 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13912 };
13913
13914 MockRead data_reads[] = {
13915 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
13916 MockRead("HTTP/1.0 302 Redirect\r\n"),
13917 MockRead("Location: http://somewhere-else.com/\r\n"),
13918 MockRead("Content-Length: 0\r\n\r\n"),
13919 MockRead(SYNCHRONOUS, OK),
13920 };
13921 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13922 arraysize(data_writes));
13923 session_deps_.socket_factory->AddSocketDataProvider(&data);
13924
13925 TestCompletionCallback callback;
13926
13927 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13928 EXPECT_EQ(ERR_IO_PENDING, rv);
13929
13930 rv = callback.WaitForResult();
13931 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5413932}
13933
13934TEST_P(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
13935 ScopedVector<UploadElementReader> element_readers;
13936 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713937 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413938
13939 HttpRequestInfo request;
13940 request.method = "POST";
13941 request.url = GURL("http://www.foo.com/");
13942 request.upload_data_stream = &upload_data_stream;
13943 request.load_flags = 0;
13944
13945 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13946 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113947 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413948 // Send headers successfully, but get an error while sending the body.
13949 MockWrite data_writes[] = {
13950 MockWrite("POST / HTTP/1.1\r\n"
13951 "Host: www.foo.com\r\n"
13952 "Connection: keep-alive\r\n"
13953 "Content-Length: 3\r\n\r\n"),
13954 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13955 };
13956
13957 MockRead data_reads[] = {
13958 MockRead("HTTP 0.9 rocks!"),
13959 MockRead(SYNCHRONOUS, OK),
13960 };
13961 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13962 arraysize(data_writes));
13963 session_deps_.socket_factory->AddSocketDataProvider(&data);
13964
13965 TestCompletionCallback callback;
13966
13967 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13968 EXPECT_EQ(ERR_IO_PENDING, rv);
13969
13970 rv = callback.WaitForResult();
13971 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5413972}
13973
13974TEST_P(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
13975 ScopedVector<UploadElementReader> element_readers;
13976 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713977 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413978
13979 HttpRequestInfo request;
13980 request.method = "POST";
13981 request.url = GURL("http://www.foo.com/");
13982 request.upload_data_stream = &upload_data_stream;
13983 request.load_flags = 0;
13984
13985 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13986 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113987 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413988 // Send headers successfully, but get an error while sending the body.
13989 MockWrite data_writes[] = {
13990 MockWrite("POST / HTTP/1.1\r\n"
13991 "Host: www.foo.com\r\n"
13992 "Connection: keep-alive\r\n"
13993 "Content-Length: 3\r\n\r\n"),
13994 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13995 };
13996
13997 MockRead data_reads[] = {
13998 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
13999 MockRead(SYNCHRONOUS, OK),
14000 };
14001 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14002 arraysize(data_writes));
14003 session_deps_.socket_factory->AddSocketDataProvider(&data);
14004
14005 TestCompletionCallback callback;
14006
14007 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14008 EXPECT_EQ(ERR_IO_PENDING, rv);
14009
14010 rv = callback.WaitForResult();
14011 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5414012}
14013
Adam Rice425cf122015-01-19 06:18:2414014// Verify that proxy headers are not sent to the destination server when
14015// establishing a tunnel for a secure WebSocket connection.
14016TEST_P(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
14017 HttpRequestInfo request;
14018 request.method = "GET";
bncce36dca22015-04-21 22:11:2314019 request.url = GURL("wss://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2414020 AddWebSocketHeaders(&request.extra_headers);
14021
14022 // Configure against proxy server "myproxy:70".
14023 session_deps_.proxy_service.reset(
14024 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
14025
14026 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14027
14028 // Since a proxy is configured, try to establish a tunnel.
14029 MockWrite data_writes[] = {
14030 MockWrite(
bncce36dca22015-04-21 22:11:2314031 "CONNECT www.example.org:443 HTTP/1.1\r\n"
14032 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414033 "Proxy-Connection: keep-alive\r\n\r\n"),
14034
14035 // After calling trans->RestartWithAuth(), this is the request we should
14036 // be issuing -- the final header line contains the credentials.
14037 MockWrite(
bncce36dca22015-04-21 22:11:2314038 "CONNECT www.example.org:443 HTTP/1.1\r\n"
14039 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414040 "Proxy-Connection: keep-alive\r\n"
14041 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
14042
14043 MockWrite(
14044 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2314045 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414046 "Connection: Upgrade\r\n"
14047 "Upgrade: websocket\r\n"
bncce36dca22015-04-21 22:11:2314048 "Origin: http://www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414049 "Sec-WebSocket-Version: 13\r\n"
14050 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
14051 };
14052
14053 // The proxy responds to the connect with a 407, using a persistent
14054 // connection.
14055 MockRead data_reads[] = {
14056 // No credentials.
14057 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
14058 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
14059 MockRead("Proxy-Connection: close\r\n\r\n"),
14060
14061 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
14062
14063 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
14064 MockRead("Upgrade: websocket\r\n"),
14065 MockRead("Connection: Upgrade\r\n"),
14066 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
14067 };
14068
14069 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14070 arraysize(data_writes));
14071 session_deps_.socket_factory->AddSocketDataProvider(&data);
14072 SSLSocketDataProvider ssl(ASYNC, OK);
14073 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14074
14075 scoped_ptr<HttpTransaction> trans(
14076 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
14077 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
14078 trans->SetWebSocketHandshakeStreamCreateHelper(
14079 &websocket_stream_create_helper);
14080
14081 {
14082 TestCompletionCallback callback;
14083
14084 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14085 EXPECT_EQ(ERR_IO_PENDING, rv);
14086
14087 rv = callback.WaitForResult();
14088 EXPECT_EQ(OK, rv);
14089 }
14090
14091 const HttpResponseInfo* response = trans->GetResponseInfo();
14092 ASSERT_TRUE(response);
14093 ASSERT_TRUE(response->headers.get());
14094 EXPECT_EQ(407, response->headers->response_code());
14095
14096 {
14097 TestCompletionCallback callback;
14098
14099 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
14100 callback.callback());
14101 EXPECT_EQ(ERR_IO_PENDING, rv);
14102
14103 rv = callback.WaitForResult();
14104 EXPECT_EQ(OK, rv);
14105 }
14106
14107 response = trans->GetResponseInfo();
14108 ASSERT_TRUE(response);
14109 ASSERT_TRUE(response->headers.get());
14110
14111 EXPECT_EQ(101, response->headers->response_code());
14112
14113 trans.reset();
14114 session->CloseAllConnections();
14115}
14116
14117// Verify that proxy headers are not sent to the destination server when
14118// establishing a tunnel for an insecure WebSocket connection.
14119// This requires the authentication info to be injected into the auth cache
14120// due to crbug.com/395064
14121// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
14122TEST_P(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
14123 HttpRequestInfo request;
14124 request.method = "GET";
bncce36dca22015-04-21 22:11:2314125 request.url = GURL("ws://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2414126 AddWebSocketHeaders(&request.extra_headers);
14127
14128 // Configure against proxy server "myproxy:70".
14129 session_deps_.proxy_service.reset(
14130 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
14131
14132 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14133
14134 MockWrite data_writes[] = {
14135 // Try to establish a tunnel for the WebSocket connection, with
14136 // credentials. Because WebSockets have a separate set of socket pools,
14137 // they cannot and will not use the same TCP/IP connection as the
14138 // preflight HTTP request.
14139 MockWrite(
bncce36dca22015-04-21 22:11:2314140 "CONNECT www.example.org:80 HTTP/1.1\r\n"
14141 "Host: www.example.org:80\r\n"
Adam Rice425cf122015-01-19 06:18:2414142 "Proxy-Connection: keep-alive\r\n"
14143 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
14144
14145 MockWrite(
14146 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2314147 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414148 "Connection: Upgrade\r\n"
14149 "Upgrade: websocket\r\n"
bncce36dca22015-04-21 22:11:2314150 "Origin: http://www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414151 "Sec-WebSocket-Version: 13\r\n"
14152 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
14153 };
14154
14155 MockRead data_reads[] = {
14156 // HTTP CONNECT with credentials.
14157 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
14158
14159 // WebSocket connection established inside tunnel.
14160 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
14161 MockRead("Upgrade: websocket\r\n"),
14162 MockRead("Connection: Upgrade\r\n"),
14163 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
14164 };
14165
14166 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14167 arraysize(data_writes));
14168 session_deps_.socket_factory->AddSocketDataProvider(&data);
14169
14170 session->http_auth_cache()->Add(
14171 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
14172 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
14173
14174 scoped_ptr<HttpTransaction> trans(
14175 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
14176 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
14177 trans->SetWebSocketHandshakeStreamCreateHelper(
14178 &websocket_stream_create_helper);
14179
14180 TestCompletionCallback callback;
14181
14182 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14183 EXPECT_EQ(ERR_IO_PENDING, rv);
14184
14185 rv = callback.WaitForResult();
14186 EXPECT_EQ(OK, rv);
14187
14188 const HttpResponseInfo* response = trans->GetResponseInfo();
14189 ASSERT_TRUE(response);
14190 ASSERT_TRUE(response->headers.get());
14191
14192 EXPECT_EQ(101, response->headers->response_code());
14193
14194 trans.reset();
14195 session->CloseAllConnections();
14196}
14197
[email protected]89ceba9a2009-03-21 03:46:0614198} // namespace net