blob: 39d58ebab9fda98ee89e465b8a235f32c9cca00b [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,
429 kProtoSPDY4_14,
430 kProtoSPDY4));
[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);
[email protected]a34f61ee2014-03-18 20:59:491444 session->http_stream_factory()->PreconnectStreams(
1445 1, request, DEFAULT_PRIORITY, ssl_config, ssl_config);
1446 // Wait for the preconnect to complete.
1447 // TODO(davidben): Some way to wait for an idle socket count might be handy.
1448 base::RunLoop().RunUntilIdle();
[email protected]09356c652014-03-25 15:36:101449 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]a34f61ee2014-03-18 20:59:491450
1451 // Make the request.
1452 TestCompletionCallback callback;
1453
1454 scoped_ptr<HttpTransaction> trans(
1455 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1456
1457 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1458 EXPECT_EQ(ERR_IO_PENDING, rv);
1459
1460 rv = callback.WaitForResult();
1461 EXPECT_EQ(OK, rv);
1462
1463 LoadTimingInfo load_timing_info;
1464 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
[email protected]09356c652014-03-25 15:36:101465 TestLoadTimingNotReused(
1466 load_timing_info,
1467 CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]a34f61ee2014-03-18 20:59:491468
1469 const HttpResponseInfo* response = trans->GetResponseInfo();
1470 ASSERT_TRUE(response != NULL);
1471
1472 EXPECT_TRUE(response->headers.get() != NULL);
1473 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1474
1475 std::string response_data;
1476 rv = ReadTransaction(trans.get(), &response_data);
1477 EXPECT_EQ(OK, rv);
[email protected]09356c652014-03-25 15:36:101478 EXPECT_EQ(kHttpData, response_data);
[email protected]a34f61ee2014-03-18 20:59:491479}
1480
[email protected]23e482282013-06-14 16:08:021481TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:231482 KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061483 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]202965992011-12-07 23:04:511484 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1485}
1486
[email protected]23e482282013-06-14 16:08:021487TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061488 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]202965992011-12-07 23:04:511489 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251490}
1491
[email protected]23e482282013-06-14 16:08:021492TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061493 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]202965992011-12-07 23:04:511494 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251495}
1496
[email protected]d58ceea82014-06-04 10:55:541497// Make sure that on a 408 response (Request Timeout), the request is retried,
1498// if the socket was a reused keep alive socket.
1499TEST_P(HttpNetworkTransactionTest, KeepAlive408) {
1500 MockRead read_failure(SYNCHRONOUS,
1501 "HTTP/1.1 408 Request Timeout\r\n"
1502 "Connection: Keep-Alive\r\n"
1503 "Content-Length: 6\r\n\r\n"
1504 "Pickle");
1505 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1506}
1507
[email protected]a34f61ee2014-03-18 20:59:491508TEST_P(HttpNetworkTransactionTest,
1509 PreconnectErrorNotConnectedOnWrite) {
1510 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]09356c652014-03-25 15:36:101511 PreconnectErrorResendRequestTest(&write_failure, NULL, false);
[email protected]a34f61ee2014-03-18 20:59:491512}
1513
1514TEST_P(HttpNetworkTransactionTest, PreconnectErrorReset) {
1515 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]09356c652014-03-25 15:36:101516 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
[email protected]a34f61ee2014-03-18 20:59:491517}
1518
1519TEST_P(HttpNetworkTransactionTest, PreconnectErrorEOF) {
1520 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]09356c652014-03-25 15:36:101521 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1522}
1523
1524TEST_P(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
1525 MockRead read_failure(ASYNC, OK); // EOF
1526 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1527}
1528
[email protected]d58ceea82014-06-04 10:55:541529// Make sure that on a 408 response (Request Timeout), the request is retried,
1530// if the socket was a preconnected (UNUSED_IDLE) socket.
1531TEST_P(HttpNetworkTransactionTest, RetryOnIdle408) {
1532 MockRead read_failure(SYNCHRONOUS,
1533 "HTTP/1.1 408 Request Timeout\r\n"
1534 "Connection: Keep-Alive\r\n"
1535 "Content-Length: 6\r\n\r\n"
1536 "Pickle");
1537 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1538 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1539}
1540
[email protected]09356c652014-03-25 15:36:101541TEST_P(HttpNetworkTransactionTest,
1542 SpdyPreconnectErrorNotConnectedOnWrite) {
1543 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1544 PreconnectErrorResendRequestTest(&write_failure, NULL, true);
1545}
1546
1547TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
1548 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1549 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1550}
1551
1552TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
1553 MockRead read_failure(SYNCHRONOUS, OK); // EOF
1554 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1555}
1556
1557TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
1558 MockRead read_failure(ASYNC, OK); // EOF
1559 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
[email protected]a34f61ee2014-03-18 20:59:491560}
1561
[email protected]23e482282013-06-14 16:08:021562TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:421563 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:251564 request.method = "GET";
bncce36dca22015-04-21 22:11:231565 request.url = GURL("http://www.example.org/");
[email protected]3d2a59b2008-09-26 19:44:251566 request.load_flags = 0;
1567
[email protected]3fe8d2f82013-10-17 08:56:071568 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271569 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411570 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271571
[email protected]3d2a59b2008-09-26 19:44:251572 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061573 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:351574 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1575 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061576 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251577 };
[email protected]31a2bfe2010-02-09 08:03:391578 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071579 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:251580
[email protected]49639fa2011-12-20 23:22:411581 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:251582
[email protected]49639fa2011-12-20 23:22:411583 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421584 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3d2a59b2008-09-26 19:44:251585
1586 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421587 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]3d2a59b2008-09-26 19:44:251588}
1589
1590// What do various browsers do when the server closes a non-keepalive
1591// connection without sending any response header or body?
1592//
1593// IE7: error page
1594// Safari 3.1.2 (Windows): error page
1595// Firefox 3.0.1: blank page
1596// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:421597// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1598// Us: error page (EMPTY_RESPONSE)
[email protected]23e482282013-06-14 16:08:021599TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:251600 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061601 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:351602 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1603 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061604 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251605 };
[email protected]31a2bfe2010-02-09 08:03:391606 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1607 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:421608 EXPECT_EQ(ERR_EMPTY_RESPONSE, out.rv);
[email protected]3d2a59b2008-09-26 19:44:251609}
[email protected]038e9a32008-10-08 22:40:161610
[email protected]1826a402014-01-08 15:40:481611// Test that network access can be deferred and resumed.
1612TEST_P(HttpNetworkTransactionTest, ThrottleBeforeNetworkStart) {
1613 HttpRequestInfo request;
1614 request.method = "GET";
bncce36dca22015-04-21 22:11:231615 request.url = GURL("http://www.example.org/");
[email protected]1826a402014-01-08 15:40:481616 request.load_flags = 0;
1617
1618 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1619 scoped_ptr<HttpTransaction> trans(
1620 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1621
1622 // Defer on OnBeforeNetworkStart.
1623 BeforeNetworkStartHandler net_start_handler(true); // defer
1624 trans->SetBeforeNetworkStartCallback(
1625 base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
1626 base::Unretained(&net_start_handler)));
1627
1628 MockRead data_reads[] = {
1629 MockRead("HTTP/1.0 200 OK\r\n"),
1630 MockRead("Content-Length: 5\r\n\r\n"),
1631 MockRead("hello"),
1632 MockRead(SYNCHRONOUS, 0),
1633 };
1634 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1635 session_deps_.socket_factory->AddSocketDataProvider(&data);
1636
1637 TestCompletionCallback callback;
1638
1639 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1640 EXPECT_EQ(ERR_IO_PENDING, rv);
1641 base::MessageLoop::current()->RunUntilIdle();
1642
1643 // Should have deferred for network start.
1644 EXPECT_TRUE(net_start_handler.observed_before_network_start());
1645 EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
[email protected]1826a402014-01-08 15:40:481646
1647 trans->ResumeNetworkStart();
1648 rv = callback.WaitForResult();
1649 EXPECT_EQ(OK, rv);
1650 EXPECT_TRUE(trans->GetResponseInfo() != NULL);
1651
1652 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
1653 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
1654 if (rv == ERR_IO_PENDING)
1655 rv = callback.WaitForResult();
1656 EXPECT_EQ(5, rv);
1657 trans.reset();
1658}
1659
1660// Test that network use can be deferred and canceled.
1661TEST_P(HttpNetworkTransactionTest, ThrottleAndCancelBeforeNetworkStart) {
1662 HttpRequestInfo request;
1663 request.method = "GET";
bncce36dca22015-04-21 22:11:231664 request.url = GURL("http://www.example.org/");
[email protected]1826a402014-01-08 15:40:481665 request.load_flags = 0;
1666
1667 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1668 scoped_ptr<HttpTransaction> trans(
1669 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1670
1671 // Defer on OnBeforeNetworkStart.
1672 BeforeNetworkStartHandler net_start_handler(true); // defer
1673 trans->SetBeforeNetworkStartCallback(
1674 base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
1675 base::Unretained(&net_start_handler)));
1676
1677 TestCompletionCallback callback;
1678
1679 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1680 EXPECT_EQ(ERR_IO_PENDING, rv);
1681 base::MessageLoop::current()->RunUntilIdle();
1682
1683 // Should have deferred for network start.
1684 EXPECT_TRUE(net_start_handler.observed_before_network_start());
1685 EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
[email protected]1826a402014-01-08 15:40:481686}
1687
[email protected]7a5378b2012-11-04 03:25:171688// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
1689// tests. There was a bug causing HttpNetworkTransaction to hang in the
1690// destructor in such situations.
1691// See http://crbug.com/154712 and http://crbug.com/156609.
[email protected]23e482282013-06-14 16:08:021692TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:171693 HttpRequestInfo request;
1694 request.method = "GET";
bncce36dca22015-04-21 22:11:231695 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171696 request.load_flags = 0;
1697
[email protected]bb88e1d32013-05-03 23:11:071698 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:361699 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501700 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171701
1702 MockRead data_reads[] = {
1703 MockRead("HTTP/1.0 200 OK\r\n"),
1704 MockRead("Connection: keep-alive\r\n"),
1705 MockRead("Content-Length: 100\r\n\r\n"),
1706 MockRead("hello"),
1707 MockRead(SYNCHRONOUS, 0),
1708 };
1709 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071710 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171711
1712 TestCompletionCallback callback;
1713
1714 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1715 EXPECT_EQ(ERR_IO_PENDING, rv);
1716
1717 rv = callback.WaitForResult();
1718 EXPECT_EQ(OK, rv);
1719
1720 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501721 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171722 if (rv == ERR_IO_PENDING)
1723 rv = callback.WaitForResult();
1724 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:501725 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171726 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1727
1728 trans.reset();
[email protected]2da659e2013-05-23 20:51:341729 base::MessageLoop::current()->RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171730 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1731}
1732
[email protected]23e482282013-06-14 16:08:021733TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:171734 HttpRequestInfo request;
1735 request.method = "GET";
bncce36dca22015-04-21 22:11:231736 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171737 request.load_flags = 0;
1738
[email protected]bb88e1d32013-05-03 23:11:071739 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:361740 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501741 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171742
1743 MockRead data_reads[] = {
1744 MockRead("HTTP/1.0 200 OK\r\n"),
1745 MockRead("Connection: keep-alive\r\n"),
1746 MockRead("Content-Length: 100\r\n\r\n"),
1747 MockRead(SYNCHRONOUS, 0),
1748 };
1749 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071750 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171751
1752 TestCompletionCallback callback;
1753
1754 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1755 EXPECT_EQ(ERR_IO_PENDING, rv);
1756
1757 rv = callback.WaitForResult();
1758 EXPECT_EQ(OK, rv);
1759
1760 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501761 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171762 if (rv == ERR_IO_PENDING)
1763 rv = callback.WaitForResult();
1764 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1765
1766 trans.reset();
[email protected]2da659e2013-05-23 20:51:341767 base::MessageLoop::current()->RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171768 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1769}
1770
[email protected]0b0bf032010-09-21 18:08:501771// Test that we correctly reuse a keep-alive connection after not explicitly
1772// reading the body.
[email protected]23e482282013-06-14 16:08:021773TEST_P(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:131774 HttpRequestInfo request;
1775 request.method = "GET";
1776 request.url = GURL("http://www.foo.com/");
1777 request.load_flags = 0;
1778
vishal.b62985ca92015-04-17 08:45:511779 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071780 session_deps_.net_log = &net_log;
1781 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271782
[email protected]0b0bf032010-09-21 18:08:501783 // Note that because all these reads happen in the same
1784 // StaticSocketDataProvider, it shows that the same socket is being reused for
1785 // all transactions.
[email protected]fc31d6a42010-06-24 18:05:131786 MockRead data1_reads[] = {
[email protected]0b0bf032010-09-21 18:08:501787 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
1788 MockRead("HTTP/1.1 205 Reset Content\r\n\r\n"),
[email protected]fc31d6a42010-06-24 18:05:131789 MockRead("HTTP/1.1 304 Not Modified\r\n\r\n"),
[email protected]0b0bf032010-09-21 18:08:501790 MockRead("HTTP/1.1 302 Found\r\n"
1791 "Content-Length: 0\r\n\r\n"),
1792 MockRead("HTTP/1.1 302 Found\r\n"
1793 "Content-Length: 5\r\n\r\n"
1794 "hello"),
1795 MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1796 "Content-Length: 0\r\n\r\n"),
1797 MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1798 "Content-Length: 5\r\n\r\n"
1799 "hello"),
[email protected]fc31d6a42010-06-24 18:05:131800 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1801 MockRead("hello"),
1802 };
1803 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071804 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]fc31d6a42010-06-24 18:05:131805
1806 MockRead data2_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061807 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]fc31d6a42010-06-24 18:05:131808 };
1809 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071810 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]fc31d6a42010-06-24 18:05:131811
[email protected]0b0bf032010-09-21 18:08:501812 const int kNumUnreadBodies = arraysize(data1_reads) - 2;
1813 std::string response_lines[kNumUnreadBodies];
1814
[email protected]58e32bb2013-01-21 18:23:251815 uint32 first_socket_log_id = NetLog::Source::kInvalidId;
[email protected]0b0bf032010-09-21 18:08:501816 for (size_t i = 0; i < arraysize(data1_reads) - 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411817 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:131818
[email protected]262eec82013-03-19 21:01:361819 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501820 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]fc31d6a42010-06-24 18:05:131821
[email protected]49639fa2011-12-20 23:22:411822 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]fc31d6a42010-06-24 18:05:131823 EXPECT_EQ(ERR_IO_PENDING, rv);
1824
1825 rv = callback.WaitForResult();
1826 EXPECT_EQ(OK, rv);
1827
[email protected]58e32bb2013-01-21 18:23:251828 LoadTimingInfo load_timing_info;
1829 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1830 if (i == 0) {
1831 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1832 first_socket_log_id = load_timing_info.socket_log_id;
1833 } else {
1834 TestLoadTimingReused(load_timing_info);
1835 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
1836 }
1837
[email protected]fc31d6a42010-06-24 18:05:131838 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]0b0bf032010-09-21 18:08:501839 ASSERT_TRUE(response != NULL);
[email protected]fc31d6a42010-06-24 18:05:131840
[email protected]90499482013-06-01 00:39:501841 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]0b0bf032010-09-21 18:08:501842 response_lines[i] = response->headers->GetStatusLine();
1843
1844 // We intentionally don't read the response bodies.
[email protected]fc31d6a42010-06-24 18:05:131845 }
[email protected]0b0bf032010-09-21 18:08:501846
1847 const char* const kStatusLines[] = {
1848 "HTTP/1.1 204 No Content",
1849 "HTTP/1.1 205 Reset Content",
1850 "HTTP/1.1 304 Not Modified",
1851 "HTTP/1.1 302 Found",
1852 "HTTP/1.1 302 Found",
1853 "HTTP/1.1 301 Moved Permanently",
1854 "HTTP/1.1 301 Moved Permanently",
1855 };
1856
mostynb91e0da982015-01-20 19:17:271857 static_assert(kNumUnreadBodies == arraysize(kStatusLines),
1858 "forgot to update kStatusLines");
[email protected]0b0bf032010-09-21 18:08:501859
1860 for (int i = 0; i < kNumUnreadBodies; ++i)
1861 EXPECT_EQ(kStatusLines[i], response_lines[i]);
1862
[email protected]49639fa2011-12-20 23:22:411863 TestCompletionCallback callback;
[email protected]262eec82013-03-19 21:01:361864 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501865 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:411866 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0b0bf032010-09-21 18:08:501867 EXPECT_EQ(ERR_IO_PENDING, rv);
1868 rv = callback.WaitForResult();
1869 EXPECT_EQ(OK, rv);
1870 const HttpResponseInfo* response = trans->GetResponseInfo();
1871 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:501872 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]0b0bf032010-09-21 18:08:501873 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1874 std::string response_data;
1875 rv = ReadTransaction(trans.get(), &response_data);
1876 EXPECT_EQ(OK, rv);
1877 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:131878}
1879
[email protected]038e9a32008-10-08 22:40:161880// Test the request-challenge-retry sequence for basic auth.
1881// (basic auth is the easiest to mock, because it has no randomness).
[email protected]23e482282013-06-14 16:08:021882TEST_P(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:421883 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:161884 request.method = "GET";
bncce36dca22015-04-21 22:11:231885 request.url = GURL("http://www.example.org/");
[email protected]038e9a32008-10-08 22:40:161886 request.load_flags = 0;
1887
vishal.b62985ca92015-04-17 08:45:511888 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:071889 session_deps_.net_log = &log;
[email protected]3fe8d2f82013-10-17 08:56:071890 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271891 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411892 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271893
[email protected]f9ee6b52008-11-08 06:46:231894 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:231895 MockWrite(
1896 "GET / HTTP/1.1\r\n"
1897 "Host: www.example.org\r\n"
1898 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:231899 };
1900
[email protected]038e9a32008-10-08 22:40:161901 MockRead data_reads1[] = {
1902 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
1903 // Give a couple authenticate options (only the middle one is actually
1904 // supported).
[email protected]22927ad2009-09-21 19:56:191905 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:161906 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1907 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
1908 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1909 // Large content-length -- won't matter, as connection will be reset.
1910 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061911 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:161912 };
1913
1914 // After calling trans->RestartWithAuth(), this is the request we should
1915 // be issuing -- the final header line contains the credentials.
1916 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:231917 MockWrite(
1918 "GET / HTTP/1.1\r\n"
1919 "Host: www.example.org\r\n"
1920 "Connection: keep-alive\r\n"
1921 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:161922 };
1923
1924 // Lastly, the server responds with the actual content.
1925 MockRead data_reads2[] = {
1926 MockRead("HTTP/1.0 200 OK\r\n"),
1927 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1928 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061929 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:161930 };
1931
[email protected]31a2bfe2010-02-09 08:03:391932 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1933 data_writes1, arraysize(data_writes1));
1934 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1935 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:071936 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1937 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:161938
[email protected]49639fa2011-12-20 23:22:411939 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:161940
[email protected]49639fa2011-12-20 23:22:411941 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421942 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:161943
1944 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421945 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:161946
[email protected]58e32bb2013-01-21 18:23:251947 LoadTimingInfo load_timing_info1;
1948 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
1949 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
1950
[email protected]b8015c42013-12-24 15:18:191951 int64 reads_size1 = ReadsSize(data_reads1, arraysize(data_reads1));
1952 EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
1953
[email protected]1c773ea12009-04-28 19:58:421954 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501955 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:041956 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:161957
[email protected]49639fa2011-12-20 23:22:411958 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:161959
[email protected]49639fa2011-12-20 23:22:411960 rv = trans->RestartWithAuth(
1961 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:421962 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:161963
1964 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421965 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:161966
[email protected]58e32bb2013-01-21 18:23:251967 LoadTimingInfo load_timing_info2;
1968 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
1969 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
1970 // The load timing after restart should have a new socket ID, and times after
1971 // those of the first load timing.
1972 EXPECT_LE(load_timing_info1.receive_headers_end,
1973 load_timing_info2.connect_timing.connect_start);
1974 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
1975
[email protected]b8015c42013-12-24 15:18:191976 int64 reads_size2 = ReadsSize(data_reads2, arraysize(data_reads2));
1977 EXPECT_EQ(reads_size1 + reads_size2, trans->GetTotalReceivedBytes());
1978
[email protected]038e9a32008-10-08 22:40:161979 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501980 ASSERT_TRUE(response != NULL);
[email protected]038e9a32008-10-08 22:40:161981 EXPECT_TRUE(response->auth_challenge.get() == NULL);
1982 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:161983}
1984
[email protected]23e482282013-06-14 16:08:021985TEST_P(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:461986 HttpRequestInfo request;
1987 request.method = "GET";
bncce36dca22015-04-21 22:11:231988 request.url = GURL("http://www.example.org/");
ttuttle859dc7a2015-04-23 19:42:291989 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]861fcd52009-08-26 02:33:461990
[email protected]3fe8d2f82013-10-17 08:56:071991 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271992 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411993 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271994
[email protected]861fcd52009-08-26 02:33:461995 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:231996 MockWrite(
1997 "GET / HTTP/1.1\r\n"
1998 "Host: www.example.org\r\n"
1999 "Connection: keep-alive\r\n\r\n"),
[email protected]861fcd52009-08-26 02:33:462000 };
2001
2002 MockRead data_reads[] = {
2003 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2004 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2005 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2006 // Large content-length -- won't matter, as connection will be reset.
2007 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062008 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:462009 };
2010
[email protected]31a2bfe2010-02-09 08:03:392011 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2012 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072013 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:412014 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:462015
[email protected]49639fa2011-12-20 23:22:412016 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]861fcd52009-08-26 02:33:462017 EXPECT_EQ(ERR_IO_PENDING, rv);
2018
2019 rv = callback.WaitForResult();
2020 EXPECT_EQ(0, rv);
2021
[email protected]b8015c42013-12-24 15:18:192022 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
2023 EXPECT_EQ(reads_size, trans->GetTotalReceivedBytes());
2024
[email protected]861fcd52009-08-26 02:33:462025 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502026 ASSERT_TRUE(response != NULL);
[email protected]861fcd52009-08-26 02:33:462027 EXPECT_TRUE(response->auth_challenge.get() == NULL);
2028}
2029
[email protected]2d2697f92009-02-18 21:00:322030// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2031// connection.
[email protected]23e482282013-06-14 16:08:022032TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
[email protected]1c773ea12009-04-28 19:58:422033 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322034 request.method = "GET";
bncce36dca22015-04-21 22:11:232035 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322036 request.load_flags = 0;
2037
vishal.b62985ca92015-04-17 08:45:512038 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072039 session_deps_.net_log = &log;
2040 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272041
[email protected]2d2697f92009-02-18 21:00:322042 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232043 MockWrite(
2044 "GET / HTTP/1.1\r\n"
2045 "Host: www.example.org\r\n"
2046 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322047
bncce36dca22015-04-21 22:11:232048 // After calling trans->RestartWithAuth(), this is the request we should
2049 // be issuing -- the final header line contains the credentials.
2050 MockWrite(
2051 "GET / HTTP/1.1\r\n"
2052 "Host: www.example.org\r\n"
2053 "Connection: keep-alive\r\n"
2054 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322055 };
2056
2057 MockRead data_reads1[] = {
2058 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2059 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2060 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2061 MockRead("Content-Length: 14\r\n\r\n"),
2062 MockRead("Unauthorized\r\n"),
2063
2064 // Lastly, the server responds with the actual content.
2065 MockRead("HTTP/1.1 200 OK\r\n"),
2066 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502067 MockRead("Content-Length: 5\r\n\r\n"),
2068 MockRead("Hello"),
[email protected]2d2697f92009-02-18 21:00:322069 };
2070
[email protected]2d0a4f92011-05-05 16:38:462071 // If there is a regression where we disconnect a Keep-Alive
2072 // connection during an auth roundtrip, we'll end up reading this.
2073 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062074 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462075 };
2076
[email protected]31a2bfe2010-02-09 08:03:392077 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2078 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462079 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2080 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072081 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2082 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322083
[email protected]49639fa2011-12-20 23:22:412084 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322085
[email protected]262eec82013-03-19 21:01:362086 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502087 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412088 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422089 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322090
2091 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422092 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322093
[email protected]58e32bb2013-01-21 18:23:252094 LoadTimingInfo load_timing_info1;
2095 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
2096 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2097
[email protected]1c773ea12009-04-28 19:58:422098 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502099 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042100 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322101
[email protected]49639fa2011-12-20 23:22:412102 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322103
[email protected]49639fa2011-12-20 23:22:412104 rv = trans->RestartWithAuth(
2105 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422106 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322107
2108 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422109 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322110
[email protected]58e32bb2013-01-21 18:23:252111 LoadTimingInfo load_timing_info2;
2112 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
2113 TestLoadTimingReused(load_timing_info2);
2114 // The load timing after restart should have the same socket ID, and times
2115 // those of the first load timing.
2116 EXPECT_LE(load_timing_info1.receive_headers_end,
2117 load_timing_info2.send_start);
2118 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2119
[email protected]2d2697f92009-02-18 21:00:322120 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502121 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322122 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502123 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]b8015c42013-12-24 15:18:192124
2125 std::string response_data;
2126 rv = ReadTransaction(trans.get(), &response_data);
2127 EXPECT_EQ(OK, rv);
2128 int64 reads_size1 = ReadsSize(data_reads1, arraysize(data_reads1));
2129 EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
[email protected]2d2697f92009-02-18 21:00:322130}
2131
2132// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2133// connection and with no response body to drain.
[email protected]23e482282013-06-14 16:08:022134TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:422135 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322136 request.method = "GET";
bncce36dca22015-04-21 22:11:232137 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322138 request.load_flags = 0;
2139
[email protected]bb88e1d32013-05-03 23:11:072140 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272141
[email protected]2d2697f92009-02-18 21:00:322142 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232143 MockWrite(
2144 "GET / HTTP/1.1\r\n"
2145 "Host: www.example.org\r\n"
2146 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322147
bncce36dca22015-04-21 22:11:232148 // After calling trans->RestartWithAuth(), this is the request we should
2149 // be issuing -- the final header line contains the credentials.
2150 MockWrite(
2151 "GET / HTTP/1.1\r\n"
2152 "Host: www.example.org\r\n"
2153 "Connection: keep-alive\r\n"
2154 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322155 };
2156
[email protected]2d2697f92009-02-18 21:00:322157 MockRead data_reads1[] = {
2158 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2159 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:312160 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:322161
2162 // Lastly, the server responds with the actual content.
2163 MockRead("HTTP/1.1 200 OK\r\n"),
2164 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502165 MockRead("Content-Length: 5\r\n\r\n"),
2166 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322167 };
2168
[email protected]2d0a4f92011-05-05 16:38:462169 // An incorrect reconnect would cause this to be read.
2170 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062171 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462172 };
2173
[email protected]31a2bfe2010-02-09 08:03:392174 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2175 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462176 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2177 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072178 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2179 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322180
[email protected]49639fa2011-12-20 23:22:412181 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322182
[email protected]262eec82013-03-19 21:01:362183 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502184 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412185 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422186 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322187
2188 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422189 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322190
[email protected]1c773ea12009-04-28 19:58:422191 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502192 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042193 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322194
[email protected]49639fa2011-12-20 23:22:412195 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322196
[email protected]49639fa2011-12-20 23:22:412197 rv = trans->RestartWithAuth(
2198 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422199 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322200
2201 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422202 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322203
2204 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502205 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322206 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502207 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322208}
2209
2210// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2211// connection and with a large response body to drain.
[email protected]23e482282013-06-14 16:08:022212TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:422213 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322214 request.method = "GET";
bncce36dca22015-04-21 22:11:232215 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322216 request.load_flags = 0;
2217
[email protected]bb88e1d32013-05-03 23:11:072218 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272219
[email protected]2d2697f92009-02-18 21:00:322220 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232221 MockWrite(
2222 "GET / HTTP/1.1\r\n"
2223 "Host: www.example.org\r\n"
2224 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322225
bncce36dca22015-04-21 22:11:232226 // After calling trans->RestartWithAuth(), this is the request we should
2227 // be issuing -- the final header line contains the credentials.
2228 MockWrite(
2229 "GET / HTTP/1.1\r\n"
2230 "Host: www.example.org\r\n"
2231 "Connection: keep-alive\r\n"
2232 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322233 };
2234
2235 // Respond with 5 kb of response body.
2236 std::string large_body_string("Unauthorized");
2237 large_body_string.append(5 * 1024, ' ');
2238 large_body_string.append("\r\n");
2239
2240 MockRead data_reads1[] = {
2241 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2242 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2243 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2244 // 5134 = 12 + 5 * 1024 + 2
2245 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062246 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:322247
2248 // Lastly, the server responds with the actual content.
2249 MockRead("HTTP/1.1 200 OK\r\n"),
2250 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502251 MockRead("Content-Length: 5\r\n\r\n"),
2252 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322253 };
2254
[email protected]2d0a4f92011-05-05 16:38:462255 // An incorrect reconnect would cause this to be read.
2256 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062257 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462258 };
2259
[email protected]31a2bfe2010-02-09 08:03:392260 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2261 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462262 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2263 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072264 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2265 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322266
[email protected]49639fa2011-12-20 23:22:412267 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322268
[email protected]262eec82013-03-19 21:01:362269 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502270 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412271 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422272 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322273
2274 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422275 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322276
[email protected]1c773ea12009-04-28 19:58:422277 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502278 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042279 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322280
[email protected]49639fa2011-12-20 23:22:412281 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322282
[email protected]49639fa2011-12-20 23:22:412283 rv = trans->RestartWithAuth(
2284 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422285 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322286
2287 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422288 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322289
2290 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502291 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322292 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502293 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322294}
2295
2296// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:312297// connection, but the server gets impatient and closes the connection.
[email protected]23e482282013-06-14 16:08:022298TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:312299 HttpRequestInfo request;
2300 request.method = "GET";
bncce36dca22015-04-21 22:11:232301 request.url = GURL("http://www.example.org/");
[email protected]11203f012009-11-12 23:02:312302 request.load_flags = 0;
2303
[email protected]bb88e1d32013-05-03 23:11:072304 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272305
[email protected]11203f012009-11-12 23:02:312306 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232307 MockWrite(
2308 "GET / HTTP/1.1\r\n"
2309 "Host: www.example.org\r\n"
2310 "Connection: keep-alive\r\n\r\n"),
2311 // This simulates the seemingly successful write to a closed connection
2312 // if the bug is not fixed.
2313 MockWrite(
2314 "GET / HTTP/1.1\r\n"
2315 "Host: www.example.org\r\n"
2316 "Connection: keep-alive\r\n"
2317 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312318 };
2319
2320 MockRead data_reads1[] = {
2321 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2322 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2323 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2324 MockRead("Content-Length: 14\r\n\r\n"),
2325 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:062326 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:312327 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:062328 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:312329 };
2330
2331 // After calling trans->RestartWithAuth(), this is the request we should
2332 // be issuing -- the final header line contains the credentials.
2333 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232334 MockWrite(
2335 "GET / HTTP/1.1\r\n"
2336 "Host: www.example.org\r\n"
2337 "Connection: keep-alive\r\n"
2338 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312339 };
2340
2341 // Lastly, the server responds with the actual content.
2342 MockRead data_reads2[] = {
2343 MockRead("HTTP/1.1 200 OK\r\n"),
2344 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502345 MockRead("Content-Length: 5\r\n\r\n"),
2346 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:312347 };
2348
[email protected]31a2bfe2010-02-09 08:03:392349 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2350 data_writes1, arraysize(data_writes1));
2351 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2352 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072353 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2354 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:312355
[email protected]49639fa2011-12-20 23:22:412356 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:312357
[email protected]262eec82013-03-19 21:01:362358 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502359 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412360 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]11203f012009-11-12 23:02:312361 EXPECT_EQ(ERR_IO_PENDING, rv);
2362
2363 rv = callback1.WaitForResult();
2364 EXPECT_EQ(OK, rv);
2365
2366 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502367 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042368 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:312369
[email protected]49639fa2011-12-20 23:22:412370 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:312371
[email protected]49639fa2011-12-20 23:22:412372 rv = trans->RestartWithAuth(
2373 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]11203f012009-11-12 23:02:312374 EXPECT_EQ(ERR_IO_PENDING, rv);
2375
2376 rv = callback2.WaitForResult();
2377 EXPECT_EQ(OK, rv);
2378
2379 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502380 ASSERT_TRUE(response != NULL);
[email protected]11203f012009-11-12 23:02:312381 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502382 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:312383}
2384
[email protected]394816e92010-08-03 07:38:592385// Test the request-challenge-retry sequence for basic auth, over a connection
2386// that requires a restart when setting up an SSL tunnel.
ttuttle34f63b52015-03-05 04:33:012387TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
2388 HttpRequestInfo request;
2389 request.method = "GET";
bncce36dca22015-04-21 22:11:232390 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:012391 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292392 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:012393
2394 // Configure against proxy server "myproxy:70".
2395 session_deps_.proxy_service.reset(
2396 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
vishal.b62985ca92015-04-17 08:45:512397 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:012398 session_deps_.net_log = log.bound().net_log();
2399 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2400
2401 // Since we have proxy, should try to establish tunnel.
2402 MockWrite data_writes1[] = {
2403 MockWrite(
bncce36dca22015-04-21 22:11:232404 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2405 "Host: www.example.org\r\n"
ttuttle34f63b52015-03-05 04:33:012406 "Proxy-Connection: keep-alive\r\n\r\n"),
2407
2408 // After calling trans->RestartWithAuth(), this is the request we should
2409 // be issuing -- the final header line contains the credentials.
2410 MockWrite(
bncce36dca22015-04-21 22:11:232411 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2412 "Host: www.example.org\r\n"
ttuttle34f63b52015-03-05 04:33:012413 "Proxy-Connection: keep-alive\r\n"
2414 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2415
2416 MockWrite(
2417 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:232418 "Host: www.example.org\r\n"
ttuttle34f63b52015-03-05 04:33:012419 "Connection: keep-alive\r\n\r\n"),
2420 };
2421
2422 // The proxy responds to the connect with a 407, using a persistent
2423 // connection.
2424 MockRead data_reads1[] = {
2425 // No credentials.
2426 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
2427 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
2428
2429 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
2430
2431 MockRead("HTTP/1.1 200 OK\r\n"),
2432 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2433 MockRead("Content-Length: 5\r\n\r\n"),
2434 MockRead(SYNCHRONOUS, "hello"),
2435 };
2436
2437 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2438 data_writes1, arraysize(data_writes1));
2439 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2440 SSLSocketDataProvider ssl(ASYNC, OK);
2441 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
2442
2443 TestCompletionCallback callback1;
2444
2445 scoped_ptr<HttpTransaction> trans(
2446 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2447
2448 int rv = trans->Start(&request, callback1.callback(), log.bound());
2449 EXPECT_EQ(ERR_IO_PENDING, rv);
2450
2451 rv = callback1.WaitForResult();
2452 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:462453 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:012454 log.GetEntries(&entries);
2455 size_t pos = ExpectLogContainsSomewhere(
2456 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
2457 NetLog::PHASE_NONE);
2458 ExpectLogContainsSomewhere(
2459 entries, pos, NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2460 NetLog::PHASE_NONE);
2461
2462 const HttpResponseInfo* response = trans->GetResponseInfo();
2463 ASSERT_TRUE(response != NULL);
2464 EXPECT_FALSE(response->headers->IsKeepAlive());
2465 ASSERT_FALSE(response->headers.get() == NULL);
2466 EXPECT_EQ(407, response->headers->response_code());
2467 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
2468 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2469
2470 LoadTimingInfo load_timing_info;
2471 // CONNECT requests and responses are handled at the connect job level, so
2472 // the transaction does not yet have a connection.
2473 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
2474
2475 TestCompletionCallback callback2;
2476
2477 rv =
2478 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
2479 EXPECT_EQ(ERR_IO_PENDING, rv);
2480
2481 rv = callback2.WaitForResult();
2482 EXPECT_EQ(OK, rv);
2483
2484 response = trans->GetResponseInfo();
2485 ASSERT_TRUE(response != NULL);
2486
2487 EXPECT_TRUE(response->headers->IsKeepAlive());
2488 EXPECT_EQ(200, response->headers->response_code());
2489 EXPECT_EQ(5, response->headers->GetContentLength());
2490 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2491
2492 // The password prompt info should not be set.
2493 EXPECT_TRUE(response->auth_challenge.get() == NULL);
2494
2495 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2496 TestLoadTimingNotReusedWithPac(load_timing_info,
2497 CONNECT_TIMING_HAS_SSL_TIMES);
2498
2499 trans.reset();
2500 session->CloseAllConnections();
2501}
2502
2503// Test the request-challenge-retry sequence for basic auth, over a connection
2504// that requires a restart when setting up an SSL tunnel.
2505TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) {
[email protected]394816e92010-08-03 07:38:592506 HttpRequestInfo request;
2507 request.method = "GET";
bncce36dca22015-04-21 22:11:232508 request.url = GURL("https://www.example.org/");
[email protected]394816e92010-08-03 07:38:592509 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292510 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]394816e92010-08-03 07:38:592511
[email protected]cb9bf6ca2011-01-28 13:15:272512 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072513 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:202514 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
vishal.b62985ca92015-04-17 08:45:512515 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072516 session_deps_.net_log = log.bound().net_log();
2517 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272518
[email protected]394816e92010-08-03 07:38:592519 // Since we have proxy, should try to establish tunnel.
2520 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232521 MockWrite(
2522 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2523 "Host: www.example.org\r\n"
2524 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]394816e92010-08-03 07:38:592525
bncce36dca22015-04-21 22:11:232526 // After calling trans->RestartWithAuth(), this is the request we should
2527 // be issuing -- the final header line contains the credentials.
2528 MockWrite(
2529 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2530 "Host: www.example.org\r\n"
2531 "Proxy-Connection: keep-alive\r\n"
2532 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]394816e92010-08-03 07:38:592533
bncce36dca22015-04-21 22:11:232534 MockWrite(
2535 "GET / HTTP/1.1\r\n"
2536 "Host: www.example.org\r\n"
2537 "Connection: keep-alive\r\n\r\n"),
[email protected]394816e92010-08-03 07:38:592538 };
2539
2540 // The proxy responds to the connect with a 407, using a persistent
2541 // connection.
2542 MockRead data_reads1[] = {
2543 // No credentials.
2544 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2545 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2546 MockRead("Proxy-Connection: close\r\n\r\n"),
2547
2548 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2549
2550 MockRead("HTTP/1.1 200 OK\r\n"),
2551 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502552 MockRead("Content-Length: 5\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062553 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:592554 };
2555
2556 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2557 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072558 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:062559 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072560 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:592561
[email protected]49639fa2011-12-20 23:22:412562 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:592563
[email protected]262eec82013-03-19 21:01:362564 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502565 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:502566
[email protected]49639fa2011-12-20 23:22:412567 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]394816e92010-08-03 07:38:592568 EXPECT_EQ(ERR_IO_PENDING, rv);
2569
2570 rv = callback1.WaitForResult();
2571 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:462572 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:402573 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:592574 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402575 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]394816e92010-08-03 07:38:592576 NetLog::PHASE_NONE);
2577 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402578 entries, pos,
[email protected]394816e92010-08-03 07:38:592579 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2580 NetLog::PHASE_NONE);
2581
2582 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502583 ASSERT_TRUE(response != NULL);
ttuttle34f63b52015-03-05 04:33:012584 EXPECT_FALSE(response->headers->IsKeepAlive());
[email protected]90499482013-06-01 00:39:502585 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]394816e92010-08-03 07:38:592586 EXPECT_EQ(407, response->headers->response_code());
2587 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042588 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:592589
[email protected]029c83b62013-01-24 05:28:202590 LoadTimingInfo load_timing_info;
2591 // CONNECT requests and responses are handled at the connect job level, so
2592 // the transaction does not yet have a connection.
2593 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
2594
[email protected]49639fa2011-12-20 23:22:412595 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:592596
[email protected]49639fa2011-12-20 23:22:412597 rv = trans->RestartWithAuth(
2598 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]394816e92010-08-03 07:38:592599 EXPECT_EQ(ERR_IO_PENDING, rv);
2600
2601 rv = callback2.WaitForResult();
2602 EXPECT_EQ(OK, rv);
2603
2604 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502605 ASSERT_TRUE(response != NULL);
[email protected]394816e92010-08-03 07:38:592606
2607 EXPECT_TRUE(response->headers->IsKeepAlive());
2608 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:502609 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:592610 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2611
2612 // The password prompt info should not be set.
2613 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502614
[email protected]029c83b62013-01-24 05:28:202615 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2616 TestLoadTimingNotReusedWithPac(load_timing_info,
2617 CONNECT_TIMING_HAS_SSL_TIMES);
2618
[email protected]0b0bf032010-09-21 18:08:502619 trans.reset();
[email protected]102e27c2011-02-23 01:01:312620 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:592621}
2622
[email protected]11203f012009-11-12 23:02:312623// Test the request-challenge-retry sequence for basic auth, over a keep-alive
ttuttle34f63b52015-03-05 04:33:012624// proxy connection with HTTP/1.0 responses, when setting up an SSL tunnel.
2625TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
2626 HttpRequestInfo request;
2627 request.method = "GET";
bncce36dca22015-04-21 22:11:232628 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:012629 // Ensure that proxy authentication is attempted even
2630 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292631 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:012632
2633 // Configure against proxy server "myproxy:70".
2634 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
vishal.b62985ca92015-04-17 08:45:512635 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:012636 session_deps_.net_log = log.bound().net_log();
2637 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2638
2639 scoped_ptr<HttpTransaction> trans(
2640 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2641
2642 // Since we have proxy, should try to establish tunnel.
2643 MockWrite data_writes1[] = {
2644 MockWrite(
bncce36dca22015-04-21 22:11:232645 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2646 "Host: www.example.org\r\n"
ttuttle34f63b52015-03-05 04:33:012647 "Proxy-Connection: keep-alive\r\n\r\n"),
2648
2649 // After calling trans->RestartWithAuth(), this is the request we should
2650 // be issuing -- the final header line contains the credentials.
2651 MockWrite(
bncce36dca22015-04-21 22:11:232652 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2653 "Host: www.example.org\r\n"
ttuttle34f63b52015-03-05 04:33:012654 "Proxy-Connection: keep-alive\r\n"
2655 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
2656 };
2657
2658 // The proxy responds to the connect with a 407, using a persistent
2659 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
2660 MockRead data_reads1[] = {
2661 // No credentials.
2662 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
2663 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2664 MockRead("Proxy-Connection: keep-alive\r\n"),
2665 MockRead("Content-Length: 10\r\n\r\n"),
2666 MockRead("0123456789"),
2667
2668 // Wrong credentials (wrong password).
2669 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
2670 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2671 MockRead("Proxy-Connection: keep-alive\r\n"),
2672 MockRead("Content-Length: 10\r\n\r\n"),
2673 // No response body because the test stops reading here.
2674 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
2675 };
2676
2677 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2678 data_writes1, arraysize(data_writes1));
2679 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2680
2681 TestCompletionCallback callback1;
2682
2683 int rv = trans->Start(&request, callback1.callback(), log.bound());
2684 EXPECT_EQ(ERR_IO_PENDING, rv);
2685
2686 rv = callback1.WaitForResult();
2687 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:462688 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:012689 log.GetEntries(&entries);
2690 size_t pos = ExpectLogContainsSomewhere(
2691 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
2692 NetLog::PHASE_NONE);
2693 ExpectLogContainsSomewhere(
2694 entries, pos, NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2695 NetLog::PHASE_NONE);
2696
2697 const HttpResponseInfo* response = trans->GetResponseInfo();
2698 ASSERT_TRUE(response);
2699 ASSERT_TRUE(response->headers);
2700 EXPECT_TRUE(response->headers->IsKeepAlive());
2701 EXPECT_EQ(407, response->headers->response_code());
2702 EXPECT_EQ(10, response->headers->GetContentLength());
2703 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
2704 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2705
2706 TestCompletionCallback callback2;
2707
2708 // Wrong password (should be "bar").
2709 rv =
2710 trans->RestartWithAuth(AuthCredentials(kFoo, kBaz), callback2.callback());
2711 EXPECT_EQ(ERR_IO_PENDING, rv);
2712
2713 rv = callback2.WaitForResult();
2714 EXPECT_EQ(OK, rv);
2715
2716 response = trans->GetResponseInfo();
2717 ASSERT_TRUE(response);
2718 ASSERT_TRUE(response->headers);
2719 EXPECT_TRUE(response->headers->IsKeepAlive());
2720 EXPECT_EQ(407, response->headers->response_code());
2721 EXPECT_EQ(10, response->headers->GetContentLength());
2722 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
2723 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2724
2725 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
2726 // out of scope.
2727 session->CloseAllConnections();
2728}
2729
2730// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2731// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel.
2732TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
[email protected]cb9bf6ca2011-01-28 13:15:272733 HttpRequestInfo request;
2734 request.method = "GET";
bncce36dca22015-04-21 22:11:232735 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:272736 // Ensure that proxy authentication is attempted even
2737 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292738 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]cb9bf6ca2011-01-28 13:15:272739
[email protected]2d2697f92009-02-18 21:00:322740 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072741 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
vishal.b62985ca92015-04-17 08:45:512742 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072743 session_deps_.net_log = log.bound().net_log();
2744 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:322745
[email protected]262eec82013-03-19 21:01:362746 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502747 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d2697f92009-02-18 21:00:322748
[email protected]2d2697f92009-02-18 21:00:322749 // Since we have proxy, should try to establish tunnel.
2750 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232751 MockWrite(
2752 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2753 "Host: www.example.org\r\n"
2754 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322755
bncce36dca22015-04-21 22:11:232756 // After calling trans->RestartWithAuth(), this is the request we should
2757 // be issuing -- the final header line contains the credentials.
2758 MockWrite(
2759 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2760 "Host: www.example.org\r\n"
2761 "Proxy-Connection: keep-alive\r\n"
2762 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322763 };
2764
2765 // The proxy responds to the connect with a 407, using a persistent
2766 // connection.
2767 MockRead data_reads1[] = {
2768 // No credentials.
2769 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2770 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2771 MockRead("Content-Length: 10\r\n\r\n"),
2772 MockRead("0123456789"),
2773
2774 // Wrong credentials (wrong password).
2775 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2776 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2777 MockRead("Content-Length: 10\r\n\r\n"),
2778 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:062779 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]2d2697f92009-02-18 21:00:322780 };
2781
[email protected]31a2bfe2010-02-09 08:03:392782 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2783 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072784 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d2697f92009-02-18 21:00:322785
[email protected]49639fa2011-12-20 23:22:412786 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322787
[email protected]49639fa2011-12-20 23:22:412788 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]1c773ea12009-04-28 19:58:422789 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322790
2791 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422792 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:462793 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:402794 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:392795 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402796 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]dbb83db2010-05-11 18:13:392797 NetLog::PHASE_NONE);
2798 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402799 entries, pos,
[email protected]dbb83db2010-05-11 18:13:392800 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2801 NetLog::PHASE_NONE);
[email protected]2d2697f92009-02-18 21:00:322802
[email protected]1c773ea12009-04-28 19:58:422803 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:242804 ASSERT_TRUE(response);
2805 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:322806 EXPECT_TRUE(response->headers->IsKeepAlive());
2807 EXPECT_EQ(407, response->headers->response_code());
ttuttle34f63b52015-03-05 04:33:012808 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422809 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042810 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322811
[email protected]49639fa2011-12-20 23:22:412812 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322813
2814 // Wrong password (should be "bar").
[email protected]49639fa2011-12-20 23:22:412815 rv = trans->RestartWithAuth(
2816 AuthCredentials(kFoo, kBaz), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422817 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322818
2819 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422820 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322821
2822 response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:242823 ASSERT_TRUE(response);
2824 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:322825 EXPECT_TRUE(response->headers->IsKeepAlive());
2826 EXPECT_EQ(407, response->headers->response_code());
ttuttle34f63b52015-03-05 04:33:012827 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422828 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042829 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]e772db3f2010-07-12 18:11:132830
[email protected]e60e47a2010-07-14 03:37:182831 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
2832 // out of scope.
[email protected]102e27c2011-02-23 01:01:312833 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:322834}
2835
[email protected]a8e9b162009-03-12 00:06:442836// Test that we don't read the response body when we fail to establish a tunnel,
2837// even if the user cancels the proxy's auth attempt.
[email protected]23e482282013-06-14 16:08:022838TEST_P(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:272839 HttpRequestInfo request;
2840 request.method = "GET";
bncce36dca22015-04-21 22:11:232841 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:272842 request.load_flags = 0;
2843
[email protected]a8e9b162009-03-12 00:06:442844 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072845 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]a8e9b162009-03-12 00:06:442846
[email protected]bb88e1d32013-05-03 23:11:072847 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:442848
[email protected]262eec82013-03-19 21:01:362849 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502850 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]a8e9b162009-03-12 00:06:442851
[email protected]a8e9b162009-03-12 00:06:442852 // Since we have proxy, should try to establish tunnel.
2853 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:232854 MockWrite(
2855 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2856 "Host: www.example.org\r\n"
2857 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:442858 };
2859
2860 // The proxy responds to the connect with a 407.
2861 MockRead data_reads[] = {
ttuttle7933c112015-01-06 00:55:242862 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2863 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2864 MockRead("Content-Length: 10\r\n\r\n"),
2865 MockRead("0123456789"), // Should not be reached.
2866 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]a8e9b162009-03-12 00:06:442867 };
2868
[email protected]31a2bfe2010-02-09 08:03:392869 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2870 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072871 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:442872
[email protected]49639fa2011-12-20 23:22:412873 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:442874
[email protected]49639fa2011-12-20 23:22:412875 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422876 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a8e9b162009-03-12 00:06:442877
2878 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422879 EXPECT_EQ(OK, rv);
[email protected]a8e9b162009-03-12 00:06:442880
[email protected]1c773ea12009-04-28 19:58:422881 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:242882 ASSERT_TRUE(response);
2883 ASSERT_TRUE(response->headers);
[email protected]a8e9b162009-03-12 00:06:442884 EXPECT_TRUE(response->headers->IsKeepAlive());
2885 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:422886 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:442887
2888 std::string response_data;
2889 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:422890 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]e60e47a2010-07-14 03:37:182891
2892 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:312893 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:442894}
2895
ttuttle7933c112015-01-06 00:55:242896// Test that we don't pass extraneous headers from the proxy's response to the
2897// caller when the proxy responds to CONNECT with 407.
2898TEST_P(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
2899 HttpRequestInfo request;
2900 request.method = "GET";
bncce36dca22015-04-21 22:11:232901 request.url = GURL("https://www.example.org/");
ttuttle7933c112015-01-06 00:55:242902 request.load_flags = 0;
2903
2904 // Configure against proxy server "myproxy:70".
2905 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
2906
2907 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2908
2909 scoped_ptr<HttpTransaction> trans(
2910 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2911
2912 // Since we have proxy, should try to establish tunnel.
2913 MockWrite data_writes[] = {
2914 MockWrite(
bncce36dca22015-04-21 22:11:232915 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2916 "Host: www.example.org\r\n"
ttuttle7933c112015-01-06 00:55:242917 "Proxy-Connection: keep-alive\r\n\r\n"),
2918 };
2919
2920 // The proxy responds to the connect with a 407.
2921 MockRead data_reads[] = {
2922 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2923 MockRead("X-Foo: bar\r\n"),
2924 MockRead("Set-Cookie: foo=bar\r\n"),
2925 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2926 MockRead("Content-Length: 10\r\n\r\n"),
2927 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
2928 };
2929
2930 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
2931 arraysize(data_writes));
2932 session_deps_.socket_factory->AddSocketDataProvider(&data);
2933
2934 TestCompletionCallback callback;
2935
2936 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
2937 EXPECT_EQ(ERR_IO_PENDING, rv);
2938
2939 rv = callback.WaitForResult();
2940 EXPECT_EQ(OK, rv);
2941
2942 const HttpResponseInfo* response = trans->GetResponseInfo();
2943 ASSERT_TRUE(response);
2944 ASSERT_TRUE(response->headers);
2945 EXPECT_TRUE(response->headers->IsKeepAlive());
2946 EXPECT_EQ(407, response->headers->response_code());
2947 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2948 EXPECT_FALSE(response->headers->HasHeader("X-Foo"));
2949 EXPECT_FALSE(response->headers->HasHeader("Set-Cookie"));
2950
2951 std::string response_data;
2952 rv = ReadTransaction(trans.get(), &response_data);
2953 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
2954
2955 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
2956 session->CloseAllConnections();
2957}
2958
[email protected]8fdbcd22010-05-05 02:54:522959// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
2960// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
[email protected]23e482282013-06-14 16:08:022961TEST_P(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:522962 HttpRequestInfo request;
2963 request.method = "GET";
bncce36dca22015-04-21 22:11:232964 request.url = GURL("http://www.example.org/");
[email protected]8fdbcd22010-05-05 02:54:522965 request.load_flags = 0;
2966
[email protected]cb9bf6ca2011-01-28 13:15:272967 // We are using a DIRECT connection (i.e. no proxy) for this session.
[email protected]3fe8d2f82013-10-17 08:56:072968 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272969 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:412970 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:272971
[email protected]8fdbcd22010-05-05 02:54:522972 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232973 MockWrite(
2974 "GET / HTTP/1.1\r\n"
2975 "Host: www.example.org\r\n"
2976 "Connection: keep-alive\r\n\r\n"),
[email protected]8fdbcd22010-05-05 02:54:522977 };
2978
2979 MockRead data_reads1[] = {
2980 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
2981 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2982 // Large content-length -- won't matter, as connection will be reset.
2983 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062984 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:522985 };
2986
2987 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2988 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072989 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:522990
[email protected]49639fa2011-12-20 23:22:412991 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:522992
[email protected]49639fa2011-12-20 23:22:412993 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]8fdbcd22010-05-05 02:54:522994 EXPECT_EQ(ERR_IO_PENDING, rv);
2995
2996 rv = callback.WaitForResult();
2997 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
2998}
2999
[email protected]7a67a8152010-11-05 18:31:103000// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
3001// through a non-authenticating proxy. The request should fail with
3002// ERR_UNEXPECTED_PROXY_AUTH.
3003// Note that it is impossible to detect if an HTTP server returns a 407 through
3004// a non-authenticating proxy - there is nothing to indicate whether the
3005// response came from the proxy or the server, so it is treated as if the proxy
3006// issued the challenge.
[email protected]23e482282013-06-14 16:08:023007TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:233008 HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:273009 HttpRequestInfo request;
3010 request.method = "GET";
bncce36dca22015-04-21 22:11:233011 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273012
[email protected]bb88e1d32013-05-03 23:11:073013 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
vishal.b62985ca92015-04-17 08:45:513014 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073015 session_deps_.net_log = log.bound().net_log();
3016 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:103017
[email protected]7a67a8152010-11-05 18:31:103018 // Since we have proxy, should try to establish tunnel.
3019 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233020 MockWrite(
3021 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3022 "Host: www.example.org\r\n"
3023 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103024
bncce36dca22015-04-21 22:11:233025 MockWrite(
3026 "GET / HTTP/1.1\r\n"
3027 "Host: www.example.org\r\n"
3028 "Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103029 };
3030
3031 MockRead data_reads1[] = {
3032 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3033
3034 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
3035 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3036 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:063037 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:103038 };
3039
3040 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3041 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073042 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063043 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073044 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:103045
[email protected]49639fa2011-12-20 23:22:413046 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:103047
[email protected]262eec82013-03-19 21:01:363048 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503049 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a67a8152010-11-05 18:31:103050
[email protected]49639fa2011-12-20 23:22:413051 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7a67a8152010-11-05 18:31:103052 EXPECT_EQ(ERR_IO_PENDING, rv);
3053
3054 rv = callback1.WaitForResult();
3055 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
mmenke43758e62015-05-04 21:09:463056 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403057 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:103058 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403059 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]7a67a8152010-11-05 18:31:103060 NetLog::PHASE_NONE);
3061 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403062 entries, pos,
[email protected]7a67a8152010-11-05 18:31:103063 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3064 NetLog::PHASE_NONE);
3065}
[email protected]2df19bb2010-08-25 20:13:463066
[email protected]029c83b62013-01-24 05:28:203067// Test the load timing for HTTPS requests with an HTTP proxy.
[email protected]23e482282013-06-14 16:08:023068TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:203069 HttpRequestInfo request1;
3070 request1.method = "GET";
bncce36dca22015-04-21 22:11:233071 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:203072
3073 HttpRequestInfo request2;
3074 request2.method = "GET";
bncce36dca22015-04-21 22:11:233075 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:203076
3077 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073078 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:203079 ProxyService::CreateFixed("PROXY myproxy:70"));
vishal.b62985ca92015-04-17 08:45:513080 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073081 session_deps_.net_log = log.bound().net_log();
3082 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:203083
3084 // Since we have proxy, should try to establish tunnel.
3085 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233086 MockWrite(
3087 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3088 "Host: www.example.org\r\n"
3089 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203090
bncce36dca22015-04-21 22:11:233091 MockWrite(
3092 "GET /1 HTTP/1.1\r\n"
3093 "Host: www.example.org\r\n"
3094 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203095
bncce36dca22015-04-21 22:11:233096 MockWrite(
3097 "GET /2 HTTP/1.1\r\n"
3098 "Host: www.example.org\r\n"
3099 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203100 };
3101
3102 // The proxy responds to the connect with a 407, using a persistent
3103 // connection.
3104 MockRead data_reads1[] = {
3105 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3106
3107 MockRead("HTTP/1.1 200 OK\r\n"),
3108 MockRead("Content-Length: 1\r\n\r\n"),
3109 MockRead(SYNCHRONOUS, "1"),
3110
3111 MockRead("HTTP/1.1 200 OK\r\n"),
3112 MockRead("Content-Length: 2\r\n\r\n"),
3113 MockRead(SYNCHRONOUS, "22"),
3114 };
3115
3116 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3117 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073118 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:203119 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073120 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:203121
3122 TestCompletionCallback callback1;
[email protected]262eec82013-03-19 21:01:363123 scoped_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:503124 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:203125
3126 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
3127 EXPECT_EQ(ERR_IO_PENDING, rv);
3128
3129 rv = callback1.WaitForResult();
3130 EXPECT_EQ(OK, rv);
3131
3132 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
3133 ASSERT_TRUE(response1 != NULL);
[email protected]90499482013-06-01 00:39:503134 ASSERT_TRUE(response1->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:203135 EXPECT_EQ(1, response1->headers->GetContentLength());
3136
3137 LoadTimingInfo load_timing_info1;
3138 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
3139 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
3140
3141 trans1.reset();
3142
3143 TestCompletionCallback callback2;
[email protected]262eec82013-03-19 21:01:363144 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503145 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:203146
3147 rv = trans2->Start(&request2, callback2.callback(), log.bound());
3148 EXPECT_EQ(ERR_IO_PENDING, rv);
3149
3150 rv = callback2.WaitForResult();
3151 EXPECT_EQ(OK, rv);
3152
3153 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
3154 ASSERT_TRUE(response2 != NULL);
[email protected]90499482013-06-01 00:39:503155 ASSERT_TRUE(response2->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:203156 EXPECT_EQ(2, response2->headers->GetContentLength());
3157
3158 LoadTimingInfo load_timing_info2;
3159 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3160 TestLoadTimingReused(load_timing_info2);
3161
3162 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
3163
3164 trans2.reset();
3165 session->CloseAllConnections();
3166}
3167
3168// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
[email protected]23e482282013-06-14 16:08:023169TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:203170 HttpRequestInfo request1;
3171 request1.method = "GET";
bncce36dca22015-04-21 22:11:233172 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:203173
3174 HttpRequestInfo request2;
3175 request2.method = "GET";
bncce36dca22015-04-21 22:11:233176 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:203177
3178 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073179 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:203180 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
vishal.b62985ca92015-04-17 08:45:513181 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073182 session_deps_.net_log = log.bound().net_log();
3183 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:203184
3185 // Since we have proxy, should try to establish tunnel.
3186 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233187 MockWrite(
3188 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3189 "Host: www.example.org\r\n"
3190 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203191
bncce36dca22015-04-21 22:11:233192 MockWrite(
3193 "GET /1 HTTP/1.1\r\n"
3194 "Host: www.example.org\r\n"
3195 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203196
bncce36dca22015-04-21 22:11:233197 MockWrite(
3198 "GET /2 HTTP/1.1\r\n"
3199 "Host: www.example.org\r\n"
3200 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203201 };
3202
3203 // The proxy responds to the connect with a 407, using a persistent
3204 // connection.
3205 MockRead data_reads1[] = {
3206 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3207
3208 MockRead("HTTP/1.1 200 OK\r\n"),
3209 MockRead("Content-Length: 1\r\n\r\n"),
3210 MockRead(SYNCHRONOUS, "1"),
3211
3212 MockRead("HTTP/1.1 200 OK\r\n"),
3213 MockRead("Content-Length: 2\r\n\r\n"),
3214 MockRead(SYNCHRONOUS, "22"),
3215 };
3216
3217 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3218 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073219 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:203220 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073221 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:203222
3223 TestCompletionCallback callback1;
[email protected]262eec82013-03-19 21:01:363224 scoped_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:503225 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:203226
3227 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
3228 EXPECT_EQ(ERR_IO_PENDING, rv);
3229
3230 rv = callback1.WaitForResult();
3231 EXPECT_EQ(OK, rv);
3232
3233 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
3234 ASSERT_TRUE(response1 != NULL);
[email protected]90499482013-06-01 00:39:503235 ASSERT_TRUE(response1->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:203236 EXPECT_EQ(1, response1->headers->GetContentLength());
3237
3238 LoadTimingInfo load_timing_info1;
3239 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
3240 TestLoadTimingNotReusedWithPac(load_timing_info1,
3241 CONNECT_TIMING_HAS_SSL_TIMES);
3242
3243 trans1.reset();
3244
3245 TestCompletionCallback callback2;
[email protected]262eec82013-03-19 21:01:363246 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503247 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:203248
3249 rv = trans2->Start(&request2, callback2.callback(), log.bound());
3250 EXPECT_EQ(ERR_IO_PENDING, rv);
3251
3252 rv = callback2.WaitForResult();
3253 EXPECT_EQ(OK, rv);
3254
3255 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
3256 ASSERT_TRUE(response2 != NULL);
[email protected]90499482013-06-01 00:39:503257 ASSERT_TRUE(response2->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:203258 EXPECT_EQ(2, response2->headers->GetContentLength());
3259
3260 LoadTimingInfo load_timing_info2;
3261 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3262 TestLoadTimingReusedWithPac(load_timing_info2);
3263
3264 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
3265
3266 trans2.reset();
3267 session->CloseAllConnections();
3268}
3269
[email protected]2df19bb2010-08-25 20:13:463270// Test a simple get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023271TEST_P(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:273272 HttpRequestInfo request;
3273 request.method = "GET";
bncce36dca22015-04-21 22:11:233274 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273275
[email protected]2df19bb2010-08-25 20:13:463276 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073277 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113278 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513279 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073280 session_deps_.net_log = log.bound().net_log();
3281 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:463282
[email protected]2df19bb2010-08-25 20:13:463283 // Since we have proxy, should use full url
3284 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233285 MockWrite(
3286 "GET http://www.example.org/ HTTP/1.1\r\n"
3287 "Host: www.example.org\r\n"
3288 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:463289 };
3290
3291 MockRead data_reads1[] = {
3292 MockRead("HTTP/1.1 200 OK\r\n"),
3293 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3294 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063295 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:463296 };
3297
3298 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3299 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073300 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063301 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073302 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:463303
[email protected]49639fa2011-12-20 23:22:413304 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:463305
[email protected]262eec82013-03-19 21:01:363306 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503307 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503308
[email protected]49639fa2011-12-20 23:22:413309 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:463310 EXPECT_EQ(ERR_IO_PENDING, rv);
3311
3312 rv = callback1.WaitForResult();
3313 EXPECT_EQ(OK, rv);
3314
[email protected]58e32bb2013-01-21 18:23:253315 LoadTimingInfo load_timing_info;
3316 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3317 TestLoadTimingNotReused(load_timing_info,
3318 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3319
[email protected]2df19bb2010-08-25 20:13:463320 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503321 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:463322
3323 EXPECT_TRUE(response->headers->IsKeepAlive());
3324 EXPECT_EQ(200, response->headers->response_code());
3325 EXPECT_EQ(100, response->headers->GetContentLength());
3326 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3327
3328 // The password prompt info should not be set.
3329 EXPECT_TRUE(response->auth_challenge.get() == NULL);
3330}
3331
[email protected]7642b5ae2010-09-01 20:55:173332// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023333TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:273334 HttpRequestInfo request;
3335 request.method = "GET";
bncce36dca22015-04-21 22:11:233336 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273337 request.load_flags = 0;
3338
[email protected]7642b5ae2010-09-01 20:55:173339 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073340 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113341 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513342 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073343 session_deps_.net_log = log.bound().net_log();
3344 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:173345
bncce36dca22015-04-21 22:11:233346 // fetch http://www.example.org/ via SPDY
[email protected]cdf8f7e72013-05-23 10:56:463347 scoped_ptr<SpdyFrame> req(
3348 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
rch8e6c6c42015-05-01 14:05:133349 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]7642b5ae2010-09-01 20:55:173350
[email protected]23e482282013-06-14 16:08:023351 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3352 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:173353 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:133354 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]7642b5ae2010-09-01 20:55:173355 };
3356
rch8e6c6c42015-05-01 14:05:133357 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3358 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073359 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:173360
[email protected]8ddf8322012-02-23 18:08:063361 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023362 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073363 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:173364
[email protected]49639fa2011-12-20 23:22:413365 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:173366
[email protected]262eec82013-03-19 21:01:363367 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503368 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503369
[email protected]49639fa2011-12-20 23:22:413370 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7642b5ae2010-09-01 20:55:173371 EXPECT_EQ(ERR_IO_PENDING, rv);
3372
3373 rv = callback1.WaitForResult();
3374 EXPECT_EQ(OK, rv);
3375
[email protected]58e32bb2013-01-21 18:23:253376 LoadTimingInfo load_timing_info;
3377 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3378 TestLoadTimingNotReused(load_timing_info,
3379 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3380
[email protected]7642b5ae2010-09-01 20:55:173381 const HttpResponseInfo* response = trans->GetResponseInfo();
3382 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503383 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]7642b5ae2010-09-01 20:55:173384 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3385
3386 std::string response_data;
3387 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:233388 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:173389}
3390
[email protected]1c173852014-06-19 12:51:503391// Verifies that a session which races and wins against the owning transaction
3392// (completing prior to host resolution), doesn't fail the transaction.
3393// Regression test for crbug.com/334413.
3394TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
3395 HttpRequestInfo request;
3396 request.method = "GET";
bncce36dca22015-04-21 22:11:233397 request.url = GURL("http://www.example.org/");
[email protected]1c173852014-06-19 12:51:503398 request.load_flags = 0;
3399
3400 // Configure SPDY proxy server "proxy:70".
3401 session_deps_.proxy_service.reset(
3402 ProxyService::CreateFixed("https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513403 BoundTestNetLog log;
[email protected]1c173852014-06-19 12:51:503404 session_deps_.net_log = log.bound().net_log();
3405 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3406
bncce36dca22015-04-21 22:11:233407 // Fetch http://www.example.org/ through the SPDY proxy.
[email protected]1c173852014-06-19 12:51:503408 scoped_ptr<SpdyFrame> req(
3409 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
rch8e6c6c42015-05-01 14:05:133410 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]1c173852014-06-19 12:51:503411
3412 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3413 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
3414 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:133415 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]1c173852014-06-19 12:51:503416 };
3417
rch8e6c6c42015-05-01 14:05:133418 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3419 arraysize(spdy_writes));
[email protected]1c173852014-06-19 12:51:503420 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
3421
3422 SSLSocketDataProvider ssl(ASYNC, OK);
3423 ssl.SetNextProto(GetParam());
3424 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3425
3426 TestCompletionCallback callback1;
3427
3428 scoped_ptr<HttpTransaction> trans(
3429 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3430
3431 // Stall the hostname resolution begun by the transaction.
3432 session_deps_.host_resolver->set_synchronous_mode(false);
3433 session_deps_.host_resolver->set_ondemand_mode(true);
3434
3435 int rv = trans->Start(&request, callback1.callback(), log.bound());
3436 EXPECT_EQ(ERR_IO_PENDING, rv);
3437
3438 // Race a session to the proxy, which completes first.
3439 session_deps_.host_resolver->set_ondemand_mode(false);
3440 SpdySessionKey key(
3441 HostPortPair("proxy", 70), ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
3442 base::WeakPtr<SpdySession> spdy_session =
3443 CreateSecureSpdySession(session, key, log.bound());
3444
3445 // Unstall the resolution begun by the transaction.
3446 session_deps_.host_resolver->set_ondemand_mode(true);
3447 session_deps_.host_resolver->ResolveAllPending();
3448
3449 EXPECT_FALSE(callback1.have_result());
3450 rv = callback1.WaitForResult();
3451 EXPECT_EQ(OK, rv);
3452
3453 const HttpResponseInfo* response = trans->GetResponseInfo();
3454 ASSERT_TRUE(response != NULL);
3455 ASSERT_TRUE(response->headers.get() != NULL);
3456 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3457
3458 std::string response_data;
3459 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
3460 EXPECT_EQ(kUploadData, response_data);
3461}
3462
[email protected]dc7bd1c52010-11-12 00:01:133463// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023464TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:273465 HttpRequestInfo request;
3466 request.method = "GET";
bncce36dca22015-04-21 22:11:233467 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273468 request.load_flags = 0;
3469
[email protected]79cb5c12011-09-12 13:12:043470 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073471 session_deps_.proxy_service.reset(
[email protected]79cb5c12011-09-12 13:12:043472 ProxyService::CreateFixed("https://myproxy:70"));
vishal.b62985ca92015-04-17 08:45:513473 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073474 session_deps_.net_log = log.bound().net_log();
3475 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:133476
[email protected]dc7bd1c52010-11-12 00:01:133477 // The first request will be a bare GET, the second request will be a
3478 // GET with a Proxy-Authorization header.
[email protected]ff98d7f02012-03-22 21:44:193479 scoped_ptr<SpdyFrame> req_get(
[email protected]cdf8f7e72013-05-23 10:56:463480 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]dc7bd1c52010-11-12 00:01:133481 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:463482 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:133483 };
[email protected]ff98d7f02012-03-22 21:44:193484 scoped_ptr<SpdyFrame> req_get_authorization(
[email protected]cdf8f7e72013-05-23 10:56:463485 spdy_util_.ConstructSpdyGet(kExtraAuthorizationHeaders,
3486 arraysize(kExtraAuthorizationHeaders) / 2,
3487 false,
3488 3,
3489 LOWEST,
3490 false));
[email protected]dc7bd1c52010-11-12 00:01:133491 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:133492 CreateMockWrite(*req_get, 0), CreateMockWrite(*req_get_authorization, 3),
[email protected]dc7bd1c52010-11-12 00:01:133493 };
3494
3495 // The first response is a 407 proxy authentication challenge, and the second
3496 // response will be a 200 response since the second request includes a valid
3497 // Authorization header.
3498 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:463499 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:133500 };
[email protected]ff98d7f02012-03-22 21:44:193501 scoped_ptr<SpdyFrame> resp_authentication(
[email protected]23e482282013-06-14 16:08:023502 spdy_util_.ConstructSpdySynReplyError(
[email protected]dc7bd1c52010-11-12 00:01:133503 "407 Proxy Authentication Required",
3504 kExtraAuthenticationHeaders, arraysize(kExtraAuthenticationHeaders)/2,
3505 1));
[email protected]ff98d7f02012-03-22 21:44:193506 scoped_ptr<SpdyFrame> body_authentication(
[email protected]23e482282013-06-14 16:08:023507 spdy_util_.ConstructSpdyBodyFrame(1, true));
3508 scoped_ptr<SpdyFrame> resp_data(
3509 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
3510 scoped_ptr<SpdyFrame> body_data(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:133511 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:133512 CreateMockRead(*resp_authentication, 1),
3513 CreateMockRead(*body_authentication, 2),
3514 CreateMockRead(*resp_data, 4),
3515 CreateMockRead(*body_data, 5),
3516 MockRead(ASYNC, 0, 6),
[email protected]dc7bd1c52010-11-12 00:01:133517 };
3518
rch8e6c6c42015-05-01 14:05:133519 SequencedSocketData data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3520 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073521 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:133522
[email protected]8ddf8322012-02-23 18:08:063523 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023524 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073525 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:133526
[email protected]49639fa2011-12-20 23:22:413527 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:133528
[email protected]262eec82013-03-19 21:01:363529 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503530 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]dc7bd1c52010-11-12 00:01:133531
[email protected]49639fa2011-12-20 23:22:413532 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]dc7bd1c52010-11-12 00:01:133533 EXPECT_EQ(ERR_IO_PENDING, rv);
3534
3535 rv = callback1.WaitForResult();
3536 EXPECT_EQ(OK, rv);
3537
3538 const HttpResponseInfo* const response = trans->GetResponseInfo();
3539
3540 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503541 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]dc7bd1c52010-11-12 00:01:133542 EXPECT_EQ(407, response->headers->response_code());
3543 EXPECT_TRUE(response->was_fetched_via_spdy);
[email protected]79cb5c12011-09-12 13:12:043544 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:133545
[email protected]49639fa2011-12-20 23:22:413546 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:133547
[email protected]49639fa2011-12-20 23:22:413548 rv = trans->RestartWithAuth(
3549 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]dc7bd1c52010-11-12 00:01:133550 EXPECT_EQ(ERR_IO_PENDING, rv);
3551
3552 rv = callback2.WaitForResult();
3553 EXPECT_EQ(OK, rv);
3554
3555 const HttpResponseInfo* const response_restart = trans->GetResponseInfo();
3556
3557 ASSERT_TRUE(response_restart != NULL);
[email protected]90499482013-06-01 00:39:503558 ASSERT_TRUE(response_restart->headers.get() != NULL);
[email protected]dc7bd1c52010-11-12 00:01:133559 EXPECT_EQ(200, response_restart->headers->response_code());
3560 // The password prompt info should not be set.
3561 EXPECT_TRUE(response_restart->auth_challenge.get() == NULL);
3562}
3563
[email protected]d9da5fe2010-10-13 22:37:163564// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
[email protected]23e482282013-06-14 16:08:023565TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:273566 HttpRequestInfo request;
3567 request.method = "GET";
bncce36dca22015-04-21 22:11:233568 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273569 request.load_flags = 0;
3570
[email protected]d9da5fe2010-10-13 22:37:163571 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073572 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113573 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513574 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073575 session_deps_.net_log = log.bound().net_log();
3576 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:163577
[email protected]262eec82013-03-19 21:01:363578 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503579 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:163580
bncce36dca22015-04-21 22:11:233581 // CONNECT to www.example.org:443 via SPDY
lgarrona91df87f2014-12-05 00:51:343582 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:233583 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
3584 // fetch https://www.example.org/ via HTTP
[email protected]d9da5fe2010-10-13 22:37:163585
bncce36dca22015-04-21 22:11:233586 const char get[] =
3587 "GET / HTTP/1.1\r\n"
3588 "Host: www.example.org\r\n"
3589 "Connection: keep-alive\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:193590 scoped_ptr<SpdyFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:023591 spdy_util_.ConstructSpdyBodyFrame(1, get, strlen(get), false));
3592 scoped_ptr<SpdyFrame> conn_resp(
3593 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:163594 const char resp[] = "HTTP/1.1 200 OK\r\n"
3595 "Content-Length: 10\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:193596 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:023597 spdy_util_.ConstructSpdyBodyFrame(1, resp, strlen(resp), false));
[email protected]ff98d7f02012-03-22 21:44:193598 scoped_ptr<SpdyFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:023599 spdy_util_.ConstructSpdyBodyFrame(1, "1234567890", 10, false));
[email protected]ff98d7f02012-03-22 21:44:193600 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203601 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
[email protected]8d2f7012012-02-16 00:08:043602
3603 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:133604 CreateMockWrite(*connect, 0),
3605 CreateMockWrite(*wrapped_get, 2),
3606 CreateMockWrite(*window_update, 6),
[email protected]8d2f7012012-02-16 00:08:043607 };
3608
[email protected]d9da5fe2010-10-13 22:37:163609 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:133610 CreateMockRead(*conn_resp, 1, ASYNC),
3611 CreateMockRead(*wrapped_get_resp, 3, ASYNC),
3612 CreateMockRead(*wrapped_body, 4, ASYNC),
3613 CreateMockRead(*wrapped_body, 5, ASYNC),
3614 MockRead(ASYNC, 0, 7),
[email protected]d9da5fe2010-10-13 22:37:163615 };
3616
rch8e6c6c42015-05-01 14:05:133617 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3618 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073619 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163620
[email protected]8ddf8322012-02-23 18:08:063621 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023622 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073623 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063624 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073625 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163626
[email protected]49639fa2011-12-20 23:22:413627 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163628
[email protected]49639fa2011-12-20 23:22:413629 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163630 EXPECT_EQ(ERR_IO_PENDING, rv);
3631
3632 rv = callback1.WaitForResult();
rch8e6c6c42015-05-01 14:05:133633 ASSERT_EQ(OK, rv);
[email protected]d9da5fe2010-10-13 22:37:163634
[email protected]58e32bb2013-01-21 18:23:253635 LoadTimingInfo load_timing_info;
3636 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3637 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3638
[email protected]d9da5fe2010-10-13 22:37:163639 const HttpResponseInfo* response = trans->GetResponseInfo();
3640 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503641 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d9da5fe2010-10-13 22:37:163642 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3643
3644 std::string response_data;
3645 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
3646 EXPECT_EQ("1234567890", response_data);
3647}
3648
3649// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
[email protected]23e482282013-06-14 16:08:023650TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
[email protected]cb9bf6ca2011-01-28 13:15:273651 HttpRequestInfo request;
3652 request.method = "GET";
bncce36dca22015-04-21 22:11:233653 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273654 request.load_flags = 0;
3655
[email protected]d9da5fe2010-10-13 22:37:163656 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073657 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113658 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513659 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073660 session_deps_.net_log = log.bound().net_log();
3661 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:163662
[email protected]262eec82013-03-19 21:01:363663 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503664 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:163665
bncce36dca22015-04-21 22:11:233666 // CONNECT to www.example.org:443 via SPDY
lgarrona91df87f2014-12-05 00:51:343667 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:233668 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
3669 // fetch https://www.example.org/ via SPDY
3670 const char kMyUrl[] = "https://www.example.org/";
[email protected]cdf8f7e72013-05-23 10:56:463671 scoped_ptr<SpdyFrame> get(
3672 spdy_util_.ConstructSpdyGet(kMyUrl, false, 1, LOWEST));
[email protected]23e482282013-06-14 16:08:023673 scoped_ptr<SpdyFrame> wrapped_get(
3674 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
3675 scoped_ptr<SpdyFrame> conn_resp(
3676 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3677 scoped_ptr<SpdyFrame> get_resp(
3678 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]ff98d7f02012-03-22 21:44:193679 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:023680 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
3681 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
3682 scoped_ptr<SpdyFrame> wrapped_body(
3683 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
[email protected]ff98d7f02012-03-22 21:44:193684 scoped_ptr<SpdyFrame> window_update_get_resp(
[email protected]c10b20852013-05-15 21:29:203685 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
[email protected]ff98d7f02012-03-22 21:44:193686 scoped_ptr<SpdyFrame> window_update_body(
[email protected]c10b20852013-05-15 21:29:203687 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body->size()));
[email protected]8d2f7012012-02-16 00:08:043688
3689 MockWrite spdy_writes[] = {
rch32320842015-05-16 15:57:093690 CreateMockWrite(*connect, 0),
3691 CreateMockWrite(*wrapped_get, 2),
3692 CreateMockWrite(*window_update_get_resp, 6),
[email protected]8d2f7012012-02-16 00:08:043693 CreateMockWrite(*window_update_body, 7),
3694 };
3695
[email protected]d9da5fe2010-10-13 22:37:163696 MockRead spdy_reads[] = {
rch32320842015-05-16 15:57:093697 CreateMockRead(*conn_resp, 1, ASYNC),
3698 MockRead(ASYNC, ERR_IO_PENDING, 3),
rch8e6c6c42015-05-01 14:05:133699 CreateMockRead(*wrapped_get_resp, 4, ASYNC),
rch32320842015-05-16 15:57:093700 CreateMockRead(*wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:133701 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:163702 };
3703
rch32320842015-05-16 15:57:093704 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3705 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073706 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163707
[email protected]8ddf8322012-02-23 18:08:063708 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023709 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073710 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063711 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023712 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073713 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163714
[email protected]49639fa2011-12-20 23:22:413715 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163716
[email protected]49639fa2011-12-20 23:22:413717 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163718 EXPECT_EQ(ERR_IO_PENDING, rv);
3719
rch32320842015-05-16 15:57:093720 // Allow the SpdyProxyClientSocket's write callback to complete.
3721 base::MessageLoop::current()->RunUntilIdle();
3722 // Now allow the read of the response to complete.
3723 spdy_data.CompleteRead();
[email protected]d9da5fe2010-10-13 22:37:163724 rv = callback1.WaitForResult();
3725 EXPECT_EQ(OK, rv);
3726
[email protected]58e32bb2013-01-21 18:23:253727 LoadTimingInfo load_timing_info;
3728 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3729 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3730
[email protected]d9da5fe2010-10-13 22:37:163731 const HttpResponseInfo* response = trans->GetResponseInfo();
3732 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503733 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d9da5fe2010-10-13 22:37:163734 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3735
3736 std::string response_data;
3737 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:233738 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:163739}
3740
3741// Test a SPDY CONNECT failure through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023742TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:273743 HttpRequestInfo request;
3744 request.method = "GET";
bncce36dca22015-04-21 22:11:233745 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273746 request.load_flags = 0;
3747
[email protected]d9da5fe2010-10-13 22:37:163748 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073749 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113750 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513751 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073752 session_deps_.net_log = log.bound().net_log();
3753 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:163754
[email protected]262eec82013-03-19 21:01:363755 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503756 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:163757
bncce36dca22015-04-21 22:11:233758 // CONNECT to www.example.org:443 via SPDY
lgarrona91df87f2014-12-05 00:51:343759 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:233760 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]c10b20852013-05-15 21:29:203761 scoped_ptr<SpdyFrame> get(
3762 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:163763
3764 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:133765 CreateMockWrite(*connect, 0), CreateMockWrite(*get, 2),
[email protected]d9da5fe2010-10-13 22:37:163766 };
3767
[email protected]23e482282013-06-14 16:08:023768 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdySynReplyError(1));
3769 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:163770 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:133771 CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 3),
[email protected]d9da5fe2010-10-13 22:37:163772 };
3773
rch8e6c6c42015-05-01 14:05:133774 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3775 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073776 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163777
[email protected]8ddf8322012-02-23 18:08:063778 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023779 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073780 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063781 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023782 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073783 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163784
[email protected]49639fa2011-12-20 23:22:413785 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163786
[email protected]49639fa2011-12-20 23:22:413787 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163788 EXPECT_EQ(ERR_IO_PENDING, rv);
3789
3790 rv = callback1.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:173791 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]d9da5fe2010-10-13 22:37:163792
[email protected]4eddbc732012-08-09 05:40:173793 // TODO(ttuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:163794}
3795
[email protected]f6c63db52013-02-02 00:35:223796// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
3797// HTTPS Proxy to different servers.
[email protected]23e482282013-06-14 16:08:023798TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:223799 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
3800 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073801 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:223802 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513803 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073804 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:223805 scoped_refptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:503806 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:223807
3808 HttpRequestInfo request1;
3809 request1.method = "GET";
bncce36dca22015-04-21 22:11:233810 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:223811 request1.load_flags = 0;
3812
3813 HttpRequestInfo request2;
3814 request2.method = "GET";
bncce36dca22015-04-21 22:11:233815 request2.url = GURL("https://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:223816 request2.load_flags = 0;
3817
bncce36dca22015-04-21 22:11:233818 // CONNECT to www.example.org:443 via SPDY.
lgarrona91df87f2014-12-05 00:51:343819 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:233820 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]23e482282013-06-14 16:08:023821 scoped_ptr<SpdyFrame> conn_resp1(
3822 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:223823
bncce36dca22015-04-21 22:11:233824 // Fetch https://www.example.org/ via HTTP.
3825 const char get1[] =
3826 "GET / HTTP/1.1\r\n"
3827 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:223828 "Connection: keep-alive\r\n\r\n";
3829 scoped_ptr<SpdyFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:023830 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:223831 const char resp1[] = "HTTP/1.1 200 OK\r\n"
3832 "Content-Length: 1\r\n\r\n";
3833 scoped_ptr<SpdyFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:023834 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
3835 scoped_ptr<SpdyFrame> wrapped_body1(
3836 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
[email protected]f6c63db52013-02-02 00:35:223837 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203838 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:223839
bncce36dca22015-04-21 22:11:233840 // CONNECT to mail.example.org:443 via SPDY.
[email protected]745aa9c2014-06-27 02:21:293841 SpdyHeaderBlock connect2_block;
3842 connect2_block[spdy_util_.GetMethodKey()] = "CONNECT";
bncce36dca22015-04-21 22:11:233843 connect2_block[spdy_util_.GetPathKey()] = "mail.example.org:443";
3844 connect2_block[spdy_util_.GetHostKey()] = "mail.example.org";
[email protected]745aa9c2014-06-27 02:21:293845 spdy_util_.MaybeAddVersionHeader(&connect2_block);
[email protected]f6c63db52013-02-02 00:35:223846 scoped_ptr<SpdyFrame> connect2(
[email protected]745aa9c2014-06-27 02:21:293847 spdy_util_.ConstructSpdySyn(3, connect2_block, LOWEST, false, false));
[email protected]601e03f12014-04-06 16:26:393848
[email protected]23e482282013-06-14 16:08:023849 scoped_ptr<SpdyFrame> conn_resp2(
3850 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:223851
bncce36dca22015-04-21 22:11:233852 // Fetch https://mail.example.org/ via HTTP.
3853 const char get2[] =
3854 "GET / HTTP/1.1\r\n"
3855 "Host: mail.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:223856 "Connection: keep-alive\r\n\r\n";
3857 scoped_ptr<SpdyFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:023858 spdy_util_.ConstructSpdyBodyFrame(3, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:223859 const char resp2[] = "HTTP/1.1 200 OK\r\n"
3860 "Content-Length: 2\r\n\r\n";
3861 scoped_ptr<SpdyFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:023862 spdy_util_.ConstructSpdyBodyFrame(3, resp2, strlen(resp2), false));
[email protected]f6c63db52013-02-02 00:35:223863 scoped_ptr<SpdyFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:023864 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:223865
3866 MockWrite spdy_writes[] = {
3867 CreateMockWrite(*connect1, 0),
3868 CreateMockWrite(*wrapped_get1, 2),
3869 CreateMockWrite(*connect2, 5),
3870 CreateMockWrite(*wrapped_get2, 7),
3871 };
3872
3873 MockRead spdy_reads[] = {
3874 CreateMockRead(*conn_resp1, 1, ASYNC),
3875 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
3876 CreateMockRead(*wrapped_body1, 4, ASYNC),
3877 CreateMockRead(*conn_resp2, 6, ASYNC),
3878 CreateMockRead(*wrapped_get_resp2, 8, ASYNC),
3879 CreateMockRead(*wrapped_body2, 9, ASYNC),
3880 MockRead(ASYNC, 0, 10),
3881 };
3882
mmenke11eb5152015-06-09 14:50:503883 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3884 arraysize(spdy_writes));
3885 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:223886
3887 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023888 ssl.SetNextProto(GetParam());
mmenke11eb5152015-06-09 14:50:503889 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:223890 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:503891 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:223892 SSLSocketDataProvider ssl3(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:503893 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:223894
3895 TestCompletionCallback callback;
3896
[email protected]262eec82013-03-19 21:01:363897 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503898 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223899 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:503900 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:223901
3902 LoadTimingInfo load_timing_info;
3903 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3904 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3905
3906 const HttpResponseInfo* response = trans->GetResponseInfo();
3907 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503908 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:223909 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3910
3911 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:293912 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
mmenke11eb5152015-06-09 14:50:503913 rv = trans->Read(buf.get(), 256, callback.callback());
3914 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:223915
[email protected]262eec82013-03-19 21:01:363916 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503917 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223918 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:503919 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:223920
3921 LoadTimingInfo load_timing_info2;
3922 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3923 // Even though the SPDY connection is reused, a new tunnelled connection has
3924 // to be created, so the socket's load timing looks like a fresh connection.
3925 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
3926
3927 // The requests should have different IDs, since they each are using their own
3928 // separate stream.
3929 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
3930
mmenke11eb5152015-06-09 14:50:503931 rv = trans2->Read(buf.get(), 256, callback.callback());
3932 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:223933}
3934
3935// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
3936// HTTPS Proxy to the same server.
[email protected]23e482282013-06-14 16:08:023937TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:223938 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
3939 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073940 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:223941 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513942 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073943 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:223944 scoped_refptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:503945 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:223946
3947 HttpRequestInfo request1;
3948 request1.method = "GET";
bncce36dca22015-04-21 22:11:233949 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:223950 request1.load_flags = 0;
3951
3952 HttpRequestInfo request2;
3953 request2.method = "GET";
bncce36dca22015-04-21 22:11:233954 request2.url = GURL("https://www.example.org/2");
[email protected]f6c63db52013-02-02 00:35:223955 request2.load_flags = 0;
3956
bncce36dca22015-04-21 22:11:233957 // CONNECT to www.example.org:443 via SPDY.
lgarrona91df87f2014-12-05 00:51:343958 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:233959 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]23e482282013-06-14 16:08:023960 scoped_ptr<SpdyFrame> conn_resp1(
3961 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:223962
bncce36dca22015-04-21 22:11:233963 // Fetch https://www.example.org/ via HTTP.
3964 const char get1[] =
3965 "GET / HTTP/1.1\r\n"
3966 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:223967 "Connection: keep-alive\r\n\r\n";
3968 scoped_ptr<SpdyFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:023969 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:223970 const char resp1[] = "HTTP/1.1 200 OK\r\n"
3971 "Content-Length: 1\r\n\r\n";
3972 scoped_ptr<SpdyFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:023973 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
3974 scoped_ptr<SpdyFrame> wrapped_body1(
3975 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
[email protected]f6c63db52013-02-02 00:35:223976 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203977 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:223978
bncce36dca22015-04-21 22:11:233979 // Fetch https://www.example.org/2 via HTTP.
3980 const char get2[] =
3981 "GET /2 HTTP/1.1\r\n"
3982 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:223983 "Connection: keep-alive\r\n\r\n";
3984 scoped_ptr<SpdyFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:023985 spdy_util_.ConstructSpdyBodyFrame(1, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:223986 const char resp2[] = "HTTP/1.1 200 OK\r\n"
3987 "Content-Length: 2\r\n\r\n";
3988 scoped_ptr<SpdyFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:023989 spdy_util_.ConstructSpdyBodyFrame(1, resp2, strlen(resp2), false));
[email protected]f6c63db52013-02-02 00:35:223990 scoped_ptr<SpdyFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:023991 spdy_util_.ConstructSpdyBodyFrame(1, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:223992
3993 MockWrite spdy_writes[] = {
3994 CreateMockWrite(*connect1, 0),
3995 CreateMockWrite(*wrapped_get1, 2),
3996 CreateMockWrite(*wrapped_get2, 5),
3997 };
3998
3999 MockRead spdy_reads[] = {
4000 CreateMockRead(*conn_resp1, 1, ASYNC),
4001 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
4002 CreateMockRead(*wrapped_body1, 4, ASYNC),
4003 CreateMockRead(*wrapped_get_resp2, 6, ASYNC),
4004 CreateMockRead(*wrapped_body2, 7, ASYNC),
4005 MockRead(ASYNC, 0, 8),
4006 };
4007
mmenke11eb5152015-06-09 14:50:504008 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4009 arraysize(spdy_writes));
4010 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:224011
4012 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:024013 ssl.SetNextProto(GetParam());
mmenke11eb5152015-06-09 14:50:504014 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:224015 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:504016 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:224017
4018 TestCompletionCallback callback;
4019
[email protected]262eec82013-03-19 21:01:364020 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504021 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224022 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
4023 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f6c63db52013-02-02 00:35:224024
4025 rv = callback.WaitForResult();
4026 EXPECT_EQ(OK, rv);
4027
4028 LoadTimingInfo load_timing_info;
4029 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4030 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
4031
4032 const HttpResponseInfo* response = trans->GetResponseInfo();
4033 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504034 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:224035 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4036
4037 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:294038 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]90499482013-06-01 00:39:504039 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:224040 trans.reset();
4041
[email protected]262eec82013-03-19 21:01:364042 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:504043 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224044 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
4045 EXPECT_EQ(ERR_IO_PENDING, rv);
4046
[email protected]f6c63db52013-02-02 00:35:224047 rv = callback.WaitForResult();
4048 EXPECT_EQ(OK, rv);
4049
4050 LoadTimingInfo load_timing_info2;
4051 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4052 TestLoadTimingReused(load_timing_info2);
4053
4054 // The requests should have the same ID.
4055 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
4056
[email protected]90499482013-06-01 00:39:504057 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:224058}
4059
4060// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
4061// Proxy to different servers.
mmenke11eb5152015-06-09 14:50:504062TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) {
[email protected]f6c63db52013-02-02 00:35:224063 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:074064 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:224065 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:514066 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074067 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:224068 scoped_refptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:504069 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:224070
4071 HttpRequestInfo request1;
4072 request1.method = "GET";
bncce36dca22015-04-21 22:11:234073 request1.url = GURL("http://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:224074 request1.load_flags = 0;
4075
4076 HttpRequestInfo request2;
4077 request2.method = "GET";
bncce36dca22015-04-21 22:11:234078 request2.url = GURL("http://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:224079 request2.load_flags = 0;
4080
bncce36dca22015-04-21 22:11:234081 // http://www.example.org/
[email protected]23e482282013-06-14 16:08:024082 scoped_ptr<SpdyHeaderBlock> headers(
bncce36dca22015-04-21 22:11:234083 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
[email protected]745aa9c2014-06-27 02:21:294084 scoped_ptr<SpdyFrame> get1(
4085 spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, false, true));
[email protected]23e482282013-06-14 16:08:024086 scoped_ptr<SpdyFrame> get_resp1(
4087 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
4088 scoped_ptr<SpdyFrame> body1(
4089 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, true));
[email protected]f6c63db52013-02-02 00:35:224090
bncce36dca22015-04-21 22:11:234091 // http://mail.example.org/
[email protected]23e482282013-06-14 16:08:024092 scoped_ptr<SpdyHeaderBlock> headers2(
bncce36dca22015-04-21 22:11:234093 spdy_util_.ConstructGetHeaderBlockForProxy("http://mail.example.org/"));
[email protected]745aa9c2014-06-27 02:21:294094 scoped_ptr<SpdyFrame> get2(
4095 spdy_util_.ConstructSpdySyn(3, *headers2, LOWEST, false, true));
[email protected]23e482282013-06-14 16:08:024096 scoped_ptr<SpdyFrame> get_resp2(
4097 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
4098 scoped_ptr<SpdyFrame> body2(
4099 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, true));
[email protected]f6c63db52013-02-02 00:35:224100
4101 MockWrite spdy_writes[] = {
4102 CreateMockWrite(*get1, 0),
4103 CreateMockWrite(*get2, 3),
4104 };
4105
4106 MockRead spdy_reads[] = {
4107 CreateMockRead(*get_resp1, 1, ASYNC),
4108 CreateMockRead(*body1, 2, ASYNC),
4109 CreateMockRead(*get_resp2, 4, ASYNC),
4110 CreateMockRead(*body2, 5, ASYNC),
4111 MockRead(ASYNC, 0, 6),
4112 };
4113
mmenke11eb5152015-06-09 14:50:504114 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4115 arraysize(spdy_writes));
4116 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:224117
4118 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:024119 ssl.SetNextProto(GetParam());
mmenke11eb5152015-06-09 14:50:504120 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:224121
4122 TestCompletionCallback callback;
4123
[email protected]262eec82013-03-19 21:01:364124 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504125 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224126 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:504127 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224128
4129 LoadTimingInfo load_timing_info;
4130 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4131 TestLoadTimingNotReused(load_timing_info,
4132 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4133
4134 const HttpResponseInfo* response = trans->GetResponseInfo();
4135 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504136 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:224137 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4138
4139 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:294140 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
mmenke11eb5152015-06-09 14:50:504141 rv = trans->Read(buf.get(), 256, callback.callback());
4142 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224143 // Delete the first request, so the second one can reuse the socket.
4144 trans.reset();
4145
[email protected]262eec82013-03-19 21:01:364146 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:504147 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224148 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:504149 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224150
4151 LoadTimingInfo load_timing_info2;
4152 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4153 TestLoadTimingReused(load_timing_info2);
4154
4155 // The requests should have the same ID.
4156 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
4157
mmenke11eb5152015-06-09 14:50:504158 rv = trans2->Read(buf.get(), 256, callback.callback());
4159 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224160}
4161
[email protected]2df19bb2010-08-25 20:13:464162// Test the challenge-response-retry sequence through an HTTPS Proxy
[email protected]23e482282013-06-14 16:08:024163TEST_P(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:464164 HttpRequestInfo request;
4165 request.method = "GET";
bncce36dca22015-04-21 22:11:234166 request.url = GURL("http://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:464167 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:294168 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]2df19bb2010-08-25 20:13:464169
[email protected]79cb5c12011-09-12 13:12:044170 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:074171 session_deps_.proxy_service.reset(
[email protected]79cb5c12011-09-12 13:12:044172 ProxyService::CreateFixed("https://myproxy:70"));
vishal.b62985ca92015-04-17 08:45:514173 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074174 session_deps_.net_log = log.bound().net_log();
4175 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274176
[email protected]2df19bb2010-08-25 20:13:464177 // Since we have proxy, should use full url
4178 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:234179 MockWrite(
4180 "GET http://www.example.org/ HTTP/1.1\r\n"
4181 "Host: www.example.org\r\n"
4182 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:464183
bncce36dca22015-04-21 22:11:234184 // After calling trans->RestartWithAuth(), this is the request we should
4185 // be issuing -- the final header line contains the credentials.
4186 MockWrite(
4187 "GET http://www.example.org/ HTTP/1.1\r\n"
4188 "Host: www.example.org\r\n"
4189 "Proxy-Connection: keep-alive\r\n"
4190 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:464191 };
4192
4193 // The proxy responds to the GET with a 407, using a persistent
4194 // connection.
4195 MockRead data_reads1[] = {
4196 // No credentials.
4197 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4198 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4199 MockRead("Proxy-Connection: keep-alive\r\n"),
4200 MockRead("Content-Length: 0\r\n\r\n"),
4201
4202 MockRead("HTTP/1.1 200 OK\r\n"),
4203 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4204 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064205 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:464206 };
4207
4208 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4209 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074210 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:064211 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074212 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:464213
[email protected]49639fa2011-12-20 23:22:414214 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:464215
[email protected]262eec82013-03-19 21:01:364216 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504217 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504218
[email protected]49639fa2011-12-20 23:22:414219 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:464220 EXPECT_EQ(ERR_IO_PENDING, rv);
4221
4222 rv = callback1.WaitForResult();
4223 EXPECT_EQ(OK, rv);
4224
[email protected]58e32bb2013-01-21 18:23:254225 LoadTimingInfo load_timing_info;
4226 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4227 TestLoadTimingNotReused(load_timing_info,
4228 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4229
[email protected]2df19bb2010-08-25 20:13:464230 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504231 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504232 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]2df19bb2010-08-25 20:13:464233 EXPECT_EQ(407, response->headers->response_code());
4234 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:044235 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:464236
[email protected]49639fa2011-12-20 23:22:414237 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:464238
[email protected]49639fa2011-12-20 23:22:414239 rv = trans->RestartWithAuth(
4240 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]2df19bb2010-08-25 20:13:464241 EXPECT_EQ(ERR_IO_PENDING, rv);
4242
4243 rv = callback2.WaitForResult();
4244 EXPECT_EQ(OK, rv);
4245
[email protected]58e32bb2013-01-21 18:23:254246 load_timing_info = LoadTimingInfo();
4247 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4248 // Retrying with HTTP AUTH is considered to be reusing a socket.
4249 TestLoadTimingReused(load_timing_info);
4250
[email protected]2df19bb2010-08-25 20:13:464251 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504252 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:464253
4254 EXPECT_TRUE(response->headers->IsKeepAlive());
4255 EXPECT_EQ(200, response->headers->response_code());
4256 EXPECT_EQ(100, response->headers->GetContentLength());
4257 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4258
4259 // The password prompt info should not be set.
4260 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4261}
4262
[email protected]23e482282013-06-14 16:08:024263void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:084264 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:424265 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:084266 request.method = "GET";
bncce36dca22015-04-21 22:11:234267 request.url = GURL("https://www.example.org/");
[email protected]c744cf22009-02-27 07:28:084268 request.load_flags = 0;
4269
[email protected]cb9bf6ca2011-01-28 13:15:274270 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:074271 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]bb88e1d32013-05-03 23:11:074272 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274273
[email protected]c744cf22009-02-27 07:28:084274 // Since we have proxy, should try to establish tunnel.
4275 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:234276 MockWrite(
4277 "CONNECT www.example.org:443 HTTP/1.1\r\n"
4278 "Host: www.example.org\r\n"
4279 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:084280 };
4281
4282 MockRead data_reads[] = {
4283 status,
4284 MockRead("Content-Length: 10\r\n\r\n"),
4285 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:064286 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]c744cf22009-02-27 07:28:084287 };
4288
[email protected]31a2bfe2010-02-09 08:03:394289 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
4290 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:074291 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:084292
[email protected]49639fa2011-12-20 23:22:414293 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:084294
[email protected]262eec82013-03-19 21:01:364295 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504296 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504297
[email protected]49639fa2011-12-20 23:22:414298 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424299 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]c744cf22009-02-27 07:28:084300
4301 rv = callback.WaitForResult();
4302 EXPECT_EQ(expected_status, rv);
4303}
4304
[email protected]23e482282013-06-14 16:08:024305void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:234306 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:084307 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:424308 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:084309}
4310
[email protected]23e482282013-06-14 16:08:024311TEST_P(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:084312 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
4313}
4314
[email protected]23e482282013-06-14 16:08:024315TEST_P(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:084316 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
4317}
4318
[email protected]23e482282013-06-14 16:08:024319TEST_P(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:084320 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
4321}
4322
[email protected]23e482282013-06-14 16:08:024323TEST_P(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:084324 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
4325}
4326
[email protected]23e482282013-06-14 16:08:024327TEST_P(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:084328 ConnectStatusHelper(
4329 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
4330}
4331
[email protected]23e482282013-06-14 16:08:024332TEST_P(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:084333 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
4334}
4335
[email protected]23e482282013-06-14 16:08:024336TEST_P(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:084337 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
4338}
4339
[email protected]23e482282013-06-14 16:08:024340TEST_P(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:084341 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
4342}
4343
[email protected]23e482282013-06-14 16:08:024344TEST_P(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:084345 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
4346}
4347
[email protected]23e482282013-06-14 16:08:024348TEST_P(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:084349 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
4350}
4351
[email protected]23e482282013-06-14 16:08:024352TEST_P(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:084353 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
4354}
4355
[email protected]23e482282013-06-14 16:08:024356TEST_P(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:084357 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
4358}
4359
[email protected]23e482282013-06-14 16:08:024360TEST_P(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:084361 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
4362}
4363
[email protected]23e482282013-06-14 16:08:024364TEST_P(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:084365 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
4366}
4367
[email protected]23e482282013-06-14 16:08:024368TEST_P(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:084369 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
4370}
4371
[email protected]23e482282013-06-14 16:08:024372TEST_P(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:084373 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
4374}
4375
[email protected]0a17aab32014-04-24 03:32:374376TEST_P(HttpNetworkTransactionTest, ConnectStatus308) {
4377 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
4378}
4379
[email protected]23e482282013-06-14 16:08:024380TEST_P(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:084381 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
4382}
4383
[email protected]23e482282013-06-14 16:08:024384TEST_P(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:084385 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
4386}
4387
[email protected]23e482282013-06-14 16:08:024388TEST_P(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:084389 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
4390}
4391
[email protected]23e482282013-06-14 16:08:024392TEST_P(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:084393 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
4394}
4395
[email protected]23e482282013-06-14 16:08:024396TEST_P(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:084397 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
4398}
4399
[email protected]23e482282013-06-14 16:08:024400TEST_P(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:084401 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
4402}
4403
[email protected]23e482282013-06-14 16:08:024404TEST_P(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:084405 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
4406}
4407
[email protected]23e482282013-06-14 16:08:024408TEST_P(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:084409 ConnectStatusHelperWithExpectedStatus(
4410 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:544411 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:084412}
4413
[email protected]23e482282013-06-14 16:08:024414TEST_P(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:084415 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
4416}
4417
[email protected]23e482282013-06-14 16:08:024418TEST_P(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:084419 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
4420}
4421
[email protected]23e482282013-06-14 16:08:024422TEST_P(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:084423 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
4424}
4425
[email protected]23e482282013-06-14 16:08:024426TEST_P(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:084427 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
4428}
4429
[email protected]23e482282013-06-14 16:08:024430TEST_P(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:084431 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
4432}
4433
[email protected]23e482282013-06-14 16:08:024434TEST_P(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:084435 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
4436}
4437
[email protected]23e482282013-06-14 16:08:024438TEST_P(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:084439 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
4440}
4441
[email protected]23e482282013-06-14 16:08:024442TEST_P(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:084443 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
4444}
4445
[email protected]23e482282013-06-14 16:08:024446TEST_P(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:084447 ConnectStatusHelper(
4448 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
4449}
4450
[email protected]23e482282013-06-14 16:08:024451TEST_P(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:084452 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
4453}
4454
[email protected]23e482282013-06-14 16:08:024455TEST_P(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:084456 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
4457}
4458
[email protected]23e482282013-06-14 16:08:024459TEST_P(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:084460 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
4461}
4462
[email protected]23e482282013-06-14 16:08:024463TEST_P(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:084464 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
4465}
4466
[email protected]23e482282013-06-14 16:08:024467TEST_P(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:084468 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
4469}
4470
[email protected]23e482282013-06-14 16:08:024471TEST_P(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:084472 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
4473}
4474
[email protected]23e482282013-06-14 16:08:024475TEST_P(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:084476 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
4477}
4478
[email protected]038e9a32008-10-08 22:40:164479// Test the flow when both the proxy server AND origin server require
4480// authentication. Again, this uses basic auth for both since that is
4481// the simplest to mock.
[email protected]23e482282013-06-14 16:08:024482TEST_P(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:274483 HttpRequestInfo request;
4484 request.method = "GET";
bncce36dca22015-04-21 22:11:234485 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274486 request.load_flags = 0;
4487
[email protected]038e9a32008-10-08 22:40:164488 // Configure against proxy server "myproxy:70".
[email protected]3fe8d2f82013-10-17 08:56:074489 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
4490 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4491
4492 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:414493 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]038e9a32008-10-08 22:40:164494
[email protected]f9ee6b52008-11-08 06:46:234495 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:234496 MockWrite(
4497 "GET http://www.example.org/ HTTP/1.1\r\n"
4498 "Host: www.example.org\r\n"
4499 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:234500 };
4501
[email protected]038e9a32008-10-08 22:40:164502 MockRead data_reads1[] = {
4503 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
4504 // Give a couple authenticate options (only the middle one is actually
4505 // supported).
[email protected]22927ad2009-09-21 19:56:194506 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:164507 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4508 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
4509 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4510 // Large content-length -- won't matter, as connection will be reset.
4511 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064512 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:164513 };
4514
4515 // After calling trans->RestartWithAuth() the first time, this is the
4516 // request we should be issuing -- the final header line contains the
4517 // proxy's credentials.
4518 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:234519 MockWrite(
4520 "GET http://www.example.org/ HTTP/1.1\r\n"
4521 "Host: www.example.org\r\n"
4522 "Proxy-Connection: keep-alive\r\n"
4523 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:164524 };
4525
4526 // Now the proxy server lets the request pass through to origin server.
4527 // The origin server responds with a 401.
4528 MockRead data_reads2[] = {
4529 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4530 // Note: We are using the same realm-name as the proxy server. This is
4531 // completely valid, as realms are unique across hosts.
4532 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4533 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4534 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064535 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:164536 };
4537
4538 // After calling trans->RestartWithAuth() the second time, we should send
4539 // the credentials for both the proxy and origin server.
4540 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:234541 MockWrite(
4542 "GET http://www.example.org/ HTTP/1.1\r\n"
4543 "Host: www.example.org\r\n"
4544 "Proxy-Connection: keep-alive\r\n"
4545 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
4546 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:164547 };
4548
4549 // Lastly we get the desired content.
4550 MockRead data_reads3[] = {
4551 MockRead("HTTP/1.0 200 OK\r\n"),
4552 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4553 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064554 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:164555 };
4556
[email protected]31a2bfe2010-02-09 08:03:394557 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4558 data_writes1, arraysize(data_writes1));
4559 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4560 data_writes2, arraysize(data_writes2));
4561 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4562 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:074563 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4564 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4565 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:164566
[email protected]49639fa2011-12-20 23:22:414567 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:164568
[email protected]49639fa2011-12-20 23:22:414569 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424570 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:164571
4572 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424573 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:164574
[email protected]1c773ea12009-04-28 19:58:424575 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504576 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044577 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:164578
[email protected]49639fa2011-12-20 23:22:414579 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:164580
[email protected]49639fa2011-12-20 23:22:414581 rv = trans->RestartWithAuth(
4582 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:424583 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:164584
4585 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424586 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:164587
4588 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504589 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044590 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:164591
[email protected]49639fa2011-12-20 23:22:414592 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:164593
[email protected]49639fa2011-12-20 23:22:414594 rv = trans->RestartWithAuth(
4595 AuthCredentials(kFoo2, kBar2), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424596 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:164597
4598 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424599 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:164600
4601 response = trans->GetResponseInfo();
4602 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4603 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:164604}
[email protected]4ddaf2502008-10-23 18:26:194605
[email protected]ea9dc9a2009-09-05 00:43:324606// For the NTLM implementation using SSPI, we skip the NTLM tests since we
4607// can't hook into its internals to cause it to generate predictable NTLM
4608// authorization headers.
4609#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:294610// The NTLM authentication unit tests were generated by capturing the HTTP
4611// requests and responses using Fiddler 2 and inspecting the generated random
4612// bytes in the debugger.
4613
4614// Enter the correct password and authenticate successfully.
[email protected]23e482282013-06-14 16:08:024615TEST_P(HttpNetworkTransactionTest, NTLMAuth1) {
[email protected]1c773ea12009-04-28 19:58:424616 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:244617 request.method = "GET";
4618 request.url = GURL("http://172.22.68.17/kids/login.aspx");
[email protected]2217aa22013-10-11 03:03:544619
4620 // Ensure load is not disrupted by flags which suppress behaviour specific
4621 // to other auth schemes.
4622 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:244623
[email protected]cb9bf6ca2011-01-28 13:15:274624 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
4625 MockGetHostName);
[email protected]bb88e1d32013-05-03 23:11:074626 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274627
[email protected]3f918782009-02-28 01:29:244628 MockWrite data_writes1[] = {
4629 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4630 "Host: 172.22.68.17\r\n"
4631 "Connection: keep-alive\r\n\r\n"),
4632 };
4633
4634 MockRead data_reads1[] = {
4635 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:044636 // Negotiate and NTLM are often requested together. However, we only want
4637 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
4638 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:244639 MockRead("WWW-Authenticate: NTLM\r\n"),
4640 MockRead("Connection: close\r\n"),
4641 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364642 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:244643 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064644 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]3f918782009-02-28 01:29:244645 };
4646
4647 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:224648 // After restarting with a null identity, this is the
[email protected]3f918782009-02-28 01:29:244649 // request we should be issuing -- the final header line contains a Type
4650 // 1 message.
4651 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4652 "Host: 172.22.68.17\r\n"
4653 "Connection: keep-alive\r\n"
4654 "Authorization: NTLM "
4655 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4656
4657 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4658 // (the credentials for the origin server). The second request continues
4659 // on the same connection.
4660 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4661 "Host: 172.22.68.17\r\n"
4662 "Connection: keep-alive\r\n"
[email protected]385a4672009-03-11 22:21:294663 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4664 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4665 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
4666 "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
4667 "ahlhx5I=\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:244668 };
4669
4670 MockRead data_reads2[] = {
4671 // The origin server responds with a Type 2 message.
4672 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4673 MockRead("WWW-Authenticate: NTLM "
[email protected]385a4672009-03-11 22:21:294674 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
[email protected]3f918782009-02-28 01:29:244675 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4676 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4677 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4678 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4679 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4680 "BtAAAAAAA=\r\n"),
4681 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364682 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:244683 MockRead("You are not authorized to view this page\r\n"),
4684
4685 // Lastly we get the desired content.
4686 MockRead("HTTP/1.1 200 OK\r\n"),
4687 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
4688 MockRead("Content-Length: 13\r\n\r\n"),
4689 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:064690 MockRead(SYNCHRONOUS, OK),
[email protected]3f918782009-02-28 01:29:244691 };
4692
[email protected]31a2bfe2010-02-09 08:03:394693 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4694 data_writes1, arraysize(data_writes1));
4695 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4696 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:074697 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4698 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:244699
[email protected]49639fa2011-12-20 23:22:414700 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:244701
[email protected]262eec82013-03-19 21:01:364702 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504703 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504704
[email protected]49639fa2011-12-20 23:22:414705 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424706 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:244707
4708 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424709 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:244710
[email protected]0757e7702009-03-27 04:00:224711 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4712
[email protected]1c773ea12009-04-28 19:58:424713 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:044714 ASSERT_FALSE(response == NULL);
4715 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:244716
[email protected]49639fa2011-12-20 23:22:414717 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:254718
[email protected]f3cf9802011-10-28 18:44:584719 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:414720 callback2.callback());
[email protected]10af5fe72011-01-31 16:17:254721 EXPECT_EQ(ERR_IO_PENDING, rv);
4722
4723 rv = callback2.WaitForResult();
4724 EXPECT_EQ(OK, rv);
4725
4726 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4727
4728 response = trans->GetResponseInfo();
4729 ASSERT_TRUE(response != NULL);
[email protected]10af5fe72011-01-31 16:17:254730 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4731
[email protected]49639fa2011-12-20 23:22:414732 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:244733
[email protected]49639fa2011-12-20 23:22:414734 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424735 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:244736
[email protected]0757e7702009-03-27 04:00:224737 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424738 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:244739
4740 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504741 ASSERT_TRUE(response != NULL);
[email protected]3f918782009-02-28 01:29:244742 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4743 EXPECT_EQ(13, response->headers->GetContentLength());
4744}
4745
[email protected]385a4672009-03-11 22:21:294746// Enter a wrong password, and then the correct one.
[email protected]23e482282013-06-14 16:08:024747TEST_P(HttpNetworkTransactionTest, NTLMAuth2) {
[email protected]1c773ea12009-04-28 19:58:424748 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:294749 request.method = "GET";
4750 request.url = GURL("http://172.22.68.17/kids/login.aspx");
4751 request.load_flags = 0;
4752
[email protected]cb9bf6ca2011-01-28 13:15:274753 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
4754 MockGetHostName);
[email protected]bb88e1d32013-05-03 23:11:074755 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274756
[email protected]385a4672009-03-11 22:21:294757 MockWrite data_writes1[] = {
4758 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4759 "Host: 172.22.68.17\r\n"
4760 "Connection: keep-alive\r\n\r\n"),
4761 };
4762
4763 MockRead data_reads1[] = {
4764 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:044765 // Negotiate and NTLM are often requested together. However, we only want
4766 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
4767 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:294768 MockRead("WWW-Authenticate: NTLM\r\n"),
4769 MockRead("Connection: close\r\n"),
4770 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364771 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294772 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064773 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:294774 };
4775
4776 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:224777 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:294778 // request we should be issuing -- the final header line contains a Type
4779 // 1 message.
4780 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4781 "Host: 172.22.68.17\r\n"
4782 "Connection: keep-alive\r\n"
4783 "Authorization: NTLM "
4784 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4785
4786 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4787 // (the credentials for the origin server). The second request continues
4788 // on the same connection.
4789 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4790 "Host: 172.22.68.17\r\n"
4791 "Connection: keep-alive\r\n"
4792 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4793 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4794 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
4795 "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
4796 "4Ww7b7E=\r\n\r\n"),
4797 };
4798
4799 MockRead data_reads2[] = {
4800 // The origin server responds with a Type 2 message.
4801 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4802 MockRead("WWW-Authenticate: NTLM "
4803 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
4804 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4805 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4806 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4807 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4808 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4809 "BtAAAAAAA=\r\n"),
4810 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364811 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294812 MockRead("You are not authorized to view this page\r\n"),
4813
4814 // Wrong password.
4815 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]385a4672009-03-11 22:21:294816 MockRead("WWW-Authenticate: NTLM\r\n"),
4817 MockRead("Connection: close\r\n"),
4818 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364819 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294820 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064821 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:294822 };
4823
4824 MockWrite data_writes3[] = {
[email protected]0757e7702009-03-27 04:00:224825 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:294826 // request we should be issuing -- the final header line contains a Type
4827 // 1 message.
4828 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4829 "Host: 172.22.68.17\r\n"
4830 "Connection: keep-alive\r\n"
4831 "Authorization: NTLM "
4832 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4833
4834 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4835 // (the credentials for the origin server). The second request continues
4836 // on the same connection.
4837 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4838 "Host: 172.22.68.17\r\n"
4839 "Connection: keep-alive\r\n"
4840 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4841 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4842 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
4843 "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
4844 "+4MUm7c=\r\n\r\n"),
4845 };
4846
4847 MockRead data_reads3[] = {
4848 // The origin server responds with a Type 2 message.
4849 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4850 MockRead("WWW-Authenticate: NTLM "
4851 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
4852 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4853 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4854 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4855 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4856 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4857 "BtAAAAAAA=\r\n"),
4858 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364859 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294860 MockRead("You are not authorized to view this page\r\n"),
4861
4862 // Lastly we get the desired content.
4863 MockRead("HTTP/1.1 200 OK\r\n"),
4864 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
4865 MockRead("Content-Length: 13\r\n\r\n"),
4866 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:064867 MockRead(SYNCHRONOUS, OK),
[email protected]385a4672009-03-11 22:21:294868 };
4869
[email protected]31a2bfe2010-02-09 08:03:394870 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4871 data_writes1, arraysize(data_writes1));
4872 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4873 data_writes2, arraysize(data_writes2));
4874 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4875 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:074876 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4877 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4878 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:294879
[email protected]49639fa2011-12-20 23:22:414880 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:294881
[email protected]262eec82013-03-19 21:01:364882 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504883 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504884
[email protected]49639fa2011-12-20 23:22:414885 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424886 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:294887
4888 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424889 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:294890
[email protected]0757e7702009-03-27 04:00:224891 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:294892
[email protected]1c773ea12009-04-28 19:58:424893 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504894 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044895 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:294896
[email protected]49639fa2011-12-20 23:22:414897 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:294898
[email protected]0757e7702009-03-27 04:00:224899 // Enter the wrong password.
[email protected]f3cf9802011-10-28 18:44:584900 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword),
[email protected]49639fa2011-12-20 23:22:414901 callback2.callback());
[email protected]1c773ea12009-04-28 19:58:424902 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:294903
[email protected]10af5fe72011-01-31 16:17:254904 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424905 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:294906
[email protected]0757e7702009-03-27 04:00:224907 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:414908 TestCompletionCallback callback3;
4909 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424910 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]10af5fe72011-01-31 16:17:254911 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424912 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:224913 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4914
4915 response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:044916 ASSERT_FALSE(response == NULL);
4917 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:224918
[email protected]49639fa2011-12-20 23:22:414919 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:224920
4921 // Now enter the right password.
[email protected]f3cf9802011-10-28 18:44:584922 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:414923 callback4.callback());
[email protected]10af5fe72011-01-31 16:17:254924 EXPECT_EQ(ERR_IO_PENDING, rv);
4925
4926 rv = callback4.WaitForResult();
4927 EXPECT_EQ(OK, rv);
4928
4929 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4930
[email protected]49639fa2011-12-20 23:22:414931 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:254932
4933 // One more roundtrip
[email protected]49639fa2011-12-20 23:22:414934 rv = trans->RestartWithAuth(AuthCredentials(), callback5.callback());
[email protected]1c773ea12009-04-28 19:58:424935 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:224936
4937 rv = callback5.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424938 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:224939
[email protected]385a4672009-03-11 22:21:294940 response = trans->GetResponseInfo();
4941 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4942 EXPECT_EQ(13, response->headers->GetContentLength());
4943}
[email protected]ea9dc9a2009-09-05 00:43:324944#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:294945
[email protected]4ddaf2502008-10-23 18:26:194946// Test reading a server response which has only headers, and no body.
4947// After some maximum number of bytes is consumed, the transaction should
4948// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
[email protected]23e482282013-06-14 16:08:024949TEST_P(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:424950 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:194951 request.method = "GET";
bncce36dca22015-04-21 22:11:234952 request.url = GURL("http://www.example.org/");
[email protected]4ddaf2502008-10-23 18:26:194953 request.load_flags = 0;
4954
[email protected]3fe8d2f82013-10-17 08:56:074955 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274956 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:414957 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:274958
[email protected]b75b7b2f2009-10-06 00:54:534959 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:434960 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:534961 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:194962
4963 MockRead data_reads[] = {
4964 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:064965 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:194966 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:064967 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:194968 };
[email protected]31a2bfe2010-02-09 08:03:394969 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:074970 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:194971
[email protected]49639fa2011-12-20 23:22:414972 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:194973
[email protected]49639fa2011-12-20 23:22:414974 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424975 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]4ddaf2502008-10-23 18:26:194976
4977 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424978 EXPECT_EQ(ERR_RESPONSE_HEADERS_TOO_BIG, rv);
[email protected]4ddaf2502008-10-23 18:26:194979}
[email protected]f4e426b2008-11-05 00:24:494980
4981// Make sure that we don't try to reuse a TCPClientSocket when failing to
4982// establish tunnel.
4983// http://code.google.com/p/chromium/issues/detail?id=3772
[email protected]23e482282013-06-14 16:08:024984TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:234985 DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:274986 HttpRequestInfo request;
4987 request.method = "GET";
bncce36dca22015-04-21 22:11:234988 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274989 request.load_flags = 0;
4990
[email protected]f4e426b2008-11-05 00:24:494991 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:074992 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]db8f44c2008-12-13 04:52:014993
[email protected]bb88e1d32013-05-03 23:11:074994 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:494995
[email protected]262eec82013-03-19 21:01:364996 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504997 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f4e426b2008-11-05 00:24:494998
[email protected]f4e426b2008-11-05 00:24:494999 // Since we have proxy, should try to establish tunnel.
5000 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235001 MockWrite(
5002 "CONNECT www.example.org:443 HTTP/1.1\r\n"
5003 "Host: www.example.org\r\n"
5004 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:495005 };
5006
[email protected]77848d12008-11-14 00:00:225007 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:495008 // connection. Usually a proxy would return 501 (not implemented),
5009 // or 200 (tunnel established).
5010 MockRead data_reads1[] = {
5011 MockRead("HTTP/1.1 404 Not Found\r\n"),
5012 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065013 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]f4e426b2008-11-05 00:24:495014 };
5015
[email protected]31a2bfe2010-02-09 08:03:395016 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5017 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075018 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:495019
[email protected]49639fa2011-12-20 23:22:415020 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:495021
[email protected]49639fa2011-12-20 23:22:415022 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425023 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f4e426b2008-11-05 00:24:495024
5025 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425026 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]f4e426b2008-11-05 00:24:495027
[email protected]b4404c02009-04-10 16:38:525028 // Empty the current queue. This is necessary because idle sockets are
5029 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345030 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:525031
[email protected]f4e426b2008-11-05 00:24:495032 // We now check to make sure the TCPClientSocket was not added back to
5033 // the pool.
[email protected]90499482013-06-01 00:39:505034 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:495035 trans.reset();
[email protected]2da659e2013-05-23 20:51:345036 base::MessageLoop::current()->RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:495037 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:505038 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:495039}
[email protected]372d34a2008-11-05 21:30:515040
[email protected]1b157c02009-04-21 01:55:405041// Make sure that we recycle a socket after reading all of the response body.
[email protected]23e482282013-06-14 16:08:025042TEST_P(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:425043 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:405044 request.method = "GET";
bncce36dca22015-04-21 22:11:235045 request.url = GURL("http://www.example.org/");
[email protected]1b157c02009-04-21 01:55:405046 request.load_flags = 0;
5047
[email protected]bb88e1d32013-05-03 23:11:075048 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275049
[email protected]262eec82013-03-19 21:01:365050 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505051 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275052
[email protected]1b157c02009-04-21 01:55:405053 MockRead data_reads[] = {
5054 // A part of the response body is received with the response headers.
5055 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
5056 // The rest of the response body is received in two parts.
5057 MockRead("lo"),
5058 MockRead(" world"),
5059 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:065060 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:405061 };
5062
[email protected]31a2bfe2010-02-09 08:03:395063 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:075064 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:405065
[email protected]49639fa2011-12-20 23:22:415066 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:405067
[email protected]49639fa2011-12-20 23:22:415068 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425069 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]1b157c02009-04-21 01:55:405070
5071 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425072 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:405073
[email protected]1c773ea12009-04-28 19:58:425074 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505075 ASSERT_TRUE(response != NULL);
[email protected]1b157c02009-04-21 01:55:405076
[email protected]90499482013-06-01 00:39:505077 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]1b157c02009-04-21 01:55:405078 std::string status_line = response->headers->GetStatusLine();
5079 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
5080
[email protected]90499482013-06-01 00:39:505081 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:405082
5083 std::string response_data;
5084 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:425085 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:405086 EXPECT_EQ("hello world", response_data);
5087
5088 // Empty the current queue. This is necessary because idle sockets are
5089 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345090 base::MessageLoop::current()->RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:405091
5092 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505093 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:405094}
5095
[email protected]76a505b2010-08-25 06:23:005096// Make sure that we recycle a SSL socket after reading all of the response
5097// body.
[email protected]23e482282013-06-14 16:08:025098TEST_P(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:005099 HttpRequestInfo request;
5100 request.method = "GET";
bncce36dca22015-04-21 22:11:235101 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:005102 request.load_flags = 0;
5103
5104 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:235105 MockWrite(
5106 "GET / HTTP/1.1\r\n"
5107 "Host: www.example.org\r\n"
5108 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:005109 };
5110
5111 MockRead data_reads[] = {
5112 MockRead("HTTP/1.1 200 OK\r\n"),
5113 MockRead("Content-Length: 11\r\n\r\n"),
5114 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:065115 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:005116 };
5117
[email protected]8ddf8322012-02-23 18:08:065118 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075119 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:005120
5121 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5122 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:075123 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:005124
[email protected]49639fa2011-12-20 23:22:415125 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:005126
[email protected]bb88e1d32013-05-03 23:11:075127 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:365128 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505129 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:005130
[email protected]49639fa2011-12-20 23:22:415131 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:005132
5133 EXPECT_EQ(ERR_IO_PENDING, rv);
5134 EXPECT_EQ(OK, callback.WaitForResult());
5135
5136 const HttpResponseInfo* response = trans->GetResponseInfo();
5137 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:505138 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:005139 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5140
[email protected]90499482013-06-01 00:39:505141 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005142
5143 std::string response_data;
5144 rv = ReadTransaction(trans.get(), &response_data);
5145 EXPECT_EQ(OK, rv);
5146 EXPECT_EQ("hello world", response_data);
5147
5148 // Empty the current queue. This is necessary because idle sockets are
5149 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345150 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:005151
5152 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505153 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005154}
5155
5156// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
5157// from the pool and make sure that we recover okay.
[email protected]23e482282013-06-14 16:08:025158TEST_P(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:005159 HttpRequestInfo request;
5160 request.method = "GET";
bncce36dca22015-04-21 22:11:235161 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:005162 request.load_flags = 0;
5163
5164 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:235165 MockWrite(
5166 "GET / HTTP/1.1\r\n"
5167 "Host: www.example.org\r\n"
5168 "Connection: keep-alive\r\n\r\n"),
5169 MockWrite(
5170 "GET / HTTP/1.1\r\n"
5171 "Host: www.example.org\r\n"
5172 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:005173 };
5174
5175 MockRead data_reads[] = {
5176 MockRead("HTTP/1.1 200 OK\r\n"),
5177 MockRead("Content-Length: 11\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065178 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:005179 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:065180 MockRead(ASYNC, 0, 0) // EOF
[email protected]76a505b2010-08-25 06:23:005181 };
5182
[email protected]8ddf8322012-02-23 18:08:065183 SSLSocketDataProvider ssl(ASYNC, OK);
5184 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075185 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5186 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:005187
5188 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5189 data_writes, arraysize(data_writes));
5190 StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
5191 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:075192 session_deps_.socket_factory->AddSocketDataProvider(&data);
5193 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:005194
[email protected]49639fa2011-12-20 23:22:415195 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:005196
[email protected]bb88e1d32013-05-03 23:11:075197 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:365198 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505199 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:005200
[email protected]49639fa2011-12-20 23:22:415201 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:005202
5203 EXPECT_EQ(ERR_IO_PENDING, rv);
5204 EXPECT_EQ(OK, callback.WaitForResult());
5205
5206 const HttpResponseInfo* response = trans->GetResponseInfo();
5207 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:505208 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:005209 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5210
[email protected]90499482013-06-01 00:39:505211 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005212
5213 std::string response_data;
5214 rv = ReadTransaction(trans.get(), &response_data);
5215 EXPECT_EQ(OK, rv);
5216 EXPECT_EQ("hello world", response_data);
5217
5218 // Empty the current queue. This is necessary because idle sockets are
5219 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345220 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:005221
5222 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505223 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005224
5225 // Now start the second transaction, which should reuse the previous socket.
5226
[email protected]90499482013-06-01 00:39:505227 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:005228
[email protected]49639fa2011-12-20 23:22:415229 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:005230
5231 EXPECT_EQ(ERR_IO_PENDING, rv);
5232 EXPECT_EQ(OK, callback.WaitForResult());
5233
5234 response = trans->GetResponseInfo();
5235 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:505236 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:005237 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5238
[email protected]90499482013-06-01 00:39:505239 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005240
5241 rv = ReadTransaction(trans.get(), &response_data);
5242 EXPECT_EQ(OK, rv);
5243 EXPECT_EQ("hello world", response_data);
5244
5245 // Empty the current queue. This is necessary because idle sockets are
5246 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345247 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:005248
5249 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505250 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005251}
5252
[email protected]b4404c02009-04-10 16:38:525253// Make sure that we recycle a socket after a zero-length response.
5254// http://crbug.com/9880
[email protected]23e482282013-06-14 16:08:025255TEST_P(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:425256 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:525257 request.method = "GET";
bncce36dca22015-04-21 22:11:235258 request.url = GURL(
5259 "http://www.example.org/csi?v=3&s=web&action=&"
5260 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
5261 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
5262 "rt=prt.2642,ol.2649,xjs.2951");
[email protected]b4404c02009-04-10 16:38:525263 request.load_flags = 0;
5264
[email protected]bb88e1d32013-05-03 23:11:075265 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275266
[email protected]262eec82013-03-19 21:01:365267 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505268 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275269
[email protected]b4404c02009-04-10 16:38:525270 MockRead data_reads[] = {
5271 MockRead("HTTP/1.1 204 No Content\r\n"
5272 "Content-Length: 0\r\n"
5273 "Content-Type: text/html\r\n\r\n"),
5274 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:065275 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:525276 };
5277
[email protected]31a2bfe2010-02-09 08:03:395278 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:075279 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:525280
[email protected]49639fa2011-12-20 23:22:415281 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:525282
[email protected]49639fa2011-12-20 23:22:415283 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425284 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]b4404c02009-04-10 16:38:525285
5286 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425287 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:525288
[email protected]1c773ea12009-04-28 19:58:425289 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505290 ASSERT_TRUE(response != NULL);
[email protected]b4404c02009-04-10 16:38:525291
[email protected]90499482013-06-01 00:39:505292 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]b4404c02009-04-10 16:38:525293 std::string status_line = response->headers->GetStatusLine();
5294 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
5295
[email protected]90499482013-06-01 00:39:505296 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:525297
5298 std::string response_data;
5299 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:425300 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:525301 EXPECT_EQ("", response_data);
5302
5303 // Empty the current queue. This is necessary because idle sockets are
5304 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345305 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:525306
5307 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505308 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:525309}
5310
[email protected]23e482282013-06-14 16:08:025311TEST_P(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
[email protected]b2d26cfd2012-12-11 10:36:065312 ScopedVector<UploadElementReader> element_readers;
5313 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:075314 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:275315
[email protected]1c773ea12009-04-28 19:58:425316 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:515317 // Transaction 1: a GET request that succeeds. The socket is recycled
5318 // after use.
5319 request[0].method = "GET";
5320 request[0].url = GURL("http://www.google.com/");
5321 request[0].load_flags = 0;
5322 // Transaction 2: a POST request. Reuses the socket kept alive from
5323 // transaction 1. The first attempts fails when writing the POST data.
5324 // This causes the transaction to retry with a new socket. The second
5325 // attempt succeeds.
5326 request[1].method = "POST";
5327 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:275328 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:515329 request[1].load_flags = 0;
5330
[email protected]bb88e1d32013-05-03 23:11:075331 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:515332
5333 // The first socket is used for transaction 1 and the first attempt of
5334 // transaction 2.
5335
5336 // The response of transaction 1.
5337 MockRead data_reads1[] = {
5338 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
5339 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:065340 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:515341 };
5342 // The mock write results of transaction 1 and the first attempt of
5343 // transaction 2.
5344 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:065345 MockWrite(SYNCHRONOUS, 64), // GET
5346 MockWrite(SYNCHRONOUS, 93), // POST
5347 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:515348 };
[email protected]31a2bfe2010-02-09 08:03:395349 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5350 data_writes1, arraysize(data_writes1));
[email protected]372d34a2008-11-05 21:30:515351
5352 // The second socket is used for the second attempt of transaction 2.
5353
5354 // The response of transaction 2.
5355 MockRead data_reads2[] = {
5356 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
5357 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:065358 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:515359 };
5360 // The mock write results of the second attempt of transaction 2.
5361 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:065362 MockWrite(SYNCHRONOUS, 93), // POST
5363 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:515364 };
[email protected]31a2bfe2010-02-09 08:03:395365 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5366 data_writes2, arraysize(data_writes2));
[email protected]372d34a2008-11-05 21:30:515367
[email protected]bb88e1d32013-05-03 23:11:075368 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5369 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:515370
thestig9d3bb0c2015-01-24 00:49:515371 const char* const kExpectedResponseData[] = {
[email protected]372d34a2008-11-05 21:30:515372 "hello world", "welcome"
5373 };
5374
5375 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:425376 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505377 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]372d34a2008-11-05 21:30:515378
[email protected]49639fa2011-12-20 23:22:415379 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:515380
[email protected]49639fa2011-12-20 23:22:415381 int rv = trans->Start(&request[i], callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425382 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]372d34a2008-11-05 21:30:515383
5384 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425385 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:515386
[email protected]1c773ea12009-04-28 19:58:425387 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505388 ASSERT_TRUE(response != NULL);
[email protected]372d34a2008-11-05 21:30:515389
[email protected]90499482013-06-01 00:39:505390 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]372d34a2008-11-05 21:30:515391 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5392
5393 std::string response_data;
5394 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:425395 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:515396 EXPECT_EQ(kExpectedResponseData[i], response_data);
5397 }
5398}
[email protected]f9ee6b52008-11-08 06:46:235399
5400// Test the request-challenge-retry sequence for basic auth when there is
5401// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:165402// it fails the identity from the URL is used to answer the challenge.
[email protected]23e482282013-06-14 16:08:025403TEST_P(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:425404 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235405 request.method = "GET";
bncce36dca22015-04-21 22:11:235406 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:415407 request.load_flags = LOAD_NORMAL;
[email protected]a97cca42009-08-14 01:00:295408
[email protected]3fe8d2f82013-10-17 08:56:075409 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275410 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415411 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275412
[email protected]a97cca42009-08-14 01:00:295413 // The password contains an escaped character -- for this test to pass it
5414 // will need to be unescaped by HttpNetworkTransaction.
5415 EXPECT_EQ("b%40r", request.url.password());
5416
[email protected]f9ee6b52008-11-08 06:46:235417 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235418 MockWrite(
5419 "GET / HTTP/1.1\r\n"
5420 "Host: www.example.org\r\n"
5421 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235422 };
5423
5424 MockRead data_reads1[] = {
5425 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5426 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5427 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065428 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235429 };
5430
[email protected]2262e3a2012-05-22 16:08:165431 // After the challenge above, the transaction will be restarted using the
5432 // identity from the url (foo, b@r) to answer the challenge.
5433 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235434 MockWrite(
5435 "GET / HTTP/1.1\r\n"
5436 "Host: www.example.org\r\n"
5437 "Connection: keep-alive\r\n"
5438 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:165439 };
5440
5441 MockRead data_reads2[] = {
5442 MockRead("HTTP/1.0 200 OK\r\n"),
5443 MockRead("Content-Length: 100\r\n\r\n"),
5444 MockRead(SYNCHRONOUS, OK),
5445 };
5446
[email protected]31a2bfe2010-02-09 08:03:395447 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5448 data_writes1, arraysize(data_writes1));
[email protected]2262e3a2012-05-22 16:08:165449 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5450 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075451 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5452 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235453
[email protected]49639fa2011-12-20 23:22:415454 TestCompletionCallback callback1;
[email protected]49639fa2011-12-20 23:22:415455 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425456 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235457 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425458 EXPECT_EQ(OK, rv);
[email protected]2262e3a2012-05-22 16:08:165459 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5460
5461 TestCompletionCallback callback2;
5462 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
5463 EXPECT_EQ(ERR_IO_PENDING, rv);
5464 rv = callback2.WaitForResult();
5465 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225466 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5467
[email protected]2262e3a2012-05-22 16:08:165468 const HttpResponseInfo* response = trans->GetResponseInfo();
5469 ASSERT_TRUE(response != NULL);
5470
5471 // There is no challenge info, since the identity in URL worked.
5472 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5473
5474 EXPECT_EQ(100, response->headers->GetContentLength());
5475
5476 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:345477 base::MessageLoop::current()->RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:165478}
5479
5480// Test the request-challenge-retry sequence for basic auth when there is an
5481// incorrect identity in the URL. The identity from the URL should be used only
5482// once.
[email protected]23e482282013-06-14 16:08:025483TEST_P(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:165484 HttpRequestInfo request;
5485 request.method = "GET";
5486 // Note: the URL has a username:password in it. The password "baz" is
5487 // wrong (should be "bar").
bncce36dca22015-04-21 22:11:235488 request.url = GURL("http://foo:[email protected]/");
[email protected]2262e3a2012-05-22 16:08:165489
5490 request.load_flags = LOAD_NORMAL;
5491
[email protected]3fe8d2f82013-10-17 08:56:075492 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2262e3a2012-05-22 16:08:165493 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415494 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2262e3a2012-05-22 16:08:165495
5496 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235497 MockWrite(
5498 "GET / HTTP/1.1\r\n"
5499 "Host: www.example.org\r\n"
5500 "Connection: keep-alive\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:165501 };
5502
5503 MockRead data_reads1[] = {
5504 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5505 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5506 MockRead("Content-Length: 10\r\n\r\n"),
5507 MockRead(SYNCHRONOUS, ERR_FAILED),
5508 };
5509
5510 // After the challenge above, the transaction will be restarted using the
5511 // identity from the url (foo, baz) to answer the challenge.
5512 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235513 MockWrite(
5514 "GET / HTTP/1.1\r\n"
5515 "Host: www.example.org\r\n"
5516 "Connection: keep-alive\r\n"
5517 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:165518 };
5519
5520 MockRead data_reads2[] = {
5521 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5522 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5523 MockRead("Content-Length: 10\r\n\r\n"),
5524 MockRead(SYNCHRONOUS, ERR_FAILED),
5525 };
5526
5527 // After the challenge above, the transaction will be restarted using the
5528 // identity supplied by the user (foo, bar) to answer the challenge.
5529 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:235530 MockWrite(
5531 "GET / HTTP/1.1\r\n"
5532 "Host: www.example.org\r\n"
5533 "Connection: keep-alive\r\n"
5534 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:165535 };
5536
5537 MockRead data_reads3[] = {
5538 MockRead("HTTP/1.0 200 OK\r\n"),
5539 MockRead("Content-Length: 100\r\n\r\n"),
5540 MockRead(SYNCHRONOUS, OK),
5541 };
5542
5543 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5544 data_writes1, arraysize(data_writes1));
5545 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5546 data_writes2, arraysize(data_writes2));
5547 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5548 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075549 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5550 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5551 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:165552
5553 TestCompletionCallback callback1;
5554
5555 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5556 EXPECT_EQ(ERR_IO_PENDING, rv);
5557
5558 rv = callback1.WaitForResult();
5559 EXPECT_EQ(OK, rv);
5560
5561 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5562 TestCompletionCallback callback2;
5563 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
5564 EXPECT_EQ(ERR_IO_PENDING, rv);
5565 rv = callback2.WaitForResult();
5566 EXPECT_EQ(OK, rv);
5567 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5568
5569 const HttpResponseInfo* response = trans->GetResponseInfo();
5570 ASSERT_TRUE(response != NULL);
5571 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
5572
5573 TestCompletionCallback callback3;
5574 rv = trans->RestartWithAuth(
5575 AuthCredentials(kFoo, kBar), callback3.callback());
5576 EXPECT_EQ(ERR_IO_PENDING, rv);
5577 rv = callback3.WaitForResult();
5578 EXPECT_EQ(OK, rv);
5579 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5580
5581 response = trans->GetResponseInfo();
5582 ASSERT_TRUE(response != NULL);
5583
5584 // There is no challenge info, since the identity worked.
5585 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5586
5587 EXPECT_EQ(100, response->headers->GetContentLength());
5588
[email protected]ea9dc9a2009-09-05 00:43:325589 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:345590 base::MessageLoop::current()->RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:325591}
5592
[email protected]2217aa22013-10-11 03:03:545593
5594// Test the request-challenge-retry sequence for basic auth when there is a
5595// correct identity in the URL, but its use is being suppressed. The identity
5596// from the URL should never be used.
5597TEST_P(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
5598 HttpRequestInfo request;
5599 request.method = "GET";
bncce36dca22015-04-21 22:11:235600 request.url = GURL("http://foo:[email protected]/");
[email protected]2217aa22013-10-11 03:03:545601 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
5602
[email protected]3fe8d2f82013-10-17 08:56:075603 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2217aa22013-10-11 03:03:545604 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415605 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2217aa22013-10-11 03:03:545606
5607 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235608 MockWrite(
5609 "GET / HTTP/1.1\r\n"
5610 "Host: www.example.org\r\n"
5611 "Connection: keep-alive\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:545612 };
5613
5614 MockRead data_reads1[] = {
5615 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5616 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5617 MockRead("Content-Length: 10\r\n\r\n"),
5618 MockRead(SYNCHRONOUS, ERR_FAILED),
5619 };
5620
5621 // After the challenge above, the transaction will be restarted using the
5622 // identity supplied by the user, not the one in the URL, to answer the
5623 // challenge.
5624 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:235625 MockWrite(
5626 "GET / HTTP/1.1\r\n"
5627 "Host: www.example.org\r\n"
5628 "Connection: keep-alive\r\n"
5629 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:545630 };
5631
5632 MockRead data_reads3[] = {
5633 MockRead("HTTP/1.0 200 OK\r\n"),
5634 MockRead("Content-Length: 100\r\n\r\n"),
5635 MockRead(SYNCHRONOUS, OK),
5636 };
5637
5638 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5639 data_writes1, arraysize(data_writes1));
5640 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5641 data_writes3, arraysize(data_writes3));
5642 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5643 session_deps_.socket_factory->AddSocketDataProvider(&data3);
5644
5645 TestCompletionCallback callback1;
5646 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5647 EXPECT_EQ(ERR_IO_PENDING, rv);
5648 rv = callback1.WaitForResult();
5649 EXPECT_EQ(OK, rv);
5650 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5651
5652 const HttpResponseInfo* response = trans->GetResponseInfo();
5653 ASSERT_TRUE(response != NULL);
5654 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
5655
5656 TestCompletionCallback callback3;
5657 rv = trans->RestartWithAuth(
5658 AuthCredentials(kFoo, kBar), callback3.callback());
5659 EXPECT_EQ(ERR_IO_PENDING, rv);
5660 rv = callback3.WaitForResult();
5661 EXPECT_EQ(OK, rv);
5662 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5663
5664 response = trans->GetResponseInfo();
5665 ASSERT_TRUE(response != NULL);
5666
5667 // There is no challenge info, since the identity worked.
5668 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5669 EXPECT_EQ(100, response->headers->GetContentLength());
5670
5671 // Empty the current queue.
5672 base::MessageLoop::current()->RunUntilIdle();
5673}
5674
[email protected]f9ee6b52008-11-08 06:46:235675// Test that previously tried username/passwords for a realm get re-used.
[email protected]23e482282013-06-14 16:08:025676TEST_P(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
[email protected]bb88e1d32013-05-03 23:11:075677 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:235678
5679 // Transaction 1: authenticate (foo, bar) on MyRealm1
5680 {
[email protected]1c773ea12009-04-28 19:58:425681 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235682 request.method = "GET";
bncce36dca22015-04-21 22:11:235683 request.url = GURL("http://www.example.org/x/y/z");
[email protected]f9ee6b52008-11-08 06:46:235684 request.load_flags = 0;
5685
[email protected]262eec82013-03-19 21:01:365686 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505687 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275688
[email protected]f9ee6b52008-11-08 06:46:235689 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235690 MockWrite(
5691 "GET /x/y/z HTTP/1.1\r\n"
5692 "Host: www.example.org\r\n"
5693 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235694 };
5695
5696 MockRead data_reads1[] = {
5697 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5698 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5699 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065700 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235701 };
5702
5703 // Resend with authorization (username=foo, password=bar)
5704 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235705 MockWrite(
5706 "GET /x/y/z HTTP/1.1\r\n"
5707 "Host: www.example.org\r\n"
5708 "Connection: keep-alive\r\n"
5709 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235710 };
5711
5712 // Sever accepts the authorization.
5713 MockRead data_reads2[] = {
5714 MockRead("HTTP/1.0 200 OK\r\n"),
5715 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065716 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235717 };
5718
[email protected]31a2bfe2010-02-09 08:03:395719 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5720 data_writes1, arraysize(data_writes1));
5721 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5722 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075723 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5724 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235725
[email protected]49639fa2011-12-20 23:22:415726 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235727
[email protected]49639fa2011-12-20 23:22:415728 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425729 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235730
5731 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425732 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235733
[email protected]1c773ea12009-04-28 19:58:425734 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505735 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045736 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:235737
[email protected]49639fa2011-12-20 23:22:415738 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:235739
[email protected]49639fa2011-12-20 23:22:415740 rv = trans->RestartWithAuth(
5741 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425742 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235743
5744 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425745 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235746
5747 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505748 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235749 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5750 EXPECT_EQ(100, response->headers->GetContentLength());
5751 }
5752
5753 // ------------------------------------------------------------------------
5754
5755 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
5756 {
[email protected]1c773ea12009-04-28 19:58:425757 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235758 request.method = "GET";
5759 // Note that Transaction 1 was at /x/y/z, so this is in the same
5760 // protection space as MyRealm1.
bncce36dca22015-04-21 22:11:235761 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]f9ee6b52008-11-08 06:46:235762 request.load_flags = 0;
5763
[email protected]262eec82013-03-19 21:01:365764 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505765 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275766
[email protected]f9ee6b52008-11-08 06:46:235767 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235768 MockWrite(
5769 "GET /x/y/a/b HTTP/1.1\r\n"
5770 "Host: www.example.org\r\n"
5771 "Connection: keep-alive\r\n"
5772 // Send preemptive authorization for MyRealm1
5773 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235774 };
5775
5776 // The server didn't like the preemptive authorization, and
5777 // challenges us for a different realm (MyRealm2).
5778 MockRead data_reads1[] = {
5779 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5780 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
5781 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065782 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235783 };
5784
5785 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
5786 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235787 MockWrite(
5788 "GET /x/y/a/b HTTP/1.1\r\n"
5789 "Host: www.example.org\r\n"
5790 "Connection: keep-alive\r\n"
5791 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235792 };
5793
5794 // Sever accepts the authorization.
5795 MockRead data_reads2[] = {
5796 MockRead("HTTP/1.0 200 OK\r\n"),
5797 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065798 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235799 };
5800
[email protected]31a2bfe2010-02-09 08:03:395801 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5802 data_writes1, arraysize(data_writes1));
5803 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5804 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075805 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5806 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235807
[email protected]49639fa2011-12-20 23:22:415808 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235809
[email protected]49639fa2011-12-20 23:22:415810 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425811 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235812
5813 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425814 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235815
[email protected]1c773ea12009-04-28 19:58:425816 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505817 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045818 ASSERT_TRUE(response->auth_challenge.get());
5819 EXPECT_FALSE(response->auth_challenge->is_proxy);
bncce36dca22015-04-21 22:11:235820 EXPECT_EQ("www.example.org:80",
[email protected]79cb5c12011-09-12 13:12:045821 response->auth_challenge->challenger.ToString());
5822 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
5823 EXPECT_EQ("basic", response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:235824
[email protected]49639fa2011-12-20 23:22:415825 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:235826
[email protected]49639fa2011-12-20 23:22:415827 rv = trans->RestartWithAuth(
5828 AuthCredentials(kFoo2, kBar2), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425829 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235830
5831 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425832 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235833
5834 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505835 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235836 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5837 EXPECT_EQ(100, response->headers->GetContentLength());
5838 }
5839
5840 // ------------------------------------------------------------------------
5841
5842 // Transaction 3: Resend a request in MyRealm's protection space --
5843 // succeed with preemptive authorization.
5844 {
[email protected]1c773ea12009-04-28 19:58:425845 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235846 request.method = "GET";
bncce36dca22015-04-21 22:11:235847 request.url = GURL("http://www.example.org/x/y/z2");
[email protected]f9ee6b52008-11-08 06:46:235848 request.load_flags = 0;
5849
[email protected]262eec82013-03-19 21:01:365850 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505851 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275852
[email protected]f9ee6b52008-11-08 06:46:235853 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235854 MockWrite(
5855 "GET /x/y/z2 HTTP/1.1\r\n"
5856 "Host: www.example.org\r\n"
5857 "Connection: keep-alive\r\n"
5858 // The authorization for MyRealm1 gets sent preemptively
5859 // (since the url is in the same protection space)
5860 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235861 };
5862
5863 // Sever accepts the preemptive authorization
5864 MockRead data_reads1[] = {
5865 MockRead("HTTP/1.0 200 OK\r\n"),
5866 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065867 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235868 };
5869
[email protected]31a2bfe2010-02-09 08:03:395870 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5871 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075872 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:235873
[email protected]49639fa2011-12-20 23:22:415874 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235875
[email protected]49639fa2011-12-20 23:22:415876 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425877 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235878
5879 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425880 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235881
[email protected]1c773ea12009-04-28 19:58:425882 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505883 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235884
5885 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5886 EXPECT_EQ(100, response->headers->GetContentLength());
5887 }
5888
5889 // ------------------------------------------------------------------------
5890
5891 // Transaction 4: request another URL in MyRealm (however the
5892 // url is not known to belong to the protection space, so no pre-auth).
5893 {
[email protected]1c773ea12009-04-28 19:58:425894 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235895 request.method = "GET";
bncce36dca22015-04-21 22:11:235896 request.url = GURL("http://www.example.org/x/1");
[email protected]f9ee6b52008-11-08 06:46:235897 request.load_flags = 0;
5898
[email protected]262eec82013-03-19 21:01:365899 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505900 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275901
[email protected]f9ee6b52008-11-08 06:46:235902 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235903 MockWrite(
5904 "GET /x/1 HTTP/1.1\r\n"
5905 "Host: www.example.org\r\n"
5906 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235907 };
5908
5909 MockRead data_reads1[] = {
5910 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5911 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5912 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065913 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235914 };
5915
5916 // Resend with authorization from MyRealm's cache.
5917 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235918 MockWrite(
5919 "GET /x/1 HTTP/1.1\r\n"
5920 "Host: www.example.org\r\n"
5921 "Connection: keep-alive\r\n"
5922 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235923 };
5924
5925 // Sever accepts the authorization.
5926 MockRead data_reads2[] = {
5927 MockRead("HTTP/1.0 200 OK\r\n"),
5928 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065929 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235930 };
5931
[email protected]31a2bfe2010-02-09 08:03:395932 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5933 data_writes1, arraysize(data_writes1));
5934 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5935 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075936 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5937 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235938
[email protected]49639fa2011-12-20 23:22:415939 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235940
[email protected]49639fa2011-12-20 23:22:415941 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425942 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235943
5944 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425945 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235946
[email protected]0757e7702009-03-27 04:00:225947 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:415948 TestCompletionCallback callback2;
5949 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425950 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:225951 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425952 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225953 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5954
[email protected]1c773ea12009-04-28 19:58:425955 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505956 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235957 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5958 EXPECT_EQ(100, response->headers->GetContentLength());
5959 }
5960
5961 // ------------------------------------------------------------------------
5962
5963 // Transaction 5: request a URL in MyRealm, but the server rejects the
5964 // cached identity. Should invalidate and re-prompt.
5965 {
[email protected]1c773ea12009-04-28 19:58:425966 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235967 request.method = "GET";
bncce36dca22015-04-21 22:11:235968 request.url = GURL("http://www.example.org/p/q/t");
[email protected]f9ee6b52008-11-08 06:46:235969 request.load_flags = 0;
5970
[email protected]262eec82013-03-19 21:01:365971 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505972 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275973
[email protected]f9ee6b52008-11-08 06:46:235974 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235975 MockWrite(
5976 "GET /p/q/t HTTP/1.1\r\n"
5977 "Host: www.example.org\r\n"
5978 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235979 };
5980
5981 MockRead data_reads1[] = {
5982 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5983 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5984 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065985 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235986 };
5987
5988 // Resend with authorization from cache for MyRealm.
5989 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235990 MockWrite(
5991 "GET /p/q/t HTTP/1.1\r\n"
5992 "Host: www.example.org\r\n"
5993 "Connection: keep-alive\r\n"
5994 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235995 };
5996
5997 // Sever rejects the authorization.
5998 MockRead data_reads2[] = {
5999 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6000 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6001 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066002 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236003 };
6004
6005 // At this point we should prompt for new credentials for MyRealm.
6006 // Restart with username=foo3, password=foo4.
6007 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236008 MockWrite(
6009 "GET /p/q/t HTTP/1.1\r\n"
6010 "Host: www.example.org\r\n"
6011 "Connection: keep-alive\r\n"
6012 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236013 };
6014
6015 // Sever accepts the authorization.
6016 MockRead data_reads3[] = {
6017 MockRead("HTTP/1.0 200 OK\r\n"),
6018 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066019 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:236020 };
6021
[email protected]31a2bfe2010-02-09 08:03:396022 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6023 data_writes1, arraysize(data_writes1));
6024 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6025 data_writes2, arraysize(data_writes2));
6026 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6027 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076028 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6029 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6030 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:236031
[email protected]49639fa2011-12-20 23:22:416032 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:236033
[email protected]49639fa2011-12-20 23:22:416034 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426035 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236036
6037 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426038 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236039
[email protected]0757e7702009-03-27 04:00:226040 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:416041 TestCompletionCallback callback2;
6042 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:426043 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:226044 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426045 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:226046 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6047
[email protected]1c773ea12009-04-28 19:58:426048 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506049 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:046050 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:236051
[email protected]49639fa2011-12-20 23:22:416052 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:236053
[email protected]49639fa2011-12-20 23:22:416054 rv = trans->RestartWithAuth(
6055 AuthCredentials(kFoo3, kBar3), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:426056 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236057
[email protected]0757e7702009-03-27 04:00:226058 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426059 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236060
6061 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506062 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:236063 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6064 EXPECT_EQ(100, response->headers->GetContentLength());
6065 }
6066}
[email protected]89ceba9a2009-03-21 03:46:066067
[email protected]3c32c5f2010-05-18 15:18:126068// Tests that nonce count increments when multiple auth attempts
6069// are started with the same nonce.
[email protected]23e482282013-06-14 16:08:026070TEST_P(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:446071 HttpAuthHandlerDigest::Factory* digest_factory =
6072 new HttpAuthHandlerDigest::Factory();
6073 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
6074 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
6075 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:076076 session_deps_.http_auth_handler_factory.reset(digest_factory);
6077 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:126078
6079 // Transaction 1: authenticate (foo, bar) on MyRealm1
6080 {
[email protected]3c32c5f2010-05-18 15:18:126081 HttpRequestInfo request;
6082 request.method = "GET";
bncce36dca22015-04-21 22:11:236083 request.url = GURL("http://www.example.org/x/y/z");
[email protected]3c32c5f2010-05-18 15:18:126084 request.load_flags = 0;
6085
[email protected]262eec82013-03-19 21:01:366086 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506087 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276088
[email protected]3c32c5f2010-05-18 15:18:126089 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236090 MockWrite(
6091 "GET /x/y/z HTTP/1.1\r\n"
6092 "Host: www.example.org\r\n"
6093 "Connection: keep-alive\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:126094 };
6095
6096 MockRead data_reads1[] = {
6097 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6098 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
6099 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066100 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:126101 };
6102
6103 // Resend with authorization (username=foo, password=bar)
6104 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236105 MockWrite(
6106 "GET /x/y/z HTTP/1.1\r\n"
6107 "Host: www.example.org\r\n"
6108 "Connection: keep-alive\r\n"
6109 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
6110 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
6111 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
6112 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:126113 };
6114
6115 // Sever accepts the authorization.
6116 MockRead data_reads2[] = {
6117 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:066118 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:126119 };
6120
6121 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6122 data_writes1, arraysize(data_writes1));
6123 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6124 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076125 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6126 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:126127
[email protected]49639fa2011-12-20 23:22:416128 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:126129
[email protected]49639fa2011-12-20 23:22:416130 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:126131 EXPECT_EQ(ERR_IO_PENDING, rv);
6132
6133 rv = callback1.WaitForResult();
6134 EXPECT_EQ(OK, rv);
6135
6136 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506137 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:046138 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:126139
[email protected]49639fa2011-12-20 23:22:416140 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:126141
[email protected]49639fa2011-12-20 23:22:416142 rv = trans->RestartWithAuth(
6143 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]3c32c5f2010-05-18 15:18:126144 EXPECT_EQ(ERR_IO_PENDING, rv);
6145
6146 rv = callback2.WaitForResult();
6147 EXPECT_EQ(OK, rv);
6148
6149 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506150 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:126151 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6152 }
6153
6154 // ------------------------------------------------------------------------
6155
6156 // Transaction 2: Request another resource in digestive's protection space.
6157 // This will preemptively add an Authorization header which should have an
6158 // "nc" value of 2 (as compared to 1 in the first use.
6159 {
[email protected]3c32c5f2010-05-18 15:18:126160 HttpRequestInfo request;
6161 request.method = "GET";
6162 // Note that Transaction 1 was at /x/y/z, so this is in the same
6163 // protection space as digest.
bncce36dca22015-04-21 22:11:236164 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]3c32c5f2010-05-18 15:18:126165 request.load_flags = 0;
6166
[email protected]262eec82013-03-19 21:01:366167 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506168 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276169
[email protected]3c32c5f2010-05-18 15:18:126170 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236171 MockWrite(
6172 "GET /x/y/a/b HTTP/1.1\r\n"
6173 "Host: www.example.org\r\n"
6174 "Connection: keep-alive\r\n"
6175 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
6176 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
6177 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
6178 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:126179 };
6180
6181 // Sever accepts the authorization.
6182 MockRead data_reads1[] = {
6183 MockRead("HTTP/1.0 200 OK\r\n"),
6184 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066185 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:126186 };
6187
6188 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6189 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:076190 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:126191
[email protected]49639fa2011-12-20 23:22:416192 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:126193
[email protected]49639fa2011-12-20 23:22:416194 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:126195 EXPECT_EQ(ERR_IO_PENDING, rv);
6196
6197 rv = callback1.WaitForResult();
6198 EXPECT_EQ(OK, rv);
6199
6200 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506201 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:126202 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6203 }
6204}
6205
[email protected]89ceba9a2009-03-21 03:46:066206// Test the ResetStateForRestart() private method.
[email protected]23e482282013-06-14 16:08:026207TEST_P(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:066208 // Create a transaction (the dependencies aren't important).
[email protected]3fe8d2f82013-10-17 08:56:076209 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:406210 scoped_ptr<HttpNetworkTransaction> trans(
dcheng48459ac22014-08-26 00:46:416211 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]89ceba9a2009-03-21 03:46:066212
6213 // Setup some state (which we expect ResetStateForRestart() will clear).
[email protected]89ceba9a2009-03-21 03:46:066214 trans->read_buf_ = new IOBuffer(15);
6215 trans->read_buf_len_ = 15;
[email protected]b94f92d2010-10-27 16:45:206216 trans->request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:066217
6218 // Setup state in response_
[email protected]a7e41312009-12-16 23:18:146219 HttpResponseInfo* response = &trans->response_;
[email protected]0877e3d2009-10-17 22:29:576220 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:086221 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:576222 response->response_time = base::Time::Now();
6223 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:066224
6225 { // Setup state for response_.vary_data
6226 HttpRequestInfo request;
6227 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
6228 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:276229 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:436230 request.extra_headers.SetHeader("Foo", "1");
6231 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:506232 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:066233 }
6234
6235 // Cause the above state to be reset.
6236 trans->ResetStateForRestart();
6237
6238 // Verify that the state that needed to be reset, has been reset.
[email protected]9b6fee12009-09-29 18:13:076239 EXPECT_TRUE(trans->read_buf_.get() == NULL);
[email protected]89ceba9a2009-03-21 03:46:066240 EXPECT_EQ(0, trans->read_buf_len_);
[email protected]b94f92d2010-10-27 16:45:206241 EXPECT_TRUE(trans->request_headers_.IsEmpty());
[email protected]0877e3d2009-10-17 22:29:576242 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6243 EXPECT_TRUE(response->headers.get() == NULL);
[email protected]34f40942010-10-04 00:34:046244 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:086245 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:576246 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:066247}
6248
[email protected]bacff652009-03-31 17:50:336249// Test HTTPS connections to a site with a bad certificate
[email protected]23e482282013-06-14 16:08:026250TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:336251 HttpRequestInfo request;
6252 request.method = "GET";
bncce36dca22015-04-21 22:11:236253 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:336254 request.load_flags = 0;
6255
[email protected]3fe8d2f82013-10-17 08:56:076256 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276257 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416258 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276259
[email protected]bacff652009-03-31 17:50:336260 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236261 MockWrite(
6262 "GET / HTTP/1.1\r\n"
6263 "Host: www.example.org\r\n"
6264 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:336265 };
6266
6267 MockRead data_reads[] = {
6268 MockRead("HTTP/1.0 200 OK\r\n"),
6269 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6270 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066271 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:336272 };
6273
[email protected]5ecc992a42009-11-11 01:41:596274 StaticSocketDataProvider ssl_bad_certificate;
[email protected]31a2bfe2010-02-09 08:03:396275 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6276 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066277 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
6278 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:336279
[email protected]bb88e1d32013-05-03 23:11:076280 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
6281 session_deps_.socket_factory->AddSocketDataProvider(&data);
6282 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
6283 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:336284
[email protected]49639fa2011-12-20 23:22:416285 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:336286
[email protected]49639fa2011-12-20 23:22:416287 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:336288 EXPECT_EQ(ERR_IO_PENDING, rv);
6289
6290 rv = callback.WaitForResult();
6291 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
6292
[email protected]49639fa2011-12-20 23:22:416293 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:336294 EXPECT_EQ(ERR_IO_PENDING, rv);
6295
6296 rv = callback.WaitForResult();
6297 EXPECT_EQ(OK, rv);
6298
6299 const HttpResponseInfo* response = trans->GetResponseInfo();
6300
[email protected]fe2255a2011-09-20 19:37:506301 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:336302 EXPECT_EQ(100, response->headers->GetContentLength());
6303}
6304
6305// Test HTTPS connections to a site with a bad certificate, going through a
6306// proxy
[email protected]23e482282013-06-14 16:08:026307TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
[email protected]bb88e1d32013-05-03 23:11:076308 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]bacff652009-03-31 17:50:336309
6310 HttpRequestInfo request;
6311 request.method = "GET";
bncce36dca22015-04-21 22:11:236312 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:336313 request.load_flags = 0;
6314
6315 MockWrite proxy_writes[] = {
bncce36dca22015-04-21 22:11:236316 MockWrite(
6317 "CONNECT www.example.org:443 HTTP/1.1\r\n"
6318 "Host: www.example.org\r\n"
6319 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:336320 };
6321
6322 MockRead proxy_reads[] = {
6323 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066324 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:336325 };
6326
6327 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236328 MockWrite(
6329 "CONNECT www.example.org:443 HTTP/1.1\r\n"
6330 "Host: www.example.org\r\n"
6331 "Proxy-Connection: keep-alive\r\n\r\n"),
6332 MockWrite(
6333 "GET / HTTP/1.1\r\n"
6334 "Host: www.example.org\r\n"
6335 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:336336 };
6337
6338 MockRead data_reads[] = {
6339 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
6340 MockRead("HTTP/1.0 200 OK\r\n"),
6341 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6342 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066343 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:336344 };
6345
[email protected]31a2bfe2010-02-09 08:03:396346 StaticSocketDataProvider ssl_bad_certificate(
6347 proxy_reads, arraysize(proxy_reads),
6348 proxy_writes, arraysize(proxy_writes));
6349 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6350 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066351 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
6352 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:336353
[email protected]bb88e1d32013-05-03 23:11:076354 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
6355 session_deps_.socket_factory->AddSocketDataProvider(&data);
6356 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
6357 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:336358
[email protected]49639fa2011-12-20 23:22:416359 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:336360
6361 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:076362 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:336363
[email protected]3fe8d2f82013-10-17 08:56:076364 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:406365 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416366 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bacff652009-03-31 17:50:336367
[email protected]49639fa2011-12-20 23:22:416368 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:336369 EXPECT_EQ(ERR_IO_PENDING, rv);
6370
6371 rv = callback.WaitForResult();
6372 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
6373
[email protected]49639fa2011-12-20 23:22:416374 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:336375 EXPECT_EQ(ERR_IO_PENDING, rv);
6376
6377 rv = callback.WaitForResult();
6378 EXPECT_EQ(OK, rv);
6379
6380 const HttpResponseInfo* response = trans->GetResponseInfo();
6381
[email protected]fe2255a2011-09-20 19:37:506382 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:336383 EXPECT_EQ(100, response->headers->GetContentLength());
6384 }
6385}
6386
[email protected]2df19bb2010-08-25 20:13:466387
6388// Test HTTPS connections to a site, going through an HTTPS proxy
[email protected]23e482282013-06-14 16:08:026389TEST_P(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076390 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206391 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
vishal.b62985ca92015-04-17 08:45:516392 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076393 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:466394
6395 HttpRequestInfo request;
6396 request.method = "GET";
bncce36dca22015-04-21 22:11:236397 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:466398 request.load_flags = 0;
6399
6400 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236401 MockWrite(
6402 "CONNECT www.example.org:443 HTTP/1.1\r\n"
6403 "Host: www.example.org\r\n"
6404 "Proxy-Connection: keep-alive\r\n\r\n"),
6405 MockWrite(
6406 "GET / HTTP/1.1\r\n"
6407 "Host: www.example.org\r\n"
6408 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:466409 };
6410
6411 MockRead data_reads[] = {
6412 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
6413 MockRead("HTTP/1.1 200 OK\r\n"),
6414 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6415 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066416 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:466417 };
6418
6419 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6420 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066421 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
6422 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:466423
[email protected]bb88e1d32013-05-03 23:11:076424 session_deps_.socket_factory->AddSocketDataProvider(&data);
6425 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
6426 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:466427
[email protected]49639fa2011-12-20 23:22:416428 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:466429
[email protected]3fe8d2f82013-10-17 08:56:076430 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:466431 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416432 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2df19bb2010-08-25 20:13:466433
[email protected]49639fa2011-12-20 23:22:416434 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:466435 EXPECT_EQ(ERR_IO_PENDING, rv);
6436
6437 rv = callback.WaitForResult();
6438 EXPECT_EQ(OK, rv);
6439 const HttpResponseInfo* response = trans->GetResponseInfo();
6440
[email protected]fe2255a2011-09-20 19:37:506441 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:466442
6443 EXPECT_TRUE(response->headers->IsKeepAlive());
6444 EXPECT_EQ(200, response->headers->response_code());
6445 EXPECT_EQ(100, response->headers->GetContentLength());
6446 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:206447
6448 LoadTimingInfo load_timing_info;
6449 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6450 TestLoadTimingNotReusedWithPac(load_timing_info,
6451 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:466452}
6453
[email protected]511f6f52010-12-17 03:58:296454// Test an HTTPS Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:026455TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076456 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206457 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
vishal.b62985ca92015-04-17 08:45:516458 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076459 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:296460
6461 HttpRequestInfo request;
6462 request.method = "GET";
bncce36dca22015-04-21 22:11:236463 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:296464 request.load_flags = 0;
6465
6466 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236467 MockWrite(
6468 "CONNECT www.example.org:443 HTTP/1.1\r\n"
6469 "Host: www.example.org\r\n"
6470 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:296471 };
6472
6473 MockRead data_reads[] = {
6474 MockRead("HTTP/1.1 302 Redirect\r\n"),
6475 MockRead("Location: http://login.example.com/\r\n"),
6476 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066477 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:296478 };
6479
6480 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6481 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066482 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:296483
[email protected]bb88e1d32013-05-03 23:11:076484 session_deps_.socket_factory->AddSocketDataProvider(&data);
6485 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296486
[email protected]49639fa2011-12-20 23:22:416487 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296488
[email protected]3fe8d2f82013-10-17 08:56:076489 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296490 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416491 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:296492
[email protected]49639fa2011-12-20 23:22:416493 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296494 EXPECT_EQ(ERR_IO_PENDING, rv);
6495
6496 rv = callback.WaitForResult();
6497 EXPECT_EQ(OK, rv);
6498 const HttpResponseInfo* response = trans->GetResponseInfo();
6499
[email protected]fe2255a2011-09-20 19:37:506500 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:296501
6502 EXPECT_EQ(302, response->headers->response_code());
6503 std::string url;
6504 EXPECT_TRUE(response->headers->IsRedirect(&url));
6505 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:206506
6507 // In the case of redirects from proxies, HttpNetworkTransaction returns
6508 // timing for the proxy connection instead of the connection to the host,
6509 // and no send / receive times.
6510 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
6511 LoadTimingInfo load_timing_info;
6512 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6513
6514 EXPECT_FALSE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:296515 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:206516
6517 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
6518 EXPECT_LE(load_timing_info.proxy_resolve_start,
6519 load_timing_info.proxy_resolve_end);
6520 EXPECT_LE(load_timing_info.proxy_resolve_end,
6521 load_timing_info.connect_timing.connect_start);
6522 ExpectConnectTimingHasTimes(
6523 load_timing_info.connect_timing,
6524 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
6525
6526 EXPECT_TRUE(load_timing_info.send_start.is_null());
6527 EXPECT_TRUE(load_timing_info.send_end.is_null());
6528 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:296529}
6530
6531// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:026532TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
[email protected]bb88e1d32013-05-03 23:11:076533 session_deps_.proxy_service.reset(
[email protected]511f6f52010-12-17 03:58:296534 ProxyService::CreateFixed("https://proxy:70"));
6535
6536 HttpRequestInfo request;
6537 request.method = "GET";
bncce36dca22015-04-21 22:11:236538 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:296539 request.load_flags = 0;
6540
lgarrona91df87f2014-12-05 00:51:346541 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:236542 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]c10b20852013-05-15 21:29:206543 scoped_ptr<SpdyFrame> goaway(
6544 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:296545 MockWrite data_writes[] = {
rch8e6c6c42015-05-01 14:05:136546 CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
6547 CreateMockWrite(*goaway.get(), 2, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:296548 };
6549
6550 static const char* const kExtraHeaders[] = {
6551 "location",
6552 "http://login.example.com/",
6553 };
[email protected]ff98d7f02012-03-22 21:44:196554 scoped_ptr<SpdyFrame> resp(
[email protected]23e482282013-06-14 16:08:026555 spdy_util_.ConstructSpdySynReplyError("302 Redirect", kExtraHeaders,
[email protected]511f6f52010-12-17 03:58:296556 arraysize(kExtraHeaders)/2, 1));
6557 MockRead data_reads[] = {
rch8e6c6c42015-05-01 14:05:136558 CreateMockRead(*resp.get(), 1), MockRead(ASYNC, 0, 3), // EOF
[email protected]511f6f52010-12-17 03:58:296559 };
6560
rch8e6c6c42015-05-01 14:05:136561 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
6562 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066563 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]23e482282013-06-14 16:08:026564 proxy_ssl.SetNextProto(GetParam());
[email protected]511f6f52010-12-17 03:58:296565
[email protected]bb88e1d32013-05-03 23:11:076566 session_deps_.socket_factory->AddSocketDataProvider(&data);
6567 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296568
[email protected]49639fa2011-12-20 23:22:416569 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296570
[email protected]3fe8d2f82013-10-17 08:56:076571 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296572 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416573 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:296574
[email protected]49639fa2011-12-20 23:22:416575 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296576 EXPECT_EQ(ERR_IO_PENDING, rv);
6577
6578 rv = callback.WaitForResult();
6579 EXPECT_EQ(OK, rv);
6580 const HttpResponseInfo* response = trans->GetResponseInfo();
6581
[email protected]fe2255a2011-09-20 19:37:506582 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:296583
6584 EXPECT_EQ(302, response->headers->response_code());
6585 std::string url;
6586 EXPECT_TRUE(response->headers->IsRedirect(&url));
6587 EXPECT_EQ("http://login.example.com/", url);
6588}
6589
[email protected]4eddbc732012-08-09 05:40:176590// Test that an HTTPS proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:026591TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:176592 ErrorResponseToHttpsConnectViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076593 session_deps_.proxy_service.reset(
[email protected]511f6f52010-12-17 03:58:296594 ProxyService::CreateFixed("https://proxy:70"));
6595
6596 HttpRequestInfo request;
6597 request.method = "GET";
bncce36dca22015-04-21 22:11:236598 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:296599 request.load_flags = 0;
6600
6601 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236602 MockWrite(
6603 "CONNECT www.example.org:443 HTTP/1.1\r\n"
6604 "Host: www.example.org\r\n"
6605 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:296606 };
6607
6608 MockRead data_reads[] = {
6609 MockRead("HTTP/1.1 404 Not Found\r\n"),
6610 MockRead("Content-Length: 23\r\n\r\n"),
6611 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:066612 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:296613 };
6614
6615 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6616 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066617 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:296618
[email protected]bb88e1d32013-05-03 23:11:076619 session_deps_.socket_factory->AddSocketDataProvider(&data);
6620 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296621
[email protected]49639fa2011-12-20 23:22:416622 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296623
[email protected]3fe8d2f82013-10-17 08:56:076624 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296625 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416626 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:296627
[email protected]49639fa2011-12-20 23:22:416628 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296629 EXPECT_EQ(ERR_IO_PENDING, rv);
6630
6631 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:176632 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:296633
[email protected]4eddbc732012-08-09 05:40:176634 // TODO(ttuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:296635}
6636
[email protected]4eddbc732012-08-09 05:40:176637// Test that a SPDY proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:026638TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:176639 ErrorResponseToHttpsConnectViaSpdyProxy) {
[email protected]bb88e1d32013-05-03 23:11:076640 session_deps_.proxy_service.reset(
6641 ProxyService::CreateFixed("https://proxy:70"));
[email protected]511f6f52010-12-17 03:58:296642
6643 HttpRequestInfo request;
6644 request.method = "GET";
bncce36dca22015-04-21 22:11:236645 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:296646 request.load_flags = 0;
6647
lgarrona91df87f2014-12-05 00:51:346648 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:236649 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]c10b20852013-05-15 21:29:206650 scoped_ptr<SpdyFrame> rst(
6651 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:296652 MockWrite data_writes[] = {
rch8e6c6c42015-05-01 14:05:136653 CreateMockWrite(*conn.get(), 0), CreateMockWrite(*rst.get(), 3),
[email protected]511f6f52010-12-17 03:58:296654 };
6655
6656 static const char* const kExtraHeaders[] = {
6657 "location",
6658 "http://login.example.com/",
6659 };
[email protected]ff98d7f02012-03-22 21:44:196660 scoped_ptr<SpdyFrame> resp(
[email protected]23e482282013-06-14 16:08:026661 spdy_util_.ConstructSpdySynReplyError("404 Not Found", kExtraHeaders,
[email protected]511f6f52010-12-17 03:58:296662 arraysize(kExtraHeaders)/2, 1));
[email protected]ff98d7f02012-03-22 21:44:196663 scoped_ptr<SpdyFrame> body(
[email protected]23e482282013-06-14 16:08:026664 spdy_util_.ConstructSpdyBodyFrame(
6665 1, "The host does not exist", 23, true));
[email protected]511f6f52010-12-17 03:58:296666 MockRead data_reads[] = {
rch8e6c6c42015-05-01 14:05:136667 CreateMockRead(*resp.get(), 1),
6668 CreateMockRead(*body.get(), 2),
6669 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:296670 };
6671
rch8e6c6c42015-05-01 14:05:136672 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
6673 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066674 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]23e482282013-06-14 16:08:026675 proxy_ssl.SetNextProto(GetParam());
[email protected]511f6f52010-12-17 03:58:296676
[email protected]bb88e1d32013-05-03 23:11:076677 session_deps_.socket_factory->AddSocketDataProvider(&data);
6678 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296679
[email protected]49639fa2011-12-20 23:22:416680 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296681
[email protected]3fe8d2f82013-10-17 08:56:076682 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296683 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416684 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:296685
[email protected]49639fa2011-12-20 23:22:416686 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296687 EXPECT_EQ(ERR_IO_PENDING, rv);
6688
6689 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:176690 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:296691
[email protected]4eddbc732012-08-09 05:40:176692 // TODO(ttuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:296693}
6694
[email protected]0c5fb722012-02-28 11:50:356695// Test the request-challenge-retry sequence for basic auth, through
6696// a SPDY proxy over a single SPDY session.
[email protected]23e482282013-06-14 16:08:026697TEST_P(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:356698 HttpRequestInfo request;
6699 request.method = "GET";
bncce36dca22015-04-21 22:11:236700 request.url = GURL("https://www.example.org/");
[email protected]0c5fb722012-02-28 11:50:356701 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:296702 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]0c5fb722012-02-28 11:50:356703
6704 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076705 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206706 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
vishal.b62985ca92015-04-17 08:45:516707 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076708 session_deps_.net_log = log.bound().net_log();
6709 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:356710
6711 // Since we have proxy, should try to establish tunnel.
lgarrona91df87f2014-12-05 00:51:346712 scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:236713 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]c10b20852013-05-15 21:29:206714 scoped_ptr<SpdyFrame> rst(
6715 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]0c5fb722012-02-28 11:50:356716
6717 // After calling trans->RestartWithAuth(), this is the request we should
6718 // be issuing -- the final header line contains the credentials.
6719 const char* const kAuthCredentials[] = {
6720 "proxy-authorization", "Basic Zm9vOmJhcg==",
6721 };
[email protected]fba2dbde2013-05-24 16:09:016722 scoped_ptr<SpdyFrame> connect2(spdy_util_.ConstructSpdyConnect(
lgarrona91df87f2014-12-05 00:51:346723 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST,
bncce36dca22015-04-21 22:11:236724 HostPortPair("www.example.org", 443)));
6725 // fetch https://www.example.org/ via HTTP
6726 const char get[] =
6727 "GET / HTTP/1.1\r\n"
6728 "Host: www.example.org\r\n"
6729 "Connection: keep-alive\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:196730 scoped_ptr<SpdyFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:026731 spdy_util_.ConstructSpdyBodyFrame(3, get, strlen(get), false));
[email protected]0c5fb722012-02-28 11:50:356732
6733 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:136734 CreateMockWrite(*req, 0, ASYNC),
6735 CreateMockWrite(*rst, 2, ASYNC),
6736 CreateMockWrite(*connect2, 3),
6737 CreateMockWrite(*wrapped_get, 5),
[email protected]0c5fb722012-02-28 11:50:356738 };
6739
6740 // The proxy responds to the connect with a 407, using a persistent
6741 // connection.
thestig9d3bb0c2015-01-24 00:49:516742 const char kAuthStatus[] = "407";
[email protected]0c5fb722012-02-28 11:50:356743 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:356744 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
6745 };
[email protected]745aa9c2014-06-27 02:21:296746 scoped_ptr<SpdyFrame> conn_auth_resp(spdy_util_.ConstructSpdySynReplyError(
6747 kAuthStatus, kAuthChallenge, arraysize(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:356748
[email protected]23e482282013-06-14 16:08:026749 scoped_ptr<SpdyFrame> conn_resp(
6750 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:356751 const char resp[] = "HTTP/1.1 200 OK\r\n"
6752 "Content-Length: 5\r\n\r\n";
6753
[email protected]ff98d7f02012-03-22 21:44:196754 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:026755 spdy_util_.ConstructSpdyBodyFrame(3, resp, strlen(resp), false));
[email protected]ff98d7f02012-03-22 21:44:196756 scoped_ptr<SpdyFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:026757 spdy_util_.ConstructSpdyBodyFrame(3, "hello", 5, false));
[email protected]0c5fb722012-02-28 11:50:356758 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:136759 CreateMockRead(*conn_auth_resp, 1, ASYNC),
6760 CreateMockRead(*conn_resp, 4, ASYNC),
6761 CreateMockRead(*wrapped_get_resp, 6, ASYNC),
6762 CreateMockRead(*wrapped_body, 7, ASYNC),
6763 MockRead(ASYNC, OK, 8), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:356764 };
6765
rch8e6c6c42015-05-01 14:05:136766 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
6767 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:076768 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:356769 // Negotiate SPDY to the proxy
6770 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:026771 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:076772 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:356773 // Vanilla SSL to the server
6774 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076775 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:356776
6777 TestCompletionCallback callback1;
6778
[email protected]262eec82013-03-19 21:01:366779 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506780 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0c5fb722012-02-28 11:50:356781
6782 int rv = trans->Start(&request, callback1.callback(), log.bound());
6783 EXPECT_EQ(ERR_IO_PENDING, rv);
6784
6785 rv = callback1.WaitForResult();
6786 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:466787 TestNetLogEntry::List entries;
[email protected]0c5fb722012-02-28 11:50:356788 log.GetEntries(&entries);
6789 size_t pos = ExpectLogContainsSomewhere(
6790 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
6791 NetLog::PHASE_NONE);
6792 ExpectLogContainsSomewhere(
6793 entries, pos,
6794 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
6795 NetLog::PHASE_NONE);
6796
6797 const HttpResponseInfo* response = trans->GetResponseInfo();
6798 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:506799 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]0c5fb722012-02-28 11:50:356800 EXPECT_EQ(407, response->headers->response_code());
6801 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6802 EXPECT_TRUE(response->auth_challenge.get() != NULL);
6803 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
6804
6805 TestCompletionCallback callback2;
6806
6807 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
6808 callback2.callback());
6809 EXPECT_EQ(ERR_IO_PENDING, rv);
6810
6811 rv = callback2.WaitForResult();
6812 EXPECT_EQ(OK, rv);
6813
6814 response = trans->GetResponseInfo();
6815 ASSERT_TRUE(response != NULL);
6816
6817 EXPECT_TRUE(response->headers->IsKeepAlive());
6818 EXPECT_EQ(200, response->headers->response_code());
6819 EXPECT_EQ(5, response->headers->GetContentLength());
6820 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6821
6822 // The password prompt info should not be set.
6823 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6824
[email protected]029c83b62013-01-24 05:28:206825 LoadTimingInfo load_timing_info;
6826 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6827 TestLoadTimingNotReusedWithPac(load_timing_info,
6828 CONNECT_TIMING_HAS_SSL_TIMES);
6829
[email protected]0c5fb722012-02-28 11:50:356830 trans.reset();
6831 session->CloseAllConnections();
6832}
6833
[email protected]7c6f7ba2012-04-03 04:09:296834// Test that an explicitly trusted SPDY proxy can push a resource from an
6835// origin that is different from that of its associated resource.
[email protected]23e482282013-06-14 16:08:026836TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPush) {
[email protected]7c6f7ba2012-04-03 04:09:296837 HttpRequestInfo request;
6838 HttpRequestInfo push_request;
6839
[email protected]7c6f7ba2012-04-03 04:09:296840 request.method = "GET";
bncce36dca22015-04-21 22:11:236841 request.url = GURL("http://www.example.org/");
[email protected]7c6f7ba2012-04-03 04:09:296842 push_request.method = "GET";
6843 push_request.url = GURL("http://www.another-origin.com/foo.dat");
6844
[email protected]7c6f7ba2012-04-03 04:09:296845 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076846 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206847 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
vishal.b62985ca92015-04-17 08:45:516848 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076849 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:506850
6851 // Enable cross-origin push.
[email protected]bb88e1d32013-05-03 23:11:076852 session_deps_.trusted_spdy_proxy = "myproxy:70";
[email protected]61b4efc2012-04-27 18:12:506853
[email protected]bb88e1d32013-05-03 23:11:076854 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:296855
[email protected]cdf8f7e72013-05-23 10:56:466856 scoped_ptr<SpdyFrame> stream1_syn(
6857 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]7c6f7ba2012-04-03 04:09:296858
6859 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:136860 CreateMockWrite(*stream1_syn, 0, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:296861 };
6862
6863 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026864 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:296865
6866 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026867 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:296868
6869 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026870 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
[email protected]7c6f7ba2012-04-03 04:09:296871 0,
6872 2,
6873 1,
6874 "http://www.another-origin.com/foo.dat"));
[email protected]8a0fc822013-06-27 20:52:436875 const char kPushedData[] = "pushed";
6876 scoped_ptr<SpdyFrame> stream2_body(
6877 spdy_util_.ConstructSpdyBodyFrame(
6878 2, kPushedData, strlen(kPushedData), true));
[email protected]7c6f7ba2012-04-03 04:09:296879
6880 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:136881 CreateMockRead(*stream1_reply, 1, ASYNC),
6882 CreateMockRead(*stream2_syn, 2, ASYNC),
6883 CreateMockRead(*stream1_body, 3, ASYNC),
6884 CreateMockRead(*stream2_body, 4, ASYNC),
6885 MockRead(ASYNC, ERR_IO_PENDING, 5), // Force a pause
[email protected]7c6f7ba2012-04-03 04:09:296886 };
6887
rch8e6c6c42015-05-01 14:05:136888 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
6889 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:076890 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:296891 // Negotiate SPDY to the proxy
6892 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:026893 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:076894 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:296895
[email protected]262eec82013-03-19 21:01:366896 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506897 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7c6f7ba2012-04-03 04:09:296898 TestCompletionCallback callback;
6899 int rv = trans->Start(&request, callback.callback(), log.bound());
6900 EXPECT_EQ(ERR_IO_PENDING, rv);
6901
6902 rv = callback.WaitForResult();
6903 EXPECT_EQ(OK, rv);
6904 const HttpResponseInfo* response = trans->GetResponseInfo();
6905
[email protected]262eec82013-03-19 21:01:366906 scoped_ptr<HttpTransaction> push_trans(
[email protected]90499482013-06-01 00:39:506907 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
6908 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
[email protected]7c6f7ba2012-04-03 04:09:296909 EXPECT_EQ(ERR_IO_PENDING, rv);
6910
6911 rv = callback.WaitForResult();
6912 EXPECT_EQ(OK, rv);
6913 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
6914
6915 ASSERT_TRUE(response != NULL);
6916 EXPECT_TRUE(response->headers->IsKeepAlive());
6917
6918 EXPECT_EQ(200, response->headers->response_code());
6919 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6920
6921 std::string response_data;
6922 rv = ReadTransaction(trans.get(), &response_data);
6923 EXPECT_EQ(OK, rv);
6924 EXPECT_EQ("hello!", response_data);
6925
[email protected]029c83b62013-01-24 05:28:206926 LoadTimingInfo load_timing_info;
6927 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6928 TestLoadTimingNotReusedWithPac(load_timing_info,
6929 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6930
[email protected]7c6f7ba2012-04-03 04:09:296931 // Verify the pushed stream.
[email protected]90499482013-06-01 00:39:506932 EXPECT_TRUE(push_response->headers.get() != NULL);
[email protected]7c6f7ba2012-04-03 04:09:296933 EXPECT_EQ(200, push_response->headers->response_code());
6934
6935 rv = ReadTransaction(push_trans.get(), &response_data);
6936 EXPECT_EQ(OK, rv);
6937 EXPECT_EQ("pushed", response_data);
6938
[email protected]029c83b62013-01-24 05:28:206939 LoadTimingInfo push_load_timing_info;
6940 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
6941 TestLoadTimingReusedWithPac(push_load_timing_info);
6942 // The transactions should share a socket ID, despite being for different
6943 // origins.
6944 EXPECT_EQ(load_timing_info.socket_log_id,
6945 push_load_timing_info.socket_log_id);
6946
[email protected]7c6f7ba2012-04-03 04:09:296947 trans.reset();
6948 push_trans.reset();
6949 session->CloseAllConnections();
6950}
6951
[email protected]8c843192012-04-05 07:15:006952// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
[email protected]23e482282013-06-14 16:08:026953TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
[email protected]8c843192012-04-05 07:15:006954 HttpRequestInfo request;
6955
6956 request.method = "GET";
bncce36dca22015-04-21 22:11:236957 request.url = GURL("http://www.example.org/");
[email protected]8c843192012-04-05 07:15:006958
[email protected]8c843192012-04-05 07:15:006959 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076960 session_deps_.proxy_service.reset(
[email protected]8c843192012-04-05 07:15:006961 ProxyService::CreateFixed("https://myproxy:70"));
vishal.b62985ca92015-04-17 08:45:516962 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076963 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:506964
6965 // Enable cross-origin push.
[email protected]bb88e1d32013-05-03 23:11:076966 session_deps_.trusted_spdy_proxy = "myproxy:70";
[email protected]61b4efc2012-04-27 18:12:506967
[email protected]bb88e1d32013-05-03 23:11:076968 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:006969
[email protected]cdf8f7e72013-05-23 10:56:466970 scoped_ptr<SpdyFrame> stream1_syn(
6971 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]8c843192012-04-05 07:15:006972
6973 scoped_ptr<SpdyFrame> push_rst(
[email protected]c10b20852013-05-15 21:29:206974 spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:006975
6976 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:136977 CreateMockWrite(*stream1_syn, 0, ASYNC), CreateMockWrite(*push_rst, 3),
[email protected]8c843192012-04-05 07:15:006978 };
6979
6980 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026981 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:006982
6983 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026984 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8c843192012-04-05 07:15:006985
6986 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026987 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
[email protected]8c843192012-04-05 07:15:006988 0,
6989 2,
6990 1,
6991 "https://www.another-origin.com/foo.dat"));
6992
6993 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:136994 CreateMockRead(*stream1_reply, 1, ASYNC),
6995 CreateMockRead(*stream2_syn, 2, ASYNC),
6996 CreateMockRead(*stream1_body, 4, ASYNC),
6997 MockRead(ASYNC, ERR_IO_PENDING, 5), // Force a pause
[email protected]8c843192012-04-05 07:15:006998 };
6999
rch8e6c6c42015-05-01 14:05:137000 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
7001 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:077002 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:007003 // Negotiate SPDY to the proxy
7004 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:027005 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:077006 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:007007
[email protected]262eec82013-03-19 21:01:367008 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507009 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c843192012-04-05 07:15:007010 TestCompletionCallback callback;
7011 int rv = trans->Start(&request, callback.callback(), log.bound());
7012 EXPECT_EQ(ERR_IO_PENDING, rv);
7013
7014 rv = callback.WaitForResult();
7015 EXPECT_EQ(OK, rv);
7016 const HttpResponseInfo* response = trans->GetResponseInfo();
7017
7018 ASSERT_TRUE(response != NULL);
7019 EXPECT_TRUE(response->headers->IsKeepAlive());
7020
7021 EXPECT_EQ(200, response->headers->response_code());
7022 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
7023
7024 std::string response_data;
7025 rv = ReadTransaction(trans.get(), &response_data);
7026 EXPECT_EQ(OK, rv);
7027 EXPECT_EQ("hello!", response_data);
7028
7029 trans.reset();
7030 session->CloseAllConnections();
7031}
7032
[email protected]2df19bb2010-08-25 20:13:467033// Test HTTPS connections to a site with a bad certificate, going through an
7034// HTTPS proxy
[email protected]23e482282013-06-14 16:08:027035TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:077036 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:117037 "https://proxy:70"));
[email protected]2df19bb2010-08-25 20:13:467038
7039 HttpRequestInfo request;
7040 request.method = "GET";
bncce36dca22015-04-21 22:11:237041 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:467042 request.load_flags = 0;
7043
7044 // Attempt to fetch the URL from a server with a bad cert
7045 MockWrite bad_cert_writes[] = {
bncce36dca22015-04-21 22:11:237046 MockWrite(
7047 "CONNECT www.example.org:443 HTTP/1.1\r\n"
7048 "Host: www.example.org\r\n"
7049 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:467050 };
7051
7052 MockRead bad_cert_reads[] = {
7053 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067054 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:467055 };
7056
7057 // Attempt to fetch the URL with a good cert
7058 MockWrite good_data_writes[] = {
bncce36dca22015-04-21 22:11:237059 MockWrite(
7060 "CONNECT www.example.org:443 HTTP/1.1\r\n"
7061 "Host: www.example.org\r\n"
7062 "Proxy-Connection: keep-alive\r\n\r\n"),
7063 MockWrite(
7064 "GET / HTTP/1.1\r\n"
7065 "Host: www.example.org\r\n"
7066 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:467067 };
7068
7069 MockRead good_cert_reads[] = {
7070 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
7071 MockRead("HTTP/1.0 200 OK\r\n"),
7072 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7073 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067074 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:467075 };
7076
7077 StaticSocketDataProvider ssl_bad_certificate(
7078 bad_cert_reads, arraysize(bad_cert_reads),
7079 bad_cert_writes, arraysize(bad_cert_writes));
7080 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
7081 good_data_writes, arraysize(good_data_writes));
[email protected]8ddf8322012-02-23 18:08:067082 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
7083 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:467084
7085 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:077086 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7087 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
7088 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:467089
7090 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:077091 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7092 session_deps_.socket_factory->AddSocketDataProvider(&data);
7093 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:467094
[email protected]49639fa2011-12-20 23:22:417095 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:467096
[email protected]3fe8d2f82013-10-17 08:56:077097 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:467098 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417099 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2df19bb2010-08-25 20:13:467100
[email protected]49639fa2011-12-20 23:22:417101 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:467102 EXPECT_EQ(ERR_IO_PENDING, rv);
7103
7104 rv = callback.WaitForResult();
7105 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
7106
[email protected]49639fa2011-12-20 23:22:417107 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]2df19bb2010-08-25 20:13:467108 EXPECT_EQ(ERR_IO_PENDING, rv);
7109
7110 rv = callback.WaitForResult();
7111 EXPECT_EQ(OK, rv);
7112
7113 const HttpResponseInfo* response = trans->GetResponseInfo();
7114
[email protected]fe2255a2011-09-20 19:37:507115 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:467116 EXPECT_EQ(100, response->headers->GetContentLength());
7117}
7118
[email protected]23e482282013-06-14 16:08:027119TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:427120 HttpRequestInfo request;
7121 request.method = "GET";
bncce36dca22015-04-21 22:11:237122 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:437123 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
7124 "Chromium Ultra Awesome X Edition");
[email protected]1c773ea12009-04-28 19:58:427125
[email protected]3fe8d2f82013-10-17 08:56:077126 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277127 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417128 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277129
[email protected]1c773ea12009-04-28 19:58:427130 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237131 MockWrite(
7132 "GET / HTTP/1.1\r\n"
7133 "Host: www.example.org\r\n"
7134 "Connection: keep-alive\r\n"
7135 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427136 };
7137
7138 // Lastly, the server responds with the actual content.
7139 MockRead data_reads[] = {
7140 MockRead("HTTP/1.0 200 OK\r\n"),
7141 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7142 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067143 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427144 };
7145
[email protected]31a2bfe2010-02-09 08:03:397146 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7147 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077148 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427149
[email protected]49639fa2011-12-20 23:22:417150 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427151
[email protected]49639fa2011-12-20 23:22:417152 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427153 EXPECT_EQ(ERR_IO_PENDING, rv);
7154
7155 rv = callback.WaitForResult();
7156 EXPECT_EQ(OK, rv);
7157}
7158
[email protected]23e482282013-06-14 16:08:027159TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:297160 HttpRequestInfo request;
7161 request.method = "GET";
bncce36dca22015-04-21 22:11:237162 request.url = GURL("https://www.example.org/");
[email protected]da81f132010-08-18 23:39:297163 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
7164 "Chromium Ultra Awesome X Edition");
7165
[email protected]bb88e1d32013-05-03 23:11:077166 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]3fe8d2f82013-10-17 08:56:077167 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277168 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417169 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277170
[email protected]da81f132010-08-18 23:39:297171 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237172 MockWrite(
7173 "CONNECT www.example.org:443 HTTP/1.1\r\n"
7174 "Host: www.example.org\r\n"
7175 "Proxy-Connection: keep-alive\r\n"
7176 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]da81f132010-08-18 23:39:297177 };
7178 MockRead data_reads[] = {
7179 // Return an error, so the transaction stops here (this test isn't
7180 // interested in the rest).
7181 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
7182 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7183 MockRead("Proxy-Connection: close\r\n\r\n"),
7184 };
7185
7186 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7187 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077188 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:297189
[email protected]49639fa2011-12-20 23:22:417190 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:297191
[email protected]49639fa2011-12-20 23:22:417192 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]da81f132010-08-18 23:39:297193 EXPECT_EQ(ERR_IO_PENDING, rv);
7194
7195 rv = callback.WaitForResult();
7196 EXPECT_EQ(OK, rv);
7197}
7198
[email protected]23e482282013-06-14 16:08:027199TEST_P(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:427200 HttpRequestInfo request;
7201 request.method = "GET";
bncce36dca22015-04-21 22:11:237202 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427203 request.load_flags = 0;
[email protected]c10450102011-06-27 09:06:167204 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
7205 "http://the.previous.site.com/");
[email protected]1c773ea12009-04-28 19:58:427206
[email protected]3fe8d2f82013-10-17 08:56:077207 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277208 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417209 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277210
[email protected]1c773ea12009-04-28 19:58:427211 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237212 MockWrite(
7213 "GET / HTTP/1.1\r\n"
7214 "Host: www.example.org\r\n"
7215 "Connection: keep-alive\r\n"
7216 "Referer: http://the.previous.site.com/\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427217 };
7218
7219 // Lastly, the server responds with the actual content.
7220 MockRead data_reads[] = {
7221 MockRead("HTTP/1.0 200 OK\r\n"),
7222 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7223 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067224 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427225 };
7226
[email protected]31a2bfe2010-02-09 08:03:397227 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7228 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077229 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427230
[email protected]49639fa2011-12-20 23:22:417231 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427232
[email protected]49639fa2011-12-20 23:22:417233 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427234 EXPECT_EQ(ERR_IO_PENDING, rv);
7235
7236 rv = callback.WaitForResult();
7237 EXPECT_EQ(OK, rv);
7238}
7239
[email protected]23e482282013-06-14 16:08:027240TEST_P(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:427241 HttpRequestInfo request;
7242 request.method = "POST";
bncce36dca22015-04-21 22:11:237243 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427244
[email protected]3fe8d2f82013-10-17 08:56:077245 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277246 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417247 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277248
[email protected]1c773ea12009-04-28 19:58:427249 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237250 MockWrite(
7251 "POST / HTTP/1.1\r\n"
7252 "Host: www.example.org\r\n"
7253 "Connection: keep-alive\r\n"
7254 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427255 };
7256
7257 // Lastly, the server responds with the actual content.
7258 MockRead data_reads[] = {
7259 MockRead("HTTP/1.0 200 OK\r\n"),
7260 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7261 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067262 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427263 };
7264
[email protected]31a2bfe2010-02-09 08:03:397265 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7266 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077267 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427268
[email protected]49639fa2011-12-20 23:22:417269 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427270
[email protected]49639fa2011-12-20 23:22:417271 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427272 EXPECT_EQ(ERR_IO_PENDING, rv);
7273
7274 rv = callback.WaitForResult();
7275 EXPECT_EQ(OK, rv);
7276}
7277
[email protected]23e482282013-06-14 16:08:027278TEST_P(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:427279 HttpRequestInfo request;
7280 request.method = "PUT";
bncce36dca22015-04-21 22:11:237281 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427282
[email protected]3fe8d2f82013-10-17 08:56:077283 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277284 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417285 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277286
[email protected]1c773ea12009-04-28 19:58:427287 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237288 MockWrite(
7289 "PUT / HTTP/1.1\r\n"
7290 "Host: www.example.org\r\n"
7291 "Connection: keep-alive\r\n"
7292 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427293 };
7294
7295 // Lastly, the server responds with the actual content.
7296 MockRead data_reads[] = {
7297 MockRead("HTTP/1.0 200 OK\r\n"),
7298 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7299 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067300 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427301 };
7302
[email protected]31a2bfe2010-02-09 08:03:397303 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7304 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077305 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427306
[email protected]49639fa2011-12-20 23:22:417307 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427308
[email protected]49639fa2011-12-20 23:22:417309 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427310 EXPECT_EQ(ERR_IO_PENDING, rv);
7311
7312 rv = callback.WaitForResult();
7313 EXPECT_EQ(OK, rv);
7314}
7315
[email protected]23e482282013-06-14 16:08:027316TEST_P(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:427317 HttpRequestInfo request;
7318 request.method = "HEAD";
bncce36dca22015-04-21 22:11:237319 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427320
[email protected]3fe8d2f82013-10-17 08:56:077321 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277322 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417323 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277324
[email protected]1c773ea12009-04-28 19:58:427325 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237326 MockWrite(
7327 "HEAD / HTTP/1.1\r\n"
7328 "Host: www.example.org\r\n"
7329 "Connection: keep-alive\r\n"
7330 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427331 };
7332
7333 // Lastly, the server responds with the actual content.
7334 MockRead data_reads[] = {
7335 MockRead("HTTP/1.0 200 OK\r\n"),
7336 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7337 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067338 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427339 };
7340
[email protected]31a2bfe2010-02-09 08:03:397341 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7342 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077343 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427344
[email protected]49639fa2011-12-20 23:22:417345 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427346
[email protected]49639fa2011-12-20 23:22:417347 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427348 EXPECT_EQ(ERR_IO_PENDING, rv);
7349
7350 rv = callback.WaitForResult();
7351 EXPECT_EQ(OK, rv);
7352}
7353
[email protected]23e482282013-06-14 16:08:027354TEST_P(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:427355 HttpRequestInfo request;
7356 request.method = "GET";
bncce36dca22015-04-21 22:11:237357 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427358 request.load_flags = LOAD_BYPASS_CACHE;
7359
[email protected]3fe8d2f82013-10-17 08:56:077360 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277361 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417362 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277363
[email protected]1c773ea12009-04-28 19:58:427364 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237365 MockWrite(
7366 "GET / HTTP/1.1\r\n"
7367 "Host: www.example.org\r\n"
7368 "Connection: keep-alive\r\n"
7369 "Pragma: no-cache\r\n"
7370 "Cache-Control: no-cache\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427371 };
7372
7373 // Lastly, the server responds with the actual content.
7374 MockRead data_reads[] = {
7375 MockRead("HTTP/1.0 200 OK\r\n"),
7376 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7377 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067378 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427379 };
7380
[email protected]31a2bfe2010-02-09 08:03:397381 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7382 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077383 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427384
[email protected]49639fa2011-12-20 23:22:417385 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427386
[email protected]49639fa2011-12-20 23:22:417387 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427388 EXPECT_EQ(ERR_IO_PENDING, rv);
7389
7390 rv = callback.WaitForResult();
7391 EXPECT_EQ(OK, rv);
7392}
7393
[email protected]23e482282013-06-14 16:08:027394TEST_P(HttpNetworkTransactionTest,
[email protected]1c773ea12009-04-28 19:58:427395 BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:427396 HttpRequestInfo request;
7397 request.method = "GET";
bncce36dca22015-04-21 22:11:237398 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427399 request.load_flags = LOAD_VALIDATE_CACHE;
7400
[email protected]3fe8d2f82013-10-17 08:56:077401 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277402 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417403 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277404
[email protected]1c773ea12009-04-28 19:58:427405 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237406 MockWrite(
7407 "GET / HTTP/1.1\r\n"
7408 "Host: www.example.org\r\n"
7409 "Connection: keep-alive\r\n"
7410 "Cache-Control: max-age=0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427411 };
7412
7413 // Lastly, the server responds with the actual content.
7414 MockRead data_reads[] = {
7415 MockRead("HTTP/1.0 200 OK\r\n"),
7416 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7417 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067418 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427419 };
7420
[email protected]31a2bfe2010-02-09 08:03:397421 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7422 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077423 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427424
[email protected]49639fa2011-12-20 23:22:417425 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427426
[email protected]49639fa2011-12-20 23:22:417427 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427428 EXPECT_EQ(ERR_IO_PENDING, rv);
7429
7430 rv = callback.WaitForResult();
7431 EXPECT_EQ(OK, rv);
7432}
7433
[email protected]23e482282013-06-14 16:08:027434TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:427435 HttpRequestInfo request;
7436 request.method = "GET";
bncce36dca22015-04-21 22:11:237437 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:437438 request.extra_headers.SetHeader("FooHeader", "Bar");
[email protected]1c773ea12009-04-28 19:58:427439
[email protected]3fe8d2f82013-10-17 08:56:077440 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277441 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417442 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277443
[email protected]1c773ea12009-04-28 19:58:427444 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237445 MockWrite(
7446 "GET / HTTP/1.1\r\n"
7447 "Host: www.example.org\r\n"
7448 "Connection: keep-alive\r\n"
7449 "FooHeader: Bar\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427450 };
7451
7452 // Lastly, the server responds with the actual content.
7453 MockRead data_reads[] = {
7454 MockRead("HTTP/1.0 200 OK\r\n"),
7455 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7456 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067457 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427458 };
7459
[email protected]31a2bfe2010-02-09 08:03:397460 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7461 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077462 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427463
[email protected]49639fa2011-12-20 23:22:417464 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427465
[email protected]49639fa2011-12-20 23:22:417466 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427467 EXPECT_EQ(ERR_IO_PENDING, rv);
7468
7469 rv = callback.WaitForResult();
7470 EXPECT_EQ(OK, rv);
7471}
7472
[email protected]23e482282013-06-14 16:08:027473TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:477474 HttpRequestInfo request;
7475 request.method = "GET";
bncce36dca22015-04-21 22:11:237476 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:437477 request.extra_headers.SetHeader("referer", "www.foo.com");
7478 request.extra_headers.SetHeader("hEllo", "Kitty");
7479 request.extra_headers.SetHeader("FoO", "bar");
[email protected]270c6412010-03-29 22:02:477480
[email protected]3fe8d2f82013-10-17 08:56:077481 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277482 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417483 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277484
[email protected]270c6412010-03-29 22:02:477485 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237486 MockWrite(
7487 "GET / HTTP/1.1\r\n"
7488 "Host: www.example.org\r\n"
7489 "Connection: keep-alive\r\n"
7490 "referer: www.foo.com\r\n"
7491 "hEllo: Kitty\r\n"
7492 "FoO: bar\r\n\r\n"),
[email protected]270c6412010-03-29 22:02:477493 };
7494
7495 // Lastly, the server responds with the actual content.
7496 MockRead data_reads[] = {
7497 MockRead("HTTP/1.0 200 OK\r\n"),
7498 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7499 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067500 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:477501 };
7502
7503 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7504 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077505 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:477506
[email protected]49639fa2011-12-20 23:22:417507 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:477508
[email protected]49639fa2011-12-20 23:22:417509 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]270c6412010-03-29 22:02:477510 EXPECT_EQ(ERR_IO_PENDING, rv);
7511
7512 rv = callback.WaitForResult();
7513 EXPECT_EQ(OK, rv);
7514}
7515
[email protected]23e482282013-06-14 16:08:027516TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277517 HttpRequestInfo request;
7518 request.method = "GET";
bncce36dca22015-04-21 22:11:237519 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:277520 request.load_flags = 0;
7521
[email protected]bb88e1d32013-05-03 23:11:077522 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207523 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
vishal.b62985ca92015-04-17 08:45:517524 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077525 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:027526
[email protected]3fe8d2f82013-10-17 08:56:077527 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3cd17242009-06-23 02:59:027528 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417529 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3cd17242009-06-23 02:59:027530
[email protected]3cd17242009-06-23 02:59:027531 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
7532 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7533
7534 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237535 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
7536 MockWrite(
7537 "GET / HTTP/1.1\r\n"
7538 "Host: www.example.org\r\n"
7539 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:027540
7541 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:067542 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:027543 MockRead("HTTP/1.0 200 OK\r\n"),
7544 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7545 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067546 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:027547 };
7548
[email protected]31a2bfe2010-02-09 08:03:397549 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7550 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077551 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:027552
[email protected]49639fa2011-12-20 23:22:417553 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:027554
[email protected]49639fa2011-12-20 23:22:417555 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:027556 EXPECT_EQ(ERR_IO_PENDING, rv);
7557
7558 rv = callback.WaitForResult();
7559 EXPECT_EQ(OK, rv);
7560
7561 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507562 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:027563
[email protected]029c83b62013-01-24 05:28:207564 LoadTimingInfo load_timing_info;
7565 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7566 TestLoadTimingNotReusedWithPac(load_timing_info,
7567 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7568
[email protected]3cd17242009-06-23 02:59:027569 std::string response_text;
7570 rv = ReadTransaction(trans.get(), &response_text);
7571 EXPECT_EQ(OK, rv);
7572 EXPECT_EQ("Payload", response_text);
7573}
7574
[email protected]23e482282013-06-14 16:08:027575TEST_P(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277576 HttpRequestInfo request;
7577 request.method = "GET";
bncce36dca22015-04-21 22:11:237578 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:277579 request.load_flags = 0;
7580
[email protected]bb88e1d32013-05-03 23:11:077581 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207582 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
vishal.b62985ca92015-04-17 08:45:517583 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077584 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:027585
[email protected]3fe8d2f82013-10-17 08:56:077586 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3cd17242009-06-23 02:59:027587 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417588 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3cd17242009-06-23 02:59:027589
[email protected]3cd17242009-06-23 02:59:027590 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
7591 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7592
7593 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237594 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
7595 arraysize(write_buffer)),
7596 MockWrite(
7597 "GET / HTTP/1.1\r\n"
7598 "Host: www.example.org\r\n"
7599 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:027600
7601 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:017602 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
7603 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:357604 MockRead("HTTP/1.0 200 OK\r\n"),
7605 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7606 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067607 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:357608 };
7609
[email protected]31a2bfe2010-02-09 08:03:397610 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7611 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077612 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:357613
[email protected]8ddf8322012-02-23 18:08:067614 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077615 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:357616
[email protected]49639fa2011-12-20 23:22:417617 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:357618
[email protected]49639fa2011-12-20 23:22:417619 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:357620 EXPECT_EQ(ERR_IO_PENDING, rv);
7621
7622 rv = callback.WaitForResult();
7623 EXPECT_EQ(OK, rv);
7624
[email protected]029c83b62013-01-24 05:28:207625 LoadTimingInfo load_timing_info;
7626 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7627 TestLoadTimingNotReusedWithPac(load_timing_info,
7628 CONNECT_TIMING_HAS_SSL_TIMES);
7629
[email protected]e0c27be2009-07-15 13:09:357630 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507631 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:357632
7633 std::string response_text;
7634 rv = ReadTransaction(trans.get(), &response_text);
7635 EXPECT_EQ(OK, rv);
7636 EXPECT_EQ("Payload", response_text);
7637}
7638
[email protected]23e482282013-06-14 16:08:027639TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:207640 HttpRequestInfo request;
7641 request.method = "GET";
bncce36dca22015-04-21 22:11:237642 request.url = GURL("http://www.example.org/");
[email protected]029c83b62013-01-24 05:28:207643 request.load_flags = 0;
7644
[email protected]bb88e1d32013-05-03 23:11:077645 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207646 ProxyService::CreateFixed("socks4://myproxy:1080"));
vishal.b62985ca92015-04-17 08:45:517647 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077648 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:207649
[email protected]3fe8d2f82013-10-17 08:56:077650 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:207651 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417652 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:207653
7654 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
7655 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7656
7657 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237658 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
7659 MockWrite(
7660 "GET / HTTP/1.1\r\n"
7661 "Host: www.example.org\r\n"
7662 "Connection: keep-alive\r\n\r\n")};
[email protected]029c83b62013-01-24 05:28:207663
7664 MockRead data_reads[] = {
7665 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
7666 MockRead("HTTP/1.0 200 OK\r\n"),
7667 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7668 MockRead("Payload"),
7669 MockRead(SYNCHRONOUS, OK)
7670 };
7671
7672 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7673 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077674 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:207675
7676 TestCompletionCallback callback;
7677
7678 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7679 EXPECT_EQ(ERR_IO_PENDING, rv);
7680
7681 rv = callback.WaitForResult();
7682 EXPECT_EQ(OK, rv);
7683
7684 const HttpResponseInfo* response = trans->GetResponseInfo();
7685 ASSERT_TRUE(response != NULL);
7686
7687 LoadTimingInfo load_timing_info;
7688 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7689 TestLoadTimingNotReused(load_timing_info,
7690 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7691
7692 std::string response_text;
7693 rv = ReadTransaction(trans.get(), &response_text);
7694 EXPECT_EQ(OK, rv);
7695 EXPECT_EQ("Payload", response_text);
7696}
7697
[email protected]23e482282013-06-14 16:08:027698TEST_P(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277699 HttpRequestInfo request;
7700 request.method = "GET";
bncce36dca22015-04-21 22:11:237701 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:277702 request.load_flags = 0;
7703
[email protected]bb88e1d32013-05-03 23:11:077704 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207705 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
vishal.b62985ca92015-04-17 08:45:517706 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077707 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:357708
[email protected]3fe8d2f82013-10-17 08:56:077709 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e0c27be2009-07-15 13:09:357710 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417711 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]e0c27be2009-07-15 13:09:357712
[email protected]e0c27be2009-07-15 13:09:357713 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
7714 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:377715 const char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:237716 0x05, // Version
7717 0x01, // Command (CONNECT)
7718 0x00, // Reserved.
7719 0x03, // Address type (DOMAINNAME).
7720 0x0F, // Length of domain (15)
7721 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
7722 '.', 'o', 'r', 'g', 0x00, 0x50, // 16-bit port (80)
[email protected]f209dba2009-12-18 00:24:377723 };
[email protected]e0c27be2009-07-15 13:09:357724 const char kSOCKS5OkResponse[] =
7725 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
7726
7727 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237728 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
7729 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
7730 MockWrite(
7731 "GET / HTTP/1.1\r\n"
7732 "Host: www.example.org\r\n"
7733 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:357734
7735 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:017736 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
7737 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:357738 MockRead("HTTP/1.0 200 OK\r\n"),
7739 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7740 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067741 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:357742 };
7743
[email protected]31a2bfe2010-02-09 08:03:397744 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7745 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077746 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:357747
[email protected]49639fa2011-12-20 23:22:417748 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:357749
[email protected]49639fa2011-12-20 23:22:417750 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:357751 EXPECT_EQ(ERR_IO_PENDING, rv);
7752
7753 rv = callback.WaitForResult();
7754 EXPECT_EQ(OK, rv);
7755
7756 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507757 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:357758
[email protected]029c83b62013-01-24 05:28:207759 LoadTimingInfo load_timing_info;
7760 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7761 TestLoadTimingNotReusedWithPac(load_timing_info,
7762 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7763
[email protected]e0c27be2009-07-15 13:09:357764 std::string response_text;
7765 rv = ReadTransaction(trans.get(), &response_text);
7766 EXPECT_EQ(OK, rv);
7767 EXPECT_EQ("Payload", response_text);
7768}
7769
[email protected]23e482282013-06-14 16:08:027770TEST_P(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277771 HttpRequestInfo request;
7772 request.method = "GET";
bncce36dca22015-04-21 22:11:237773 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:277774 request.load_flags = 0;
7775
[email protected]bb88e1d32013-05-03 23:11:077776 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207777 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
vishal.b62985ca92015-04-17 08:45:517778 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077779 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:357780
[email protected]3fe8d2f82013-10-17 08:56:077781 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e0c27be2009-07-15 13:09:357782 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417783 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]e0c27be2009-07-15 13:09:357784
[email protected]e0c27be2009-07-15 13:09:357785 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
7786 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:377787 const unsigned char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:237788 0x05, // Version
7789 0x01, // Command (CONNECT)
7790 0x00, // Reserved.
7791 0x03, // Address type (DOMAINNAME).
7792 0x0F, // Length of domain (15)
7793 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
7794 '.', 'o', 'r', 'g', 0x01, 0xBB, // 16-bit port (443)
[email protected]f209dba2009-12-18 00:24:377795 };
7796
[email protected]e0c27be2009-07-15 13:09:357797 const char kSOCKS5OkResponse[] =
7798 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
7799
7800 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237801 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
7802 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
7803 arraysize(kSOCKS5OkRequest)),
7804 MockWrite(
7805 "GET / HTTP/1.1\r\n"
7806 "Host: www.example.org\r\n"
7807 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:357808
7809 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:017810 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
7811 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:027812 MockRead("HTTP/1.0 200 OK\r\n"),
7813 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7814 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067815 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:027816 };
7817
[email protected]31a2bfe2010-02-09 08:03:397818 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7819 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077820 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:027821
[email protected]8ddf8322012-02-23 18:08:067822 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077823 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:027824
[email protected]49639fa2011-12-20 23:22:417825 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:027826
[email protected]49639fa2011-12-20 23:22:417827 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:027828 EXPECT_EQ(ERR_IO_PENDING, rv);
7829
7830 rv = callback.WaitForResult();
7831 EXPECT_EQ(OK, rv);
7832
7833 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507834 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:027835
[email protected]029c83b62013-01-24 05:28:207836 LoadTimingInfo load_timing_info;
7837 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7838 TestLoadTimingNotReusedWithPac(load_timing_info,
7839 CONNECT_TIMING_HAS_SSL_TIMES);
7840
[email protected]3cd17242009-06-23 02:59:027841 std::string response_text;
7842 rv = ReadTransaction(trans.get(), &response_text);
7843 EXPECT_EQ(OK, rv);
7844 EXPECT_EQ("Payload", response_text);
7845}
7846
[email protected]448d4ca52012-03-04 04:12:237847namespace {
7848
[email protected]04e5be32009-06-26 20:00:317849// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:067850
7851struct GroupNameTest {
7852 std::string proxy_server;
7853 std::string url;
7854 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:187855 bool ssl;
[email protected]2d731a32010-04-29 01:04:067856};
7857
7858scoped_refptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]8a0fc822013-06-27 20:52:437859 NextProto next_proto,
[email protected]bb88e1d32013-05-03 23:11:077860 SpdySessionDependencies* session_deps_) {
7861 scoped_refptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:067862
[email protected]30d4c022013-07-18 22:58:167863 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:537864 session->http_server_properties();
bnccacc0992015-03-20 20:22:227865 AlternativeService alternative_service(
bnc4988e432015-03-31 03:06:257866 AlternateProtocolFromNextProto(next_proto), "", 443);
bnccacc0992015-03-20 20:22:227867 http_server_properties->SetAlternativeService(
7868 HostPortPair("host.with.alternate", 80), alternative_service, 1.0);
[email protected]2d731a32010-04-29 01:04:067869
7870 return session;
7871}
7872
7873int GroupNameTransactionHelper(
7874 const std::string& url,
7875 const scoped_refptr<HttpNetworkSession>& session) {
[email protected]2d731a32010-04-29 01:04:067876 HttpRequestInfo request;
7877 request.method = "GET";
7878 request.url = GURL(url);
7879 request.load_flags = 0;
7880
[email protected]262eec82013-03-19 21:01:367881 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507882 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277883
[email protected]49639fa2011-12-20 23:22:417884 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:067885
7886 // We do not complete this request, the dtor will clean the transaction up.
[email protected]49639fa2011-12-20 23:22:417887 return trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d731a32010-04-29 01:04:067888}
7889
[email protected]448d4ca52012-03-04 04:12:237890} // namespace
7891
[email protected]23e482282013-06-14 16:08:027892TEST_P(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:067893 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:237894 {
7895 "", // unused
7896 "http://www.example.org/direct",
7897 "www.example.org:80",
7898 false,
7899 },
7900 {
7901 "", // unused
7902 "http://[2001:1418:13:1::25]/direct",
7903 "[2001:1418:13:1::25]:80",
7904 false,
7905 },
[email protected]04e5be32009-06-26 20:00:317906
bncce36dca22015-04-21 22:11:237907 // SSL Tests
7908 {
7909 "", // unused
7910 "https://www.example.org/direct_ssl",
7911 "ssl/www.example.org:443",
7912 true,
7913 },
7914 {
7915 "", // unused
7916 "https://[2001:1418:13:1::25]/direct",
7917 "ssl/[2001:1418:13:1::25]:443",
7918 true,
7919 },
7920 {
7921 "", // unused
7922 "http://host.with.alternate/direct",
7923 "ssl/host.with.alternate:443",
7924 true,
7925 },
[email protected]2d731a32010-04-29 01:04:067926 };
[email protected]2ff8b312010-04-26 22:20:547927
[email protected]d7599122014-05-24 03:37:237928 session_deps_.use_alternate_protocols = true;
[email protected]2d731a32010-04-29 01:04:067929
viettrungluue4a8b882014-10-16 06:17:387930 for (size_t i = 0; i < arraysize(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:077931 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:027932 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:067933 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:437934 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:067935
7936 HttpNetworkSessionPeer peer(session);
[email protected]ab739042011-04-07 15:22:287937 CaptureGroupNameTransportSocketPool* transport_conn_pool =
7938 new CaptureGroupNameTransportSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:137939 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347940 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]831e4a32013-11-14 02:14:447941 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
7942 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:027943 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
7944 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
dchenge3d1ddc2014-10-15 19:30:517945 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]2d731a32010-04-29 01:04:067946
7947 EXPECT_EQ(ERR_IO_PENDING,
7948 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:187949 if (tests[i].ssl)
7950 EXPECT_EQ(tests[i].expected_group_name,
7951 ssl_conn_pool->last_group_name_received());
7952 else
7953 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:287954 transport_conn_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:067955 }
7956
[email protected]2d731a32010-04-29 01:04:067957}
7958
[email protected]23e482282013-06-14 16:08:027959TEST_P(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:067960 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:237961 {
7962 "http_proxy",
7963 "http://www.example.org/http_proxy_normal",
7964 "www.example.org:80",
7965 false,
7966 },
[email protected]2d731a32010-04-29 01:04:067967
bncce36dca22015-04-21 22:11:237968 // SSL Tests
7969 {
7970 "http_proxy",
7971 "https://www.example.org/http_connect_ssl",
7972 "ssl/www.example.org:443",
7973 true,
7974 },
[email protected]af3490e2010-10-16 21:02:297975
bncce36dca22015-04-21 22:11:237976 {
7977 "http_proxy",
7978 "http://host.with.alternate/direct",
7979 "ssl/host.with.alternate:443",
7980 true,
7981 },
[email protected]45499252013-01-23 17:12:567982
bncce36dca22015-04-21 22:11:237983 {
7984 "http_proxy",
7985 "ftp://ftp.google.com/http_proxy_normal",
7986 "ftp/ftp.google.com:21",
7987 false,
7988 },
[email protected]2d731a32010-04-29 01:04:067989 };
7990
[email protected]d7599122014-05-24 03:37:237991 session_deps_.use_alternate_protocols = true;
[email protected]2d731a32010-04-29 01:04:067992
viettrungluue4a8b882014-10-16 06:17:387993 for (size_t i = 0; i < arraysize(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:077994 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:027995 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:067996 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:437997 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:067998
7999 HttpNetworkSessionPeer peer(session);
8000
[email protected]e60e47a2010-07-14 03:37:188001 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:138002 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:348003 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:138004 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:348005 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:028006
[email protected]831e4a32013-11-14 02:14:448007 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
8008 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:028009 mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool);
8010 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
dchenge3d1ddc2014-10-15 19:30:518011 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]2d731a32010-04-29 01:04:068012
8013 EXPECT_EQ(ERR_IO_PENDING,
8014 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:188015 if (tests[i].ssl)
8016 EXPECT_EQ(tests[i].expected_group_name,
8017 ssl_conn_pool->last_group_name_received());
8018 else
8019 EXPECT_EQ(tests[i].expected_group_name,
8020 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:068021 }
[email protected]2d731a32010-04-29 01:04:068022}
8023
[email protected]23e482282013-06-14 16:08:028024TEST_P(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:068025 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:238026 {
8027 "socks4://socks_proxy:1080",
8028 "http://www.example.org/socks4_direct",
8029 "socks4/www.example.org:80",
8030 false,
8031 },
8032 {
8033 "socks5://socks_proxy:1080",
8034 "http://www.example.org/socks5_direct",
8035 "socks5/www.example.org:80",
8036 false,
8037 },
[email protected]2d731a32010-04-29 01:04:068038
bncce36dca22015-04-21 22:11:238039 // SSL Tests
8040 {
8041 "socks4://socks_proxy:1080",
8042 "https://www.example.org/socks4_ssl",
8043 "socks4/ssl/www.example.org:443",
8044 true,
8045 },
8046 {
8047 "socks5://socks_proxy:1080",
8048 "https://www.example.org/socks5_ssl",
8049 "socks5/ssl/www.example.org:443",
8050 true,
8051 },
[email protected]af3490e2010-10-16 21:02:298052
bncce36dca22015-04-21 22:11:238053 {
8054 "socks4://socks_proxy:1080",
8055 "http://host.with.alternate/direct",
8056 "socks4/ssl/host.with.alternate:443",
8057 true,
8058 },
[email protected]04e5be32009-06-26 20:00:318059 };
8060
[email protected]d7599122014-05-24 03:37:238061 session_deps_.use_alternate_protocols = true;
[email protected]2ff8b312010-04-26 22:20:548062
viettrungluue4a8b882014-10-16 06:17:388063 for (size_t i = 0; i < arraysize(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:078064 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:028065 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:068066 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:438067 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]8b114dd72011-03-25 05:33:028068
[email protected]2d731a32010-04-29 01:04:068069 HttpNetworkSessionPeer peer(session);
[email protected]04e5be32009-06-26 20:00:318070
[email protected]e60e47a2010-07-14 03:37:188071 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:138072 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:348073 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:138074 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:348075 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:028076
[email protected]831e4a32013-11-14 02:14:448077 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
8078 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:028079 mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_conn_pool);
8080 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
dchenge3d1ddc2014-10-15 19:30:518081 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]04e5be32009-06-26 20:00:318082
[email protected]262eec82013-03-19 21:01:368083 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508084 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]04e5be32009-06-26 20:00:318085
[email protected]2d731a32010-04-29 01:04:068086 EXPECT_EQ(ERR_IO_PENDING,
8087 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:188088 if (tests[i].ssl)
8089 EXPECT_EQ(tests[i].expected_group_name,
8090 ssl_conn_pool->last_group_name_received());
8091 else
8092 EXPECT_EQ(tests[i].expected_group_name,
8093 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:318094 }
8095}
8096
[email protected]23e482282013-06-14 16:08:028097TEST_P(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:278098 HttpRequestInfo request;
8099 request.method = "GET";
bncce36dca22015-04-21 22:11:238100 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278101
[email protected]bb88e1d32013-05-03 23:11:078102 session_deps_.proxy_service.reset(
[email protected]81cdfcd2010-10-16 00:49:008103 ProxyService::CreateFixed("myproxy:70;foobar:80"));
[email protected]b59ff372009-07-15 22:04:328104
[email protected]69719062010-01-05 20:09:218105 // This simulates failure resolving all hostnames; that means we will fail
8106 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:078107 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:328108
[email protected]3fe8d2f82013-10-17 08:56:078109 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]9172a982009-06-06 00:30:258110 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418111 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]9172a982009-06-06 00:30:258112
[email protected]49639fa2011-12-20 23:22:418113 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:258114
[email protected]49639fa2011-12-20 23:22:418115 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9172a982009-06-06 00:30:258116 EXPECT_EQ(ERR_IO_PENDING, rv);
8117
[email protected]9172a982009-06-06 00:30:258118 rv = callback.WaitForResult();
[email protected]f7fccee2010-09-16 20:53:018119 EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
[email protected]9172a982009-06-06 00:30:258120}
8121
[email protected]685af592010-05-11 19:31:248122// Base test to make sure that when the load flags for a request specify to
8123// bypass the cache, the DNS cache is not used.
[email protected]23e482282013-06-14 16:08:028124void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
[email protected]bb88e1d32013-05-03 23:11:078125 int load_flags) {
[email protected]cb9bf6ca2011-01-28 13:15:278126 // Issue a request, asking to bypass the cache(s).
8127 HttpRequestInfo request;
8128 request.method = "GET";
8129 request.load_flags = load_flags;
bncce36dca22015-04-21 22:11:238130 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278131
[email protected]a2c2fb92009-07-18 07:31:048132 // Select a host resolver that does caching.
[email protected]bb88e1d32013-05-03 23:11:078133 session_deps_.host_resolver.reset(new MockCachingHostResolver);
[email protected]b59ff372009-07-15 22:04:328134
[email protected]3fe8d2f82013-10-17 08:56:078135 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8136 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418137 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3b9cca42009-06-16 01:08:288138
bncce36dca22015-04-21 22:11:238139 // Warm up the host cache so it has an entry for "www.example.org".
[email protected]3b9cca42009-06-16 01:08:288140 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:298141 TestCompletionCallback callback;
[email protected]bb88e1d32013-05-03 23:11:078142 int rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:238143 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
8144 DEFAULT_PRIORITY, &addrlist, callback.callback(), NULL, BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:478145 EXPECT_EQ(ERR_IO_PENDING, rv);
8146 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:288147 EXPECT_EQ(OK, rv);
8148
8149 // Verify that it was added to host cache, by doing a subsequent async lookup
8150 // and confirming it completes synchronously.
[email protected]bb88e1d32013-05-03 23:11:078151 rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:238152 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
8153 DEFAULT_PRIORITY, &addrlist, callback.callback(), NULL, BoundNetLog());
[email protected]b59ff372009-07-15 22:04:328154 ASSERT_EQ(OK, rv);
[email protected]3b9cca42009-06-16 01:08:288155
bncce36dca22015-04-21 22:11:238156 // Inject a failure the next time that "www.example.org" is resolved. This way
[email protected]3b9cca42009-06-16 01:08:288157 // we can tell if the next lookup hit the cache, or the "network".
8158 // (cache --> success, "network" --> failure).
bncce36dca22015-04-21 22:11:238159 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.example.org");
[email protected]3b9cca42009-06-16 01:08:288160
8161 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
8162 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:068163 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
[email protected]31a2bfe2010-02-09 08:03:398164 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078165 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:288166
[email protected]3b9cca42009-06-16 01:08:288167 // Run the request.
[email protected]49639fa2011-12-20 23:22:418168 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3b9cca42009-06-16 01:08:288169 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:418170 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:288171
8172 // If we bypassed the cache, we would have gotten a failure while resolving
bncce36dca22015-04-21 22:11:238173 // "www.example.org".
[email protected]3b9cca42009-06-16 01:08:288174 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
8175}
8176
[email protected]685af592010-05-11 19:31:248177// There are multiple load flags that should trigger the host cache bypass.
8178// Test each in isolation:
[email protected]23e482282013-06-14 16:08:028179TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
[email protected]685af592010-05-11 19:31:248180 BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
8181}
8182
[email protected]23e482282013-06-14 16:08:028183TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
[email protected]685af592010-05-11 19:31:248184 BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
8185}
8186
[email protected]23e482282013-06-14 16:08:028187TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
[email protected]685af592010-05-11 19:31:248188 BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
8189}
8190
[email protected]0877e3d2009-10-17 22:29:578191// Make sure we can handle an error when writing the request.
[email protected]23e482282013-06-14 16:08:028192TEST_P(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:578193 HttpRequestInfo request;
8194 request.method = "GET";
8195 request.url = GURL("http://www.foo.com/");
8196 request.load_flags = 0;
8197
8198 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:068199 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:578200 };
[email protected]31a2bfe2010-02-09 08:03:398201 StaticSocketDataProvider data(NULL, 0,
8202 write_failure, arraysize(write_failure));
[email protected]bb88e1d32013-05-03 23:11:078203 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3fe8d2f82013-10-17 08:56:078204 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578205
[email protected]49639fa2011-12-20 23:22:418206 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:578207
8208 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418209 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:578210
[email protected]49639fa2011-12-20 23:22:418211 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578212 EXPECT_EQ(ERR_IO_PENDING, rv);
8213
8214 rv = callback.WaitForResult();
8215 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
8216}
8217
8218// Check that a connection closed after the start of the headers finishes ok.
[email protected]23e482282013-06-14 16:08:028219TEST_P(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:578220 HttpRequestInfo request;
8221 request.method = "GET";
8222 request.url = GURL("http://www.foo.com/");
8223 request.load_flags = 0;
8224
8225 MockRead data_reads[] = {
8226 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:068227 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:578228 };
8229
[email protected]31a2bfe2010-02-09 08:03:398230 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078231 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3fe8d2f82013-10-17 08:56:078232 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578233
[email protected]49639fa2011-12-20 23:22:418234 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:578235
8236 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418237 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:578238
[email protected]49639fa2011-12-20 23:22:418239 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578240 EXPECT_EQ(ERR_IO_PENDING, rv);
8241
8242 rv = callback.WaitForResult();
8243 EXPECT_EQ(OK, rv);
8244
8245 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508246 ASSERT_TRUE(response != NULL);
[email protected]0877e3d2009-10-17 22:29:578247
[email protected]90499482013-06-01 00:39:508248 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]0877e3d2009-10-17 22:29:578249 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
8250
8251 std::string response_data;
8252 rv = ReadTransaction(trans.get(), &response_data);
8253 EXPECT_EQ(OK, rv);
8254 EXPECT_EQ("", response_data);
8255}
8256
8257// Make sure that a dropped connection while draining the body for auth
8258// restart does the right thing.
[email protected]23e482282013-06-14 16:08:028259TEST_P(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:578260 HttpRequestInfo request;
8261 request.method = "GET";
bncce36dca22015-04-21 22:11:238262 request.url = GURL("http://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:578263 request.load_flags = 0;
8264
8265 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238266 MockWrite(
8267 "GET / HTTP/1.1\r\n"
8268 "Host: www.example.org\r\n"
8269 "Connection: keep-alive\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:578270 };
8271
8272 MockRead data_reads1[] = {
8273 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
8274 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8275 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8276 MockRead("Content-Length: 14\r\n\r\n"),
8277 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:068278 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:578279 };
8280
[email protected]31a2bfe2010-02-09 08:03:398281 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8282 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:078283 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:578284
8285 // After calling trans->RestartWithAuth(), this is the request we should
8286 // be issuing -- the final header line contains the credentials.
8287 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238288 MockWrite(
8289 "GET / HTTP/1.1\r\n"
8290 "Host: www.example.org\r\n"
8291 "Connection: keep-alive\r\n"
8292 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:578293 };
8294
8295 // Lastly, the server responds with the actual content.
8296 MockRead data_reads2[] = {
8297 MockRead("HTTP/1.1 200 OK\r\n"),
8298 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8299 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068300 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:578301 };
8302
[email protected]31a2bfe2010-02-09 08:03:398303 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8304 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:078305 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3fe8d2f82013-10-17 08:56:078306 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578307
[email protected]49639fa2011-12-20 23:22:418308 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:578309
[email protected]262eec82013-03-19 21:01:368310 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508311 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:508312
[email protected]49639fa2011-12-20 23:22:418313 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578314 EXPECT_EQ(ERR_IO_PENDING, rv);
8315
8316 rv = callback1.WaitForResult();
8317 EXPECT_EQ(OK, rv);
8318
8319 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508320 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048321 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:578322
[email protected]49639fa2011-12-20 23:22:418323 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:578324
[email protected]49639fa2011-12-20 23:22:418325 rv = trans->RestartWithAuth(
8326 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]0877e3d2009-10-17 22:29:578327 EXPECT_EQ(ERR_IO_PENDING, rv);
8328
8329 rv = callback2.WaitForResult();
8330 EXPECT_EQ(OK, rv);
8331
8332 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508333 ASSERT_TRUE(response != NULL);
[email protected]0877e3d2009-10-17 22:29:578334 EXPECT_TRUE(response->auth_challenge.get() == NULL);
8335 EXPECT_EQ(100, response->headers->GetContentLength());
8336}
8337
8338// Test HTTPS connections going through a proxy that sends extra data.
[email protected]23e482282013-06-14 16:08:028339TEST_P(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
[email protected]bb88e1d32013-05-03 23:11:078340 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]0877e3d2009-10-17 22:29:578341
8342 HttpRequestInfo request;
8343 request.method = "GET";
bncce36dca22015-04-21 22:11:238344 request.url = GURL("https://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:578345 request.load_flags = 0;
8346
8347 MockRead proxy_reads[] = {
8348 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:068349 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:578350 };
8351
[email protected]31a2bfe2010-02-09 08:03:398352 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
[email protected]8ddf8322012-02-23 18:08:068353 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:578354
[email protected]bb88e1d32013-05-03 23:11:078355 session_deps_.socket_factory->AddSocketDataProvider(&data);
8356 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:578357
[email protected]49639fa2011-12-20 23:22:418358 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:578359
[email protected]bb88e1d32013-05-03 23:11:078360 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:578361
[email protected]3fe8d2f82013-10-17 08:56:078362 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578363 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418364 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:578365
[email protected]49639fa2011-12-20 23:22:418366 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578367 EXPECT_EQ(ERR_IO_PENDING, rv);
8368
8369 rv = callback.WaitForResult();
8370 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
8371}
8372
[email protected]23e482282013-06-14 16:08:028373TEST_P(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:468374 HttpRequestInfo request;
8375 request.method = "GET";
bncce36dca22015-04-21 22:11:238376 request.url = GURL("http://www.example.org/");
[email protected]9492e4a2010-02-24 00:58:468377 request.load_flags = 0;
8378
[email protected]3fe8d2f82013-10-17 08:56:078379 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:278380 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418381 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278382
[email protected]e22e1362009-11-23 21:31:128383 MockRead data_reads[] = {
8384 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068385 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:128386 };
[email protected]9492e4a2010-02-24 00:58:468387
8388 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078389 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:468390
[email protected]49639fa2011-12-20 23:22:418391 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:468392
[email protected]49639fa2011-12-20 23:22:418393 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9492e4a2010-02-24 00:58:468394 EXPECT_EQ(ERR_IO_PENDING, rv);
8395
8396 EXPECT_EQ(OK, callback.WaitForResult());
8397
8398 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508399 ASSERT_TRUE(response != NULL);
[email protected]9492e4a2010-02-24 00:58:468400
[email protected]90499482013-06-01 00:39:508401 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]9492e4a2010-02-24 00:58:468402 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
8403
8404 std::string response_data;
8405 rv = ReadTransaction(trans.get(), &response_data);
[email protected]5543cbb2012-04-20 16:35:238406 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
[email protected]e22e1362009-11-23 21:31:128407}
8408
[email protected]23e482282013-06-14 16:08:028409TEST_P(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:158410 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:528411 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
[email protected]95d88ffe2010-02-04 21:25:338412 const uint64 kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:218413 UploadFileElementReader::ScopedOverridingContentLengthForTests
8414 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:338415
[email protected]b2d26cfd2012-12-11 10:36:068416 ScopedVector<UploadElementReader> element_readers;
8417 element_readers.push_back(
skyostil4891b25b2015-06-11 11:43:458418 new UploadFileElementReader(base::ThreadTaskRunnerHandle::Get().get(),
8419 temp_file_path, 0, kuint64max, base::Time()));
mmenkecbc2b712014-10-09 20:29:078420 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:278421
8422 HttpRequestInfo request;
8423 request.method = "POST";
bncce36dca22015-04-21 22:11:238424 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:278425 request.upload_data_stream = &upload_data_stream;
8426 request.load_flags = 0;
8427
[email protected]3fe8d2f82013-10-17 08:56:078428 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]329b68b2012-11-14 17:54:278429 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418430 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]95d88ffe2010-02-04 21:25:338431
8432 MockRead data_reads[] = {
8433 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
8434 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068435 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:338436 };
[email protected]31a2bfe2010-02-09 08:03:398437 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078438 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:338439
[email protected]49639fa2011-12-20 23:22:418440 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:338441
[email protected]49639fa2011-12-20 23:22:418442 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]95d88ffe2010-02-04 21:25:338443 EXPECT_EQ(ERR_IO_PENDING, rv);
8444
8445 rv = callback.WaitForResult();
8446 EXPECT_EQ(OK, rv);
8447
8448 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508449 ASSERT_TRUE(response != NULL);
[email protected]95d88ffe2010-02-04 21:25:338450
[email protected]90499482013-06-01 00:39:508451 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]95d88ffe2010-02-04 21:25:338452 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
8453
8454 std::string response_data;
8455 rv = ReadTransaction(trans.get(), &response_data);
8456 EXPECT_EQ(OK, rv);
8457 EXPECT_EQ("hello world", response_data);
8458
[email protected]dd3aa792013-07-16 19:10:238459 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:338460}
8461
[email protected]23e482282013-06-14 16:08:028462TEST_P(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:158463 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:528464 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:368465 std::string temp_file_content("Unreadable file.");
[email protected]e5c2a22e2014-03-06 20:42:308466 ASSERT_TRUE(base::WriteFile(temp_file, temp_file_content.c_str(),
[email protected]6624b4622010-03-29 19:58:368467 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:118468 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:368469
[email protected]b2d26cfd2012-12-11 10:36:068470 ScopedVector<UploadElementReader> element_readers;
8471 element_readers.push_back(
skyostil4891b25b2015-06-11 11:43:458472 new UploadFileElementReader(base::ThreadTaskRunnerHandle::Get().get(),
8473 temp_file, 0, kuint64max, base::Time()));
mmenkecbc2b712014-10-09 20:29:078474 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:278475
8476 HttpRequestInfo request;
8477 request.method = "POST";
bncce36dca22015-04-21 22:11:238478 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:278479 request.upload_data_stream = &upload_data_stream;
8480 request.load_flags = 0;
8481
[email protected]999dd8c2013-11-12 06:45:548482 // If we try to upload an unreadable file, the transaction should fail.
[email protected]3fe8d2f82013-10-17 08:56:078483 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]329b68b2012-11-14 17:54:278484 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418485 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]6624b4622010-03-29 19:58:368486
[email protected]999dd8c2013-11-12 06:45:548487 StaticSocketDataProvider data(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078488 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:368489
[email protected]49639fa2011-12-20 23:22:418490 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:368491
[email protected]49639fa2011-12-20 23:22:418492 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]6624b4622010-03-29 19:58:368493 EXPECT_EQ(ERR_IO_PENDING, rv);
8494
8495 rv = callback.WaitForResult();
[email protected]999dd8c2013-11-12 06:45:548496 EXPECT_EQ(ERR_ACCESS_DENIED, rv);
[email protected]6624b4622010-03-29 19:58:368497
[email protected]dd3aa792013-07-16 19:10:238498 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:368499}
8500
[email protected]02cad5d2013-10-02 08:14:038501TEST_P(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
8502 class FakeUploadElementReader : public UploadElementReader {
8503 public:
8504 FakeUploadElementReader() {}
dchengb03027d2014-10-21 12:00:208505 ~FakeUploadElementReader() override {}
[email protected]02cad5d2013-10-02 08:14:038506
8507 const CompletionCallback& callback() const { return callback_; }
8508
8509 // UploadElementReader overrides:
dchengb03027d2014-10-21 12:00:208510 int Init(const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:038511 callback_ = callback;
8512 return ERR_IO_PENDING;
8513 }
dchengb03027d2014-10-21 12:00:208514 uint64 GetContentLength() const override { return 0; }
8515 uint64 BytesRemaining() const override { return 0; }
8516 int Read(IOBuffer* buf,
8517 int buf_length,
8518 const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:038519 return ERR_FAILED;
8520 }
8521
8522 private:
8523 CompletionCallback callback_;
8524 };
8525
8526 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
8527 ScopedVector<UploadElementReader> element_readers;
8528 element_readers.push_back(fake_reader);
mmenkecbc2b712014-10-09 20:29:078529 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02cad5d2013-10-02 08:14:038530
8531 HttpRequestInfo request;
8532 request.method = "POST";
bncce36dca22015-04-21 22:11:238533 request.url = GURL("http://www.example.org/upload");
[email protected]02cad5d2013-10-02 08:14:038534 request.upload_data_stream = &upload_data_stream;
8535 request.load_flags = 0;
8536
[email protected]3fe8d2f82013-10-17 08:56:078537 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02cad5d2013-10-02 08:14:038538 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418539 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02cad5d2013-10-02 08:14:038540
8541 StaticSocketDataProvider data;
8542 session_deps_.socket_factory->AddSocketDataProvider(&data);
8543
8544 TestCompletionCallback callback;
8545 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8546 EXPECT_EQ(ERR_IO_PENDING, rv);
8547 base::MessageLoop::current()->RunUntilIdle();
8548
8549 // Transaction is pending on request body initialization.
8550 ASSERT_FALSE(fake_reader->callback().is_null());
8551
8552 // Return Init()'s result after the transaction gets destroyed.
8553 trans.reset();
8554 fake_reader->callback().Run(OK); // Should not crash.
8555}
8556
[email protected]aeefc9e82010-02-19 16:18:278557// Tests that changes to Auth realms are treated like auth rejections.
[email protected]23e482282013-06-14 16:08:028558TEST_P(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:278559
8560 HttpRequestInfo request;
8561 request.method = "GET";
bncce36dca22015-04-21 22:11:238562 request.url = GURL("http://www.example.org/");
[email protected]aeefc9e82010-02-19 16:18:278563 request.load_flags = 0;
8564
8565 // First transaction will request a resource and receive a Basic challenge
8566 // with realm="first_realm".
8567 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238568 MockWrite(
8569 "GET / HTTP/1.1\r\n"
8570 "Host: www.example.org\r\n"
8571 "Connection: keep-alive\r\n"
8572 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:278573 };
8574 MockRead data_reads1[] = {
8575 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8576 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
8577 "\r\n"),
8578 };
8579
8580 // After calling trans->RestartWithAuth(), provide an Authentication header
8581 // for first_realm. The server will reject and provide a challenge with
8582 // second_realm.
8583 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238584 MockWrite(
8585 "GET / HTTP/1.1\r\n"
8586 "Host: www.example.org\r\n"
8587 "Connection: keep-alive\r\n"
8588 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
8589 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:278590 };
8591 MockRead data_reads2[] = {
8592 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8593 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
8594 "\r\n"),
8595 };
8596
8597 // This again fails, and goes back to first_realm. Make sure that the
8598 // entry is removed from cache.
8599 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:238600 MockWrite(
8601 "GET / HTTP/1.1\r\n"
8602 "Host: www.example.org\r\n"
8603 "Connection: keep-alive\r\n"
8604 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
8605 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:278606 };
8607 MockRead data_reads3[] = {
8608 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8609 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
8610 "\r\n"),
8611 };
8612
8613 // Try one last time (with the correct password) and get the resource.
8614 MockWrite data_writes4[] = {
bncce36dca22015-04-21 22:11:238615 MockWrite(
8616 "GET / HTTP/1.1\r\n"
8617 "Host: www.example.org\r\n"
8618 "Connection: keep-alive\r\n"
8619 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
8620 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:278621 };
8622 MockRead data_reads4[] = {
8623 MockRead("HTTP/1.1 200 OK\r\n"
8624 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:508625 "Content-Length: 5\r\n"
8626 "\r\n"
8627 "hello"),
[email protected]aeefc9e82010-02-19 16:18:278628 };
8629
8630 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8631 data_writes1, arraysize(data_writes1));
8632 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8633 data_writes2, arraysize(data_writes2));
8634 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
8635 data_writes3, arraysize(data_writes3));
8636 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
8637 data_writes4, arraysize(data_writes4));
[email protected]bb88e1d32013-05-03 23:11:078638 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8639 session_deps_.socket_factory->AddSocketDataProvider(&data2);
8640 session_deps_.socket_factory->AddSocketDataProvider(&data3);
8641 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:278642
[email protected]49639fa2011-12-20 23:22:418643 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:278644
[email protected]3fe8d2f82013-10-17 08:56:078645 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0b0bf032010-09-21 18:08:508646 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418647 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:508648
[email protected]aeefc9e82010-02-19 16:18:278649 // Issue the first request with Authorize headers. There should be a
8650 // password prompt for first_realm waiting to be filled in after the
8651 // transaction completes.
[email protected]49639fa2011-12-20 23:22:418652 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]aeefc9e82010-02-19 16:18:278653 EXPECT_EQ(ERR_IO_PENDING, rv);
8654 rv = callback1.WaitForResult();
8655 EXPECT_EQ(OK, rv);
8656 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508657 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048658 const AuthChallengeInfo* challenge = response->auth_challenge.get();
8659 ASSERT_FALSE(challenge == NULL);
8660 EXPECT_FALSE(challenge->is_proxy);
bncce36dca22015-04-21 22:11:238661 EXPECT_EQ("www.example.org:80", challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:048662 EXPECT_EQ("first_realm", challenge->realm);
8663 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278664
8665 // Issue the second request with an incorrect password. There should be a
8666 // password prompt for second_realm waiting to be filled in after the
8667 // transaction completes.
[email protected]49639fa2011-12-20 23:22:418668 TestCompletionCallback callback2;
8669 rv = trans->RestartWithAuth(
8670 AuthCredentials(kFirst, kBaz), callback2.callback());
[email protected]aeefc9e82010-02-19 16:18:278671 EXPECT_EQ(ERR_IO_PENDING, rv);
8672 rv = callback2.WaitForResult();
8673 EXPECT_EQ(OK, rv);
8674 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508675 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048676 challenge = response->auth_challenge.get();
8677 ASSERT_FALSE(challenge == NULL);
8678 EXPECT_FALSE(challenge->is_proxy);
bncce36dca22015-04-21 22:11:238679 EXPECT_EQ("www.example.org:80", challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:048680 EXPECT_EQ("second_realm", challenge->realm);
8681 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278682
8683 // Issue the third request with another incorrect password. There should be
8684 // a password prompt for first_realm waiting to be filled in. If the password
8685 // prompt is not present, it indicates that the HttpAuthCacheEntry for
8686 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:418687 TestCompletionCallback callback3;
8688 rv = trans->RestartWithAuth(
8689 AuthCredentials(kSecond, kFou), callback3.callback());
[email protected]aeefc9e82010-02-19 16:18:278690 EXPECT_EQ(ERR_IO_PENDING, rv);
8691 rv = callback3.WaitForResult();
8692 EXPECT_EQ(OK, rv);
8693 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508694 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048695 challenge = response->auth_challenge.get();
8696 ASSERT_FALSE(challenge == NULL);
8697 EXPECT_FALSE(challenge->is_proxy);
bncce36dca22015-04-21 22:11:238698 EXPECT_EQ("www.example.org:80", challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:048699 EXPECT_EQ("first_realm", challenge->realm);
8700 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278701
8702 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:418703 TestCompletionCallback callback4;
8704 rv = trans->RestartWithAuth(
8705 AuthCredentials(kFirst, kBar), callback4.callback());
[email protected]aeefc9e82010-02-19 16:18:278706 EXPECT_EQ(ERR_IO_PENDING, rv);
8707 rv = callback4.WaitForResult();
8708 EXPECT_EQ(OK, rv);
8709 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508710 ASSERT_TRUE(response != NULL);
[email protected]aeefc9e82010-02-19 16:18:278711 EXPECT_TRUE(response->auth_challenge.get() == NULL);
8712}
8713
[email protected]23e482282013-06-14 16:08:028714TEST_P(HttpNetworkTransactionTest, HonorAlternateProtocolHeader) {
[email protected]d7599122014-05-24 03:37:238715 session_deps_.next_protos = SpdyNextProtos();
8716 session_deps_.use_alternate_protocols = true;
[email protected]a2cb8122010-03-10 17:22:428717
[email protected]8a0fc822013-06-27 20:52:438718 std::string alternate_protocol_http_header =
8719 GetAlternateProtocolHttpHeader();
8720
[email protected]564b4912010-03-09 16:30:428721 MockRead data_reads[] = {
8722 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438723 MockRead(alternate_protocol_http_header.c_str()),
[email protected]564b4912010-03-09 16:30:428724 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068725 MockRead(SYNCHRONOUS, OK),
[email protected]564b4912010-03-09 16:30:428726 };
8727
8728 HttpRequestInfo request;
8729 request.method = "GET";
bncce36dca22015-04-21 22:11:238730 request.url = GURL("http://www.example.org/");
[email protected]564b4912010-03-09 16:30:428731 request.load_flags = 0;
8732
8733 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
8734
[email protected]bb88e1d32013-05-03 23:11:078735 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]564b4912010-03-09 16:30:428736
[email protected]49639fa2011-12-20 23:22:418737 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:428738
[email protected]bb88e1d32013-05-03 23:11:078739 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:368740 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508741 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]564b4912010-03-09 16:30:428742
[email protected]49639fa2011-12-20 23:22:418743 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:428744 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]9e743cd2010-03-16 07:03:538745
bncce36dca22015-04-21 22:11:238746 HostPortPair http_host_port_pair("www.example.org", 80);
[email protected]9801e3702014-03-07 09:33:558747 HttpServerProperties& http_server_properties =
[email protected]17291a022011-10-10 07:32:538748 *session->http_server_properties();
bnc181b39a2015-03-17 21:36:478749 AlternativeService alternative_service =
8750 http_server_properties.GetAlternativeService(http_host_port_pair);
8751 EXPECT_EQ(alternative_service.protocol, UNINITIALIZED_ALTERNATE_PROTOCOL);
[email protected]564b4912010-03-09 16:30:428752
8753 EXPECT_EQ(OK, callback.WaitForResult());
8754
8755 const HttpResponseInfo* response = trans->GetResponseInfo();
8756 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508757 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:428758 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:538759 EXPECT_FALSE(response->was_fetched_via_spdy);
8760 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]564b4912010-03-09 16:30:428761
8762 std::string response_data;
8763 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8764 EXPECT_EQ("hello world", response_data);
8765
bnc181b39a2015-03-17 21:36:478766 alternative_service =
8767 http_server_properties.GetAlternativeService(http_host_port_pair);
8768 EXPECT_EQ(443, alternative_service.port);
8769 EXPECT_EQ(AlternateProtocolFromNextProto(GetParam()),
8770 alternative_service.protocol);
[email protected]564b4912010-03-09 16:30:428771}
8772
rch89c6e102015-03-18 18:56:528773TEST_P(HttpNetworkTransactionTest, EmptyAlternateProtocolHeader) {
8774 session_deps_.next_protos = SpdyNextProtos();
8775 session_deps_.use_alternate_protocols = true;
8776
8777 MockRead data_reads[] = {
8778 MockRead("HTTP/1.1 200 OK\r\n"),
8779 MockRead("Alternate-Protocol: \r\n\r\n"),
8780 MockRead("hello world"),
8781 MockRead(SYNCHRONOUS, OK),
8782 };
8783
8784 HttpRequestInfo request;
8785 request.method = "GET";
bncce36dca22015-04-21 22:11:238786 request.url = GURL("http://www.example.org/");
rch89c6e102015-03-18 18:56:528787 request.load_flags = 0;
8788
8789 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
8790
8791 session_deps_.socket_factory->AddSocketDataProvider(&data);
8792
8793 TestCompletionCallback callback;
8794
8795 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8796
bncce36dca22015-04-21 22:11:238797 HostPortPair http_host_port_pair("www.example.org", 80);
rch89c6e102015-03-18 18:56:528798 HttpServerProperties& http_server_properties =
8799 *session->http_server_properties();
bnccacc0992015-03-20 20:22:228800 AlternativeService alternative_service(QUIC, "", 80);
8801 http_server_properties.SetAlternativeService(http_host_port_pair,
8802 alternative_service, 1.0);
8803
8804 alternative_service =
rch89c6e102015-03-18 18:56:528805 http_server_properties.GetAlternativeService(http_host_port_pair);
8806 EXPECT_EQ(alternative_service.protocol, QUIC);
8807
8808 scoped_ptr<HttpTransaction> trans(
8809 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8810
8811 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8812 EXPECT_EQ(ERR_IO_PENDING, rv);
8813
8814 EXPECT_EQ(OK, callback.WaitForResult());
8815
8816 const HttpResponseInfo* response = trans->GetResponseInfo();
8817 ASSERT_TRUE(response != NULL);
8818 ASSERT_TRUE(response->headers.get() != NULL);
8819 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8820 EXPECT_FALSE(response->was_fetched_via_spdy);
8821 EXPECT_FALSE(response->was_npn_negotiated);
8822
8823 std::string response_data;
8824 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8825 EXPECT_EQ("hello world", response_data);
8826
8827 alternative_service =
8828 http_server_properties.GetAlternativeService(http_host_port_pair);
8829 EXPECT_EQ(alternative_service.protocol, UNINITIALIZED_ALTERNATE_PROTOCOL);
8830}
8831
[email protected]23e482282013-06-14 16:08:028832TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238833 MarkBrokenAlternateProtocolAndFallback) {
[email protected]d7599122014-05-24 03:37:238834 session_deps_.use_alternate_protocols = true;
[email protected]564b4912010-03-09 16:30:428835
8836 HttpRequestInfo request;
8837 request.method = "GET";
bncce36dca22015-04-21 22:11:238838 request.url = GURL("http://www.example.org/");
[email protected]564b4912010-03-09 16:30:428839 request.load_flags = 0;
8840
[email protected]d973e99a2012-02-17 21:02:368841 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:428842 StaticSocketDataProvider first_data;
8843 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078844 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]564b4912010-03-09 16:30:428845
8846 MockRead data_reads[] = {
8847 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8848 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068849 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:428850 };
8851 StaticSocketDataProvider second_data(
8852 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078853 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:428854
[email protected]bb88e1d32013-05-03 23:11:078855 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:428856
[email protected]30d4c022013-07-18 22:58:168857 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538858 session->http_server_properties();
bnc8445b3002015-03-13 01:57:098859 const HostPortPair host_port_pair = HostPortPair::FromURL(request.url);
[email protected]3912662a32011-10-04 00:51:118860 // Port must be < 1024, or the header will be ignored (since initial port was
8861 // port 80 (another restricted port).
bnccacc0992015-03-20 20:22:228862 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:238863 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:228864 666); /* port is ignored by MockConnect anyway */
8865 http_server_properties->SetAlternativeService(host_port_pair,
8866 alternative_service, 1.0);
[email protected]564b4912010-03-09 16:30:428867
[email protected]262eec82013-03-19 21:01:368868 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508869 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418870 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:428871
[email protected]49639fa2011-12-20 23:22:418872 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:428873 EXPECT_EQ(ERR_IO_PENDING, rv);
8874 EXPECT_EQ(OK, callback.WaitForResult());
8875
8876 const HttpResponseInfo* response = trans->GetResponseInfo();
8877 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508878 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:428879 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8880
8881 std::string response_data;
8882 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8883 EXPECT_EQ("hello world", response_data);
8884
bnccacc0992015-03-20 20:22:228885 alternative_service =
bnc181b39a2015-03-17 21:36:478886 http_server_properties->GetAlternativeService(host_port_pair);
8887 EXPECT_NE(UNINITIALIZED_ALTERNATE_PROTOCOL, alternative_service.protocol);
bnc8445b3002015-03-13 01:57:098888 EXPECT_TRUE(
8889 http_server_properties->IsAlternativeServiceBroken(alternative_service));
[email protected]564b4912010-03-09 16:30:428890}
8891
[email protected]23e482282013-06-14 16:08:028892TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238893 AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:118894 // Ensure that we're not allowed to redirect traffic via an alternate
8895 // protocol to an unrestricted (port >= 1024) when the original traffic was
8896 // on a restricted port (port < 1024). Ensure that we can redirect in all
8897 // other cases.
[email protected]d7599122014-05-24 03:37:238898 session_deps_.use_alternate_protocols = true;
[email protected]3912662a32011-10-04 00:51:118899
8900 HttpRequestInfo restricted_port_request;
8901 restricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:238902 restricted_port_request.url = GURL("http://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:118903 restricted_port_request.load_flags = 0;
8904
[email protected]d973e99a2012-02-17 21:02:368905 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118906 StaticSocketDataProvider first_data;
8907 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078908 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118909
8910 MockRead data_reads[] = {
8911 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8912 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068913 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118914 };
8915 StaticSocketDataProvider second_data(
8916 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078917 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118918
[email protected]bb88e1d32013-05-03 23:11:078919 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118920
[email protected]30d4c022013-07-18 22:58:168921 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538922 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118923 const int kUnrestrictedAlternatePort = 1024;
bnccacc0992015-03-20 20:22:228924 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:238925 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:228926 kUnrestrictedAlternatePort);
8927 http_server_properties->SetAlternativeService(
8928 HostPortPair::FromURL(restricted_port_request.url), alternative_service,
bnc1102b552015-01-30 20:11:018929 1.0);
[email protected]3912662a32011-10-04 00:51:118930
[email protected]262eec82013-03-19 21:01:368931 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508932 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418933 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118934
[email protected]49639fa2011-12-20 23:22:418935 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:368936 &restricted_port_request,
8937 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118938 EXPECT_EQ(ERR_IO_PENDING, rv);
8939 // Invalid change to unrestricted port should fail.
8940 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.WaitForResult());
[email protected]c54c6962013-02-01 04:53:198941}
[email protected]3912662a32011-10-04 00:51:118942
[email protected]23e482282013-06-14 16:08:028943TEST_P(HttpNetworkTransactionTest,
[email protected]c54c6962013-02-01 04:53:198944 AlternateProtocolPortRestrictedPermitted) {
8945 // Ensure that we're allowed to redirect traffic via an alternate
8946 // protocol to an unrestricted (port >= 1024) when the original traffic was
8947 // on a restricted port (port < 1024) if we set
8948 // enable_user_alternate_protocol_ports.
8949
[email protected]d7599122014-05-24 03:37:238950 session_deps_.use_alternate_protocols = true;
[email protected]bb88e1d32013-05-03 23:11:078951 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:198952
8953 HttpRequestInfo restricted_port_request;
8954 restricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:238955 restricted_port_request.url = GURL("http://www.example.org:1023/");
[email protected]c54c6962013-02-01 04:53:198956 restricted_port_request.load_flags = 0;
8957
8958 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
8959 StaticSocketDataProvider first_data;
8960 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078961 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:198962
8963 MockRead data_reads[] = {
8964 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8965 MockRead("hello world"),
8966 MockRead(ASYNC, OK),
8967 };
8968 StaticSocketDataProvider second_data(
8969 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078970 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]c54c6962013-02-01 04:53:198971
[email protected]bb88e1d32013-05-03 23:11:078972 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:198973
[email protected]30d4c022013-07-18 22:58:168974 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]c54c6962013-02-01 04:53:198975 session->http_server_properties();
8976 const int kUnrestrictedAlternatePort = 1024;
bnccacc0992015-03-20 20:22:228977 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:238978 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:228979 kUnrestrictedAlternatePort);
8980 http_server_properties->SetAlternativeService(
8981 HostPortPair::FromURL(restricted_port_request.url), alternative_service,
bnc1102b552015-01-30 20:11:018982 1.0);
[email protected]c54c6962013-02-01 04:53:198983
[email protected]262eec82013-03-19 21:01:368984 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508985 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]c54c6962013-02-01 04:53:198986 TestCompletionCallback callback;
8987
8988 EXPECT_EQ(ERR_IO_PENDING, trans->Start(
[email protected]262eec82013-03-19 21:01:368989 &restricted_port_request,
8990 callback.callback(), BoundNetLog()));
[email protected]c54c6962013-02-01 04:53:198991 // Change to unrestricted port should succeed.
8992 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:118993}
8994
[email protected]23e482282013-06-14 16:08:028995TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238996 AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:118997 // Ensure that we're not allowed to redirect traffic via an alternate
8998 // protocol to an unrestricted (port >= 1024) when the original traffic was
8999 // on a restricted port (port < 1024). Ensure that we can redirect in all
9000 // other cases.
[email protected]d7599122014-05-24 03:37:239001 session_deps_.use_alternate_protocols = true;
[email protected]3912662a32011-10-04 00:51:119002
9003 HttpRequestInfo restricted_port_request;
9004 restricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:239005 restricted_port_request.url = GURL("http://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:119006 restricted_port_request.load_flags = 0;
9007
[email protected]d973e99a2012-02-17 21:02:369008 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:119009 StaticSocketDataProvider first_data;
9010 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079011 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:119012
9013 MockRead data_reads[] = {
9014 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9015 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069016 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:119017 };
9018 StaticSocketDataProvider second_data(
9019 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079020 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:119021
[email protected]bb88e1d32013-05-03 23:11:079022 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:119023
[email protected]30d4c022013-07-18 22:58:169024 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:539025 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:119026 const int kRestrictedAlternatePort = 80;
bnccacc0992015-03-20 20:22:229027 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239028 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229029 kRestrictedAlternatePort);
9030 http_server_properties->SetAlternativeService(
9031 HostPortPair::FromURL(restricted_port_request.url), alternative_service,
bnc1102b552015-01-30 20:11:019032 1.0);
[email protected]3912662a32011-10-04 00:51:119033
[email protected]262eec82013-03-19 21:01:369034 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509035 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419036 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:119037
[email protected]49639fa2011-12-20 23:22:419038 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:369039 &restricted_port_request,
9040 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:119041 EXPECT_EQ(ERR_IO_PENDING, rv);
9042 // Valid change to restricted port should pass.
9043 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:119044}
9045
[email protected]23e482282013-06-14 16:08:029046TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239047 AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:119048 // Ensure that we're not allowed to redirect traffic via an alternate
9049 // protocol to an unrestricted (port >= 1024) when the original traffic was
9050 // on a restricted port (port < 1024). Ensure that we can redirect in all
9051 // other cases.
[email protected]d7599122014-05-24 03:37:239052 session_deps_.use_alternate_protocols = true;
[email protected]3912662a32011-10-04 00:51:119053
9054 HttpRequestInfo unrestricted_port_request;
9055 unrestricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:239056 unrestricted_port_request.url = GURL("http://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:119057 unrestricted_port_request.load_flags = 0;
9058
[email protected]d973e99a2012-02-17 21:02:369059 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:119060 StaticSocketDataProvider first_data;
9061 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079062 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:119063
9064 MockRead data_reads[] = {
9065 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9066 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069067 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:119068 };
9069 StaticSocketDataProvider second_data(
9070 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079071 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:119072
[email protected]bb88e1d32013-05-03 23:11:079073 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:119074
[email protected]30d4c022013-07-18 22:58:169075 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:539076 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:119077 const int kRestrictedAlternatePort = 80;
bnccacc0992015-03-20 20:22:229078 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239079 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229080 kRestrictedAlternatePort);
9081 http_server_properties->SetAlternativeService(
9082 HostPortPair::FromURL(unrestricted_port_request.url), alternative_service,
bnc1102b552015-01-30 20:11:019083 1.0);
[email protected]3912662a32011-10-04 00:51:119084
[email protected]262eec82013-03-19 21:01:369085 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509086 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419087 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:119088
[email protected]49639fa2011-12-20 23:22:419089 int rv = trans->Start(
9090 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:119091 EXPECT_EQ(ERR_IO_PENDING, rv);
9092 // Valid change to restricted port should pass.
9093 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:119094}
9095
[email protected]23e482282013-06-14 16:08:029096TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239097 AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:119098 // Ensure that we're not allowed to redirect traffic via an alternate
9099 // protocol to an unrestricted (port >= 1024) when the original traffic was
9100 // on a restricted port (port < 1024). Ensure that we can redirect in all
9101 // other cases.
[email protected]d7599122014-05-24 03:37:239102 session_deps_.use_alternate_protocols = true;
[email protected]3912662a32011-10-04 00:51:119103
9104 HttpRequestInfo unrestricted_port_request;
9105 unrestricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:239106 unrestricted_port_request.url = GURL("http://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:119107 unrestricted_port_request.load_flags = 0;
9108
[email protected]d973e99a2012-02-17 21:02:369109 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:119110 StaticSocketDataProvider first_data;
9111 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079112 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:119113
9114 MockRead data_reads[] = {
9115 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9116 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069117 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:119118 };
9119 StaticSocketDataProvider second_data(
9120 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079121 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:119122
[email protected]bb88e1d32013-05-03 23:11:079123 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:119124
[email protected]30d4c022013-07-18 22:58:169125 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:539126 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:119127 const int kUnrestrictedAlternatePort = 1024;
bnccacc0992015-03-20 20:22:229128 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239129 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229130 kUnrestrictedAlternatePort);
9131 http_server_properties->SetAlternativeService(
9132 HostPortPair::FromURL(unrestricted_port_request.url), alternative_service,
bnc1102b552015-01-30 20:11:019133 1.0);
[email protected]3912662a32011-10-04 00:51:119134
[email protected]262eec82013-03-19 21:01:369135 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509136 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419137 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:119138
[email protected]49639fa2011-12-20 23:22:419139 int rv = trans->Start(
9140 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:119141 EXPECT_EQ(ERR_IO_PENDING, rv);
9142 // Valid change to an unrestricted port should pass.
9143 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:119144}
9145
[email protected]d7599122014-05-24 03:37:239146TEST_P(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:029147 // Ensure that we're not allowed to redirect traffic via an alternate
9148 // protocol to an unsafe port, and that we resume the second
9149 // HttpStreamFactoryImpl::Job once the alternate protocol request fails.
[email protected]d7599122014-05-24 03:37:239150 session_deps_.use_alternate_protocols = true;
[email protected]eb6234e2012-01-19 01:50:029151
9152 HttpRequestInfo request;
9153 request.method = "GET";
bncce36dca22015-04-21 22:11:239154 request.url = GURL("http://www.example.org/");
[email protected]eb6234e2012-01-19 01:50:029155 request.load_flags = 0;
9156
9157 // The alternate protocol request will error out before we attempt to connect,
9158 // so only the standard HTTP request will try to connect.
9159 MockRead data_reads[] = {
9160 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9161 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069162 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:029163 };
9164 StaticSocketDataProvider data(
9165 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079166 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:029167
[email protected]bb88e1d32013-05-03 23:11:079168 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:029169
[email protected]30d4c022013-07-18 22:58:169170 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]eb6234e2012-01-19 01:50:029171 session->http_server_properties();
9172 const int kUnsafePort = 7;
bnccacc0992015-03-20 20:22:229173 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239174 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229175 kUnsafePort);
9176 http_server_properties->SetAlternativeService(
9177 HostPortPair::FromURL(request.url), alternative_service, 1.0);
[email protected]eb6234e2012-01-19 01:50:029178
[email protected]262eec82013-03-19 21:01:369179 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509180 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]eb6234e2012-01-19 01:50:029181 TestCompletionCallback callback;
9182
9183 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9184 EXPECT_EQ(ERR_IO_PENDING, rv);
9185 // The HTTP request should succeed.
9186 EXPECT_EQ(OK, callback.WaitForResult());
9187
9188 // Disable alternate protocol before the asserts.
[email protected]d7599122014-05-24 03:37:239189 // HttpStreamFactory::set_use_alternate_protocols(false);
[email protected]eb6234e2012-01-19 01:50:029190
9191 const HttpResponseInfo* response = trans->GetResponseInfo();
9192 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509193 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]eb6234e2012-01-19 01:50:029194 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9195
9196 std::string response_data;
9197 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9198 EXPECT_EQ("hello world", response_data);
9199}
9200
[email protected]23e482282013-06-14 16:08:029201TEST_P(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]d7599122014-05-24 03:37:239202 session_deps_.use_alternate_protocols = true;
9203 session_deps_.next_protos = SpdyNextProtos();
[email protected]2ff8b312010-04-26 22:20:549204
9205 HttpRequestInfo request;
9206 request.method = "GET";
bncce36dca22015-04-21 22:11:239207 request.url = GURL("http://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:549208 request.load_flags = 0;
9209
[email protected]8a0fc822013-06-27 20:52:439210 std::string alternate_protocol_http_header =
9211 GetAlternateProtocolHttpHeader();
9212
[email protected]2ff8b312010-04-26 22:20:549213 MockRead data_reads[] = {
9214 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439215 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2ff8b312010-04-26 22:20:549216 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:179217 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
9218 MockRead(ASYNC, OK)
[email protected]2ff8b312010-04-26 22:20:549219 };
9220
9221 StaticSocketDataProvider first_transaction(
9222 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079223 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:549224
[email protected]8ddf8322012-02-23 18:08:069225 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029226 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:239227 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
9228 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:079229 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:549230
[email protected]cdf8f7e72013-05-23 10:56:469231 scoped_ptr<SpdyFrame> req(
9232 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
rch8e6c6c42015-05-01 14:05:139233 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]2ff8b312010-04-26 22:20:549234
[email protected]23e482282013-06-14 16:08:029235 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9236 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:549237 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:139238 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:549239 };
9240
rch8e6c6c42015-05-01 14:05:139241 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9242 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079243 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:549244
[email protected]d973e99a2012-02-17 21:02:369245 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559246 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
9247 NULL, 0, NULL, 0);
9248 hanging_non_alternate_protocol_socket.set_connect_data(
9249 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:079250 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:559251 &hanging_non_alternate_protocol_socket);
9252
[email protected]49639fa2011-12-20 23:22:419253 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:549254
[email protected]bb88e1d32013-05-03 23:11:079255 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369256 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509257 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:549258
[email protected]49639fa2011-12-20 23:22:419259 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:549260 EXPECT_EQ(ERR_IO_PENDING, rv);
9261 EXPECT_EQ(OK, callback.WaitForResult());
9262
9263 const HttpResponseInfo* response = trans->GetResponseInfo();
9264 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509265 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:549266 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9267
9268 std::string response_data;
9269 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9270 EXPECT_EQ("hello world", response_data);
9271
[email protected]90499482013-06-01 00:39:509272 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:549273
[email protected]49639fa2011-12-20 23:22:419274 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:549275 EXPECT_EQ(ERR_IO_PENDING, rv);
9276 EXPECT_EQ(OK, callback.WaitForResult());
9277
9278 response = trans->GetResponseInfo();
9279 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509280 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:549281 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539282 EXPECT_TRUE(response->was_fetched_via_spdy);
9283 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:549284
9285 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9286 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:549287}
9288
[email protected]23e482282013-06-14 16:08:029289TEST_P(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]d7599122014-05-24 03:37:239290 session_deps_.use_alternate_protocols = true;
9291 session_deps_.next_protos = SpdyNextProtos();
[email protected]2d6728692011-03-12 01:39:559292
9293 HttpRequestInfo request;
9294 request.method = "GET";
bncce36dca22015-04-21 22:11:239295 request.url = GURL("http://www.example.org/");
[email protected]2d6728692011-03-12 01:39:559296 request.load_flags = 0;
9297
[email protected]8a0fc822013-06-27 20:52:439298 std::string alternate_protocol_http_header =
9299 GetAlternateProtocolHttpHeader();
9300
[email protected]2d6728692011-03-12 01:39:559301 MockRead data_reads[] = {
9302 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439303 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2d6728692011-03-12 01:39:559304 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:179305 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:069306 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:559307 };
9308
9309 StaticSocketDataProvider first_transaction(
9310 data_reads, arraysize(data_reads), NULL, 0);
9311 // Socket 1 is the HTTP transaction with the Alternate-Protocol header.
[email protected]bb88e1d32013-05-03 23:11:079312 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:559313
[email protected]d973e99a2012-02-17 21:02:369314 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559315 StaticSocketDataProvider hanging_socket(
9316 NULL, 0, NULL, 0);
9317 hanging_socket.set_connect_data(never_finishing_connect);
9318 // Socket 2 and 3 are the hanging Alternate-Protocol and
9319 // non-Alternate-Protocol jobs from the 2nd transaction.
[email protected]bb88e1d32013-05-03 23:11:079320 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
9321 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
[email protected]2d6728692011-03-12 01:39:559322
[email protected]8ddf8322012-02-23 18:08:069323 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029324 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:239325 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
9326 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:079327 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:559328
[email protected]cdf8f7e72013-05-23 10:56:469329 scoped_ptr<SpdyFrame> req1(
9330 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
9331 scoped_ptr<SpdyFrame> req2(
9332 spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
[email protected]2d6728692011-03-12 01:39:559333 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:139334 CreateMockWrite(*req1, 0), CreateMockWrite(*req2, 1),
[email protected]2d6728692011-03-12 01:39:559335 };
[email protected]23e482282013-06-14 16:08:029336 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9337 scoped_ptr<SpdyFrame> data1(spdy_util_.ConstructSpdyBodyFrame(1, true));
9338 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
9339 scoped_ptr<SpdyFrame> data2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]2d6728692011-03-12 01:39:559340 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:139341 CreateMockRead(*resp1, 2),
9342 CreateMockRead(*data1, 3),
9343 CreateMockRead(*resp2, 4),
9344 CreateMockRead(*data2, 5),
9345 MockRead(ASYNC, 0, 6),
[email protected]2d6728692011-03-12 01:39:559346 };
9347
rch8e6c6c42015-05-01 14:05:139348 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9349 arraysize(spdy_writes));
[email protected]2d6728692011-03-12 01:39:559350 // Socket 4 is the successful Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:079351 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:559352
9353 // Socket 5 is the unsuccessful non-Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:079354 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
[email protected]2d6728692011-03-12 01:39:559355
[email protected]bb88e1d32013-05-03 23:11:079356 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:419357 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:509358 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:559359
[email protected]49639fa2011-12-20 23:22:419360 int rv = trans1.Start(&request, callback1.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559361 EXPECT_EQ(ERR_IO_PENDING, rv);
9362 EXPECT_EQ(OK, callback1.WaitForResult());
9363
9364 const HttpResponseInfo* response = trans1.GetResponseInfo();
9365 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509366 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559367 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9368
9369 std::string response_data;
9370 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
9371 EXPECT_EQ("hello world", response_data);
9372
[email protected]49639fa2011-12-20 23:22:419373 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:509374 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:419375 rv = trans2.Start(&request, callback2.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559376 EXPECT_EQ(ERR_IO_PENDING, rv);
9377
[email protected]49639fa2011-12-20 23:22:419378 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:509379 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:419380 rv = trans3.Start(&request, callback3.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559381 EXPECT_EQ(ERR_IO_PENDING, rv);
9382
9383 EXPECT_EQ(OK, callback2.WaitForResult());
9384 EXPECT_EQ(OK, callback3.WaitForResult());
9385
9386 response = trans2.GetResponseInfo();
9387 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509388 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559389 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9390 EXPECT_TRUE(response->was_fetched_via_spdy);
9391 EXPECT_TRUE(response->was_npn_negotiated);
9392 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
9393 EXPECT_EQ("hello!", response_data);
9394
9395 response = trans3.GetResponseInfo();
9396 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509397 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559398 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9399 EXPECT_TRUE(response->was_fetched_via_spdy);
9400 EXPECT_TRUE(response->was_npn_negotiated);
9401 ASSERT_EQ(OK, ReadTransaction(&trans3, &response_data));
9402 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:559403}
9404
[email protected]23e482282013-06-14 16:08:029405TEST_P(HttpNetworkTransactionTest, StallAlternateProtocolForNpnSpdy) {
[email protected]d7599122014-05-24 03:37:239406 session_deps_.use_alternate_protocols = true;
9407 session_deps_.next_protos = SpdyNextProtos();
[email protected]2d6728692011-03-12 01:39:559408
9409 HttpRequestInfo request;
9410 request.method = "GET";
bncce36dca22015-04-21 22:11:239411 request.url = GURL("http://www.example.org/");
[email protected]2d6728692011-03-12 01:39:559412 request.load_flags = 0;
9413
[email protected]8a0fc822013-06-27 20:52:439414 std::string alternate_protocol_http_header =
9415 GetAlternateProtocolHttpHeader();
9416
[email protected]2d6728692011-03-12 01:39:559417 MockRead data_reads[] = {
9418 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439419 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2d6728692011-03-12 01:39:559420 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:179421 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:069422 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:559423 };
9424
9425 StaticSocketDataProvider first_transaction(
9426 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079427 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:559428
[email protected]8ddf8322012-02-23 18:08:069429 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029430 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:079431 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:559432
[email protected]d973e99a2012-02-17 21:02:369433 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559434 StaticSocketDataProvider hanging_alternate_protocol_socket(
9435 NULL, 0, NULL, 0);
9436 hanging_alternate_protocol_socket.set_connect_data(
9437 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:079438 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:559439 &hanging_alternate_protocol_socket);
9440
9441 // 2nd request is just a copy of the first one, over HTTP again.
[email protected]bb88e1d32013-05-03 23:11:079442 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:559443
[email protected]49639fa2011-12-20 23:22:419444 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:559445
[email protected]bb88e1d32013-05-03 23:11:079446 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369447 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509448 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:559449
[email protected]49639fa2011-12-20 23:22:419450 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559451 EXPECT_EQ(ERR_IO_PENDING, rv);
9452 EXPECT_EQ(OK, callback.WaitForResult());
9453
9454 const HttpResponseInfo* response = trans->GetResponseInfo();
9455 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509456 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559457 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9458
9459 std::string response_data;
9460 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9461 EXPECT_EQ("hello world", response_data);
9462
[email protected]90499482013-06-01 00:39:509463 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:559464
[email protected]49639fa2011-12-20 23:22:419465 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559466 EXPECT_EQ(ERR_IO_PENDING, rv);
9467 EXPECT_EQ(OK, callback.WaitForResult());
9468
9469 response = trans->GetResponseInfo();
9470 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509471 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559472 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9473 EXPECT_FALSE(response->was_fetched_via_spdy);
9474 EXPECT_FALSE(response->was_npn_negotiated);
9475
9476 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9477 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:559478}
9479
[email protected]631f1322010-04-30 17:59:119480class CapturingProxyResolver : public ProxyResolver {
9481 public:
sammce90c9212015-05-27 23:43:359482 CapturingProxyResolver() {}
dchengb03027d2014-10-21 12:00:209483 ~CapturingProxyResolver() override {}
[email protected]631f1322010-04-30 17:59:119484
dchengb03027d2014-10-21 12:00:209485 int GetProxyForURL(const GURL& url,
9486 ProxyInfo* results,
9487 const CompletionCallback& callback,
9488 RequestHandle* request,
9489 const BoundNetLog& net_log) override {
[email protected]fae7669f2010-08-02 21:49:409490 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
9491 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:429492 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:119493 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:429494 return OK;
[email protected]631f1322010-04-30 17:59:119495 }
9496
dchengb03027d2014-10-21 12:00:209497 void CancelRequest(RequestHandle request) override { NOTREACHED(); }
[email protected]631f1322010-04-30 17:59:119498
dchengb03027d2014-10-21 12:00:209499 LoadState GetLoadState(RequestHandle request) const override {
[email protected]f2c971f2011-11-08 00:33:179500 NOTREACHED();
9501 return LOAD_STATE_IDLE;
9502 }
9503
[email protected]24476402010-07-20 20:55:179504 const std::vector<GURL>& resolved() const { return resolved_; }
9505
9506 private:
[email protected]631f1322010-04-30 17:59:119507 std::vector<GURL> resolved_;
9508
9509 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
9510};
9511
sammce64b2362015-04-29 03:50:239512class CapturingProxyResolverFactory : public ProxyResolverFactory {
9513 public:
9514 explicit CapturingProxyResolverFactory(CapturingProxyResolver* resolver)
9515 : ProxyResolverFactory(false), resolver_(resolver) {}
9516
9517 int CreateProxyResolver(
9518 const scoped_refptr<ProxyResolverScriptData>& pac_script,
9519 scoped_ptr<ProxyResolver>* resolver,
9520 const net::CompletionCallback& callback,
9521 scoped_ptr<Request>* request) override {
9522 resolver->reset(new ForwardingProxyResolver(resolver_));
9523 return OK;
9524 }
9525
9526 private:
9527 ProxyResolver* resolver_;
9528};
9529
[email protected]23e482282013-06-14 16:08:029530TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239531 UseAlternateProtocolForTunneledNpnSpdy) {
[email protected]d7599122014-05-24 03:37:239532 session_deps_.use_alternate_protocols = true;
9533 session_deps_.next_protos = SpdyNextProtos();
[email protected]631f1322010-04-30 17:59:119534
9535 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:429536 proxy_config.set_auto_detect(true);
9537 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:119538
sammc5dd160c2015-04-02 02:43:139539 CapturingProxyResolver capturing_proxy_resolver;
[email protected]bb88e1d32013-05-03 23:11:079540 session_deps_.proxy_service.reset(new ProxyService(
sammc5dd160c2015-04-02 02:43:139541 new ProxyConfigServiceFixed(proxy_config),
9542 make_scoped_ptr(
sammce64b2362015-04-29 03:50:239543 new CapturingProxyResolverFactory(&capturing_proxy_resolver)),
[email protected]66761b952010-06-25 21:30:389544 NULL));
vishal.b62985ca92015-04-17 08:45:519545 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079546 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:119547
9548 HttpRequestInfo request;
9549 request.method = "GET";
bncce36dca22015-04-21 22:11:239550 request.url = GURL("http://www.example.org/");
[email protected]631f1322010-04-30 17:59:119551 request.load_flags = 0;
9552
[email protected]8a0fc822013-06-27 20:52:439553 std::string alternate_protocol_http_header =
9554 GetAlternateProtocolHttpHeader();
9555
[email protected]631f1322010-04-30 17:59:119556 MockRead data_reads[] = {
9557 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439558 MockRead(alternate_protocol_http_header.c_str()),
[email protected]631f1322010-04-30 17:59:119559 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:179560 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:069561 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:119562 };
9563
9564 StaticSocketDataProvider first_transaction(
9565 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079566 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]631f1322010-04-30 17:59:119567
[email protected]8ddf8322012-02-23 18:08:069568 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029569 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:239570 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
9571 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:079572 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]631f1322010-04-30 17:59:119573
[email protected]cdf8f7e72013-05-23 10:56:469574 scoped_ptr<SpdyFrame> req(
9575 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]631f1322010-04-30 17:59:119576 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:139577 MockWrite(ASYNC, 0,
9578 "CONNECT www.example.org:443 HTTP/1.1\r\n"
9579 "Host: www.example.org\r\n"
9580 "Proxy-Connection: keep-alive\r\n\r\n"),
9581 CreateMockWrite(*req, 2),
[email protected]631f1322010-04-30 17:59:119582 };
9583
[email protected]d911f1b2010-05-05 22:39:429584 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
9585
[email protected]23e482282013-06-14 16:08:029586 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9587 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]631f1322010-04-30 17:59:119588 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:139589 MockRead(ASYNC, 1, kCONNECTResponse),
9590 CreateMockRead(*resp.get(), 3),
9591 CreateMockRead(*data.get(), 4),
9592 MockRead(ASYNC, ERR_IO_PENDING, 5),
[email protected]631f1322010-04-30 17:59:119593 };
9594
rch8e6c6c42015-05-01 14:05:139595 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9596 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079597 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:119598
[email protected]d973e99a2012-02-17 21:02:369599 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559600 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
9601 NULL, 0, NULL, 0);
9602 hanging_non_alternate_protocol_socket.set_connect_data(
9603 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:079604 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:559605 &hanging_non_alternate_protocol_socket);
9606
[email protected]49639fa2011-12-20 23:22:419607 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:119608
[email protected]bb88e1d32013-05-03 23:11:079609 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369610 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509611 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:119612
[email protected]49639fa2011-12-20 23:22:419613 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:119614 EXPECT_EQ(ERR_IO_PENDING, rv);
9615 EXPECT_EQ(OK, callback.WaitForResult());
9616
9617 const HttpResponseInfo* response = trans->GetResponseInfo();
9618 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509619 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]631f1322010-04-30 17:59:119620 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539621 EXPECT_FALSE(response->was_fetched_via_spdy);
9622 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:119623
9624 std::string response_data;
9625 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9626 EXPECT_EQ("hello world", response_data);
9627
[email protected]90499482013-06-01 00:39:509628 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:119629
[email protected]49639fa2011-12-20 23:22:419630 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:119631 EXPECT_EQ(ERR_IO_PENDING, rv);
9632 EXPECT_EQ(OK, callback.WaitForResult());
9633
9634 response = trans->GetResponseInfo();
9635 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509636 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]631f1322010-04-30 17:59:119637 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539638 EXPECT_TRUE(response->was_fetched_via_spdy);
9639 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:119640
9641 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9642 EXPECT_EQ("hello!", response_data);
sammc5dd160c2015-04-02 02:43:139643 ASSERT_EQ(3u, capturing_proxy_resolver.resolved().size());
bncce36dca22015-04-21 22:11:239644 EXPECT_EQ("http://www.example.org/",
sammc5dd160c2015-04-02 02:43:139645 capturing_proxy_resolver.resolved()[0].spec());
bncce36dca22015-04-21 22:11:239646 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:139647 capturing_proxy_resolver.resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:119648
[email protected]029c83b62013-01-24 05:28:209649 LoadTimingInfo load_timing_info;
9650 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
9651 TestLoadTimingNotReusedWithPac(load_timing_info,
9652 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:119653}
[email protected]631f1322010-04-30 17:59:119654
[email protected]23e482282013-06-14 16:08:029655TEST_P(HttpNetworkTransactionTest,
[email protected]2ff8b312010-04-26 22:20:549656 UseAlternateProtocolForNpnSpdyWithExistingSpdySession) {
[email protected]d7599122014-05-24 03:37:239657 session_deps_.use_alternate_protocols = true;
9658 session_deps_.next_protos = SpdyNextProtos();
[email protected]2ff8b312010-04-26 22:20:549659
9660 HttpRequestInfo request;
9661 request.method = "GET";
bncce36dca22015-04-21 22:11:239662 request.url = GURL("http://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:549663 request.load_flags = 0;
9664
[email protected]8a0fc822013-06-27 20:52:439665 std::string alternate_protocol_http_header =
9666 GetAlternateProtocolHttpHeader();
9667
[email protected]2ff8b312010-04-26 22:20:549668 MockRead data_reads[] = {
9669 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439670 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2ff8b312010-04-26 22:20:549671 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069672 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:549673 };
9674
9675 StaticSocketDataProvider first_transaction(
9676 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079677 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:549678
[email protected]8ddf8322012-02-23 18:08:069679 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029680 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:239681 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
9682 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:079683 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:549684
[email protected]cdf8f7e72013-05-23 10:56:469685 scoped_ptr<SpdyFrame> req(
9686 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
rch8e6c6c42015-05-01 14:05:139687 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]2ff8b312010-04-26 22:20:549688
[email protected]23e482282013-06-14 16:08:029689 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9690 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:549691 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:139692 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:549693 };
9694
rch8e6c6c42015-05-01 14:05:139695 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9696 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079697 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:549698
[email protected]83039bb2011-12-09 18:43:559699 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:549700
[email protected]bb88e1d32013-05-03 23:11:079701 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:549702
[email protected]262eec82013-03-19 21:01:369703 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509704 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:549705
[email protected]49639fa2011-12-20 23:22:419706 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:549707 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:419708 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:549709
9710 const HttpResponseInfo* response = trans->GetResponseInfo();
9711 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509712 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:549713 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9714
9715 std::string response_data;
9716 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9717 EXPECT_EQ("hello world", response_data);
9718
9719 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:239720 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:409721 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:539722 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:279723 base::WeakPtr<SpdySession> spdy_session =
[email protected]41d64e82013-07-03 22:44:269724 CreateSecureSpdySession(session, key, BoundNetLog());
[email protected]02b0c342010-09-25 21:09:389725
[email protected]90499482013-06-01 00:39:509726 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:549727
[email protected]49639fa2011-12-20 23:22:419728 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:549729 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:419730 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:549731
9732 response = trans->GetResponseInfo();
9733 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509734 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:549735 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539736 EXPECT_TRUE(response->was_fetched_via_spdy);
9737 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:549738
9739 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9740 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:429741}
9742
[email protected]044de0642010-06-17 10:42:159743// GenerateAuthToken is a mighty big test.
9744// It tests all permutation of GenerateAuthToken behavior:
9745// - Synchronous and Asynchronous completion.
9746// - OK or error on completion.
9747// - Direct connection, non-authenticating proxy, and authenticating proxy.
9748// - HTTP or HTTPS backend (to include proxy tunneling).
9749// - Non-authenticating and authenticating backend.
9750//
[email protected]fe3b7dc2012-02-03 19:52:099751// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:159752// problems generating an auth token for an authenticating proxy, we don't
9753// need to test all permutations of the backend server).
9754//
9755// The test proceeds by going over each of the configuration cases, and
9756// potentially running up to three rounds in each of the tests. The TestConfig
9757// specifies both the configuration for the test as well as the expectations
9758// for the results.
[email protected]23e482282013-06-14 16:08:029759TEST_P(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:509760 static const char kServer[] = "http://www.example.com";
9761 static const char kSecureServer[] = "https://www.example.com";
9762 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:159763 const int kAuthErr = ERR_INVALID_AUTH_CREDENTIALS;
9764
9765 enum AuthTiming {
9766 AUTH_NONE,
9767 AUTH_SYNC,
9768 AUTH_ASYNC,
9769 };
9770
9771 const MockWrite kGet(
9772 "GET / HTTP/1.1\r\n"
9773 "Host: www.example.com\r\n"
9774 "Connection: keep-alive\r\n\r\n");
9775 const MockWrite kGetProxy(
9776 "GET http://www.example.com/ HTTP/1.1\r\n"
9777 "Host: www.example.com\r\n"
9778 "Proxy-Connection: keep-alive\r\n\r\n");
9779 const MockWrite kGetAuth(
9780 "GET / HTTP/1.1\r\n"
9781 "Host: www.example.com\r\n"
9782 "Connection: keep-alive\r\n"
9783 "Authorization: auth_token\r\n\r\n");
9784 const MockWrite kGetProxyAuth(
9785 "GET http://www.example.com/ HTTP/1.1\r\n"
9786 "Host: www.example.com\r\n"
9787 "Proxy-Connection: keep-alive\r\n"
9788 "Proxy-Authorization: auth_token\r\n\r\n");
9789 const MockWrite kGetAuthThroughProxy(
9790 "GET http://www.example.com/ HTTP/1.1\r\n"
9791 "Host: www.example.com\r\n"
9792 "Proxy-Connection: keep-alive\r\n"
9793 "Authorization: auth_token\r\n\r\n");
9794 const MockWrite kGetAuthWithProxyAuth(
9795 "GET http://www.example.com/ HTTP/1.1\r\n"
9796 "Host: www.example.com\r\n"
9797 "Proxy-Connection: keep-alive\r\n"
9798 "Proxy-Authorization: auth_token\r\n"
9799 "Authorization: auth_token\r\n\r\n");
9800 const MockWrite kConnect(
9801 "CONNECT www.example.com:443 HTTP/1.1\r\n"
9802 "Host: www.example.com\r\n"
9803 "Proxy-Connection: keep-alive\r\n\r\n");
9804 const MockWrite kConnectProxyAuth(
9805 "CONNECT www.example.com:443 HTTP/1.1\r\n"
9806 "Host: www.example.com\r\n"
9807 "Proxy-Connection: keep-alive\r\n"
9808 "Proxy-Authorization: auth_token\r\n\r\n");
9809
9810 const MockRead kSuccess(
9811 "HTTP/1.1 200 OK\r\n"
9812 "Content-Type: text/html; charset=iso-8859-1\r\n"
9813 "Content-Length: 3\r\n\r\n"
9814 "Yes");
9815 const MockRead kFailure(
9816 "Should not be called.");
9817 const MockRead kServerChallenge(
9818 "HTTP/1.1 401 Unauthorized\r\n"
9819 "WWW-Authenticate: Mock realm=server\r\n"
9820 "Content-Type: text/html; charset=iso-8859-1\r\n"
9821 "Content-Length: 14\r\n\r\n"
9822 "Unauthorized\r\n");
9823 const MockRead kProxyChallenge(
9824 "HTTP/1.1 407 Unauthorized\r\n"
9825 "Proxy-Authenticate: Mock realm=proxy\r\n"
9826 "Proxy-Connection: close\r\n"
9827 "Content-Type: text/html; charset=iso-8859-1\r\n"
9828 "Content-Length: 14\r\n\r\n"
9829 "Unauthorized\r\n");
9830 const MockRead kProxyConnected(
9831 "HTTP/1.1 200 Connection Established\r\n\r\n");
9832
9833 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
9834 // no constructors, but the C++ compiler on Windows warns about
9835 // unspecified data in compound literals. So, moved to using constructors,
9836 // and TestRound's created with the default constructor should not be used.
9837 struct TestRound {
9838 TestRound()
9839 : expected_rv(ERR_UNEXPECTED),
9840 extra_write(NULL),
9841 extra_read(NULL) {
9842 }
9843 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
9844 int expected_rv_arg)
9845 : write(write_arg),
9846 read(read_arg),
9847 expected_rv(expected_rv_arg),
9848 extra_write(NULL),
9849 extra_read(NULL) {
9850 }
9851 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
9852 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:019853 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:159854 : write(write_arg),
9855 read(read_arg),
9856 expected_rv(expected_rv_arg),
9857 extra_write(extra_write_arg),
9858 extra_read(extra_read_arg) {
9859 }
9860 MockWrite write;
9861 MockRead read;
9862 int expected_rv;
9863 const MockWrite* extra_write;
9864 const MockRead* extra_read;
9865 };
9866
9867 static const int kNoSSL = 500;
9868
9869 struct TestConfig {
thestig9d3bb0c2015-01-24 00:49:519870 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:159871 AuthTiming proxy_auth_timing;
9872 int proxy_auth_rv;
thestig9d3bb0c2015-01-24 00:49:519873 const char* const server_url;
[email protected]044de0642010-06-17 10:42:159874 AuthTiming server_auth_timing;
9875 int server_auth_rv;
9876 int num_auth_rounds;
9877 int first_ssl_round;
9878 TestRound rounds[3];
9879 } test_configs[] = {
9880 // Non-authenticating HTTP server with a direct connection.
9881 { NULL, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
9882 { TestRound(kGet, kSuccess, OK)}},
9883 // Authenticating HTTP server with a direct connection.
9884 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
9885 { TestRound(kGet, kServerChallenge, OK),
9886 TestRound(kGetAuth, kSuccess, OK)}},
9887 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
9888 { TestRound(kGet, kServerChallenge, OK),
9889 TestRound(kGetAuth, kFailure, kAuthErr)}},
9890 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
9891 { TestRound(kGet, kServerChallenge, OK),
9892 TestRound(kGetAuth, kSuccess, OK)}},
9893 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
9894 { TestRound(kGet, kServerChallenge, OK),
9895 TestRound(kGetAuth, kFailure, kAuthErr)}},
9896 // Non-authenticating HTTP server through a non-authenticating proxy.
9897 { kProxy, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
9898 { TestRound(kGetProxy, kSuccess, OK)}},
9899 // Authenticating HTTP server through a non-authenticating proxy.
9900 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
9901 { TestRound(kGetProxy, kServerChallenge, OK),
9902 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
9903 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
9904 { TestRound(kGetProxy, kServerChallenge, OK),
9905 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
9906 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
9907 { TestRound(kGetProxy, kServerChallenge, OK),
9908 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
9909 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
9910 { TestRound(kGetProxy, kServerChallenge, OK),
9911 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
9912 // Non-authenticating HTTP server through an authenticating proxy.
9913 { kProxy, AUTH_SYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
9914 { TestRound(kGetProxy, kProxyChallenge, OK),
9915 TestRound(kGetProxyAuth, kSuccess, OK)}},
9916 { kProxy, AUTH_SYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
9917 { TestRound(kGetProxy, kProxyChallenge, OK),
9918 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
9919 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
9920 { TestRound(kGetProxy, kProxyChallenge, OK),
9921 TestRound(kGetProxyAuth, kSuccess, OK)}},
9922 { kProxy, AUTH_ASYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
9923 { TestRound(kGetProxy, kProxyChallenge, OK),
9924 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
9925 // Authenticating HTTP server through an authenticating proxy.
9926 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
9927 { TestRound(kGetProxy, kProxyChallenge, OK),
9928 TestRound(kGetProxyAuth, kServerChallenge, OK),
9929 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9930 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
9931 { TestRound(kGetProxy, kProxyChallenge, OK),
9932 TestRound(kGetProxyAuth, kServerChallenge, OK),
9933 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9934 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
9935 { TestRound(kGetProxy, kProxyChallenge, OK),
9936 TestRound(kGetProxyAuth, kServerChallenge, OK),
9937 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9938 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
9939 { TestRound(kGetProxy, kProxyChallenge, OK),
9940 TestRound(kGetProxyAuth, kServerChallenge, OK),
9941 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9942 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
9943 { TestRound(kGetProxy, kProxyChallenge, OK),
9944 TestRound(kGetProxyAuth, kServerChallenge, OK),
9945 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9946 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
9947 { TestRound(kGetProxy, kProxyChallenge, OK),
9948 TestRound(kGetProxyAuth, kServerChallenge, OK),
9949 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9950 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
9951 { TestRound(kGetProxy, kProxyChallenge, OK),
9952 TestRound(kGetProxyAuth, kServerChallenge, OK),
9953 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9954 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
9955 { TestRound(kGetProxy, kProxyChallenge, OK),
9956 TestRound(kGetProxyAuth, kServerChallenge, OK),
9957 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9958 // Non-authenticating HTTPS server with a direct connection.
9959 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
9960 { TestRound(kGet, kSuccess, OK)}},
9961 // Authenticating HTTPS server with a direct connection.
9962 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
9963 { TestRound(kGet, kServerChallenge, OK),
9964 TestRound(kGetAuth, kSuccess, OK)}},
9965 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
9966 { TestRound(kGet, kServerChallenge, OK),
9967 TestRound(kGetAuth, kFailure, kAuthErr)}},
9968 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
9969 { TestRound(kGet, kServerChallenge, OK),
9970 TestRound(kGetAuth, kSuccess, OK)}},
9971 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
9972 { TestRound(kGet, kServerChallenge, OK),
9973 TestRound(kGetAuth, kFailure, kAuthErr)}},
9974 // Non-authenticating HTTPS server with a non-authenticating proxy.
9975 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
9976 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
9977 // Authenticating HTTPS server through a non-authenticating proxy.
9978 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
9979 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9980 TestRound(kGetAuth, kSuccess, OK)}},
9981 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
9982 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9983 TestRound(kGetAuth, kFailure, kAuthErr)}},
9984 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
9985 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9986 TestRound(kGetAuth, kSuccess, OK)}},
9987 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
9988 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9989 TestRound(kGetAuth, kFailure, kAuthErr)}},
9990 // Non-Authenticating HTTPS server through an authenticating proxy.
9991 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
9992 { TestRound(kConnect, kProxyChallenge, OK),
9993 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
9994 { kProxy, AUTH_SYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
9995 { TestRound(kConnect, kProxyChallenge, OK),
9996 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
9997 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
9998 { TestRound(kConnect, kProxyChallenge, OK),
9999 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
10000 { kProxy, AUTH_ASYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
10001 { TestRound(kConnect, kProxyChallenge, OK),
10002 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
10003 // Authenticating HTTPS server through an authenticating proxy.
10004 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
10005 { TestRound(kConnect, kProxyChallenge, OK),
10006 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10007 &kGet, &kServerChallenge),
10008 TestRound(kGetAuth, kSuccess, OK)}},
10009 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
10010 { TestRound(kConnect, kProxyChallenge, OK),
10011 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10012 &kGet, &kServerChallenge),
10013 TestRound(kGetAuth, kFailure, kAuthErr)}},
10014 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
10015 { TestRound(kConnect, kProxyChallenge, OK),
10016 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10017 &kGet, &kServerChallenge),
10018 TestRound(kGetAuth, kSuccess, OK)}},
10019 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
10020 { TestRound(kConnect, kProxyChallenge, OK),
10021 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10022 &kGet, &kServerChallenge),
10023 TestRound(kGetAuth, kFailure, kAuthErr)}},
10024 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
10025 { TestRound(kConnect, kProxyChallenge, OK),
10026 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10027 &kGet, &kServerChallenge),
10028 TestRound(kGetAuth, kSuccess, OK)}},
10029 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
10030 { TestRound(kConnect, kProxyChallenge, OK),
10031 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10032 &kGet, &kServerChallenge),
10033 TestRound(kGetAuth, kFailure, kAuthErr)}},
10034 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
10035 { TestRound(kConnect, kProxyChallenge, OK),
10036 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10037 &kGet, &kServerChallenge),
10038 TestRound(kGetAuth, kSuccess, OK)}},
10039 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
10040 { TestRound(kConnect, kProxyChallenge, OK),
10041 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10042 &kGet, &kServerChallenge),
10043 TestRound(kGetAuth, kFailure, kAuthErr)}},
10044 };
10045
viettrungluue4a8b882014-10-16 06:17:3810046 for (size_t i = 0; i < arraysize(test_configs); ++i) {
[email protected]2d01c262011-08-11 23:07:0810047 HttpAuthHandlerMock::Factory* auth_factory(
10048 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0710049 session_deps_.http_auth_handler_factory.reset(auth_factory);
[email protected]044de0642010-06-17 10:42:1510050 const TestConfig& test_config = test_configs[i];
[email protected]65d34382010-07-01 18:12:2610051
10052 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:1510053 if (test_config.proxy_auth_timing != AUTH_NONE) {
[email protected]2d01c262011-08-11 23:07:0810054 for (int n = 0; n < 2; n++) {
10055 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
10056 std::string auth_challenge = "Mock realm=proxy";
10057 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:2410058 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
10059 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:0810060 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
10061 origin, BoundNetLog());
10062 auth_handler->SetGenerateExpectation(
10063 test_config.proxy_auth_timing == AUTH_ASYNC,
10064 test_config.proxy_auth_rv);
10065 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
10066 }
[email protected]044de0642010-06-17 10:42:1510067 }
10068 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:0010069 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:1510070 std::string auth_challenge = "Mock realm=server";
10071 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:2410072 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
10073 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:1510074 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
10075 origin, BoundNetLog());
10076 auth_handler->SetGenerateExpectation(
10077 test_config.server_auth_timing == AUTH_ASYNC,
10078 test_config.server_auth_rv);
[email protected]2d01c262011-08-11 23:07:0810079 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:1510080 }
10081 if (test_config.proxy_url) {
[email protected]bb88e1d32013-05-03 23:11:0710082 session_deps_.proxy_service.reset(
[email protected]6104ea5d2011-04-27 21:37:1210083 ProxyService::CreateFixed(test_config.proxy_url));
[email protected]044de0642010-06-17 10:42:1510084 } else {
[email protected]bb88e1d32013-05-03 23:11:0710085 session_deps_.proxy_service.reset(ProxyService::CreateDirect());
[email protected]044de0642010-06-17 10:42:1510086 }
10087
10088 HttpRequestInfo request;
10089 request.method = "GET";
10090 request.url = GURL(test_config.server_url);
10091 request.load_flags = 0;
10092
[email protected]bb88e1d32013-05-03 23:11:0710093 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
dcheng48459ac22014-08-26 00:46:4110094 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]044de0642010-06-17 10:42:1510095
rchcb68dc62015-05-21 04:45:3610096 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
10097
10098 std::vector<std::vector<MockRead>> mock_reads(1);
10099 std::vector<std::vector<MockWrite>> mock_writes(1);
[email protected]044de0642010-06-17 10:42:1510100 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
10101 const TestRound& read_write_round = test_config.rounds[round];
10102
10103 // Set up expected reads and writes.
rchcb68dc62015-05-21 04:45:3610104 mock_reads.back().push_back(read_write_round.read);
10105 mock_writes.back().push_back(read_write_round.write);
10106
10107 // kProxyChallenge uses Proxy-Connection: close which means that the
10108 // socket is closed and a new one will be created for the next request.
10109 if (read_write_round.read.data == kProxyChallenge.data &&
10110 read_write_round.write.data != kConnect.data) {
10111 mock_reads.push_back(std::vector<MockRead>());
10112 mock_writes.push_back(std::vector<MockWrite>());
[email protected]044de0642010-06-17 10:42:1510113 }
10114
rchcb68dc62015-05-21 04:45:3610115 if (read_write_round.extra_read) {
10116 mock_reads.back().push_back(*read_write_round.extra_read);
[email protected]044de0642010-06-17 10:42:1510117 }
rchcb68dc62015-05-21 04:45:3610118 if (read_write_round.extra_write) {
10119 mock_writes.back().push_back(*read_write_round.extra_write);
10120 }
[email protected]044de0642010-06-17 10:42:1510121
10122 // Add an SSL sequence if necessary.
[email protected]044de0642010-06-17 10:42:1510123 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0710124 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1510125 &ssl_socket_data_provider);
rchcb68dc62015-05-21 04:45:3610126 }
[email protected]044de0642010-06-17 10:42:1510127
rchcb68dc62015-05-21 04:45:3610128 ScopedVector<StaticSocketDataProvider> data_providers;
10129 for (size_t i = 0; i < mock_reads.size(); ++i) {
10130 data_providers.push_back(new StaticSocketDataProvider(
10131 vector_as_array(&mock_reads[i]), mock_reads[i].size(),
10132 vector_as_array(&mock_writes[i]), mock_writes[i].size()));
10133 session_deps_.socket_factory->AddSocketDataProvider(
10134 data_providers.back());
10135 }
10136
10137 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
10138 const TestRound& read_write_round = test_config.rounds[round];
[email protected]044de0642010-06-17 10:42:1510139 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4110140 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1510141 int rv;
10142 if (round == 0) {
[email protected]49639fa2011-12-20 23:22:4110143 rv = trans.Start(&request, callback.callback(), BoundNetLog());
[email protected]044de0642010-06-17 10:42:1510144 } else {
[email protected]49639fa2011-12-20 23:22:4110145 rv = trans.RestartWithAuth(
10146 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1510147 }
10148 if (rv == ERR_IO_PENDING)
10149 rv = callback.WaitForResult();
10150
10151 // Compare results with expected data.
10152 EXPECT_EQ(read_write_round.expected_rv, rv);
[email protected]0b0bf032010-09-21 18:08:5010153 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttlec0c828492015-05-15 01:25:5510154 if (read_write_round.expected_rv != OK) {
[email protected]044de0642010-06-17 10:42:1510155 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
10156 continue;
10157 }
10158 if (round + 1 < test_config.num_auth_rounds) {
10159 EXPECT_FALSE(response->auth_challenge.get() == NULL);
10160 } else {
10161 EXPECT_TRUE(response->auth_challenge.get() == NULL);
10162 }
10163 }
[email protected]e5ae96a2010-04-14 20:12:4510164 }
10165}
10166
[email protected]23e482282013-06-14 16:08:0210167TEST_P(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1410168 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1410169 HttpAuthHandlerMock::Factory* auth_factory(
10170 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0710171 session_deps_.http_auth_handler_factory.reset(auth_factory);
10172 session_deps_.proxy_service.reset(ProxyService::CreateDirect());
10173 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
10174 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:1410175
10176 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
10177 auth_handler->set_connection_based(true);
10178 std::string auth_challenge = "Mock realm=server";
10179 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2410180 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
10181 auth_challenge.end());
[email protected]c871bce92010-07-15 21:51:1410182 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
10183 origin, BoundNetLog());
[email protected]2d01c262011-08-11 23:07:0810184 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1410185
[email protected]c871bce92010-07-15 21:51:1410186 int rv = OK;
10187 const HttpResponseInfo* response = NULL;
10188 HttpRequestInfo request;
10189 request.method = "GET";
10190 request.url = origin;
10191 request.load_flags = 0;
[email protected]cb9bf6ca2011-01-28 13:15:2710192
[email protected]bb88e1d32013-05-03 23:11:0710193 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1010194
10195 // Use a TCP Socket Pool with only one connection per group. This is used
10196 // to validate that the TCP socket is not released to the pool between
10197 // each round of multi-round authentication.
10198 HttpNetworkSessionPeer session_peer(session);
[email protected]ab739042011-04-07 15:22:2810199 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:1010200 50, // Max sockets for pool
10201 1, // Max sockets per group
[email protected]bb88e1d32013-05-03 23:11:0710202 session_deps_.host_resolver.get(),
10203 session_deps_.socket_factory.get(),
10204 session_deps_.net_log);
[email protected]831e4a32013-11-14 02:14:4410205 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
10206 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:0210207 mock_pool_manager->SetTransportSocketPool(transport_pool);
dchenge3d1ddc2014-10-15 19:30:5110208 session_peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]7ef4cbbb2011-02-06 11:19:1010209
[email protected]262eec82013-03-19 21:01:3610210 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010211 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110212 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1410213
10214 const MockWrite kGet(
10215 "GET / HTTP/1.1\r\n"
10216 "Host: www.example.com\r\n"
10217 "Connection: keep-alive\r\n\r\n");
10218 const MockWrite kGetAuth(
10219 "GET / HTTP/1.1\r\n"
10220 "Host: www.example.com\r\n"
10221 "Connection: keep-alive\r\n"
10222 "Authorization: auth_token\r\n\r\n");
10223
10224 const MockRead kServerChallenge(
10225 "HTTP/1.1 401 Unauthorized\r\n"
10226 "WWW-Authenticate: Mock realm=server\r\n"
10227 "Content-Type: text/html; charset=iso-8859-1\r\n"
10228 "Content-Length: 14\r\n\r\n"
10229 "Unauthorized\r\n");
10230 const MockRead kSuccess(
10231 "HTTP/1.1 200 OK\r\n"
10232 "Content-Type: text/html; charset=iso-8859-1\r\n"
10233 "Content-Length: 3\r\n\r\n"
10234 "Yes");
10235
10236 MockWrite writes[] = {
10237 // First round
10238 kGet,
10239 // Second round
10240 kGetAuth,
10241 // Third round
10242 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3010243 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1010244 kGetAuth,
10245 // Competing request
10246 kGet,
[email protected]c871bce92010-07-15 21:51:1410247 };
10248 MockRead reads[] = {
10249 // First round
10250 kServerChallenge,
10251 // Second round
10252 kServerChallenge,
10253 // Third round
[email protected]eca50e122010-09-11 14:03:3010254 kServerChallenge,
10255 // Fourth round
[email protected]c871bce92010-07-15 21:51:1410256 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1010257 // Competing response
10258 kSuccess,
[email protected]c871bce92010-07-15 21:51:1410259 };
10260 StaticSocketDataProvider data_provider(reads, arraysize(reads),
10261 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:0710262 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1410263
thestig9d3bb0c2015-01-24 00:49:5110264 const char kSocketGroup[] = "www.example.com:80";
[email protected]7ef4cbbb2011-02-06 11:19:1010265
10266 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1410267 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4110268 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]c871bce92010-07-15 21:51:1410269 if (rv == ERR_IO_PENDING)
10270 rv = callback.WaitForResult();
10271 EXPECT_EQ(OK, rv);
10272 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010273 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:1410274 EXPECT_FALSE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2810275 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1410276
[email protected]7ef4cbbb2011-02-06 11:19:1010277 // In between rounds, another request comes in for the same domain.
10278 // It should not be able to grab the TCP socket that trans has already
10279 // claimed.
10280 scoped_ptr<HttpTransaction> trans_compete(
[email protected]90499482013-06-01 00:39:5010281 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110282 TestCompletionCallback callback_compete;
10283 rv = trans_compete->Start(
10284 &request, callback_compete.callback(), BoundNetLog());
[email protected]7ef4cbbb2011-02-06 11:19:1010285 EXPECT_EQ(ERR_IO_PENDING, rv);
10286 // callback_compete.WaitForResult at this point would stall forever,
10287 // since the HttpNetworkTransaction does not release the request back to
10288 // the pool until after authentication completes.
10289
10290 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1410291 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4110292 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1410293 if (rv == ERR_IO_PENDING)
10294 rv = callback.WaitForResult();
10295 EXPECT_EQ(OK, rv);
10296 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010297 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:1410298 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2810299 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1410300
[email protected]7ef4cbbb2011-02-06 11:19:1010301 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1410302 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4110303 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1410304 if (rv == ERR_IO_PENDING)
10305 rv = callback.WaitForResult();
10306 EXPECT_EQ(OK, rv);
10307 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010308 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:1410309 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2810310 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]eca50e122010-09-11 14:03:3010311
[email protected]7ef4cbbb2011-02-06 11:19:1010312 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3010313 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4110314 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3010315 if (rv == ERR_IO_PENDING)
10316 rv = callback.WaitForResult();
10317 EXPECT_EQ(OK, rv);
10318 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010319 ASSERT_TRUE(response != NULL);
[email protected]eca50e122010-09-11 14:03:3010320 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2810321 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1010322
10323 // Read the body since the fourth round was successful. This will also
10324 // release the socket back to the pool.
10325 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
[email protected]90499482013-06-01 00:39:5010326 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1010327 if (rv == ERR_IO_PENDING)
10328 rv = callback.WaitForResult();
10329 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:5010330 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1010331 EXPECT_EQ(0, rv);
10332 // There are still 0 idle sockets, since the trans_compete transaction
10333 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:2810334 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1010335
10336 // The competing request can now finish. Wait for the headers and then
10337 // read the body.
10338 rv = callback_compete.WaitForResult();
10339 EXPECT_EQ(OK, rv);
[email protected]90499482013-06-01 00:39:5010340 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1010341 if (rv == ERR_IO_PENDING)
10342 rv = callback.WaitForResult();
10343 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:5010344 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1010345 EXPECT_EQ(0, rv);
10346
10347 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:2810348 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1410349}
10350
[email protected]65041fa2010-05-21 06:56:5310351// This tests the case that a request is issued via http instead of spdy after
10352// npn is negotiated.
[email protected]23e482282013-06-14 16:08:0210353TEST_P(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]d7599122014-05-24 03:37:2310354 session_deps_.use_alternate_protocols = true;
10355 NextProtoVector next_protos;
[email protected]0ce3af82013-07-22 16:17:1610356 next_protos.push_back(kProtoHTTP11);
[email protected]d7599122014-05-24 03:37:2310357 session_deps_.next_protos = next_protos;
10358
[email protected]65041fa2010-05-21 06:56:5310359 HttpRequestInfo request;
10360 request.method = "GET";
bncce36dca22015-04-21 22:11:2310361 request.url = GURL("https://www.example.org/");
[email protected]65041fa2010-05-21 06:56:5310362 request.load_flags = 0;
10363
10364 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310365 MockWrite(
10366 "GET / HTTP/1.1\r\n"
10367 "Host: www.example.org\r\n"
10368 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5310369 };
10370
[email protected]8a0fc822013-06-27 20:52:4310371 std::string alternate_protocol_http_header =
10372 GetAlternateProtocolHttpHeader();
10373
[email protected]65041fa2010-05-21 06:56:5310374 MockRead data_reads[] = {
10375 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:4310376 MockRead(alternate_protocol_http_header.c_str()),
[email protected]65041fa2010-05-21 06:56:5310377 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610378 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5310379 };
10380
[email protected]8ddf8322012-02-23 18:08:0610381 SSLSocketDataProvider ssl(ASYNC, OK);
davidben6974bf72015-04-27 17:52:4810382 ssl.SetNextProto(kProtoHTTP11);
[email protected]65041fa2010-05-21 06:56:5310383
[email protected]bb88e1d32013-05-03 23:11:0710384 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5310385
10386 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
10387 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0710388 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5310389
[email protected]49639fa2011-12-20 23:22:4110390 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5310391
[email protected]bb88e1d32013-05-03 23:11:0710392 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610393 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010394 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]65041fa2010-05-21 06:56:5310395
[email protected]49639fa2011-12-20 23:22:4110396 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]65041fa2010-05-21 06:56:5310397
10398 EXPECT_EQ(ERR_IO_PENDING, rv);
10399 EXPECT_EQ(OK, callback.WaitForResult());
10400
10401 const HttpResponseInfo* response = trans->GetResponseInfo();
10402 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010403 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]65041fa2010-05-21 06:56:5310404 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10405
10406 std::string response_data;
10407 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10408 EXPECT_EQ("hello world", response_data);
10409
10410 EXPECT_FALSE(response->was_fetched_via_spdy);
10411 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]65041fa2010-05-21 06:56:5310412}
[email protected]26ef6582010-06-24 02:30:4710413
[email protected]23e482282013-06-14 16:08:0210414TEST_P(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:4710415 // Simulate the SSL handshake completing with an NPN negotiation
10416 // followed by an immediate server closing of the socket.
10417 // Fix crash: http://crbug.com/46369
[email protected]d7599122014-05-24 03:37:2310418 session_deps_.use_alternate_protocols = true;
10419 session_deps_.next_protos = SpdyNextProtos();
[email protected]26ef6582010-06-24 02:30:4710420
10421 HttpRequestInfo request;
10422 request.method = "GET";
bncce36dca22015-04-21 22:11:2310423 request.url = GURL("https://www.example.org/");
[email protected]26ef6582010-06-24 02:30:4710424 request.load_flags = 0;
10425
[email protected]8ddf8322012-02-23 18:08:0610426 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210427 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710428 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4710429
[email protected]cdf8f7e72013-05-23 10:56:4610430 scoped_ptr<SpdyFrame> req(
10431 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
rch8e6c6c42015-05-01 14:05:1310432 MockWrite spdy_writes[] = {CreateMockWrite(*req, 1)};
[email protected]26ef6582010-06-24 02:30:4710433
10434 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0610435 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4710436 };
10437
rch8e6c6c42015-05-01 14:05:1310438 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10439 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710440 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4710441
[email protected]49639fa2011-12-20 23:22:4110442 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4710443
[email protected]bb88e1d32013-05-03 23:11:0710444 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610445 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010446 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]26ef6582010-06-24 02:30:4710447
[email protected]49639fa2011-12-20 23:22:4110448 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]26ef6582010-06-24 02:30:4710449 EXPECT_EQ(ERR_IO_PENDING, rv);
10450 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult());
[email protected]26ef6582010-06-24 02:30:4710451}
[email protected]65d34382010-07-01 18:12:2610452
[email protected]795cbf82013-07-22 09:37:2710453// A subclass of HttpAuthHandlerMock that records the request URL when
10454// it gets it. This is needed since the auth handler may get destroyed
10455// before we get a chance to query it.
10456class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
10457 public:
10458 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
10459
dchengb03027d2014-10-21 12:00:2010460 ~UrlRecordingHttpAuthHandlerMock() override {}
[email protected]795cbf82013-07-22 09:37:2710461
10462 protected:
dchengb03027d2014-10-21 12:00:2010463 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
10464 const HttpRequestInfo* request,
10465 const CompletionCallback& callback,
10466 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2710467 *url_ = request->url;
10468 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
10469 credentials, request, callback, auth_token);
10470 }
10471
10472 private:
10473 GURL* url_;
10474};
10475
[email protected]23e482282013-06-14 16:08:0210476TEST_P(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) {
[email protected]f45c1ee2010-08-03 00:54:3010477 // This test ensures that the URL passed into the proxy is upgraded
10478 // to https when doing an Alternate Protocol upgrade.
[email protected]d7599122014-05-24 03:37:2310479 session_deps_.use_alternate_protocols = true;
10480 session_deps_.next_protos = SpdyNextProtos();
[email protected]f45c1ee2010-08-03 00:54:3010481
[email protected]bb88e1d32013-05-03 23:11:0710482 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:2010483 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
vishal.b62985ca92015-04-17 08:45:5110484 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710485 session_deps_.net_log = &net_log;
[email protected]795cbf82013-07-22 09:37:2710486 GURL request_url;
10487 {
10488 HttpAuthHandlerMock::Factory* auth_factory =
10489 new HttpAuthHandlerMock::Factory();
10490 UrlRecordingHttpAuthHandlerMock* auth_handler =
10491 new UrlRecordingHttpAuthHandlerMock(&request_url);
10492 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
10493 auth_factory->set_do_init_from_challenge(true);
10494 session_deps_.http_auth_handler_factory.reset(auth_factory);
10495 }
[email protected]f45c1ee2010-08-03 00:54:3010496
10497 HttpRequestInfo request;
10498 request.method = "GET";
bncce36dca22015-04-21 22:11:2310499 request.url = GURL("http://www.example.org");
[email protected]f45c1ee2010-08-03 00:54:3010500 request.load_flags = 0;
10501
10502 // First round goes unauthenticated through the proxy.
10503 MockWrite data_writes_1[] = {
bncce36dca22015-04-21 22:11:2310504 MockWrite(
10505 "GET http://www.example.org/ HTTP/1.1\r\n"
10506 "Host: www.example.org\r\n"
10507 "Proxy-Connection: keep-alive\r\n"
10508 "\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3010509 };
10510 MockRead data_reads_1[] = {
[email protected]8ddf8322012-02-23 18:08:0610511 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
bnc33b8cef42014-11-19 17:30:3810512 MockRead("HTTP/1.1 200 OK\r\n"),
10513 MockRead("Alternate-Protocol: 443:"),
10514 MockRead(GetAlternateProtocolFromParam()),
10515 MockRead("\r\n"),
10516 MockRead("Proxy-Connection: close\r\n"),
10517 MockRead("\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3010518 };
10519 StaticSocketDataProvider data_1(data_reads_1, arraysize(data_reads_1),
10520 data_writes_1, arraysize(data_writes_1));
10521
bncce36dca22015-04-21 22:11:2310522 // Second round tries to tunnel to www.example.org due to the
[email protected]f45c1ee2010-08-03 00:54:3010523 // Alternate-Protocol announcement in the first round. It fails due
10524 // to a proxy authentication challenge.
bncce36dca22015-04-21 22:11:2310525 // After the failure, a tunnel is established to www.example.org using
[email protected]394816e92010-08-03 07:38:5910526 // Proxy-Authorization headers. There is then a SPDY request round.
10527 //
[email protected]fe3b7dc2012-02-03 19:52:0910528 // NOTE: Despite the "Proxy-Connection: Close", these are done on the
10529 // same MockTCPClientSocket since the underlying HttpNetworkClientSocket
10530 // does a Disconnect and Connect on the same socket, rather than trying
10531 // to obtain a new one.
10532 //
[email protected]394816e92010-08-03 07:38:5910533 // NOTE: Originally, the proxy response to the second CONNECT request
10534 // simply returned another 407 so the unit test could skip the SSL connection
10535 // establishment and SPDY framing issues. Alas, the
10536 // retry-http-when-alternate-protocol fails logic kicks in, which was more
[email protected]f45c1ee2010-08-03 00:54:3010537 // complicated to set up expectations for than the SPDY session.
[email protected]394816e92010-08-03 07:38:5910538
[email protected]cdf8f7e72013-05-23 10:56:4610539 scoped_ptr<SpdyFrame> req(
10540 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]23e482282013-06-14 16:08:0210541 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10542 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]f45c1ee2010-08-03 00:54:3010543
[email protected]394816e92010-08-03 07:38:5910544 MockWrite data_writes_2[] = {
bncce36dca22015-04-21 22:11:2310545 // First connection attempt without Proxy-Authorization.
rch8e6c6c42015-05-01 14:05:1310546 MockWrite(ASYNC, 0,
10547 "CONNECT www.example.org:443 HTTP/1.1\r\n"
10548 "Host: www.example.org\r\n"
10549 "Proxy-Connection: keep-alive\r\n"
10550 "\r\n"),
[email protected]394816e92010-08-03 07:38:5910551
bncce36dca22015-04-21 22:11:2310552 // Second connection attempt with Proxy-Authorization.
rch8e6c6c42015-05-01 14:05:1310553 MockWrite(ASYNC, 2,
10554 "CONNECT www.example.org:443 HTTP/1.1\r\n"
10555 "Host: www.example.org\r\n"
10556 "Proxy-Connection: keep-alive\r\n"
10557 "Proxy-Authorization: auth_token\r\n"
10558 "\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3010559
bncce36dca22015-04-21 22:11:2310560 // SPDY request
rch8e6c6c42015-05-01 14:05:1310561 CreateMockWrite(*req, 4),
[email protected]f45c1ee2010-08-03 00:54:3010562 };
[email protected]394816e92010-08-03 07:38:5910563 const char kRejectConnectResponse[] = ("HTTP/1.1 407 Unauthorized\r\n"
10564 "Proxy-Authenticate: Mock\r\n"
10565 "Proxy-Connection: close\r\n"
10566 "\r\n");
10567 const char kAcceptConnectResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
10568 MockRead data_reads_2[] = {
rch8e6c6c42015-05-01 14:05:1310569 // First connection attempt fails
10570 MockRead(ASYNC, kRejectConnectResponse,
10571 arraysize(kRejectConnectResponse) - 1, 1),
[email protected]394816e92010-08-03 07:38:5910572
rch8e6c6c42015-05-01 14:05:1310573 // Second connection attempt passes
10574 MockRead(ASYNC, kAcceptConnectResponse,
10575 arraysize(kAcceptConnectResponse) - 1, 3),
[email protected]394816e92010-08-03 07:38:5910576
rch8e6c6c42015-05-01 14:05:1310577 // SPDY response
10578 CreateMockRead(*resp.get(), 5),
10579 CreateMockRead(*data.get(), 6),
10580 MockRead(ASYNC, 0, 0, 7),
[email protected]394816e92010-08-03 07:38:5910581 };
rch8e6c6c42015-05-01 14:05:1310582 SequencedSocketData data_2(data_reads_2, arraysize(data_reads_2),
10583 data_writes_2, arraysize(data_writes_2));
[email protected]f45c1ee2010-08-03 00:54:3010584
[email protected]8ddf8322012-02-23 18:08:0610585 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210586 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:2310587 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
10588 ASSERT_TRUE(ssl.cert.get());
[email protected]f45c1ee2010-08-03 00:54:3010589
[email protected]d973e99a2012-02-17 21:02:3610590 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5510591 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
10592 NULL, 0, NULL, 0);
10593 hanging_non_alternate_protocol_socket.set_connect_data(
10594 never_finishing_connect);
10595
[email protected]bb88e1d32013-05-03 23:11:0710596 session_deps_.socket_factory->AddSocketDataProvider(&data_1);
10597 session_deps_.socket_factory->AddSocketDataProvider(&data_2);
10598 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10599 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5510600 &hanging_non_alternate_protocol_socket);
[email protected]bb88e1d32013-05-03 23:11:0710601 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f45c1ee2010-08-03 00:54:3010602
10603 // First round should work and provide the Alternate-Protocol state.
[email protected]49639fa2011-12-20 23:22:4110604 TestCompletionCallback callback_1;
[email protected]262eec82013-03-19 21:01:3610605 scoped_ptr<HttpTransaction> trans_1(
[email protected]90499482013-06-01 00:39:5010606 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110607 int rv = trans_1->Start(&request, callback_1.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:3010608 EXPECT_EQ(ERR_IO_PENDING, rv);
10609 EXPECT_EQ(OK, callback_1.WaitForResult());
10610
10611 // Second round should attempt a tunnel connect and get an auth challenge.
[email protected]49639fa2011-12-20 23:22:4110612 TestCompletionCallback callback_2;
[email protected]262eec82013-03-19 21:01:3610613 scoped_ptr<HttpTransaction> trans_2(
[email protected]90499482013-06-01 00:39:5010614 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110615 rv = trans_2->Start(&request, callback_2.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:3010616 EXPECT_EQ(ERR_IO_PENDING, rv);
10617 EXPECT_EQ(OK, callback_2.WaitForResult());
10618 const HttpResponseInfo* response = trans_2->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010619 ASSERT_TRUE(response != NULL);
[email protected]f45c1ee2010-08-03 00:54:3010620 ASSERT_FALSE(response->auth_challenge.get() == NULL);
10621
10622 // Restart with auth. Tunnel should work and response received.
[email protected]49639fa2011-12-20 23:22:4110623 TestCompletionCallback callback_3;
10624 rv = trans_2->RestartWithAuth(
10625 AuthCredentials(kFoo, kBar), callback_3.callback());
[email protected]f45c1ee2010-08-03 00:54:3010626 EXPECT_EQ(ERR_IO_PENDING, rv);
10627 EXPECT_EQ(OK, callback_3.WaitForResult());
10628
10629 // After all that work, these two lines (or actually, just the scheme) are
10630 // what this test is all about. Make sure it happens correctly.
[email protected]f45c1ee2010-08-03 00:54:3010631 EXPECT_EQ("https", request_url.scheme());
bncce36dca22015-04-21 22:11:2310632 EXPECT_EQ("www.example.org", request_url.host());
[email protected]f45c1ee2010-08-03 00:54:3010633
[email protected]029c83b62013-01-24 05:28:2010634 LoadTimingInfo load_timing_info;
10635 EXPECT_TRUE(trans_2->GetLoadTimingInfo(&load_timing_info));
10636 TestLoadTimingNotReusedWithPac(load_timing_info,
10637 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]8e6441ca2010-08-19 05:56:3810638}
10639
10640// Test that if we cancel the transaction as the connection is completing, that
10641// everything tears down correctly.
[email protected]23e482282013-06-14 16:08:0210642TEST_P(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3810643 // Setup everything about the connection to complete synchronously, so that
10644 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
10645 // for is the callback from the HttpStreamRequest.
10646 // Then cancel the transaction.
10647 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3610648 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3810649 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0610650 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
10651 MockRead(SYNCHRONOUS, "hello world"),
10652 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3810653 };
10654
[email protected]8e6441ca2010-08-19 05:56:3810655 HttpRequestInfo request;
10656 request.method = "GET";
bncce36dca22015-04-21 22:11:2310657 request.url = GURL("http://www.example.org/");
[email protected]8e6441ca2010-08-19 05:56:3810658 request.load_flags = 0;
10659
[email protected]bb88e1d32013-05-03 23:11:0710660 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]3fe8d2f82013-10-17 08:56:0710661 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:2710662 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4110663 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:2710664
[email protected]8e6441ca2010-08-19 05:56:3810665 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10666 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710667 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3810668
[email protected]49639fa2011-12-20 23:22:4110669 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3810670
vishal.b62985ca92015-04-17 08:45:5110671 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4110672 int rv = trans->Start(&request, callback.callback(), log.bound());
[email protected]8e6441ca2010-08-19 05:56:3810673 EXPECT_EQ(ERR_IO_PENDING, rv);
10674 trans.reset(); // Cancel the transaction here.
10675
[email protected]2da659e2013-05-23 20:51:3410676 base::MessageLoop::current()->RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3010677}
10678
[email protected]ecab6e052014-05-16 14:58:1210679// Test that if a transaction is cancelled after receiving the headers, the
10680// stream is drained properly and added back to the socket pool. The main
10681// purpose of this test is to make sure that an HttpStreamParser can be read
10682// from after the HttpNetworkTransaction and the objects it owns have been
10683// deleted.
10684// See http://crbug.com/368418
10685TEST_P(HttpNetworkTransactionTest, CancelAfterHeaders) {
10686 MockRead data_reads[] = {
10687 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
10688 MockRead(ASYNC, "Content-Length: 2\r\n"),
10689 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
10690 MockRead(ASYNC, "1"),
10691 // 2 async reads are necessary to trigger a ReadResponseBody call after the
10692 // HttpNetworkTransaction has been deleted.
10693 MockRead(ASYNC, "2"),
10694 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
10695 };
10696 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10697 session_deps_.socket_factory->AddSocketDataProvider(&data);
10698
10699 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10700
10701 {
10702 HttpRequestInfo request;
10703 request.method = "GET";
bncce36dca22015-04-21 22:11:2310704 request.url = GURL("http://www.example.org/");
[email protected]ecab6e052014-05-16 14:58:1210705 request.load_flags = 0;
10706
dcheng48459ac22014-08-26 00:46:4110707 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1210708 TestCompletionCallback callback;
10709
10710 int rv = trans.Start(&request, callback.callback(), BoundNetLog());
10711 EXPECT_EQ(ERR_IO_PENDING, rv);
10712 callback.WaitForResult();
10713
10714 const HttpResponseInfo* response = trans.GetResponseInfo();
10715 ASSERT_TRUE(response != NULL);
10716 EXPECT_TRUE(response->headers.get() != NULL);
10717 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10718
10719 // The transaction and HttpRequestInfo are deleted.
10720 }
10721
10722 // Let the HttpResponseBodyDrainer drain the socket.
10723 base::MessageLoop::current()->RunUntilIdle();
10724
10725 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4110726 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1210727}
10728
[email protected]76a505b2010-08-25 06:23:0010729// Test a basic GET request through a proxy.
[email protected]23e482282013-06-14 16:08:0210730TEST_P(HttpNetworkTransactionTest, ProxyGet) {
[email protected]bb88e1d32013-05-03 23:11:0710731 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:2010732 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
vishal.b62985ca92015-04-17 08:45:5110733 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710734 session_deps_.net_log = log.bound().net_log();
10735 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0010736
[email protected]76a505b2010-08-25 06:23:0010737 HttpRequestInfo request;
10738 request.method = "GET";
bncce36dca22015-04-21 22:11:2310739 request.url = GURL("http://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0010740
10741 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2310742 MockWrite(
10743 "GET http://www.example.org/ HTTP/1.1\r\n"
10744 "Host: www.example.org\r\n"
10745 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0010746 };
10747
10748 MockRead data_reads1[] = {
10749 MockRead("HTTP/1.1 200 OK\r\n"),
10750 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10751 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610752 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0010753 };
10754
10755 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10756 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710757 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0010758
[email protected]49639fa2011-12-20 23:22:4110759 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0010760
[email protected]262eec82013-03-19 21:01:3610761 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010762 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]597a1ab2014-06-26 08:12:2710763 BeforeProxyHeadersSentHandler proxy_headers_handler;
10764 trans->SetBeforeProxyHeadersSentCallback(
10765 base::Bind(&BeforeProxyHeadersSentHandler::OnBeforeProxyHeadersSent,
10766 base::Unretained(&proxy_headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5010767
[email protected]49639fa2011-12-20 23:22:4110768 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0010769 EXPECT_EQ(ERR_IO_PENDING, rv);
10770
10771 rv = callback1.WaitForResult();
10772 EXPECT_EQ(OK, rv);
10773
10774 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010775 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:0010776
10777 EXPECT_TRUE(response->headers->IsKeepAlive());
10778 EXPECT_EQ(200, response->headers->response_code());
10779 EXPECT_EQ(100, response->headers->GetContentLength());
10780 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]d8fc4722014-06-13 13:17:1510781 EXPECT_TRUE(
10782 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
[email protected]597a1ab2014-06-26 08:12:2710783 EXPECT_TRUE(proxy_headers_handler.observed_before_proxy_headers_sent());
10784 EXPECT_EQ("myproxy:70", proxy_headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0010785 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2010786
10787 LoadTimingInfo load_timing_info;
10788 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10789 TestLoadTimingNotReusedWithPac(load_timing_info,
10790 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0010791}
10792
10793// Test a basic HTTPS GET request through a proxy.
[email protected]23e482282013-06-14 16:08:0210794TEST_P(HttpNetworkTransactionTest, ProxyTunnelGet) {
[email protected]bb88e1d32013-05-03 23:11:0710795 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:2010796 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
vishal.b62985ca92015-04-17 08:45:5110797 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710798 session_deps_.net_log = log.bound().net_log();
10799 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0010800
[email protected]76a505b2010-08-25 06:23:0010801 HttpRequestInfo request;
10802 request.method = "GET";
bncce36dca22015-04-21 22:11:2310803 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0010804
10805 // Since we have proxy, should try to establish tunnel.
10806 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2310807 MockWrite(
10808 "CONNECT www.example.org:443 HTTP/1.1\r\n"
10809 "Host: www.example.org\r\n"
10810 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0010811
bncce36dca22015-04-21 22:11:2310812 MockWrite(
10813 "GET / HTTP/1.1\r\n"
10814 "Host: www.example.org\r\n"
10815 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0010816 };
10817
10818 MockRead data_reads1[] = {
10819 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
10820
10821 MockRead("HTTP/1.1 200 OK\r\n"),
10822 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10823 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610824 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0010825 };
10826
10827 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10828 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710829 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0610830 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710831 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0010832
[email protected]49639fa2011-12-20 23:22:4110833 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0010834
[email protected]262eec82013-03-19 21:01:3610835 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010836 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5010837
[email protected]49639fa2011-12-20 23:22:4110838 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0010839 EXPECT_EQ(ERR_IO_PENDING, rv);
10840
10841 rv = callback1.WaitForResult();
10842 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:4610843 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4010844 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0010845 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010846 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0010847 NetLog::PHASE_NONE);
10848 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010849 entries, pos,
[email protected]76a505b2010-08-25 06:23:0010850 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
10851 NetLog::PHASE_NONE);
10852
10853 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010854 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:0010855
10856 EXPECT_TRUE(response->headers->IsKeepAlive());
10857 EXPECT_EQ(200, response->headers->response_code());
10858 EXPECT_EQ(100, response->headers->GetContentLength());
10859 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10860 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]d8fc4722014-06-13 13:17:1510861 EXPECT_TRUE(
10862 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
[email protected]029c83b62013-01-24 05:28:2010863
10864 LoadTimingInfo load_timing_info;
10865 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10866 TestLoadTimingNotReusedWithPac(load_timing_info,
10867 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0010868}
10869
10870// Test a basic HTTPS GET request through a proxy, but the server hangs up
10871// while establishing the tunnel.
[email protected]23e482282013-06-14 16:08:0210872TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
[email protected]bb88e1d32013-05-03 23:11:0710873 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
vishal.b62985ca92015-04-17 08:45:5110874 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710875 session_deps_.net_log = log.bound().net_log();
10876 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0010877
[email protected]76a505b2010-08-25 06:23:0010878 HttpRequestInfo request;
10879 request.method = "GET";
bncce36dca22015-04-21 22:11:2310880 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0010881
10882 // Since we have proxy, should try to establish tunnel.
10883 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2310884 MockWrite(
10885 "CONNECT www.example.org:443 HTTP/1.1\r\n"
10886 "Host: www.example.org\r\n"
10887 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0010888
bncce36dca22015-04-21 22:11:2310889 MockWrite(
10890 "GET / HTTP/1.1\r\n"
10891 "Host: www.example.org\r\n"
10892 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0010893 };
10894
10895 MockRead data_reads1[] = {
[email protected]8ddf8322012-02-23 18:08:0610896 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:0010897 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610898 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0010899 };
10900
10901 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10902 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710903 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0610904 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710905 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0010906
[email protected]49639fa2011-12-20 23:22:4110907 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0010908
[email protected]262eec82013-03-19 21:01:3610909 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010910 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5010911
[email protected]49639fa2011-12-20 23:22:4110912 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0010913 EXPECT_EQ(ERR_IO_PENDING, rv);
10914
10915 rv = callback1.WaitForResult();
10916 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
mmenke43758e62015-05-04 21:09:4610917 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4010918 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0010919 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010920 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0010921 NetLog::PHASE_NONE);
10922 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010923 entries, pos,
[email protected]76a505b2010-08-25 06:23:0010924 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
10925 NetLog::PHASE_NONE);
10926}
10927
[email protected]749eefa82010-09-13 22:14:0310928// Test for crbug.com/55424.
[email protected]23e482282013-06-14 16:08:0210929TEST_P(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
[email protected]cdf8f7e72013-05-23 10:56:4610930 scoped_ptr<SpdyFrame> req(
bncce36dca22015-04-21 22:11:2310931 spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
rch8e6c6c42015-05-01 14:05:1310932 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]749eefa82010-09-13 22:14:0310933
[email protected]23e482282013-06-14 16:08:0210934 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10935 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0310936 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1310937 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0310938 };
10939
rch8e6c6c42015-05-01 14:05:1310940 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10941 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710942 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0310943
[email protected]8ddf8322012-02-23 18:08:0610944 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210945 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710946 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0310947
[email protected]bb88e1d32013-05-03 23:11:0710948 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0310949
10950 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2310951 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4010952 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5310953 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2710954 base::WeakPtr<SpdySession> spdy_session =
[email protected]41d64e82013-07-03 22:44:2610955 CreateInsecureSpdySession(session, key, BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0310956
10957 HttpRequestInfo request;
10958 request.method = "GET";
bncce36dca22015-04-21 22:11:2310959 request.url = GURL("https://www.example.org/");
[email protected]749eefa82010-09-13 22:14:0310960 request.load_flags = 0;
10961
10962 // This is the important line that marks this as a preconnect.
10963 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
10964
[email protected]262eec82013-03-19 21:01:3610965 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010966 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]749eefa82010-09-13 22:14:0310967
[email protected]41d64e82013-07-03 22:44:2610968 TestCompletionCallback callback;
[email protected]49639fa2011-12-20 23:22:4110969 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0310970 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110971 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]749eefa82010-09-13 22:14:0310972}
10973
[email protected]73b8dd222010-11-11 19:55:2410974// Given a net error, cause that error to be returned from the first Write()
10975// call and verify that the HttpTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0210976void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0710977 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2910978 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2710979 request_info.url = GURL("https://www.example.com/");
10980 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2910981 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2710982
[email protected]8ddf8322012-02-23 18:08:0610983 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2910984 MockWrite data_writes[] = {
10985 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2410986 };
ttuttle859dc7a2015-04-23 19:42:2910987 StaticSocketDataProvider data(NULL, 0, data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0710988 session_deps_.socket_factory->AddSocketDataProvider(&data);
10989 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2410990
[email protected]bb88e1d32013-05-03 23:11:0710991 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610992 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010993 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]73b8dd222010-11-11 19:55:2410994
[email protected]49639fa2011-12-20 23:22:4110995 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2910996 int rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
10997 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2410998 rv = callback.WaitForResult();
10999 ASSERT_EQ(error, rv);
11000}
11001
[email protected]23e482282013-06-14 16:08:0211002TEST_P(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2411003 // Just check a grab bag of cert errors.
11004 static const int kErrors[] = {
11005 ERR_CERT_COMMON_NAME_INVALID,
11006 ERR_CERT_AUTHORITY_INVALID,
11007 ERR_CERT_DATE_INVALID,
11008 };
11009 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0611010 CheckErrorIsPassedBack(kErrors[i], ASYNC);
11011 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2411012 }
11013}
11014
[email protected]bd0b6772011-01-11 19:59:3011015// Ensure that a client certificate is removed from the SSL client auth
11016// cache when:
11017// 1) No proxy is involved.
11018// 2) TLS False Start is disabled.
11019// 3) The initial TLS handshake requests a client certificate.
11020// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0211021TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2311022 ClientAuthCertCache_Direct_NoFalseStart) {
ttuttle859dc7a2015-04-23 19:42:2911023 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2711024 request_info.url = GURL("https://www.example.com/");
11025 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2911026 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2711027
[email protected]bd0b6772011-01-11 19:59:3011028 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4111029 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3011030
11031 // [ssl_]data1 contains the data for the first SSL handshake. When a
11032 // CertificateRequest is received for the first time, the handshake will
11033 // be aborted to allow the caller to provide a certificate.
ttuttle859dc7a2015-04-23 19:42:2911034 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3011035 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711036 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2911037 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711038 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3011039
11040 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
11041 // False Start is not being used, the result of the SSL handshake will be
11042 // returned as part of the SSLClientSocket::Connect() call. This test
11043 // matches the result of a server sending a handshake_failure alert,
11044 // rather than a Finished message, because it requires a client
11045 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2911046 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3011047 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711048 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2911049 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711050 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3011051
11052 // [ssl_]data3 contains the data for the third SSL handshake. When a
11053 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4211054 // HttpNetworkTransaction will attempt to fallback to TLSv1.1 if the previous
11055 // connection was attempted with TLSv1.2. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3011056 // of the HttpNetworkTransaction. Because this test failure is due to
11057 // requiring a client certificate, this fallback handshake should also
11058 // fail.
ttuttle859dc7a2015-04-23 19:42:2911059 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3011060 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711061 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2911062 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711063 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3011064
[email protected]80c75f682012-05-26 16:22:1711065 // [ssl_]data4 contains the data for the fourth 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 if the previous
11068 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]80c75f682012-05-26 16:22:1711069 // 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_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1711073 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711074 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2911075 StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711076 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1711077
[email protected]bb88e1d32013-05-03 23:11:0711078 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3611079 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011080 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3011081
[email protected]bd0b6772011-01-11 19:59:3011082 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4111083 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2911084 int rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
11085 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3011086
11087 // Complete the SSL handshake, which should abort due to requiring a
11088 // client certificate.
11089 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911090 ASSERT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
[email protected]bd0b6772011-01-11 19:59:3011091
11092 // Indicate that no certificate should be supplied. From the perspective
11093 // of SSLClientCertCache, NULL is just as meaningful as a real
11094 // certificate, so this is the same as supply a
11095 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4111096 rv = trans->RestartWithCertificate(NULL, callback.callback());
ttuttle859dc7a2015-04-23 19:42:2911097 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3011098
11099 // Ensure the certificate was added to the client auth cache before
11100 // allowing the connection to continue restarting.
11101 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4111102 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
11103 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3011104 ASSERT_EQ(NULL, client_cert.get());
11105
11106 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1711107 // then consume ssl_data3 and ssl_data4, both of which should also fail.
11108 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3011109 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911110 ASSERT_EQ(ERR_SSL_PROTOCOL_ERROR, rv);
[email protected]bd0b6772011-01-11 19:59:3011111
11112 // Ensure that the client certificate is removed from the cache on a
11113 // handshake failure.
[email protected]791879c2013-12-17 07:22:4111114 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11115 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3011116}
11117
11118// Ensure that a client certificate is removed from the SSL client auth
11119// cache when:
11120// 1) No proxy is involved.
11121// 2) TLS False Start is enabled.
11122// 3) The initial TLS handshake requests a client certificate.
11123// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0211124TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2311125 ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2911126 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2711127 request_info.url = GURL("https://www.example.com/");
11128 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2911129 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2711130
[email protected]bd0b6772011-01-11 19:59:3011131 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4111132 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3011133
11134 // When TLS False Start is used, SSLClientSocket::Connect() calls will
11135 // return successfully after reading up to the peer's Certificate message.
11136 // This is to allow the caller to call SSLClientSocket::Write(), which can
11137 // enqueue application data to be sent in the same packet as the
11138 // ChangeCipherSpec and Finished messages.
11139 // The actual handshake will be finished when SSLClientSocket::Read() is
11140 // called, which expects to process the peer's ChangeCipherSpec and
11141 // Finished messages. If there was an error negotiating with the peer,
11142 // such as due to the peer requiring a client certificate when none was
11143 // supplied, the alert sent by the peer won't be processed until Read() is
11144 // called.
11145
11146 // Like the non-False Start case, when a client certificate is requested by
11147 // the peer, the handshake is aborted during the Connect() call.
11148 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2911149 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3011150 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711151 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2911152 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711153 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3011154
11155 // When a client certificate is supplied, Connect() will not be aborted
11156 // when the peer requests the certificate. Instead, the handshake will
11157 // artificially succeed, allowing the caller to write the HTTP request to
11158 // the socket. The handshake messages are not processed until Read() is
11159 // called, which then detects that the handshake was aborted, due to the
11160 // peer sending a handshake_failure because it requires a client
11161 // certificate.
ttuttle859dc7a2015-04-23 19:42:2911162 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3011163 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711164 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2911165 MockRead data2_reads[] = {
11166 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3011167 };
ttuttle859dc7a2015-04-23 19:42:2911168 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711169 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3011170
11171 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1711172 // the data for the SSL handshake once the TLSv1.1 connection falls back to
11173 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2911174 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3011175 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711176 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2911177 StaticSocketDataProvider data3(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711178 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3011179
[email protected]80c75f682012-05-26 16:22:1711180 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
11181 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2911182 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1711183 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711184 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2911185 StaticSocketDataProvider data4(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711186 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1711187
[email protected]7799de12013-05-30 05:52:5111188 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2911189 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5111190 ssl_data5.cert_request_info = cert_request.get();
11191 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
ttuttle859dc7a2015-04-23 19:42:2911192 StaticSocketDataProvider data5(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]7799de12013-05-30 05:52:5111193 session_deps_.socket_factory->AddSocketDataProvider(&data5);
11194
[email protected]bb88e1d32013-05-03 23:11:0711195 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3611196 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011197 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3011198
[email protected]bd0b6772011-01-11 19:59:3011199 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4111200 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2911201 int rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
11202 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3011203
11204 // Complete the SSL handshake, which should abort due to requiring a
11205 // client certificate.
11206 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911207 ASSERT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
[email protected]bd0b6772011-01-11 19:59:3011208
11209 // Indicate that no certificate should be supplied. From the perspective
11210 // of SSLClientCertCache, NULL is just as meaningful as a real
11211 // certificate, so this is the same as supply a
11212 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4111213 rv = trans->RestartWithCertificate(NULL, callback.callback());
ttuttle859dc7a2015-04-23 19:42:2911214 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3011215
11216 // Ensure the certificate was added to the client auth cache before
11217 // allowing the connection to continue restarting.
11218 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4111219 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
11220 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3011221 ASSERT_EQ(NULL, client_cert.get());
11222
[email protected]bd0b6772011-01-11 19:59:3011223 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1711224 // then consume ssl_data3 and ssl_data4, both of which should also fail.
11225 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3011226 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911227 ASSERT_EQ(ERR_SSL_PROTOCOL_ERROR, rv);
[email protected]bd0b6772011-01-11 19:59:3011228
11229 // Ensure that the client certificate is removed from the cache on a
11230 // handshake failure.
[email protected]791879c2013-12-17 07:22:4111231 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11232 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3011233}
11234
[email protected]8c405132011-01-11 22:03:1811235// Ensure that a client certificate is removed from the SSL client auth
11236// cache when:
11237// 1) An HTTPS proxy is involved.
11238// 3) The HTTPS proxy requests a client certificate.
11239// 4) The client supplies an invalid/unacceptable certificate for the
11240// proxy.
11241// The test is repeated twice, first for connecting to an HTTPS endpoint,
11242// then for connecting to an HTTP endpoint.
[email protected]23e482282013-06-14 16:08:0211243TEST_P(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
[email protected]bb88e1d32013-05-03 23:11:0711244 session_deps_.proxy_service.reset(
[email protected]8c405132011-01-11 22:03:1811245 ProxyService::CreateFixed("https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:5111246 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0711247 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1811248
11249 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4111250 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1811251
11252 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
11253 // [ssl_]data[1-3]. Rather than represending the endpoint
11254 // (www.example.com:443), they represent failures with the HTTPS proxy
11255 // (proxy:70).
ttuttle859dc7a2015-04-23 19:42:2911256 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1811257 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711258 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2911259 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711260 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1811261
ttuttle859dc7a2015-04-23 19:42:2911262 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1811263 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711264 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2911265 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711266 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1811267
[email protected]80c75f682012-05-26 16:22:1711268 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
11269#if 0
ttuttle859dc7a2015-04-23 19:42:2911270 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1811271 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711272 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2911273 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711274 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1711275#endif
[email protected]8c405132011-01-11 22:03:1811276
ttuttle859dc7a2015-04-23 19:42:2911277 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1811278 requests[0].url = GURL("https://www.example.com/");
11279 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2911280 requests[0].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1811281
11282 requests[1].url = GURL("http://www.example.com/");
11283 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2911284 requests[1].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1811285
11286 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0711287 session_deps_.socket_factory->ResetNextMockIndexes();
11288 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c405132011-01-11 22:03:1811289 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5011290 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c405132011-01-11 22:03:1811291
11292 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4111293 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2911294 int rv = trans->Start(&requests[i], callback.callback(), BoundNetLog());
11295 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]8c405132011-01-11 22:03:1811296
11297 // Complete the SSL handshake, which should abort due to requiring a
11298 // client certificate.
11299 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911300 ASSERT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
[email protected]8c405132011-01-11 22:03:1811301
11302 // Indicate that no certificate should be supplied. From the perspective
11303 // of SSLClientCertCache, NULL is just as meaningful as a real
11304 // certificate, so this is the same as supply a
11305 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4111306 rv = trans->RestartWithCertificate(NULL, callback.callback());
ttuttle859dc7a2015-04-23 19:42:2911307 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]8c405132011-01-11 22:03:1811308
11309 // Ensure the certificate was added to the client auth cache before
11310 // allowing the connection to continue restarting.
11311 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4111312 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
11313 HostPortPair("proxy", 70), &client_cert));
[email protected]8c405132011-01-11 22:03:1811314 ASSERT_EQ(NULL, client_cert.get());
11315 // Ensure the certificate was NOT cached for the endpoint. This only
11316 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4111317 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11318 HostPortPair("www.example.com", 443), &client_cert));
[email protected]8c405132011-01-11 22:03:1811319
11320 // Restart the handshake. This will consume ssl_data2, which fails, and
11321 // then consume ssl_data3, which should also fail. The result code is
11322 // checked against what ssl_data3 should return.
11323 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911324 ASSERT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
[email protected]8c405132011-01-11 22:03:1811325
11326 // Now that the new handshake has failed, ensure that the client
11327 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4111328 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11329 HostPortPair("proxy", 70), &client_cert));
11330 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}
11334
mmenke5c642132015-06-02 16:05:1311335TEST_P(HttpNetworkTransactionTest, UseIPConnectionPooling) {
[email protected]d7599122014-05-24 03:37:2311336 session_deps_.use_alternate_protocols = true;
11337 session_deps_.next_protos = SpdyNextProtos();
[email protected]e3ceb682011-06-28 23:55:4611338
11339 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0711340 session_deps_.host_resolver.reset(new MockCachingHostResolver());
11341 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2611342 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
11343 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4611344
[email protected]8ddf8322012-02-23 18:08:0611345 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211346 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711347 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4611348
[email protected]cdf8f7e72013-05-23 10:56:4611349 scoped_ptr<SpdyFrame> host1_req(
bncce36dca22015-04-21 22:11:2311350 spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
[email protected]cdf8f7e72013-05-23 10:56:4611351 scoped_ptr<SpdyFrame> host2_req(
11352 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4611353 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1311354 CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4611355 };
[email protected]23e482282013-06-14 16:08:0211356 scoped_ptr<SpdyFrame> host1_resp(
11357 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11358 scoped_ptr<SpdyFrame> host1_resp_body(
11359 spdy_util_.ConstructSpdyBodyFrame(1, true));
11360 scoped_ptr<SpdyFrame> host2_resp(
11361 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11362 scoped_ptr<SpdyFrame> host2_resp_body(
11363 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4611364 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1311365 CreateMockRead(*host1_resp, 1),
11366 CreateMockRead(*host1_resp_body, 2),
11367 CreateMockRead(*host2_resp, 4),
11368 CreateMockRead(*host2_resp_body, 5),
11369 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4611370 };
11371
[email protected]d2b5f092012-06-08 23:55:0211372 IPAddressNumber ip;
11373 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
11374 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11375 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1311376 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
11377 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711378 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4611379
[email protected]aa22b242011-11-16 18:58:2911380 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4611381 HttpRequestInfo request1;
11382 request1.method = "GET";
bncce36dca22015-04-21 22:11:2311383 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4611384 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011385 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611386
[email protected]49639fa2011-12-20 23:22:4111387 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611388 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111389 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611390
11391 const HttpResponseInfo* response = trans1.GetResponseInfo();
11392 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011393 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611394 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11395
11396 std::string response_data;
11397 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
11398 EXPECT_EQ("hello!", response_data);
11399
11400 // Preload www.gmail.com into HostCache.
11401 HostPortPair host_port("www.gmail.com", 443);
[email protected]5109c1952013-08-20 18:44:1011402 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4611403 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1011404 rv = session_deps_.host_resolver->Resolve(resolve_info,
11405 DEFAULT_PRIORITY,
11406 &ignored,
11407 callback.callback(),
11408 NULL,
11409 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4711410 EXPECT_EQ(ERR_IO_PENDING, rv);
11411 rv = callback.WaitForResult();
11412 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4611413
11414 HttpRequestInfo request2;
11415 request2.method = "GET";
11416 request2.url = GURL("https://www.gmail.com/");
11417 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011418 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611419
[email protected]49639fa2011-12-20 23:22:4111420 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611421 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111422 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611423
11424 response = trans2.GetResponseInfo();
11425 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011426 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611427 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11428 EXPECT_TRUE(response->was_fetched_via_spdy);
11429 EXPECT_TRUE(response->was_npn_negotiated);
11430 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
11431 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4611432}
11433
[email protected]23e482282013-06-14 16:08:0211434TEST_P(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d7599122014-05-24 03:37:2311435 session_deps_.use_alternate_protocols = true;
11436 session_deps_.next_protos = SpdyNextProtos();
[email protected]d2b5f092012-06-08 23:55:0211437
11438 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0711439 session_deps_.host_resolver.reset(new MockCachingHostResolver());
11440 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0211441 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
11442 pool_peer.DisableDomainAuthenticationVerification();
11443
11444 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211445 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711446 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]d2b5f092012-06-08 23:55:0211447
[email protected]cdf8f7e72013-05-23 10:56:4611448 scoped_ptr<SpdyFrame> host1_req(
bncce36dca22015-04-21 22:11:2311449 spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
[email protected]cdf8f7e72013-05-23 10:56:4611450 scoped_ptr<SpdyFrame> host2_req(
11451 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0211452 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1311453 CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0211454 };
[email protected]23e482282013-06-14 16:08:0211455 scoped_ptr<SpdyFrame> host1_resp(
11456 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11457 scoped_ptr<SpdyFrame> host1_resp_body(
11458 spdy_util_.ConstructSpdyBodyFrame(1, true));
11459 scoped_ptr<SpdyFrame> host2_resp(
11460 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11461 scoped_ptr<SpdyFrame> host2_resp_body(
11462 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0211463 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1311464 CreateMockRead(*host1_resp, 1),
11465 CreateMockRead(*host1_resp_body, 2),
11466 CreateMockRead(*host2_resp, 4),
11467 CreateMockRead(*host2_resp_body, 5),
11468 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0211469 };
11470
11471 IPAddressNumber ip;
11472 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
11473 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11474 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1311475 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
11476 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711477 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0211478
11479 TestCompletionCallback callback;
11480 HttpRequestInfo request1;
11481 request1.method = "GET";
bncce36dca22015-04-21 22:11:2311482 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0211483 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011484 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0211485
11486 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
11487 EXPECT_EQ(ERR_IO_PENDING, rv);
11488 EXPECT_EQ(OK, callback.WaitForResult());
11489
11490 const HttpResponseInfo* response = trans1.GetResponseInfo();
11491 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011492 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d2b5f092012-06-08 23:55:0211493 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11494
11495 std::string response_data;
11496 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
11497 EXPECT_EQ("hello!", response_data);
11498
11499 HttpRequestInfo request2;
11500 request2.method = "GET";
11501 request2.url = GURL("https://www.gmail.com/");
11502 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011503 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0211504
11505 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
11506 EXPECT_EQ(ERR_IO_PENDING, rv);
11507 EXPECT_EQ(OK, callback.WaitForResult());
11508
11509 response = trans2.GetResponseInfo();
11510 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011511 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d2b5f092012-06-08 23:55:0211512 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11513 EXPECT_TRUE(response->was_fetched_via_spdy);
11514 EXPECT_TRUE(response->was_npn_negotiated);
11515 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
11516 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0211517}
11518
ttuttle859dc7a2015-04-23 19:42:2911519class OneTimeCachingHostResolver : public HostResolver {
[email protected]e3ceb682011-06-28 23:55:4611520 public:
11521 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
11522 : host_port_(host_port) {}
dchengb03027d2014-10-21 12:00:2011523 ~OneTimeCachingHostResolver() override {}
[email protected]e3ceb682011-06-28 23:55:4611524
11525 RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); }
11526
11527 // HostResolver methods:
dchengb03027d2014-10-21 12:00:2011528 int Resolve(const RequestInfo& info,
11529 RequestPriority priority,
11530 AddressList* addresses,
11531 const CompletionCallback& callback,
11532 RequestHandle* out_req,
11533 const BoundNetLog& net_log) override {
[email protected]95a214c2011-08-04 21:50:4011534 return host_resolver_.Resolve(
[email protected]5109c1952013-08-20 18:44:1011535 info, priority, addresses, callback, out_req, net_log);
[email protected]95a214c2011-08-04 21:50:4011536 }
11537
dchengb03027d2014-10-21 12:00:2011538 int ResolveFromCache(const RequestInfo& info,
11539 AddressList* addresses,
11540 const BoundNetLog& net_log) override {
[email protected]95a214c2011-08-04 21:50:4011541 int rv = host_resolver_.ResolveFromCache(info, addresses, net_log);
11542 if (rv == OK && info.host_port_pair().Equals(host_port_))
[email protected]98e1cd012011-11-08 15:33:0911543 host_resolver_.GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4611544 return rv;
11545 }
11546
dchengb03027d2014-10-21 12:00:2011547 void CancelRequest(RequestHandle req) override {
[email protected]e3ceb682011-06-28 23:55:4611548 host_resolver_.CancelRequest(req);
11549 }
11550
[email protected]46da33be2011-07-19 21:58:0411551 MockCachingHostResolver* GetMockHostResolver() {
11552 return &host_resolver_;
11553 }
11554
[email protected]e3ceb682011-06-28 23:55:4611555 private:
11556 MockCachingHostResolver host_resolver_;
11557 const HostPortPair host_port_;
11558};
11559
mmenke5c642132015-06-02 16:05:1311560TEST_P(HttpNetworkTransactionTest,
11561 UseIPConnectionPoolingWithHostCacheExpiration) {
[email protected]d7599122014-05-24 03:37:2311562 session_deps_.use_alternate_protocols = true;
11563 session_deps_.next_protos = SpdyNextProtos();
[email protected]e3ceb682011-06-28 23:55:4611564
11565 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
[email protected]e3ceb682011-06-28 23:55:4611566 OneTimeCachingHostResolver host_resolver(HostPortPair("www.gmail.com", 443));
[email protected]c6bf8152012-12-02 07:43:3411567 HttpNetworkSession::Params params =
[email protected]bb88e1d32013-05-03 23:11:0711568 SpdySessionDependencies::CreateSessionParams(&session_deps_);
[email protected]e3ceb682011-06-28 23:55:4611569 params.host_resolver = &host_resolver;
[email protected]bb88e1d32013-05-03 23:11:0711570 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2611571 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
11572 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4611573
[email protected]8ddf8322012-02-23 18:08:0611574 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211575 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711576 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4611577
[email protected]cdf8f7e72013-05-23 10:56:4611578 scoped_ptr<SpdyFrame> host1_req(
bncce36dca22015-04-21 22:11:2311579 spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
[email protected]cdf8f7e72013-05-23 10:56:4611580 scoped_ptr<SpdyFrame> host2_req(
11581 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4611582 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1311583 CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4611584 };
[email protected]23e482282013-06-14 16:08:0211585 scoped_ptr<SpdyFrame> host1_resp(
11586 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11587 scoped_ptr<SpdyFrame> host1_resp_body(
11588 spdy_util_.ConstructSpdyBodyFrame(1, true));
11589 scoped_ptr<SpdyFrame> host2_resp(
11590 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11591 scoped_ptr<SpdyFrame> host2_resp_body(
11592 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4611593 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1311594 CreateMockRead(*host1_resp, 1),
11595 CreateMockRead(*host1_resp_body, 2),
11596 CreateMockRead(*host2_resp, 4),
11597 CreateMockRead(*host2_resp_body, 5),
11598 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4611599 };
11600
[email protected]d2b5f092012-06-08 23:55:0211601 IPAddressNumber ip;
11602 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
11603 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11604 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1311605 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
11606 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711607 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4611608
[email protected]aa22b242011-11-16 18:58:2911609 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4611610 HttpRequestInfo request1;
11611 request1.method = "GET";
bncce36dca22015-04-21 22:11:2311612 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4611613 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011614 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611615
[email protected]49639fa2011-12-20 23:22:4111616 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611617 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111618 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611619
11620 const HttpResponseInfo* response = trans1.GetResponseInfo();
11621 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011622 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611623 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11624
11625 std::string response_data;
11626 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
11627 EXPECT_EQ("hello!", response_data);
11628
11629 // Preload cache entries into HostCache.
[email protected]5109c1952013-08-20 18:44:1011630 HostResolver::RequestInfo resolve_info(HostPortPair("www.gmail.com", 443));
[email protected]e3ceb682011-06-28 23:55:4611631 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1011632 rv = host_resolver.Resolve(resolve_info,
11633 DEFAULT_PRIORITY,
11634 &ignored,
11635 callback.callback(),
11636 NULL,
11637 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4711638 EXPECT_EQ(ERR_IO_PENDING, rv);
11639 rv = callback.WaitForResult();
11640 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4611641
11642 HttpRequestInfo request2;
11643 request2.method = "GET";
11644 request2.url = GURL("https://www.gmail.com/");
11645 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011646 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611647
[email protected]49639fa2011-12-20 23:22:4111648 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611649 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111650 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611651
11652 response = trans2.GetResponseInfo();
11653 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011654 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611655 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11656 EXPECT_TRUE(response->was_fetched_via_spdy);
11657 EXPECT_TRUE(response->was_npn_negotiated);
11658 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
11659 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4611660}
11661
[email protected]23e482282013-06-14 16:08:0211662TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2311663 const std::string https_url = "https://www.example.org:8080/";
11664 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0411665
11666 // SPDY GET for HTTPS URL
[email protected]cdf8f7e72013-05-23 10:56:4611667 scoped_ptr<SpdyFrame> req1(
11668 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0411669
11670 MockWrite writes1[] = {
11671 CreateMockWrite(*req1, 0),
11672 };
11673
[email protected]23e482282013-06-14 16:08:0211674 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11675 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8450d722012-07-02 19:14:0411676 MockRead reads1[] = {
11677 CreateMockRead(*resp1, 1),
11678 CreateMockRead(*body1, 2),
11679 MockRead(ASYNC, ERR_IO_PENDING, 3)
11680 };
11681
rch8e6c6c42015-05-01 14:05:1311682 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
11683 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0411684 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5711685 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0411686
11687 // HTTP GET for the HTTP URL
11688 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1311689 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3411690 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2311691 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3411692 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0411693 };
11694
11695 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1311696 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
11697 MockRead(ASYNC, 2, "hello"),
11698 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0411699 };
11700
rch8e6c6c42015-05-01 14:05:1311701 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
11702 arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0411703
[email protected]8450d722012-07-02 19:14:0411704 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211705 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711706 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11707 session_deps_.socket_factory->AddSocketDataProvider(&data1);
11708 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0411709
[email protected]bb88e1d32013-05-03 23:11:0711710 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0411711
11712 // Start the first transaction to set up the SpdySession
11713 HttpRequestInfo request1;
11714 request1.method = "GET";
11715 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0411716 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011717 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0411718 TestCompletionCallback callback1;
11719 EXPECT_EQ(ERR_IO_PENDING,
11720 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411721 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411722
11723 EXPECT_EQ(OK, callback1.WaitForResult());
11724 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11725
11726 // Now, start the HTTP request
11727 HttpRequestInfo request2;
11728 request2.method = "GET";
11729 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0411730 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011731 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0411732 TestCompletionCallback callback2;
11733 EXPECT_EQ(ERR_IO_PENDING,
11734 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411735 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411736
11737 EXPECT_EQ(OK, callback2.WaitForResult());
11738 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11739}
11740
bnc1b0e36852015-04-28 15:32:5911741class AltSvcCertificateVerificationTest : public HttpNetworkTransactionTest {
11742 public:
11743 void Run(bool pooling, bool valid) {
11744 HostPortPair origin(valid ? "mail.example.org" : "invalid.example.org",
11745 443);
11746 HostPortPair alternative("www.example.org", 443);
11747
11748 base::FilePath certs_dir = GetTestCertsDirectory();
11749 scoped_refptr<X509Certificate> cert(
11750 ImportCertFromFile(certs_dir, "spdy_pooling.pem"));
11751 ASSERT_TRUE(cert.get());
11752 bool common_name_fallback_used;
11753 EXPECT_EQ(valid,
11754 cert->VerifyNameMatch(origin.host(), &common_name_fallback_used));
11755 EXPECT_TRUE(
11756 cert->VerifyNameMatch(alternative.host(), &common_name_fallback_used));
11757 SSLSocketDataProvider ssl(ASYNC, OK);
11758 ssl.SetNextProto(GetParam());
11759 ssl.cert = cert;
11760 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11761
11762 // If pooling, then start a request to alternative first to create a
11763 // SpdySession.
11764 std::string url0 = "https://www.example.org:443";
11765 // Second request to origin, which has an alternative service, and could
11766 // open a connection to the alternative host or pool to the existing one.
11767 std::string url1("https://");
11768 url1.append(origin.host());
11769 url1.append(":443");
11770
11771 scoped_ptr<SpdyFrame> req0;
11772 scoped_ptr<SpdyFrame> req1;
11773 scoped_ptr<SpdyFrame> resp0;
11774 scoped_ptr<SpdyFrame> body0;
11775 scoped_ptr<SpdyFrame> resp1;
11776 scoped_ptr<SpdyFrame> body1;
11777 std::vector<MockWrite> writes;
11778 std::vector<MockRead> reads;
11779
11780 if (pooling) {
11781 req0.reset(spdy_util_.ConstructSpdyGet(url0.c_str(), false, 1, LOWEST));
11782 req1.reset(spdy_util_.ConstructSpdyGet(url1.c_str(), false, 3, LOWEST));
11783
11784 writes.push_back(CreateMockWrite(*req0, 0));
11785 writes.push_back(CreateMockWrite(*req1, 3));
11786
11787 resp0.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11788 body0.reset(spdy_util_.ConstructSpdyBodyFrame(1, true));
11789 resp1.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11790 body1.reset(spdy_util_.ConstructSpdyBodyFrame(3, true));
11791
11792 reads.push_back(CreateMockRead(*resp0, 1));
11793 reads.push_back(CreateMockRead(*body0, 2));
11794 reads.push_back(MockRead(ASYNC, ERR_IO_PENDING, 4));
11795 reads.push_back(CreateMockRead(*resp1, 5));
11796 reads.push_back(CreateMockRead(*body1, 6));
11797 reads.push_back(MockRead(ASYNC, OK, 7));
11798 } else {
11799 req1.reset(spdy_util_.ConstructSpdyGet(url1.c_str(), false, 1, LOWEST));
11800
11801 writes.push_back(CreateMockWrite(*req1, 0));
11802
11803 resp1.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11804 body1.reset(spdy_util_.ConstructSpdyBodyFrame(1, true));
11805
11806 reads.push_back(CreateMockRead(*resp1, 1));
11807 reads.push_back(CreateMockRead(*body1, 2));
11808 reads.push_back(MockRead(ASYNC, OK, 3));
11809 }
11810
rch32320842015-05-16 15:57:0911811 SequencedSocketData data(vector_as_array(&reads), reads.size(),
11812 vector_as_array(&writes), writes.size());
bnc1b0e36852015-04-28 15:32:5911813 session_deps_.socket_factory->AddSocketDataProvider(&data);
11814
11815 // Connection to the origin fails.
11816 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11817 StaticSocketDataProvider data_refused;
11818 data_refused.set_connect_data(mock_connect);
11819 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
11820
11821 session_deps_.use_alternate_protocols = true;
11822 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11823 base::WeakPtr<HttpServerProperties> http_server_properties =
11824 session->http_server_properties();
11825 AlternativeService alternative_service(
11826 AlternateProtocolFromNextProto(GetParam()), alternative);
11827 http_server_properties->SetAlternativeService(origin, alternative_service,
11828 1.0);
11829
11830 // First request to alternative.
11831 if (pooling) {
11832 scoped_ptr<HttpTransaction> trans0(
11833 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
11834 HttpRequestInfo request0;
11835 request0.method = "GET";
11836 request0.url = GURL(url0);
11837 request0.load_flags = 0;
11838 TestCompletionCallback callback0;
11839
11840 int rv = trans0->Start(&request0, callback0.callback(), BoundNetLog());
11841 EXPECT_EQ(ERR_IO_PENDING, rv);
11842 rv = callback0.WaitForResult();
11843 EXPECT_EQ(OK, rv);
11844 }
11845
11846 // Second request to origin.
11847 scoped_ptr<HttpTransaction> trans1(
11848 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
11849 HttpRequestInfo request1;
11850 request1.method = "GET";
11851 request1.url = GURL(url1);
11852 request1.load_flags = 0;
11853 TestCompletionCallback callback1;
11854
11855 int rv = trans1->Start(&request1, callback1.callback(), BoundNetLog());
11856 EXPECT_EQ(ERR_IO_PENDING, rv);
rch32320842015-05-16 15:57:0911857 base::MessageLoop::current()->RunUntilIdle();
11858 if (data.IsReadPaused()) {
11859 data.CompleteRead();
11860 }
bnc1b0e36852015-04-28 15:32:5911861 rv = callback1.WaitForResult();
11862 if (valid) {
11863 EXPECT_EQ(OK, rv);
11864 } else {
11865 if (pooling) {
11866 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
11867 } else {
11868 EXPECT_EQ(ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN, rv);
11869 }
11870 }
11871 }
11872};
11873
11874INSTANTIATE_TEST_CASE_P(NextProto,
11875 AltSvcCertificateVerificationTest,
11876 testing::Values(kProtoSPDY31,
11877 kProtoSPDY4_14,
11878 kProtoSPDY4));
11879
11880// The alternative service host must exhibit a certificate that is valid for the
11881// origin host. Test that this is enforced when pooling to an existing
11882// connection.
11883TEST_P(AltSvcCertificateVerificationTest, PoolingValid) {
11884 Run(true, true);
11885}
11886
11887TEST_P(AltSvcCertificateVerificationTest, PoolingInvalid) {
11888 Run(true, false);
11889}
11890
11891// The alternative service host must exhibit a certificate that is valid for the
11892// origin host. Test that this is enforced when opening a new connection.
11893TEST_P(AltSvcCertificateVerificationTest, NewConnectionValid) {
11894 Run(false, true);
11895}
11896
11897TEST_P(AltSvcCertificateVerificationTest, NewConnectionInvalid) {
11898 Run(false, false);
11899}
11900
bnc5452e2a2015-05-08 16:27:4211901// Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
11902// with the alternative server. That connection should not be used.
11903TEST_P(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
11904 HostPortPair origin("origin.example.org", 443);
11905 HostPortPair alternative("alternative.example.org", 443);
11906
11907 // Negotiate HTTP/1.1 with alternative.example.org.
11908 SSLSocketDataProvider ssl(ASYNC, OK);
11909 ssl.SetNextProto(kProtoHTTP11);
11910 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11911
11912 // No data should be read from the alternative, because HTTP/1.1 is
11913 // negotiated.
11914 StaticSocketDataProvider data;
11915 session_deps_.socket_factory->AddSocketDataProvider(&data);
11916
11917 // This test documents that an alternate Job should not be used if HTTP/1.1 is
11918 // negotiated. In order to test this, a failed connection to the origin is
11919 // mocked. This way the request relies on the alternate Job.
11920 StaticSocketDataProvider data_refused;
11921 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
11922 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
11923
11924 // Set up alternative service for origin.
11925 session_deps_.use_alternate_protocols = true;
11926 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11927 base::WeakPtr<HttpServerProperties> http_server_properties =
11928 session->http_server_properties();
11929 AlternativeService alternative_service(
11930 AlternateProtocolFromNextProto(GetParam()), alternative);
11931 http_server_properties->SetAlternativeService(origin, alternative_service,
11932 1.0);
11933
11934 scoped_ptr<HttpTransaction> trans(
11935 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
11936 HttpRequestInfo request;
11937 request.method = "GET";
11938 request.url = GURL("https://origin.example.org:443");
11939 request.load_flags = 0;
11940 TestCompletionCallback callback;
11941
11942 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
11943 // negotiated, the alternate Job should fail with ERR_NPN_NEGOTIATION_FAILED.
11944 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11945 EXPECT_EQ(ERR_NPN_NEGOTIATION_FAILED, callback.GetResult(rv));
11946}
11947
bnc40448a532015-05-11 19:13:1411948// A request to a server with an alternative service fires two Jobs: one to the
11949// origin, and an alternate one to the alternative server. If the former
11950// succeeds, the request should succeed, even if the latter fails because
11951// HTTP/1.1 is negotiated which is insufficient for alternative service.
11952TEST_P(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
11953 HostPortPair origin("origin.example.org", 443);
11954 HostPortPair alternative("alternative.example.org", 443);
11955
11956 // Negotiate HTTP/1.1 with alternative.
11957 SSLSocketDataProvider alternative_ssl(ASYNC, OK);
11958 alternative_ssl.SetNextProto(kProtoHTTP11);
11959 session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
11960
11961 // No data should be read from the alternative, because HTTP/1.1 is
11962 // negotiated.
11963 StaticSocketDataProvider data;
11964 session_deps_.socket_factory->AddSocketDataProvider(&data);
11965
11966 // Negotiate HTTP/1.1 with origin.
11967 SSLSocketDataProvider origin_ssl(ASYNC, OK);
11968 origin_ssl.SetNextProto(kProtoHTTP11);
11969 session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
11970
11971 MockWrite http_writes[] = {
11972 MockWrite(
11973 "GET / HTTP/1.1\r\n"
11974 "Host: origin.example.org\r\n"
11975 "Connection: keep-alive\r\n\r\n"),
11976 MockWrite(
11977 "GET /second HTTP/1.1\r\n"
11978 "Host: origin.example.org\r\n"
11979 "Connection: keep-alive\r\n\r\n"),
11980 };
11981
11982 MockRead http_reads[] = {
11983 MockRead("HTTP/1.1 200 OK\r\n"),
11984 MockRead("Content-Type: text/html\r\n"),
11985 MockRead("Content-Length: 6\r\n\r\n"),
11986 MockRead("foobar"),
11987 MockRead("HTTP/1.1 200 OK\r\n"),
11988 MockRead("Content-Type: text/html\r\n"),
11989 MockRead("Content-Length: 7\r\n\r\n"),
11990 MockRead("another"),
11991 };
11992 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
11993 http_writes, arraysize(http_writes));
11994 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
11995
11996 // Set up alternative service for origin.
11997 session_deps_.use_alternate_protocols = true;
11998 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11999 base::WeakPtr<HttpServerProperties> http_server_properties =
12000 session->http_server_properties();
12001 AlternativeService alternative_service(
12002 AlternateProtocolFromNextProto(GetParam()), alternative);
12003 http_server_properties->SetAlternativeService(origin, alternative_service,
12004 1.0);
12005
12006 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
12007 HttpRequestInfo request1;
12008 request1.method = "GET";
12009 request1.url = GURL("https://origin.example.org:443");
12010 request1.load_flags = 0;
12011 TestCompletionCallback callback1;
12012
12013 int rv = trans1.Start(&request1, callback1.callback(), BoundNetLog());
12014 rv = callback1.GetResult(rv);
12015 EXPECT_EQ(OK, rv);
12016
12017 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
12018 ASSERT_TRUE(response1 != nullptr);
12019 ASSERT_TRUE(response1->headers.get() != nullptr);
12020 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
12021
12022 std::string response_data1;
12023 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data1));
12024 EXPECT_EQ("foobar", response_data1);
12025
12026 // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
12027 // for alternative service.
12028 EXPECT_TRUE(
12029 http_server_properties->IsAlternativeServiceBroken(alternative_service));
12030
12031 // Since |alternative_service| is broken, a second transaction to origin
12032 // should not start an alternate Job. It should pool to existing connection
12033 // to origin.
12034 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
12035 HttpRequestInfo request2;
12036 request2.method = "GET";
12037 request2.url = GURL("https://origin.example.org:443/second");
12038 request2.load_flags = 0;
12039 TestCompletionCallback callback2;
12040
12041 rv = trans2.Start(&request2, callback2.callback(), BoundNetLog());
12042 rv = callback2.GetResult(rv);
12043 EXPECT_EQ(OK, rv);
12044
12045 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
12046 ASSERT_TRUE(response2 != nullptr);
12047 ASSERT_TRUE(response2->headers.get() != nullptr);
12048 EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
12049
12050 std::string response_data2;
12051 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data2));
12052 EXPECT_EQ("another", response_data2);
12053}
12054
bnc5452e2a2015-05-08 16:27:4212055// Alternative service requires HTTP/2 (or SPDY), but there is already a
12056// HTTP/1.1 socket open to the alternative server. That socket should not be
12057// used.
12058TEST_P(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
12059 HostPortPair origin("origin.example.org", 443);
12060 HostPortPair alternative("alternative.example.org", 443);
12061 std::string origin_url = "https://origin.example.org:443";
12062 std::string alternative_url = "https://alternative.example.org:443";
12063
12064 // Negotiate HTTP/1.1 with alternative.example.org.
12065 SSLSocketDataProvider ssl(ASYNC, OK);
12066 ssl.SetNextProto(kProtoHTTP11);
12067 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12068
12069 // HTTP/1.1 data for |request1| and |request2|.
12070 MockWrite http_writes[] = {
12071 MockWrite(
12072 "GET / HTTP/1.1\r\n"
12073 "Host: alternative.example.org\r\n"
12074 "Connection: keep-alive\r\n\r\n"),
12075 MockWrite(
12076 "GET / HTTP/1.1\r\n"
12077 "Host: alternative.example.org\r\n"
12078 "Connection: keep-alive\r\n\r\n"),
12079 };
12080
12081 MockRead http_reads[] = {
12082 MockRead(
12083 "HTTP/1.1 200 OK\r\n"
12084 "Content-Type: text/html; charset=iso-8859-1\r\n"
12085 "Content-Length: 40\r\n\r\n"
12086 "first HTTP/1.1 response from alternative"),
12087 MockRead(
12088 "HTTP/1.1 200 OK\r\n"
12089 "Content-Type: text/html; charset=iso-8859-1\r\n"
12090 "Content-Length: 41\r\n\r\n"
12091 "second HTTP/1.1 response from alternative"),
12092 };
12093 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
12094 http_writes, arraysize(http_writes));
12095 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12096
12097 // This test documents that an alternate Job should not pool to an already
12098 // existing HTTP/1.1 connection. In order to test this, a failed connection
12099 // to the origin is mocked. This way |request2| relies on the alternate Job.
12100 StaticSocketDataProvider data_refused;
12101 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
12102 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
12103
12104 // Set up alternative service for origin.
12105 session_deps_.use_alternate_protocols = true;
12106 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12107 base::WeakPtr<HttpServerProperties> http_server_properties =
12108 session->http_server_properties();
12109 AlternativeService alternative_service(
12110 AlternateProtocolFromNextProto(GetParam()), alternative);
12111 http_server_properties->SetAlternativeService(origin, alternative_service,
12112 1.0);
12113
12114 // First transaction to alternative to open an HTTP/1.1 socket.
12115 scoped_ptr<HttpTransaction> trans1(
12116 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12117 HttpRequestInfo request1;
12118 request1.method = "GET";
12119 request1.url = GURL(alternative_url);
12120 request1.load_flags = 0;
12121 TestCompletionCallback callback1;
12122
12123 int rv = trans1->Start(&request1, callback1.callback(), BoundNetLog());
12124 EXPECT_EQ(OK, callback1.GetResult(rv));
12125 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
12126 ASSERT_TRUE(response1);
12127 ASSERT_TRUE(response1->headers.get());
12128 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
12129 EXPECT_TRUE(response1->was_npn_negotiated);
12130 EXPECT_FALSE(response1->was_fetched_via_spdy);
12131 std::string response_data1;
12132 ASSERT_EQ(OK, ReadTransaction(trans1.get(), &response_data1));
12133 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
12134
12135 // Request for origin.example.org, which has an alternative service. This
12136 // will start two Jobs: the alternative looks for connections to pool to,
12137 // finds one which is HTTP/1.1, and should ignore it, and should not try to
12138 // open other connections to alternative server. The Job to origin fails, so
12139 // this request fails.
12140 scoped_ptr<HttpTransaction> trans2(
12141 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12142 HttpRequestInfo request2;
12143 request2.method = "GET";
12144 request2.url = GURL(origin_url);
12145 request2.load_flags = 0;
12146 TestCompletionCallback callback2;
12147
12148 rv = trans2->Start(&request2, callback2.callback(), BoundNetLog());
12149 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback2.GetResult(rv));
12150
12151 // Another transaction to alternative. This is to test that the HTTP/1.1
12152 // socket is still open and in the pool.
12153 scoped_ptr<HttpTransaction> trans3(
12154 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12155 HttpRequestInfo request3;
12156 request3.method = "GET";
12157 request3.url = GURL(alternative_url);
12158 request3.load_flags = 0;
12159 TestCompletionCallback callback3;
12160
12161 rv = trans3->Start(&request3, callback3.callback(), BoundNetLog());
12162 EXPECT_EQ(OK, callback3.GetResult(rv));
12163 const HttpResponseInfo* response3 = trans3->GetResponseInfo();
12164 ASSERT_TRUE(response3);
12165 ASSERT_TRUE(response3->headers.get());
12166 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
12167 EXPECT_TRUE(response3->was_npn_negotiated);
12168 EXPECT_FALSE(response3->was_fetched_via_spdy);
12169 std::string response_data3;
12170 ASSERT_EQ(OK, ReadTransaction(trans3.get(), &response_data3));
12171 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
12172}
12173
[email protected]23e482282013-06-14 16:08:0212174TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2312175 const std::string https_url = "https://www.example.org:8080/";
12176 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0412177
12178 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2312179 const HostPortPair host_port_pair("www.example.org", 8080);
lgarrona91df87f2014-12-05 00:51:3412180 scoped_ptr<SpdyFrame> connect(
12181 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
[email protected]cdf8f7e72013-05-23 10:56:4612182 scoped_ptr<SpdyFrame> req1(
12183 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]23e482282013-06-14 16:08:0212184 scoped_ptr<SpdyFrame> wrapped_req1(
12185 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3912186
12187 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
[email protected]745aa9c2014-06-27 02:21:2912188 SpdyHeaderBlock req2_block;
12189 req2_block[spdy_util_.GetMethodKey()] = "GET";
bnc33b8cef42014-11-19 17:30:3812190 req2_block[spdy_util_.GetPathKey()] = "/";
bncce36dca22015-04-21 22:11:2312191 req2_block[spdy_util_.GetHostKey()] = "www.example.org:8080";
[email protected]745aa9c2014-06-27 02:21:2912192 req2_block[spdy_util_.GetSchemeKey()] = "http";
12193 spdy_util_.MaybeAddVersionHeader(&req2_block);
[email protected]601e03f12014-04-06 16:26:3912194 scoped_ptr<SpdyFrame> req2(
[email protected]745aa9c2014-06-27 02:21:2912195 spdy_util_.ConstructSpdySyn(3, req2_block, MEDIUM, false, true));
[email protected]8450d722012-07-02 19:14:0412196
12197 MockWrite writes1[] = {
12198 CreateMockWrite(*connect, 0),
12199 CreateMockWrite(*wrapped_req1, 2),
12200 CreateMockWrite(*req2, 5),
12201 };
12202
[email protected]23e482282013-06-14 16:08:0212203 scoped_ptr<SpdyFrame> conn_resp(
12204 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12205 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12206 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
12207 scoped_ptr<SpdyFrame> wrapped_resp1(
12208 spdy_util_.ConstructWrappedSpdyFrame(resp1, 1));
12209 scoped_ptr<SpdyFrame> wrapped_body1(
12210 spdy_util_.ConstructWrappedSpdyFrame(body1, 1));
12211 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
12212 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]8450d722012-07-02 19:14:0412213 MockRead reads1[] = {
12214 CreateMockRead(*conn_resp, 1),
12215 CreateMockRead(*wrapped_resp1, 3),
12216 CreateMockRead(*wrapped_body1, 4),
12217 CreateMockRead(*resp2, 6),
12218 CreateMockRead(*body2, 7),
12219 MockRead(ASYNC, ERR_IO_PENDING, 8)
12220 };
12221
[email protected]dd54bd82012-07-19 23:44:5712222 DeterministicSocketData data1(reads1, arraysize(reads1),
12223 writes1, arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0412224 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5712225 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0412226
[email protected]bb88e1d32013-05-03 23:11:0712227 session_deps_.proxy_service.reset(
[email protected]f6c63db52013-02-02 00:35:2212228 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
vishal.b62985ca92015-04-17 08:45:5112229 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712230 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0412231 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
[email protected]23e482282013-06-14 16:08:0212232 ssl1.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0712233 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0412234 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
[email protected]23e482282013-06-14 16:08:0212235 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0712236 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
12237 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0412238
12239 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0712240 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]8450d722012-07-02 19:14:0412241
12242 // Start the first transaction to set up the SpdySession
12243 HttpRequestInfo request1;
12244 request1.method = "GET";
12245 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0412246 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012247 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0412248 TestCompletionCallback callback1;
12249 EXPECT_EQ(ERR_IO_PENDING,
12250 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412251 base::MessageLoop::current()->RunUntilIdle();
[email protected]dd54bd82012-07-19 23:44:5712252 data1.RunFor(4);
[email protected]8450d722012-07-02 19:14:0412253
12254 EXPECT_EQ(OK, callback1.WaitForResult());
12255 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
12256
[email protected]f6c63db52013-02-02 00:35:2212257 LoadTimingInfo load_timing_info1;
12258 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
12259 TestLoadTimingNotReusedWithPac(load_timing_info1,
12260 CONNECT_TIMING_HAS_SSL_TIMES);
12261
[email protected]8450d722012-07-02 19:14:0412262 // Now, start the HTTP request
12263 HttpRequestInfo request2;
12264 request2.method = "GET";
12265 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0412266 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012267 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0412268 TestCompletionCallback callback2;
12269 EXPECT_EQ(ERR_IO_PENDING,
12270 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412271 base::MessageLoop::current()->RunUntilIdle();
[email protected]dd54bd82012-07-19 23:44:5712272 data1.RunFor(3);
[email protected]8450d722012-07-02 19:14:0412273
12274 EXPECT_EQ(OK, callback2.WaitForResult());
12275 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2212276
12277 LoadTimingInfo load_timing_info2;
12278 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
12279 // The established SPDY sessions is considered reused by the HTTP request.
12280 TestLoadTimingReusedWithPac(load_timing_info2);
12281 // HTTP requests over a SPDY session should have a different connection
12282 // socket_log_id than requests over a tunnel.
12283 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0412284}
12285
[email protected]2d88e7d2012-07-19 17:55:1712286// Test that in the case where we have a SPDY session to a SPDY proxy
12287// that we do not pool other origins that resolve to the same IP when
12288// the certificate does not match the new origin.
12289// http://crbug.com/134690
[email protected]23e482282013-06-14 16:08:0212290TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2312291 const std::string url1 = "http://www.example.org/";
12292 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1712293 const std::string ip_addr = "1.2.3.4";
12294
12295 // SPDY GET for HTTP URL (through SPDY proxy)
[email protected]23e482282013-06-14 16:08:0212296 scoped_ptr<SpdyHeaderBlock> headers(
bncce36dca22015-04-21 22:11:2312297 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
[email protected]745aa9c2014-06-27 02:21:2912298 scoped_ptr<SpdyFrame> req1(
12299 spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, false, true));
[email protected]2d88e7d2012-07-19 17:55:1712300
12301 MockWrite writes1[] = {
12302 CreateMockWrite(*req1, 0),
12303 };
12304
[email protected]23e482282013-06-14 16:08:0212305 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12306 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1712307 MockRead reads1[] = {
12308 CreateMockRead(*resp1, 1),
12309 CreateMockRead(*body1, 2),
12310 MockRead(ASYNC, OK, 3) // EOF
12311 };
12312
12313 scoped_ptr<DeterministicSocketData> data1(
12314 new DeterministicSocketData(reads1, arraysize(reads1),
12315 writes1, arraysize(writes1)));
12316 IPAddressNumber ip;
12317 ASSERT_TRUE(ParseIPLiteralToNumber(ip_addr, &ip));
12318 IPEndPoint peer_addr = IPEndPoint(ip, 443);
12319 MockConnect connect_data1(ASYNC, OK, peer_addr);
12320 data1->set_connect_data(connect_data1);
12321
12322 // SPDY GET for HTTPS URL (direct)
[email protected]cdf8f7e72013-05-23 10:56:4612323 scoped_ptr<SpdyFrame> req2(
12324 spdy_util_.ConstructSpdyGet(url2.c_str(), false, 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1712325
12326 MockWrite writes2[] = {
12327 CreateMockWrite(*req2, 0),
12328 };
12329
[email protected]23e482282013-06-14 16:08:0212330 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12331 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1712332 MockRead reads2[] = {
12333 CreateMockRead(*resp2, 1),
12334 CreateMockRead(*body2, 2),
12335 MockRead(ASYNC, OK, 3) // EOF
12336 };
12337
12338 scoped_ptr<DeterministicSocketData> data2(
12339 new DeterministicSocketData(reads2, arraysize(reads2),
12340 writes2, arraysize(writes2)));
12341 MockConnect connect_data2(ASYNC, OK);
12342 data2->set_connect_data(connect_data2);
12343
12344 // Set up a proxy config that sends HTTP requests to a proxy, and
12345 // all others direct.
12346 ProxyConfig proxy_config;
12347 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
[email protected]bb88e1d32013-05-03 23:11:0712348 session_deps_.proxy_service.reset(new ProxyService(
sammc5dd160c2015-04-02 02:43:1312349 new ProxyConfigServiceFixed(proxy_config), nullptr, NULL));
[email protected]2d88e7d2012-07-19 17:55:1712350
bncce36dca22015-04-21 22:11:2312351 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
12352 ssl1.SetNextProto(GetParam());
[email protected]2d88e7d2012-07-19 17:55:1712353 // Load a valid cert. Note, that this does not need to
12354 // be valid for proxy because the MockSSLClientSocket does
12355 // not actually verify it. But SpdySession will use this
12356 // to see if it is valid for the new origin
bncce36dca22015-04-21 22:11:2312357 ssl1.cert = ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
12358 ASSERT_TRUE(ssl1.cert.get());
[email protected]bb88e1d32013-05-03 23:11:0712359 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
12360 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
12361 data1.get());
[email protected]2d88e7d2012-07-19 17:55:1712362
12363 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
[email protected]23e482282013-06-14 16:08:0212364 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0712365 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
12366 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
12367 data2.get());
[email protected]2d88e7d2012-07-19 17:55:1712368
[email protected]bb88e1d32013-05-03 23:11:0712369 session_deps_.host_resolver.reset(new MockCachingHostResolver());
bncce36dca22015-04-21 22:11:2312370 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0712371 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1712372
12373 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0712374 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]2d88e7d2012-07-19 17:55:1712375
12376 // Start the first transaction to set up the SpdySession
12377 HttpRequestInfo request1;
12378 request1.method = "GET";
12379 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1712380 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012381 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1712382 TestCompletionCallback callback1;
12383 ASSERT_EQ(ERR_IO_PENDING,
12384 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
12385 data1->RunFor(3);
12386
12387 ASSERT_TRUE(callback1.have_result());
12388 EXPECT_EQ(OK, callback1.WaitForResult());
12389 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
12390
12391 // Now, start the HTTP request
12392 HttpRequestInfo request2;
12393 request2.method = "GET";
12394 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1712395 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012396 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1712397 TestCompletionCallback callback2;
12398 EXPECT_EQ(ERR_IO_PENDING,
12399 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412400 base::MessageLoop::current()->RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1712401 data2->RunFor(3);
12402
12403 ASSERT_TRUE(callback2.have_result());
12404 EXPECT_EQ(OK, callback2.WaitForResult());
12405 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
12406}
12407
[email protected]85f97342013-04-17 06:12:2412408// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
12409// error) in SPDY session, removes the socket from pool and closes the SPDY
12410// session. Verify that new url's from the same HttpNetworkSession (and a new
12411// SpdySession) do work. http://crbug.com/224701
[email protected]23e482282013-06-14 16:08:0212412TEST_P(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2312413 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2412414
12415 MockRead reads1[] = {
12416 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
12417 };
12418
mmenke11eb5152015-06-09 14:50:5012419 SequencedSocketData data1(reads1, arraysize(reads1), NULL, 0);
[email protected]85f97342013-04-17 06:12:2412420
[email protected]cdf8f7e72013-05-23 10:56:4612421 scoped_ptr<SpdyFrame> req2(
12422 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2412423 MockWrite writes2[] = {
12424 CreateMockWrite(*req2, 0),
12425 };
12426
[email protected]23e482282013-06-14 16:08:0212427 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12428 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]85f97342013-04-17 06:12:2412429 MockRead reads2[] = {
12430 CreateMockRead(*resp2, 1),
12431 CreateMockRead(*body2, 2),
12432 MockRead(ASYNC, OK, 3) // EOF
12433 };
12434
mmenke11eb5152015-06-09 14:50:5012435 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
12436 arraysize(writes2));
[email protected]85f97342013-04-17 06:12:2412437
[email protected]85f97342013-04-17 06:12:2412438 SSLSocketDataProvider ssl1(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212439 ssl1.SetNextProto(GetParam());
mmenke11eb5152015-06-09 14:50:5012440 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
12441 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]85f97342013-04-17 06:12:2412442
12443 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212444 ssl2.SetNextProto(GetParam());
mmenke11eb5152015-06-09 14:50:5012445 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
12446 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]85f97342013-04-17 06:12:2412447
12448 scoped_refptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:5012449 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]85f97342013-04-17 06:12:2412450
12451 // Start the first transaction to set up the SpdySession and verify that
12452 // connection was closed.
12453 HttpRequestInfo request1;
12454 request1.method = "GET";
12455 request1.url = GURL(https_url);
12456 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012457 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2412458 TestCompletionCallback callback1;
12459 EXPECT_EQ(ERR_IO_PENDING,
12460 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]85f97342013-04-17 06:12:2412461 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback1.WaitForResult());
12462
12463 // Now, start the second request and make sure it succeeds.
12464 HttpRequestInfo request2;
12465 request2.method = "GET";
12466 request2.url = GURL(https_url);
12467 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012468 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2412469 TestCompletionCallback callback2;
12470 EXPECT_EQ(ERR_IO_PENDING,
12471 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]85f97342013-04-17 06:12:2412472
mmenke11eb5152015-06-09 14:50:5012473 ASSERT_EQ(OK, callback2.WaitForResult());
[email protected]85f97342013-04-17 06:12:2412474 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
12475}
12476
[email protected]23e482282013-06-14 16:08:0212477TEST_P(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]d7599122014-05-24 03:37:2312478 session_deps_.next_protos = SpdyNextProtos();
[email protected]483fa202013-05-14 01:07:0312479 ClientSocketPoolManager::set_max_sockets_per_group(
12480 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12481 ClientSocketPoolManager::set_max_sockets_per_pool(
12482 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12483
12484 // Use two different hosts with different IPs so they don't get pooled.
12485 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
12486 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
12487 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12488
12489 SSLSocketDataProvider ssl1(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212490 ssl1.SetNextProto(GetParam());
[email protected]483fa202013-05-14 01:07:0312491 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212492 ssl2.SetNextProto(GetParam());
[email protected]483fa202013-05-14 01:07:0312493 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
12494 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
12495
[email protected]cdf8f7e72013-05-23 10:56:4612496 scoped_ptr<SpdyFrame> host1_req(spdy_util_.ConstructSpdyGet(
[email protected]483fa202013-05-14 01:07:0312497 "https://www.a.com", false, 1, DEFAULT_PRIORITY));
12498 MockWrite spdy1_writes[] = {
rch8e6c6c42015-05-01 14:05:1312499 CreateMockWrite(*host1_req, 0),
[email protected]483fa202013-05-14 01:07:0312500 };
[email protected]23e482282013-06-14 16:08:0212501 scoped_ptr<SpdyFrame> host1_resp(
12502 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12503 scoped_ptr<SpdyFrame> host1_resp_body(
12504 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0312505 MockRead spdy1_reads[] = {
rch8e6c6c42015-05-01 14:05:1312506 CreateMockRead(*host1_resp, 1),
12507 CreateMockRead(*host1_resp_body, 2),
12508 MockRead(ASYNC, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0312509 };
12510
rch8e6c6c42015-05-01 14:05:1312511 scoped_ptr<SequencedSocketData> spdy1_data(
12512 new SequencedSocketData(spdy1_reads, arraysize(spdy1_reads), spdy1_writes,
12513 arraysize(spdy1_writes)));
[email protected]483fa202013-05-14 01:07:0312514 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
12515
[email protected]cdf8f7e72013-05-23 10:56:4612516 scoped_ptr<SpdyFrame> host2_req(spdy_util_.ConstructSpdyGet(
[email protected]483fa202013-05-14 01:07:0312517 "https://www.b.com", false, 1, DEFAULT_PRIORITY));
12518 MockWrite spdy2_writes[] = {
rch8e6c6c42015-05-01 14:05:1312519 CreateMockWrite(*host2_req, 0),
[email protected]483fa202013-05-14 01:07:0312520 };
[email protected]23e482282013-06-14 16:08:0212521 scoped_ptr<SpdyFrame> host2_resp(
12522 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12523 scoped_ptr<SpdyFrame> host2_resp_body(
12524 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0312525 MockRead spdy2_reads[] = {
rch8e6c6c42015-05-01 14:05:1312526 CreateMockRead(*host2_resp, 1),
12527 CreateMockRead(*host2_resp_body, 2),
12528 MockRead(ASYNC, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0312529 };
12530
rch8e6c6c42015-05-01 14:05:1312531 scoped_ptr<SequencedSocketData> spdy2_data(
12532 new SequencedSocketData(spdy2_reads, arraysize(spdy2_reads), spdy2_writes,
12533 arraysize(spdy2_writes)));
[email protected]483fa202013-05-14 01:07:0312534 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
12535
12536 MockWrite http_write[] = {
12537 MockWrite("GET / HTTP/1.1\r\n"
12538 "Host: www.a.com\r\n"
12539 "Connection: keep-alive\r\n\r\n"),
12540 };
12541
12542 MockRead http_read[] = {
12543 MockRead("HTTP/1.1 200 OK\r\n"),
12544 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12545 MockRead("Content-Length: 6\r\n\r\n"),
12546 MockRead("hello!"),
12547 };
12548 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
12549 http_write, arraysize(http_write));
12550 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12551
12552 HostPortPair host_port_pair_a("www.a.com", 443);
[email protected]e6d017652013-05-17 18:01:4012553 SpdySessionKey spdy_session_key_a(
[email protected]314b03992014-04-01 01:28:5312554 host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0312555 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2612556 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0312557
12558 TestCompletionCallback callback;
12559 HttpRequestInfo request1;
12560 request1.method = "GET";
12561 request1.url = GURL("https://www.a.com/");
12562 request1.load_flags = 0;
12563 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5012564 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0312565
12566 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
12567 EXPECT_EQ(ERR_IO_PENDING, rv);
12568 EXPECT_EQ(OK, callback.WaitForResult());
12569
12570 const HttpResponseInfo* response = trans->GetResponseInfo();
12571 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5012572 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0312573 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12574 EXPECT_TRUE(response->was_fetched_via_spdy);
12575 EXPECT_TRUE(response->was_npn_negotiated);
12576
12577 std::string response_data;
12578 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
12579 EXPECT_EQ("hello!", response_data);
12580 trans.reset();
12581 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2612582 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0312583
12584 HostPortPair host_port_pair_b("www.b.com", 443);
[email protected]e6d017652013-05-17 18:01:4012585 SpdySessionKey spdy_session_key_b(
[email protected]314b03992014-04-01 01:28:5312586 host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0312587 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2612588 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0312589 HttpRequestInfo request2;
12590 request2.method = "GET";
12591 request2.url = GURL("https://www.b.com/");
12592 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012593 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0312594
12595 rv = trans->Start(&request2, callback.callback(), BoundNetLog());
12596 EXPECT_EQ(ERR_IO_PENDING, rv);
12597 EXPECT_EQ(OK, callback.WaitForResult());
12598
12599 response = trans->GetResponseInfo();
12600 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5012601 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0312602 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12603 EXPECT_TRUE(response->was_fetched_via_spdy);
12604 EXPECT_TRUE(response->was_npn_negotiated);
12605 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
12606 EXPECT_EQ("hello!", response_data);
12607 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2612608 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0312609 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2612610 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0312611
12612 HostPortPair host_port_pair_a1("www.a.com", 80);
[email protected]e6d017652013-05-17 18:01:4012613 SpdySessionKey spdy_session_key_a1(
[email protected]314b03992014-04-01 01:28:5312614 host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0312615 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2612616 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0312617 HttpRequestInfo request3;
12618 request3.method = "GET";
12619 request3.url = GURL("http://www.a.com/");
12620 request3.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012621 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0312622
12623 rv = trans->Start(&request3, callback.callback(), BoundNetLog());
12624 EXPECT_EQ(ERR_IO_PENDING, rv);
12625 EXPECT_EQ(OK, callback.WaitForResult());
12626
12627 response = trans->GetResponseInfo();
12628 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5012629 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0312630 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12631 EXPECT_FALSE(response->was_fetched_via_spdy);
12632 EXPECT_FALSE(response->was_npn_negotiated);
12633 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
12634 EXPECT_EQ("hello!", response_data);
12635 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2612636 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0312637 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2612638 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0312639}
12640
[email protected]79e1fd62013-06-20 06:50:0412641TEST_P(HttpNetworkTransactionTest, HttpSyncConnectError) {
12642 HttpRequestInfo request;
12643 request.method = "GET";
bncce36dca22015-04-21 22:11:2312644 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0412645 request.load_flags = 0;
12646
[email protected]3fe8d2f82013-10-17 08:56:0712647 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412648 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112649 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412650
12651 MockConnect mock_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
12652 StaticSocketDataProvider data;
12653 data.set_connect_data(mock_connect);
12654 session_deps_.socket_factory->AddSocketDataProvider(&data);
12655
12656 TestCompletionCallback callback;
12657
12658 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12659 EXPECT_EQ(ERR_IO_PENDING, rv);
12660
12661 rv = callback.WaitForResult();
12662 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
12663
[email protected]79e1fd62013-06-20 06:50:0412664 // We don't care whether this succeeds or fails, but it shouldn't crash.
12665 HttpRequestHeaders request_headers;
12666 trans->GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4712667
12668 ConnectionAttempts attempts;
12669 trans->GetConnectionAttempts(&attempts);
12670 ASSERT_EQ(1u, attempts.size());
12671 EXPECT_EQ(ERR_CONNECTION_REFUSED, attempts[0].result);
[email protected]79e1fd62013-06-20 06:50:0412672}
12673
12674TEST_P(HttpNetworkTransactionTest, HttpAsyncConnectError) {
12675 HttpRequestInfo request;
12676 request.method = "GET";
bncce36dca22015-04-21 22:11:2312677 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0412678 request.load_flags = 0;
12679
[email protected]3fe8d2f82013-10-17 08:56:0712680 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412681 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112682 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412683
12684 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
12685 StaticSocketDataProvider data;
12686 data.set_connect_data(mock_connect);
12687 session_deps_.socket_factory->AddSocketDataProvider(&data);
12688
12689 TestCompletionCallback callback;
12690
12691 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12692 EXPECT_EQ(ERR_IO_PENDING, rv);
12693
12694 rv = callback.WaitForResult();
12695 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
12696
[email protected]79e1fd62013-06-20 06:50:0412697 // We don't care whether this succeeds or fails, but it shouldn't crash.
12698 HttpRequestHeaders request_headers;
12699 trans->GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4712700
12701 ConnectionAttempts attempts;
12702 trans->GetConnectionAttempts(&attempts);
12703 ASSERT_EQ(1u, attempts.size());
12704 EXPECT_EQ(ERR_CONNECTION_REFUSED, attempts[0].result);
[email protected]79e1fd62013-06-20 06:50:0412705}
12706
12707TEST_P(HttpNetworkTransactionTest, HttpSyncWriteError) {
12708 HttpRequestInfo request;
12709 request.method = "GET";
bncce36dca22015-04-21 22:11:2312710 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0412711 request.load_flags = 0;
12712
[email protected]3fe8d2f82013-10-17 08:56:0712713 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412714 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112715 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412716
12717 MockWrite data_writes[] = {
12718 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
12719 };
12720 MockRead data_reads[] = {
12721 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
12722 };
12723
12724 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12725 data_writes, arraysize(data_writes));
12726 session_deps_.socket_factory->AddSocketDataProvider(&data);
12727
12728 TestCompletionCallback callback;
12729
12730 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12731 EXPECT_EQ(ERR_IO_PENDING, rv);
12732
12733 rv = callback.WaitForResult();
12734 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12735
[email protected]79e1fd62013-06-20 06:50:0412736 HttpRequestHeaders request_headers;
12737 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12738 EXPECT_TRUE(request_headers.HasHeader("Host"));
12739}
12740
12741TEST_P(HttpNetworkTransactionTest, HttpAsyncWriteError) {
12742 HttpRequestInfo request;
12743 request.method = "GET";
bncce36dca22015-04-21 22:11:2312744 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0412745 request.load_flags = 0;
12746
[email protected]3fe8d2f82013-10-17 08:56:0712747 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412748 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112749 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412750
12751 MockWrite data_writes[] = {
12752 MockWrite(ASYNC, ERR_CONNECTION_RESET),
12753 };
12754 MockRead data_reads[] = {
12755 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
12756 };
12757
12758 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12759 data_writes, arraysize(data_writes));
12760 session_deps_.socket_factory->AddSocketDataProvider(&data);
12761
12762 TestCompletionCallback callback;
12763
12764 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12765 EXPECT_EQ(ERR_IO_PENDING, rv);
12766
12767 rv = callback.WaitForResult();
12768 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12769
[email protected]79e1fd62013-06-20 06:50:0412770 HttpRequestHeaders request_headers;
12771 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12772 EXPECT_TRUE(request_headers.HasHeader("Host"));
12773}
12774
12775TEST_P(HttpNetworkTransactionTest, HttpSyncReadError) {
12776 HttpRequestInfo request;
12777 request.method = "GET";
bncce36dca22015-04-21 22:11:2312778 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0412779 request.load_flags = 0;
12780
[email protected]3fe8d2f82013-10-17 08:56:0712781 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412782 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112783 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412784
12785 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2312786 MockWrite(
12787 "GET / HTTP/1.1\r\n"
12788 "Host: www.example.org\r\n"
12789 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0412790 };
12791 MockRead data_reads[] = {
12792 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
12793 };
12794
12795 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12796 data_writes, arraysize(data_writes));
12797 session_deps_.socket_factory->AddSocketDataProvider(&data);
12798
12799 TestCompletionCallback callback;
12800
12801 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12802 EXPECT_EQ(ERR_IO_PENDING, rv);
12803
12804 rv = callback.WaitForResult();
12805 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12806
[email protected]79e1fd62013-06-20 06:50:0412807 HttpRequestHeaders request_headers;
12808 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12809 EXPECT_TRUE(request_headers.HasHeader("Host"));
12810}
12811
12812TEST_P(HttpNetworkTransactionTest, HttpAsyncReadError) {
12813 HttpRequestInfo request;
12814 request.method = "GET";
bncce36dca22015-04-21 22:11:2312815 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0412816 request.load_flags = 0;
12817
[email protected]3fe8d2f82013-10-17 08:56:0712818 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412819 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112820 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412821
12822 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2312823 MockWrite(
12824 "GET / HTTP/1.1\r\n"
12825 "Host: www.example.org\r\n"
12826 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0412827 };
12828 MockRead data_reads[] = {
12829 MockRead(ASYNC, ERR_CONNECTION_RESET),
12830 };
12831
12832 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12833 data_writes, arraysize(data_writes));
12834 session_deps_.socket_factory->AddSocketDataProvider(&data);
12835
12836 TestCompletionCallback callback;
12837
12838 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12839 EXPECT_EQ(ERR_IO_PENDING, rv);
12840
12841 rv = callback.WaitForResult();
12842 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12843
[email protected]79e1fd62013-06-20 06:50:0412844 HttpRequestHeaders request_headers;
12845 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12846 EXPECT_TRUE(request_headers.HasHeader("Host"));
12847}
12848
12849TEST_P(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
12850 HttpRequestInfo request;
12851 request.method = "GET";
bncce36dca22015-04-21 22:11:2312852 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0412853 request.load_flags = 0;
12854 request.extra_headers.SetHeader("X-Foo", "bar");
12855
[email protected]3fe8d2f82013-10-17 08:56:0712856 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412857 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112858 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412859
12860 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2312861 MockWrite(
12862 "GET / HTTP/1.1\r\n"
12863 "Host: www.example.org\r\n"
12864 "Connection: keep-alive\r\n"
12865 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0412866 };
12867 MockRead data_reads[] = {
12868 MockRead("HTTP/1.1 200 OK\r\n"
12869 "Content-Length: 5\r\n\r\n"
12870 "hello"),
12871 MockRead(ASYNC, ERR_UNEXPECTED),
12872 };
12873
12874 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12875 data_writes, arraysize(data_writes));
12876 session_deps_.socket_factory->AddSocketDataProvider(&data);
12877
12878 TestCompletionCallback callback;
12879
12880 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12881 EXPECT_EQ(ERR_IO_PENDING, rv);
12882
12883 rv = callback.WaitForResult();
12884 EXPECT_EQ(OK, rv);
12885
12886 HttpRequestHeaders request_headers;
12887 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12888 std::string foo;
12889 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
12890 EXPECT_EQ("bar", foo);
12891}
12892
[email protected]bf828982013-08-14 18:01:4712893namespace {
12894
yhiranoa7e05bb2014-11-06 05:40:3912895// Fake HttpStream that simply records calls to SetPriority().
12896class FakeStream : public HttpStream,
[email protected]e86839fd2013-08-14 18:29:0312897 public base::SupportsWeakPtr<FakeStream> {
12898 public:
12899 explicit FakeStream(RequestPriority priority) : priority_(priority) {}
dchengb03027d2014-10-21 12:00:2012900 ~FakeStream() override {}
[email protected]e86839fd2013-08-14 18:29:0312901
12902 RequestPriority priority() const { return priority_; }
12903
dchengb03027d2014-10-21 12:00:2012904 int InitializeStream(const HttpRequestInfo* request_info,
12905 RequestPriority priority,
12906 const BoundNetLog& net_log,
12907 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0312908 return ERR_IO_PENDING;
12909 }
12910
dchengb03027d2014-10-21 12:00:2012911 int SendRequest(const HttpRequestHeaders& request_headers,
12912 HttpResponseInfo* response,
12913 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0312914 ADD_FAILURE();
12915 return ERR_UNEXPECTED;
12916 }
12917
dchengb03027d2014-10-21 12:00:2012918 int ReadResponseHeaders(const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0312919 ADD_FAILURE();
12920 return ERR_UNEXPECTED;
12921 }
12922
dchengb03027d2014-10-21 12:00:2012923 int ReadResponseBody(IOBuffer* buf,
12924 int buf_len,
12925 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0312926 ADD_FAILURE();
12927 return ERR_UNEXPECTED;
12928 }
12929
dchengb03027d2014-10-21 12:00:2012930 void Close(bool not_reusable) override {}
[email protected]e86839fd2013-08-14 18:29:0312931
dchengb03027d2014-10-21 12:00:2012932 bool IsResponseBodyComplete() const override {
[email protected]e86839fd2013-08-14 18:29:0312933 ADD_FAILURE();
12934 return false;
12935 }
12936
dchengb03027d2014-10-21 12:00:2012937 bool CanFindEndOfResponse() const override { return false; }
[email protected]e86839fd2013-08-14 18:29:0312938
dchengb03027d2014-10-21 12:00:2012939 bool IsConnectionReused() const override {
[email protected]e86839fd2013-08-14 18:29:0312940 ADD_FAILURE();
12941 return false;
12942 }
12943
dchengb03027d2014-10-21 12:00:2012944 void SetConnectionReused() override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0312945
dchengb03027d2014-10-21 12:00:2012946 bool IsConnectionReusable() const override {
[email protected]e86839fd2013-08-14 18:29:0312947 ADD_FAILURE();
12948 return false;
12949 }
12950
dchengb03027d2014-10-21 12:00:2012951 int64 GetTotalReceivedBytes() const override {
[email protected]bc92bc972013-12-13 08:32:5912952 ADD_FAILURE();
12953 return 0;
12954 }
12955
dchengb03027d2014-10-21 12:00:2012956 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
[email protected]e86839fd2013-08-14 18:29:0312957 ADD_FAILURE();
12958 return false;
12959 }
12960
dchengb03027d2014-10-21 12:00:2012961 void GetSSLInfo(SSLInfo* ssl_info) override { ADD_FAILURE(); }
12962
12963 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
[email protected]e86839fd2013-08-14 18:29:0312964 ADD_FAILURE();
12965 }
12966
dchengb03027d2014-10-21 12:00:2012967 bool IsSpdyHttpStream() const override {
[email protected]e86839fd2013-08-14 18:29:0312968 ADD_FAILURE();
12969 return false;
12970 }
12971
dchengb03027d2014-10-21 12:00:2012972 void Drain(HttpNetworkSession* session) override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0312973
dchengb03027d2014-10-21 12:00:2012974 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]e86839fd2013-08-14 18:29:0312975
yhiranoa7e05bb2014-11-06 05:40:3912976 UploadProgress GetUploadProgress() const override { return UploadProgress(); }
12977
12978 HttpStream* RenewStreamForAuth() override { return NULL; }
12979
[email protected]e86839fd2013-08-14 18:29:0312980 private:
12981 RequestPriority priority_;
12982
12983 DISALLOW_COPY_AND_ASSIGN(FakeStream);
12984};
12985
12986// Fake HttpStreamRequest that simply records calls to SetPriority()
12987// and vends FakeStreams with its current priority.
[email protected]bf828982013-08-14 18:01:4712988class FakeStreamRequest : public HttpStreamRequest,
12989 public base::SupportsWeakPtr<FakeStreamRequest> {
12990 public:
[email protected]e86839fd2013-08-14 18:29:0312991 FakeStreamRequest(RequestPriority priority,
12992 HttpStreamRequest::Delegate* delegate)
12993 : priority_(priority),
[email protected]831e4a32013-11-14 02:14:4412994 delegate_(delegate),
12995 websocket_stream_create_helper_(NULL) {}
12996
12997 FakeStreamRequest(RequestPriority priority,
12998 HttpStreamRequest::Delegate* delegate,
12999 WebSocketHandshakeStreamBase::CreateHelper* create_helper)
13000 : priority_(priority),
13001 delegate_(delegate),
13002 websocket_stream_create_helper_(create_helper) {}
[email protected]e86839fd2013-08-14 18:29:0313003
dchengb03027d2014-10-21 12:00:2013004 ~FakeStreamRequest() override {}
[email protected]bf828982013-08-14 18:01:4713005
13006 RequestPriority priority() const { return priority_; }
13007
[email protected]831e4a32013-11-14 02:14:4413008 const WebSocketHandshakeStreamBase::CreateHelper*
13009 websocket_stream_create_helper() const {
13010 return websocket_stream_create_helper_;
13011 }
13012
[email protected]e86839fd2013-08-14 18:29:0313013 // Create a new FakeStream and pass it to the request's
13014 // delegate. Returns a weak pointer to the FakeStream.
13015 base::WeakPtr<FakeStream> FinishStreamRequest() {
13016 FakeStream* fake_stream = new FakeStream(priority_);
13017 // Do this before calling OnStreamReady() as OnStreamReady() may
13018 // immediately delete |fake_stream|.
13019 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
13020 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), fake_stream);
13021 return weak_stream;
13022 }
13023
dchengb03027d2014-10-21 12:00:2013024 int RestartTunnelWithProxyAuth(const AuthCredentials& credentials) override {
[email protected]bf828982013-08-14 18:01:4713025 ADD_FAILURE();
13026 return ERR_UNEXPECTED;
13027 }
13028
dchengb03027d2014-10-21 12:00:2013029 LoadState GetLoadState() const override {
[email protected]bf828982013-08-14 18:01:4713030 ADD_FAILURE();
13031 return LoadState();
13032 }
13033
dchengb03027d2014-10-21 12:00:2013034 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]bf828982013-08-14 18:01:4713035
dchengb03027d2014-10-21 12:00:2013036 bool was_npn_negotiated() const override { return false; }
[email protected]bf828982013-08-14 18:01:4713037
dchengb03027d2014-10-21 12:00:2013038 NextProto protocol_negotiated() const override { return kProtoUnknown; }
[email protected]bf828982013-08-14 18:01:4713039
dchengb03027d2014-10-21 12:00:2013040 bool using_spdy() const override { return false; }
[email protected]bf828982013-08-14 18:01:4713041
ttuttle1f2d7e92015-04-28 16:17:4713042 const ConnectionAttempts& connection_attempts() const override {
13043 static ConnectionAttempts no_attempts;
13044 return no_attempts;
13045 }
13046
[email protected]bf828982013-08-14 18:01:4713047 private:
13048 RequestPriority priority_;
[email protected]e86839fd2013-08-14 18:29:0313049 HttpStreamRequest::Delegate* const delegate_;
[email protected]831e4a32013-11-14 02:14:4413050 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
[email protected]bf828982013-08-14 18:01:4713051
13052 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
13053};
13054
13055// Fake HttpStreamFactory that vends FakeStreamRequests.
13056class FakeStreamFactory : public HttpStreamFactory {
13057 public:
13058 FakeStreamFactory() {}
dchengb03027d2014-10-21 12:00:2013059 ~FakeStreamFactory() override {}
[email protected]bf828982013-08-14 18:01:4713060
13061 // Returns a WeakPtr<> to the last HttpStreamRequest returned by
13062 // RequestStream() (which may be NULL if it was destroyed already).
13063 base::WeakPtr<FakeStreamRequest> last_stream_request() {
13064 return last_stream_request_;
13065 }
13066
dchengb03027d2014-10-21 12:00:2013067 HttpStreamRequest* RequestStream(const HttpRequestInfo& info,
13068 RequestPriority priority,
13069 const SSLConfig& server_ssl_config,
13070 const SSLConfig& proxy_ssl_config,
13071 HttpStreamRequest::Delegate* delegate,
13072 const BoundNetLog& net_log) override {
[email protected]e86839fd2013-08-14 18:29:0313073 FakeStreamRequest* fake_request = new FakeStreamRequest(priority, delegate);
[email protected]bf828982013-08-14 18:01:4713074 last_stream_request_ = fake_request->AsWeakPtr();
13075 return fake_request;
13076 }
13077
dchengb03027d2014-10-21 12:00:2013078 HttpStreamRequest* RequestWebSocketHandshakeStream(
[email protected]bf828982013-08-14 18:01:4713079 const HttpRequestInfo& info,
13080 RequestPriority priority,
13081 const SSLConfig& server_ssl_config,
13082 const SSLConfig& proxy_ssl_config,
13083 HttpStreamRequest::Delegate* delegate,
[email protected]467086b2013-11-12 08:19:4613084 WebSocketHandshakeStreamBase::CreateHelper* create_helper,
mostynbba063d6032014-10-09 11:01:1313085 const BoundNetLog& net_log) override {
[email protected]831e4a32013-11-14 02:14:4413086 FakeStreamRequest* fake_request =
13087 new FakeStreamRequest(priority, delegate, create_helper);
13088 last_stream_request_ = fake_request->AsWeakPtr();
13089 return fake_request;
[email protected]bf828982013-08-14 18:01:4713090 }
13091
dchengb03027d2014-10-21 12:00:2013092 void PreconnectStreams(int num_streams,
13093 const HttpRequestInfo& info,
13094 RequestPriority priority,
13095 const SSLConfig& server_ssl_config,
13096 const SSLConfig& proxy_ssl_config) override {
[email protected]bf828982013-08-14 18:01:4713097 ADD_FAILURE();
13098 }
13099
dchengb03027d2014-10-21 12:00:2013100 const HostMappingRules* GetHostMappingRules() const override {
[email protected]bf828982013-08-14 18:01:4713101 ADD_FAILURE();
13102 return NULL;
13103 }
13104
13105 private:
13106 base::WeakPtr<FakeStreamRequest> last_stream_request_;
13107
13108 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
13109};
13110
Adam Rice425cf122015-01-19 06:18:2413111// TODO(ricea): Maybe unify this with the one in
13112// url_request_http_job_unittest.cc ?
13113class FakeWebSocketBasicHandshakeStream : public WebSocketHandshakeStreamBase {
13114 public:
13115 FakeWebSocketBasicHandshakeStream(scoped_ptr<ClientSocketHandle> connection,
13116 bool using_proxy)
13117 : state_(connection.release(), using_proxy) {}
13118
13119 // Fake implementation of HttpStreamBase methods.
13120 // This ends up being quite "real" because this object has to really send data
13121 // on the mock socket. It might be easier to use the real implementation, but
13122 // the fact that the WebSocket code is not compiled on iOS makes that
13123 // difficult.
13124 int InitializeStream(const HttpRequestInfo* request_info,
13125 RequestPriority priority,
13126 const BoundNetLog& net_log,
13127 const CompletionCallback& callback) override {
13128 state_.Initialize(request_info, priority, net_log, callback);
13129 return OK;
13130 }
13131
13132 int SendRequest(const HttpRequestHeaders& request_headers,
13133 HttpResponseInfo* response,
13134 const CompletionCallback& callback) override {
13135 return parser()->SendRequest(state_.GenerateRequestLine(), request_headers,
13136 response, callback);
13137 }
13138
13139 int ReadResponseHeaders(const CompletionCallback& callback) override {
13140 return parser()->ReadResponseHeaders(callback);
13141 }
13142
13143 int ReadResponseBody(IOBuffer* buf,
13144 int buf_len,
13145 const CompletionCallback& callback) override {
13146 NOTREACHED();
13147 return ERR_IO_PENDING;
13148 }
13149
13150 void Close(bool not_reusable) override {
13151 if (parser())
13152 parser()->Close(true);
13153 }
13154
13155 bool IsResponseBodyComplete() const override {
13156 NOTREACHED();
13157 return false;
13158 }
13159
13160 bool CanFindEndOfResponse() const override {
13161 return parser()->CanFindEndOfResponse();
13162 }
13163
13164 bool IsConnectionReused() const override {
13165 NOTREACHED();
13166 return false;
13167 }
13168 void SetConnectionReused() override { NOTREACHED(); }
13169
13170 bool IsConnectionReusable() const override {
13171 NOTREACHED();
13172 return false;
13173 }
13174
13175 int64 GetTotalReceivedBytes() const override {
13176 NOTREACHED();
13177 return 0;
13178 }
13179
13180 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
13181 NOTREACHED();
13182 return false;
13183 }
13184
Adam Ricecb76ac62015-02-20 05:33:2513185 void GetSSLInfo(SSLInfo* ssl_info) override {}
Adam Rice425cf122015-01-19 06:18:2413186
13187 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
13188 NOTREACHED();
13189 }
13190
13191 bool IsSpdyHttpStream() const override {
13192 NOTREACHED();
13193 return false;
13194 }
13195
13196 void Drain(HttpNetworkSession* session) override { NOTREACHED(); }
13197
13198 void SetPriority(RequestPriority priority) override { NOTREACHED(); }
13199
13200 UploadProgress GetUploadProgress() const override {
13201 NOTREACHED();
13202 return UploadProgress();
13203 }
13204
13205 HttpStream* RenewStreamForAuth() override {
13206 NOTREACHED();
13207 return nullptr;
13208 }
13209
13210 // Fake implementation of WebSocketHandshakeStreamBase method(s)
13211 scoped_ptr<WebSocketStream> Upgrade() override {
13212 NOTREACHED();
13213 return scoped_ptr<WebSocketStream>();
13214 }
13215
13216 private:
13217 HttpStreamParser* parser() const { return state_.parser(); }
13218 HttpBasicState state_;
13219
13220 DISALLOW_COPY_AND_ASSIGN(FakeWebSocketBasicHandshakeStream);
13221};
13222
[email protected]831e4a32013-11-14 02:14:4413223// TODO(yhirano): Split this class out into a net/websockets file, if it is
13224// worth doing.
13225class FakeWebSocketStreamCreateHelper :
13226 public WebSocketHandshakeStreamBase::CreateHelper {
13227 public:
dchengb03027d2014-10-21 12:00:2013228 WebSocketHandshakeStreamBase* CreateBasicStream(
[email protected]7e841a52013-11-22 09:04:2113229 scoped_ptr<ClientSocketHandle> connection,
mostynbba063d6032014-10-09 11:01:1313230 bool using_proxy) override {
Adam Rice425cf122015-01-19 06:18:2413231 return new FakeWebSocketBasicHandshakeStream(connection.Pass(),
13232 using_proxy);
[email protected]831e4a32013-11-14 02:14:4413233 }
13234
dchengb03027d2014-10-21 12:00:2013235 WebSocketHandshakeStreamBase* CreateSpdyStream(
[email protected]831e4a32013-11-14 02:14:4413236 const base::WeakPtr<SpdySession>& session,
mostynbba063d6032014-10-09 11:01:1313237 bool use_relative_url) override {
[email protected]831e4a32013-11-14 02:14:4413238 NOTREACHED();
13239 return NULL;
13240 };
13241
dchengb03027d2014-10-21 12:00:2013242 ~FakeWebSocketStreamCreateHelper() override {}
[email protected]831e4a32013-11-14 02:14:4413243
13244 virtual scoped_ptr<WebSocketStream> Upgrade() {
13245 NOTREACHED();
13246 return scoped_ptr<WebSocketStream>();
13247 }
13248};
13249
[email protected]bf828982013-08-14 18:01:4713250} // namespace
13251
13252// Make sure that HttpNetworkTransaction passes on its priority to its
13253// stream request on start.
13254TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
13255 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13256 HttpNetworkSessionPeer peer(session);
13257 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4413258 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4713259
dcheng48459ac22014-08-26 00:46:4113260 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4713261
13262 ASSERT_TRUE(fake_factory->last_stream_request() == NULL);
13263
13264 HttpRequestInfo request;
13265 TestCompletionCallback callback;
13266 EXPECT_EQ(ERR_IO_PENDING,
13267 trans.Start(&request, callback.callback(), BoundNetLog()));
13268
13269 base::WeakPtr<FakeStreamRequest> fake_request =
13270 fake_factory->last_stream_request();
13271 ASSERT_TRUE(fake_request != NULL);
13272 EXPECT_EQ(LOW, fake_request->priority());
13273}
13274
13275// Make sure that HttpNetworkTransaction passes on its priority
13276// updates to its stream request.
13277TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriority) {
13278 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13279 HttpNetworkSessionPeer peer(session);
13280 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4413281 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4713282
dcheng48459ac22014-08-26 00:46:4113283 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4713284
13285 HttpRequestInfo request;
13286 TestCompletionCallback callback;
13287 EXPECT_EQ(ERR_IO_PENDING,
13288 trans.Start(&request, callback.callback(), BoundNetLog()));
13289
13290 base::WeakPtr<FakeStreamRequest> fake_request =
13291 fake_factory->last_stream_request();
13292 ASSERT_TRUE(fake_request != NULL);
13293 EXPECT_EQ(LOW, fake_request->priority());
13294
13295 trans.SetPriority(LOWEST);
13296 ASSERT_TRUE(fake_request != NULL);
13297 EXPECT_EQ(LOWEST, fake_request->priority());
13298}
13299
[email protected]e86839fd2013-08-14 18:29:0313300// Make sure that HttpNetworkTransaction passes on its priority
13301// updates to its stream.
13302TEST_P(HttpNetworkTransactionTest, SetStreamPriority) {
13303 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13304 HttpNetworkSessionPeer peer(session);
13305 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4413306 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]e86839fd2013-08-14 18:29:0313307
dcheng48459ac22014-08-26 00:46:4113308 HttpNetworkTransaction trans(LOW, session.get());
[email protected]e86839fd2013-08-14 18:29:0313309
13310 HttpRequestInfo request;
13311 TestCompletionCallback callback;
13312 EXPECT_EQ(ERR_IO_PENDING,
13313 trans.Start(&request, callback.callback(), BoundNetLog()));
13314
13315 base::WeakPtr<FakeStreamRequest> fake_request =
13316 fake_factory->last_stream_request();
13317 ASSERT_TRUE(fake_request != NULL);
13318 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
13319 ASSERT_TRUE(fake_stream != NULL);
13320 EXPECT_EQ(LOW, fake_stream->priority());
13321
13322 trans.SetPriority(LOWEST);
13323 EXPECT_EQ(LOWEST, fake_stream->priority());
13324}
13325
[email protected]831e4a32013-11-14 02:14:4413326TEST_P(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
13327 // The same logic needs to be tested for both ws: and wss: schemes, but this
13328 // test is already parameterised on NextProto, so it uses a loop to verify
13329 // that the different schemes work.
bncce36dca22015-04-21 22:11:2313330 std::string test_cases[] = {"ws://www.example.org/",
13331 "wss://www.example.org/"};
[email protected]831e4a32013-11-14 02:14:4413332 for (size_t i = 0; i < arraysize(test_cases); ++i) {
13333 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13334 HttpNetworkSessionPeer peer(session);
13335 FakeStreamFactory* fake_factory = new FakeStreamFactory();
13336 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
[email protected]0191b51c2013-11-18 10:55:2313337 peer.SetHttpStreamFactoryForWebSocket(
[email protected]831e4a32013-11-14 02:14:4413338 scoped_ptr<HttpStreamFactory>(fake_factory));
13339
dcheng48459ac22014-08-26 00:46:4113340 HttpNetworkTransaction trans(LOW, session.get());
[email protected]831e4a32013-11-14 02:14:4413341 trans.SetWebSocketHandshakeStreamCreateHelper(
13342 &websocket_stream_create_helper);
13343
13344 HttpRequestInfo request;
13345 TestCompletionCallback callback;
13346 request.method = "GET";
13347 request.url = GURL(test_cases[i]);
13348
13349 EXPECT_EQ(ERR_IO_PENDING,
13350 trans.Start(&request, callback.callback(), BoundNetLog()));
13351
13352 base::WeakPtr<FakeStreamRequest> fake_request =
13353 fake_factory->last_stream_request();
13354 ASSERT_TRUE(fake_request != NULL);
13355 EXPECT_EQ(&websocket_stream_create_helper,
13356 fake_request->websocket_stream_create_helper());
13357 }
13358}
13359
[email protected]043b68c82013-08-22 23:41:5213360// Tests that when a used socket is returned to the SSL socket pool, it's closed
13361// if the transport socket pool is stalled on the global socket limit.
13362TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
13363 ClientSocketPoolManager::set_max_sockets_per_group(
13364 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13365 ClientSocketPoolManager::set_max_sockets_per_pool(
13366 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13367
13368 // Set up SSL request.
13369
13370 HttpRequestInfo ssl_request;
13371 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2313372 ssl_request.url = GURL("https://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5213373
13374 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2313375 MockWrite(
13376 "GET / HTTP/1.1\r\n"
13377 "Host: www.example.org\r\n"
13378 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5213379 };
13380 MockRead ssl_reads[] = {
13381 MockRead("HTTP/1.1 200 OK\r\n"),
13382 MockRead("Content-Length: 11\r\n\r\n"),
13383 MockRead("hello world"),
13384 MockRead(SYNCHRONOUS, OK),
13385 };
13386 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
13387 ssl_writes, arraysize(ssl_writes));
13388 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
13389
13390 SSLSocketDataProvider ssl(ASYNC, OK);
13391 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13392
13393 // Set up HTTP request.
13394
13395 HttpRequestInfo http_request;
13396 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2313397 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5213398
13399 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2313400 MockWrite(
13401 "GET / HTTP/1.1\r\n"
13402 "Host: www.example.org\r\n"
13403 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5213404 };
13405 MockRead http_reads[] = {
13406 MockRead("HTTP/1.1 200 OK\r\n"),
13407 MockRead("Content-Length: 7\r\n\r\n"),
13408 MockRead("falafel"),
13409 MockRead(SYNCHRONOUS, OK),
13410 };
13411 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
13412 http_writes, arraysize(http_writes));
13413 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13414
13415 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13416
13417 // Start the SSL request.
13418 TestCompletionCallback ssl_callback;
13419 scoped_ptr<HttpTransaction> ssl_trans(
13420 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13421 ASSERT_EQ(ERR_IO_PENDING,
13422 ssl_trans->Start(&ssl_request, ssl_callback.callback(),
13423 BoundNetLog()));
13424
13425 // Start the HTTP request. Pool should stall.
13426 TestCompletionCallback http_callback;
13427 scoped_ptr<HttpTransaction> http_trans(
13428 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13429 ASSERT_EQ(ERR_IO_PENDING,
13430 http_trans->Start(&http_request, http_callback.callback(),
13431 BoundNetLog()));
dcheng48459ac22014-08-26 00:46:4113432 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5213433
13434 // Wait for response from SSL request.
13435 ASSERT_EQ(OK, ssl_callback.WaitForResult());
13436 std::string response_data;
13437 ASSERT_EQ(OK, ReadTransaction(ssl_trans.get(), &response_data));
13438 EXPECT_EQ("hello world", response_data);
13439
13440 // The SSL socket should automatically be closed, so the HTTP request can
13441 // start.
dcheng48459ac22014-08-26 00:46:4113442 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
13443 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5213444
13445 // The HTTP request can now complete.
13446 ASSERT_EQ(OK, http_callback.WaitForResult());
13447 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
13448 EXPECT_EQ("falafel", response_data);
13449
dcheng48459ac22014-08-26 00:46:4113450 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5213451}
13452
13453// Tests that when a SSL connection is established but there's no corresponding
13454// request that needs it, the new socket is closed if the transport socket pool
13455// is stalled on the global socket limit.
13456TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
13457 ClientSocketPoolManager::set_max_sockets_per_group(
13458 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13459 ClientSocketPoolManager::set_max_sockets_per_pool(
13460 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13461
13462 // Set up an ssl request.
13463
13464 HttpRequestInfo ssl_request;
13465 ssl_request.method = "GET";
13466 ssl_request.url = GURL("https://www.foopy.com/");
13467
13468 // No data will be sent on the SSL socket.
13469 StaticSocketDataProvider ssl_data;
13470 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
13471
13472 SSLSocketDataProvider ssl(ASYNC, OK);
13473 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13474
13475 // Set up HTTP request.
13476
13477 HttpRequestInfo http_request;
13478 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2313479 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5213480
13481 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2313482 MockWrite(
13483 "GET / HTTP/1.1\r\n"
13484 "Host: www.example.org\r\n"
13485 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5213486 };
13487 MockRead http_reads[] = {
13488 MockRead("HTTP/1.1 200 OK\r\n"),
13489 MockRead("Content-Length: 7\r\n\r\n"),
13490 MockRead("falafel"),
13491 MockRead(SYNCHRONOUS, OK),
13492 };
13493 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
13494 http_writes, arraysize(http_writes));
13495 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13496
13497 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13498
13499 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
13500 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2913501 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
13502 SSLConfig ssl_config;
[email protected]043b68c82013-08-22 23:41:5213503 session->ssl_config_service()->GetSSLConfig(&ssl_config);
13504 http_stream_factory->PreconnectStreams(1, ssl_request, DEFAULT_PRIORITY,
13505 ssl_config, ssl_config);
dcheng48459ac22014-08-26 00:46:4113506 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5213507
13508 // Start the HTTP request. Pool should stall.
13509 TestCompletionCallback http_callback;
13510 scoped_ptr<HttpTransaction> http_trans(
13511 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13512 ASSERT_EQ(ERR_IO_PENDING,
13513 http_trans->Start(&http_request, http_callback.callback(),
13514 BoundNetLog()));
dcheng48459ac22014-08-26 00:46:4113515 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5213516
13517 // The SSL connection will automatically be closed once the connection is
13518 // established, to let the HTTP request start.
13519 ASSERT_EQ(OK, http_callback.WaitForResult());
13520 std::string response_data;
13521 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
13522 EXPECT_EQ("falafel", response_data);
13523
dcheng48459ac22014-08-26 00:46:4113524 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5213525}
13526
[email protected]02d74a02014-04-23 18:10:5413527TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
13528 ScopedVector<UploadElementReader> element_readers;
13529 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713530 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413531
13532 HttpRequestInfo request;
13533 request.method = "POST";
13534 request.url = GURL("http://www.foo.com/");
13535 request.upload_data_stream = &upload_data_stream;
13536 request.load_flags = 0;
13537
13538 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13539 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113540 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413541 // Send headers successfully, but get an error while sending the body.
13542 MockWrite data_writes[] = {
13543 MockWrite("POST / HTTP/1.1\r\n"
13544 "Host: www.foo.com\r\n"
13545 "Connection: keep-alive\r\n"
13546 "Content-Length: 3\r\n\r\n"),
13547 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13548 };
13549
13550 MockRead data_reads[] = {
13551 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
13552 MockRead("hello world"),
13553 MockRead(SYNCHRONOUS, OK),
13554 };
13555 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13556 arraysize(data_writes));
13557 session_deps_.socket_factory->AddSocketDataProvider(&data);
13558
13559 TestCompletionCallback callback;
13560
13561 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13562 EXPECT_EQ(ERR_IO_PENDING, rv);
13563
13564 rv = callback.WaitForResult();
13565 EXPECT_EQ(OK, rv);
13566
13567 const HttpResponseInfo* response = trans->GetResponseInfo();
13568 ASSERT_TRUE(response != NULL);
13569
13570 EXPECT_TRUE(response->headers.get() != NULL);
13571 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
13572
13573 std::string response_data;
13574 rv = ReadTransaction(trans.get(), &response_data);
13575 EXPECT_EQ(OK, rv);
13576 EXPECT_EQ("hello world", response_data);
13577}
13578
13579// This test makes sure the retry logic doesn't trigger when reading an error
13580// response from a server that rejected a POST with a CONNECTION_RESET.
13581TEST_P(HttpNetworkTransactionTest,
13582 PostReadsErrorResponseAfterResetOnReusedSocket) {
13583 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13584 MockWrite data_writes[] = {
13585 MockWrite("GET / HTTP/1.1\r\n"
13586 "Host: www.foo.com\r\n"
13587 "Connection: keep-alive\r\n\r\n"),
13588 MockWrite("POST / HTTP/1.1\r\n"
13589 "Host: www.foo.com\r\n"
13590 "Connection: keep-alive\r\n"
13591 "Content-Length: 3\r\n\r\n"),
13592 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13593 };
13594
13595 MockRead data_reads[] = {
13596 MockRead("HTTP/1.1 200 Peachy\r\n"
13597 "Content-Length: 14\r\n\r\n"),
13598 MockRead("first response"),
13599 MockRead("HTTP/1.1 400 Not OK\r\n"
13600 "Content-Length: 15\r\n\r\n"),
13601 MockRead("second response"),
13602 MockRead(SYNCHRONOUS, OK),
13603 };
13604 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13605 arraysize(data_writes));
13606 session_deps_.socket_factory->AddSocketDataProvider(&data);
13607
13608 TestCompletionCallback callback;
13609 HttpRequestInfo request1;
13610 request1.method = "GET";
13611 request1.url = GURL("http://www.foo.com/");
13612 request1.load_flags = 0;
13613
13614 scoped_ptr<HttpTransaction> trans1(
dcheng48459ac22014-08-26 00:46:4113615 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413616 int rv = trans1->Start(&request1, callback.callback(), BoundNetLog());
13617 EXPECT_EQ(ERR_IO_PENDING, rv);
13618
13619 rv = callback.WaitForResult();
13620 EXPECT_EQ(OK, rv);
13621
13622 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
13623 ASSERT_TRUE(response1 != NULL);
13624
13625 EXPECT_TRUE(response1->headers.get() != NULL);
13626 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
13627
13628 std::string response_data1;
13629 rv = ReadTransaction(trans1.get(), &response_data1);
13630 EXPECT_EQ(OK, rv);
13631 EXPECT_EQ("first response", response_data1);
13632 // Delete the transaction to release the socket back into the socket pool.
13633 trans1.reset();
13634
13635 ScopedVector<UploadElementReader> element_readers;
13636 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713637 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413638
13639 HttpRequestInfo request2;
13640 request2.method = "POST";
13641 request2.url = GURL("http://www.foo.com/");
13642 request2.upload_data_stream = &upload_data_stream;
13643 request2.load_flags = 0;
13644
13645 scoped_ptr<HttpTransaction> trans2(
dcheng48459ac22014-08-26 00:46:4113646 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413647 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
13648 EXPECT_EQ(ERR_IO_PENDING, rv);
13649
13650 rv = callback.WaitForResult();
13651 EXPECT_EQ(OK, rv);
13652
13653 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
13654 ASSERT_TRUE(response2 != NULL);
13655
13656 EXPECT_TRUE(response2->headers.get() != NULL);
13657 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
13658
13659 std::string response_data2;
13660 rv = ReadTransaction(trans2.get(), &response_data2);
13661 EXPECT_EQ(OK, rv);
13662 EXPECT_EQ("second response", response_data2);
13663}
13664
13665TEST_P(HttpNetworkTransactionTest,
13666 PostReadsErrorResponseAfterResetPartialBodySent) {
13667 ScopedVector<UploadElementReader> element_readers;
13668 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713669 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413670
13671 HttpRequestInfo request;
13672 request.method = "POST";
13673 request.url = GURL("http://www.foo.com/");
13674 request.upload_data_stream = &upload_data_stream;
13675 request.load_flags = 0;
13676
13677 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13678 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113679 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413680 // Send headers successfully, but get an error while sending the body.
13681 MockWrite data_writes[] = {
13682 MockWrite("POST / HTTP/1.1\r\n"
13683 "Host: www.foo.com\r\n"
13684 "Connection: keep-alive\r\n"
13685 "Content-Length: 3\r\n\r\n"
13686 "fo"),
13687 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13688 };
13689
13690 MockRead data_reads[] = {
13691 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
13692 MockRead("hello world"),
13693 MockRead(SYNCHRONOUS, OK),
13694 };
13695 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13696 arraysize(data_writes));
13697 session_deps_.socket_factory->AddSocketDataProvider(&data);
13698
13699 TestCompletionCallback callback;
13700
13701 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13702 EXPECT_EQ(ERR_IO_PENDING, rv);
13703
13704 rv = callback.WaitForResult();
13705 EXPECT_EQ(OK, rv);
13706
13707 const HttpResponseInfo* response = trans->GetResponseInfo();
13708 ASSERT_TRUE(response != NULL);
13709
13710 EXPECT_TRUE(response->headers.get() != NULL);
13711 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
13712
13713 std::string response_data;
13714 rv = ReadTransaction(trans.get(), &response_data);
13715 EXPECT_EQ(OK, rv);
13716 EXPECT_EQ("hello world", response_data);
13717}
13718
13719// This tests the more common case than the previous test, where headers and
13720// body are not merged into a single request.
13721TEST_P(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
13722 ScopedVector<UploadElementReader> element_readers;
13723 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713724 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5413725
13726 HttpRequestInfo request;
13727 request.method = "POST";
13728 request.url = GURL("http://www.foo.com/");
13729 request.upload_data_stream = &upload_data_stream;
13730 request.load_flags = 0;
13731
13732 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13733 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113734 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413735 // Send headers successfully, but get an error while sending the body.
13736 MockWrite data_writes[] = {
13737 MockWrite("POST / HTTP/1.1\r\n"
13738 "Host: www.foo.com\r\n"
13739 "Connection: keep-alive\r\n"
13740 "Transfer-Encoding: chunked\r\n\r\n"),
13741 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13742 };
13743
13744 MockRead data_reads[] = {
13745 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
13746 MockRead("hello world"),
13747 MockRead(SYNCHRONOUS, OK),
13748 };
13749 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13750 arraysize(data_writes));
13751 session_deps_.socket_factory->AddSocketDataProvider(&data);
13752
13753 TestCompletionCallback callback;
13754
13755 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13756 EXPECT_EQ(ERR_IO_PENDING, rv);
13757 // Make sure the headers are sent before adding a chunk. This ensures that
13758 // they can't be merged with the body in a single send. Not currently
13759 // necessary since a chunked body is never merged with headers, but this makes
13760 // the test more future proof.
13761 base::RunLoop().RunUntilIdle();
13762
mmenkecbc2b712014-10-09 20:29:0713763 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5413764
13765 rv = callback.WaitForResult();
13766 EXPECT_EQ(OK, rv);
13767
13768 const HttpResponseInfo* response = trans->GetResponseInfo();
13769 ASSERT_TRUE(response != NULL);
13770
13771 EXPECT_TRUE(response->headers.get() != NULL);
13772 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
13773
13774 std::string response_data;
13775 rv = ReadTransaction(trans.get(), &response_data);
13776 EXPECT_EQ(OK, rv);
13777 EXPECT_EQ("hello world", response_data);
13778}
13779
13780TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
13781 ScopedVector<UploadElementReader> element_readers;
13782 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713783 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413784
13785 HttpRequestInfo request;
13786 request.method = "POST";
13787 request.url = GURL("http://www.foo.com/");
13788 request.upload_data_stream = &upload_data_stream;
13789 request.load_flags = 0;
13790
13791 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13792 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113793 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413794
13795 MockWrite data_writes[] = {
13796 MockWrite("POST / HTTP/1.1\r\n"
13797 "Host: www.foo.com\r\n"
13798 "Connection: keep-alive\r\n"
13799 "Content-Length: 3\r\n\r\n"),
13800 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13801 };
13802
13803 MockRead data_reads[] = {
13804 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
13805 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
13806 MockRead("hello world"),
13807 MockRead(SYNCHRONOUS, OK),
13808 };
13809 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13810 arraysize(data_writes));
13811 session_deps_.socket_factory->AddSocketDataProvider(&data);
13812
13813 TestCompletionCallback callback;
13814
13815 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13816 EXPECT_EQ(ERR_IO_PENDING, rv);
13817
13818 rv = callback.WaitForResult();
13819 EXPECT_EQ(OK, rv);
13820
13821 const HttpResponseInfo* response = trans->GetResponseInfo();
13822 ASSERT_TRUE(response != NULL);
13823
13824 EXPECT_TRUE(response->headers.get() != NULL);
13825 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
13826
13827 std::string response_data;
13828 rv = ReadTransaction(trans.get(), &response_data);
13829 EXPECT_EQ(OK, rv);
13830 EXPECT_EQ("hello world", response_data);
13831}
13832
13833TEST_P(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
13834 ScopedVector<UploadElementReader> element_readers;
13835 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713836 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413837
13838 HttpRequestInfo request;
13839 request.method = "POST";
13840 request.url = GURL("http://www.foo.com/");
13841 request.upload_data_stream = &upload_data_stream;
13842 request.load_flags = 0;
13843
13844 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13845 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113846 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413847 // Send headers successfully, but get an error while sending the body.
13848 MockWrite data_writes[] = {
13849 MockWrite("POST / HTTP/1.1\r\n"
13850 "Host: www.foo.com\r\n"
13851 "Connection: keep-alive\r\n"
13852 "Content-Length: 3\r\n\r\n"),
13853 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13854 };
13855
13856 MockRead data_reads[] = {
13857 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
13858 MockRead("hello world"),
13859 MockRead(SYNCHRONOUS, OK),
13860 };
13861 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13862 arraysize(data_writes));
13863 session_deps_.socket_factory->AddSocketDataProvider(&data);
13864
13865 TestCompletionCallback callback;
13866
13867 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13868 EXPECT_EQ(ERR_IO_PENDING, rv);
13869
13870 rv = callback.WaitForResult();
13871 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5413872}
13873
13874TEST_P(HttpNetworkTransactionTest,
13875 PostIgnoresNonErrorResponseAfterResetAnd100) {
13876 ScopedVector<UploadElementReader> element_readers;
13877 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713878 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413879
13880 HttpRequestInfo request;
13881 request.method = "POST";
13882 request.url = GURL("http://www.foo.com/");
13883 request.upload_data_stream = &upload_data_stream;
13884 request.load_flags = 0;
13885
13886 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13887 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113888 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413889 // Send headers successfully, but get an error while sending the body.
13890 MockWrite data_writes[] = {
13891 MockWrite("POST / HTTP/1.1\r\n"
13892 "Host: www.foo.com\r\n"
13893 "Connection: keep-alive\r\n"
13894 "Content-Length: 3\r\n\r\n"),
13895 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13896 };
13897
13898 MockRead data_reads[] = {
13899 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
13900 MockRead("HTTP/1.0 302 Redirect\r\n"),
13901 MockRead("Location: http://somewhere-else.com/\r\n"),
13902 MockRead("Content-Length: 0\r\n\r\n"),
13903 MockRead(SYNCHRONOUS, OK),
13904 };
13905 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13906 arraysize(data_writes));
13907 session_deps_.socket_factory->AddSocketDataProvider(&data);
13908
13909 TestCompletionCallback callback;
13910
13911 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13912 EXPECT_EQ(ERR_IO_PENDING, rv);
13913
13914 rv = callback.WaitForResult();
13915 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5413916}
13917
13918TEST_P(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
13919 ScopedVector<UploadElementReader> element_readers;
13920 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713921 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413922
13923 HttpRequestInfo request;
13924 request.method = "POST";
13925 request.url = GURL("http://www.foo.com/");
13926 request.upload_data_stream = &upload_data_stream;
13927 request.load_flags = 0;
13928
13929 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13930 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113931 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413932 // Send headers successfully, but get an error while sending the body.
13933 MockWrite data_writes[] = {
13934 MockWrite("POST / HTTP/1.1\r\n"
13935 "Host: www.foo.com\r\n"
13936 "Connection: keep-alive\r\n"
13937 "Content-Length: 3\r\n\r\n"),
13938 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13939 };
13940
13941 MockRead data_reads[] = {
13942 MockRead("HTTP 0.9 rocks!"),
13943 MockRead(SYNCHRONOUS, OK),
13944 };
13945 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13946 arraysize(data_writes));
13947 session_deps_.socket_factory->AddSocketDataProvider(&data);
13948
13949 TestCompletionCallback callback;
13950
13951 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13952 EXPECT_EQ(ERR_IO_PENDING, rv);
13953
13954 rv = callback.WaitForResult();
13955 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5413956}
13957
13958TEST_P(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
13959 ScopedVector<UploadElementReader> element_readers;
13960 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713961 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413962
13963 HttpRequestInfo request;
13964 request.method = "POST";
13965 request.url = GURL("http://www.foo.com/");
13966 request.upload_data_stream = &upload_data_stream;
13967 request.load_flags = 0;
13968
13969 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13970 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113971 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413972 // Send headers successfully, but get an error while sending the body.
13973 MockWrite data_writes[] = {
13974 MockWrite("POST / HTTP/1.1\r\n"
13975 "Host: www.foo.com\r\n"
13976 "Connection: keep-alive\r\n"
13977 "Content-Length: 3\r\n\r\n"),
13978 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13979 };
13980
13981 MockRead data_reads[] = {
13982 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
13983 MockRead(SYNCHRONOUS, OK),
13984 };
13985 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13986 arraysize(data_writes));
13987 session_deps_.socket_factory->AddSocketDataProvider(&data);
13988
13989 TestCompletionCallback callback;
13990
13991 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13992 EXPECT_EQ(ERR_IO_PENDING, rv);
13993
13994 rv = callback.WaitForResult();
13995 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5413996}
13997
Adam Rice425cf122015-01-19 06:18:2413998// Verify that proxy headers are not sent to the destination server when
13999// establishing a tunnel for a secure WebSocket connection.
14000TEST_P(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
14001 HttpRequestInfo request;
14002 request.method = "GET";
bncce36dca22015-04-21 22:11:2314003 request.url = GURL("wss://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2414004 AddWebSocketHeaders(&request.extra_headers);
14005
14006 // Configure against proxy server "myproxy:70".
14007 session_deps_.proxy_service.reset(
14008 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
14009
14010 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14011
14012 // Since a proxy is configured, try to establish a tunnel.
14013 MockWrite data_writes[] = {
14014 MockWrite(
bncce36dca22015-04-21 22:11:2314015 "CONNECT www.example.org:443 HTTP/1.1\r\n"
14016 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414017 "Proxy-Connection: keep-alive\r\n\r\n"),
14018
14019 // After calling trans->RestartWithAuth(), this is the request we should
14020 // be issuing -- the final header line contains the credentials.
14021 MockWrite(
bncce36dca22015-04-21 22:11:2314022 "CONNECT www.example.org:443 HTTP/1.1\r\n"
14023 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414024 "Proxy-Connection: keep-alive\r\n"
14025 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
14026
14027 MockWrite(
14028 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2314029 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414030 "Connection: Upgrade\r\n"
14031 "Upgrade: websocket\r\n"
bncce36dca22015-04-21 22:11:2314032 "Origin: http://www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414033 "Sec-WebSocket-Version: 13\r\n"
14034 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
14035 };
14036
14037 // The proxy responds to the connect with a 407, using a persistent
14038 // connection.
14039 MockRead data_reads[] = {
14040 // No credentials.
14041 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
14042 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
14043 MockRead("Proxy-Connection: close\r\n\r\n"),
14044
14045 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
14046
14047 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
14048 MockRead("Upgrade: websocket\r\n"),
14049 MockRead("Connection: Upgrade\r\n"),
14050 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
14051 };
14052
14053 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14054 arraysize(data_writes));
14055 session_deps_.socket_factory->AddSocketDataProvider(&data);
14056 SSLSocketDataProvider ssl(ASYNC, OK);
14057 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14058
14059 scoped_ptr<HttpTransaction> trans(
14060 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
14061 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
14062 trans->SetWebSocketHandshakeStreamCreateHelper(
14063 &websocket_stream_create_helper);
14064
14065 {
14066 TestCompletionCallback callback;
14067
14068 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14069 EXPECT_EQ(ERR_IO_PENDING, rv);
14070
14071 rv = callback.WaitForResult();
14072 EXPECT_EQ(OK, rv);
14073 }
14074
14075 const HttpResponseInfo* response = trans->GetResponseInfo();
14076 ASSERT_TRUE(response);
14077 ASSERT_TRUE(response->headers.get());
14078 EXPECT_EQ(407, response->headers->response_code());
14079
14080 {
14081 TestCompletionCallback callback;
14082
14083 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
14084 callback.callback());
14085 EXPECT_EQ(ERR_IO_PENDING, rv);
14086
14087 rv = callback.WaitForResult();
14088 EXPECT_EQ(OK, rv);
14089 }
14090
14091 response = trans->GetResponseInfo();
14092 ASSERT_TRUE(response);
14093 ASSERT_TRUE(response->headers.get());
14094
14095 EXPECT_EQ(101, response->headers->response_code());
14096
14097 trans.reset();
14098 session->CloseAllConnections();
14099}
14100
14101// Verify that proxy headers are not sent to the destination server when
14102// establishing a tunnel for an insecure WebSocket connection.
14103// This requires the authentication info to be injected into the auth cache
14104// due to crbug.com/395064
14105// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
14106TEST_P(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
14107 HttpRequestInfo request;
14108 request.method = "GET";
bncce36dca22015-04-21 22:11:2314109 request.url = GURL("ws://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2414110 AddWebSocketHeaders(&request.extra_headers);
14111
14112 // Configure against proxy server "myproxy:70".
14113 session_deps_.proxy_service.reset(
14114 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
14115
14116 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14117
14118 MockWrite data_writes[] = {
14119 // Try to establish a tunnel for the WebSocket connection, with
14120 // credentials. Because WebSockets have a separate set of socket pools,
14121 // they cannot and will not use the same TCP/IP connection as the
14122 // preflight HTTP request.
14123 MockWrite(
bncce36dca22015-04-21 22:11:2314124 "CONNECT www.example.org:80 HTTP/1.1\r\n"
14125 "Host: www.example.org:80\r\n"
Adam Rice425cf122015-01-19 06:18:2414126 "Proxy-Connection: keep-alive\r\n"
14127 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
14128
14129 MockWrite(
14130 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2314131 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414132 "Connection: Upgrade\r\n"
14133 "Upgrade: websocket\r\n"
bncce36dca22015-04-21 22:11:2314134 "Origin: http://www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414135 "Sec-WebSocket-Version: 13\r\n"
14136 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
14137 };
14138
14139 MockRead data_reads[] = {
14140 // HTTP CONNECT with credentials.
14141 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
14142
14143 // WebSocket connection established inside tunnel.
14144 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
14145 MockRead("Upgrade: websocket\r\n"),
14146 MockRead("Connection: Upgrade\r\n"),
14147 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
14148 };
14149
14150 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14151 arraysize(data_writes));
14152 session_deps_.socket_factory->AddSocketDataProvider(&data);
14153
14154 session->http_auth_cache()->Add(
14155 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
14156 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
14157
14158 scoped_ptr<HttpTransaction> trans(
14159 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
14160 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
14161 trans->SetWebSocketHandshakeStreamCreateHelper(
14162 &websocket_stream_create_helper);
14163
14164 TestCompletionCallback callback;
14165
14166 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14167 EXPECT_EQ(ERR_IO_PENDING, rv);
14168
14169 rv = callback.WaitForResult();
14170 EXPECT_EQ(OK, rv);
14171
14172 const HttpResponseInfo* response = trans->GetResponseInfo();
14173 ASSERT_TRUE(response);
14174 ASSERT_TRUE(response->headers.get());
14175
14176 EXPECT_EQ(101, response->headers->response_code());
14177
14178 trans.reset();
14179 session->CloseAllConnections();
14180}
14181
[email protected]89ceba9a2009-03-21 03:46:0614182} // namespace net