blob: 727ef700f95e5b4ee57c3fc7372b5900b7cfe2ae [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"
[email protected]125ef482013-06-11 18:32:4721#include "base/strings/string_util.h"
[email protected]750b2f3c2013-06-07 18:41:0522#include "base/strings/utf_string_conversions.h"
[email protected]f36a8132011-09-02 18:36:3323#include "base/test/test_file_util.h"
[email protected]277d5942010-08-11 21:02:3524#include "net/base/auth.h"
[email protected]169d0012010-05-10 23:20:1225#include "net/base/capturing_net_log.h"
mmenkecbc2b712014-10-09 20:29:0726#include "net/base/chunked_upload_data_stream.h"
[email protected]bacff652009-03-31 17:50:3327#include "net/base/completion_callback.h"
mmenkecbc2b712014-10-09 20:29:0728#include "net/base/elements_upload_data_stream.h"
[email protected]58e32bb2013-01-21 18:23:2529#include "net/base/load_timing_info.h"
30#include "net/base/load_timing_info_test_util.h"
Adam Rice425cf122015-01-19 06:18:2431#include "net/base/net_errors.h"
[email protected]169d0012010-05-10 23:20:1232#include "net/base/net_log.h"
33#include "net/base/net_log_unittest.h"
[email protected]ac790b42009-12-02 04:31:3134#include "net/base/request_priority.h"
initial.commit586acc5fe2008-07-26 22:42:5235#include "net/base/test_completion_callback.h"
[email protected]42fdb452012-11-01 12:44:4036#include "net/base/test_data_directory.h"
[email protected]b2d26cfd2012-12-11 10:36:0637#include "net/base/upload_bytes_element_reader.h"
[email protected]d98961652012-09-11 20:27:2138#include "net/base/upload_file_element_reader.h"
[email protected]6e7845ae2013-03-29 21:48:1139#include "net/cert/mock_cert_verifier.h"
[email protected]bc71b8772013-04-10 20:55:1640#include "net/dns/host_cache.h"
[email protected]f2cb3cf2013-03-21 01:40:5341#include "net/dns/mock_host_resolver.h"
[email protected]df41d0d82014-03-13 00:43:2442#include "net/http/http_auth_challenge_tokenizer.h"
[email protected]3c32c5f2010-05-18 15:18:1243#include "net/http/http_auth_handler_digest.h"
[email protected]3fd9dae2010-06-21 11:39:0044#include "net/http/http_auth_handler_mock.h"
[email protected]385a4672009-03-11 22:21:2945#include "net/http/http_auth_handler_ntlm.h"
Adam Rice425cf122015-01-19 06:18:2446#include "net/http/http_basic_state.h"
[email protected]0877e3d2009-10-17 22:29:5747#include "net/http/http_basic_stream.h"
initial.commit586acc5fe2008-07-26 22:42:5248#include "net/http/http_network_session.h"
[email protected]87bfa3f2010-09-30 14:54:5649#include "net/http/http_network_session_peer.h"
Adam Rice425cf122015-01-19 06:18:2450#include "net/http/http_request_headers.h"
[email protected]17291a022011-10-10 07:32:5351#include "net/http/http_server_properties_impl.h"
[email protected]0877e3d2009-10-17 22:29:5752#include "net/http/http_stream.h"
[email protected]8e6441ca2010-08-19 05:56:3853#include "net/http/http_stream_factory.h"
Adam Rice425cf122015-01-19 06:18:2454#include "net/http/http_stream_parser.h"
[email protected]c41737d2014-05-14 07:47:1955#include "net/http/http_transaction_test_util.h"
[email protected]51fff29d2008-12-19 22:17:5356#include "net/proxy/proxy_config_service_fixed.h"
[email protected]e86839fd2013-08-14 18:29:0357#include "net/proxy/proxy_info.h"
[email protected]631f1322010-04-30 17:59:1158#include "net/proxy/proxy_resolver.h"
59#include "net/proxy/proxy_service.h"
[email protected]f7984fc62009-06-22 23:26:4460#include "net/socket/client_socket_factory.h"
[email protected]483fa202013-05-14 01:07:0361#include "net/socket/client_socket_pool_manager.h"
[email protected]a42dbd142011-11-17 16:42:0262#include "net/socket/mock_client_socket_pool_manager.h"
[email protected]bb88e1d32013-05-03 23:11:0763#include "net/socket/next_proto.h"
[email protected]f7984fc62009-06-22 23:26:4464#include "net/socket/socket_test_util.h"
65#include "net/socket/ssl_client_socket.h"
[email protected]2ff8b312010-04-26 22:20:5466#include "net/spdy/spdy_framer.h"
67#include "net/spdy/spdy_session.h"
68#include "net/spdy/spdy_session_pool.h"
[email protected]23e482282013-06-14 16:08:0269#include "net/spdy/spdy_test_util_common.h"
[email protected]536fd0b2013-03-14 17:41:5770#include "net/ssl/ssl_cert_request_info.h"
[email protected]e86839fd2013-08-14 18:29:0371#include "net/ssl/ssl_config_service.h"
[email protected]536fd0b2013-03-14 17:41:5772#include "net/ssl/ssl_config_service_defaults.h"
73#include "net/ssl/ssl_info.h"
[email protected]6e7845ae2013-03-29 21:48:1174#include "net/test/cert_test_util.h"
[email protected]831e4a32013-11-14 02:14:4475#include "net/websockets/websocket_handshake_stream_base.h"
initial.commit586acc5fe2008-07-26 22:42:5276#include "testing/gtest/include/gtest/gtest.h"
[email protected]23887f04f2008-12-02 19:20:1577#include "testing/platform_test.h"
[email protected]795cbf82013-07-22 09:37:2778#include "url/gurl.h"
initial.commit586acc5fe2008-07-26 22:42:5279
[email protected]ad65a3e2013-12-25 18:18:0180using base::ASCIIToUTF16;
81
initial.commit586acc5fe2008-07-26 22:42:5282//-----------------------------------------------------------------------------
83
[email protected]13c8a092010-07-29 06:15:4484namespace {
85
[email protected]42cba2fb2013-03-29 19:58:5786const base::string16 kBar(ASCIIToUTF16("bar"));
87const base::string16 kBar2(ASCIIToUTF16("bar2"));
88const base::string16 kBar3(ASCIIToUTF16("bar3"));
89const base::string16 kBaz(ASCIIToUTF16("baz"));
90const base::string16 kFirst(ASCIIToUTF16("first"));
91const base::string16 kFoo(ASCIIToUTF16("foo"));
92const base::string16 kFoo2(ASCIIToUTF16("foo2"));
93const base::string16 kFoo3(ASCIIToUTF16("foo3"));
94const base::string16 kFou(ASCIIToUTF16("fou"));
95const base::string16 kSecond(ASCIIToUTF16("second"));
96const base::string16 kTestingNTLM(ASCIIToUTF16("testing-ntlm"));
97const base::string16 kWrongPassword(ASCIIToUTF16("wrongpassword"));
[email protected]13c8a092010-07-29 06:15:4498
[email protected]e5c026642012-03-17 00:14:0299int GetIdleSocketCountInTransportSocketPool(net::HttpNetworkSession* session) {
100 return session->GetTransportSocketPool(
101 net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IdleSocketCount();
102}
103
104int GetIdleSocketCountInSSLSocketPool(net::HttpNetworkSession* session) {
105 return session->GetSSLSocketPool(
106 net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IdleSocketCount();
107}
108
[email protected]043b68c82013-08-22 23:41:52109bool IsTransportSocketPoolStalled(net::HttpNetworkSession* session) {
110 return session->GetTransportSocketPool(
111 net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IsStalled();
112}
113
[email protected]f3da152d2012-06-02 01:00:57114// Takes in a Value created from a NetLogHttpResponseParameter, and returns
115// a JSONified list of headers as a single string. Uses single quotes instead
116// of double quotes for easier comparison. Returns false on failure.
[email protected]ea5ef4c2013-06-13 22:50:27117bool GetHeaders(base::DictionaryValue* params, std::string* headers) {
[email protected]f3da152d2012-06-02 01:00:57118 if (!params)
119 return false;
[email protected]ea5ef4c2013-06-13 22:50:27120 base::ListValue* header_list;
[email protected]f3da152d2012-06-02 01:00:57121 if (!params->GetList("headers", &header_list))
122 return false;
123 std::string double_quote_headers;
124 base::JSONWriter::Write(header_list, &double_quote_headers);
[email protected]466c9862013-12-03 22:05:28125 base::ReplaceChars(double_quote_headers, "\"", "'", headers);
[email protected]f3da152d2012-06-02 01:00:57126 return true;
127}
128
[email protected]029c83b62013-01-24 05:28:20129// Tests LoadTimingInfo in the case a socket is reused and no PAC script is
130// used.
131void TestLoadTimingReused(const net::LoadTimingInfo& load_timing_info) {
132 EXPECT_TRUE(load_timing_info.socket_reused);
[email protected]58e32bb2013-01-21 18:23:25133 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
134
[email protected]029c83b62013-01-24 05:28:20135 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
136 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
137
138 net::ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
139 EXPECT_FALSE(load_timing_info.send_start.is_null());
[email protected]58e32bb2013-01-21 18:23:25140
141 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]58e32bb2013-01-21 18:23:25142
[email protected]3b23a222013-05-15 21:33:25143 // Set at a higher level.
[email protected]58e32bb2013-01-21 18:23:25144 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
145 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25146 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25147}
148
[email protected]029c83b62013-01-24 05:28:20149// Tests LoadTimingInfo in the case a new socket is used and no PAC script is
150// used.
[email protected]58e32bb2013-01-21 18:23:25151void TestLoadTimingNotReused(const net::LoadTimingInfo& load_timing_info,
152 int connect_timing_flags) {
[email protected]029c83b62013-01-24 05:28:20153 EXPECT_FALSE(load_timing_info.socket_reused);
154 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
155
156 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
157 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
158
159 net::ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
[email protected]3b23a222013-05-15 21:33:25160 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20161 EXPECT_LE(load_timing_info.connect_timing.connect_end,
162 load_timing_info.send_start);
163
164 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20165
[email protected]3b23a222013-05-15 21:33:25166 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20167 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
168 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25169 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20170}
171
172// Tests LoadTimingInfo in the case a socket is reused and a PAC script is
173// used.
174void TestLoadTimingReusedWithPac(const net::LoadTimingInfo& load_timing_info) {
175 EXPECT_TRUE(load_timing_info.socket_reused);
176 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
177
178 net::ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
179
180 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
181 EXPECT_LE(load_timing_info.proxy_resolve_start,
182 load_timing_info.proxy_resolve_end);
183 EXPECT_LE(load_timing_info.proxy_resolve_end,
184 load_timing_info.send_start);
185 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20186
[email protected]3b23a222013-05-15 21:33:25187 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20188 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
189 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25190 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20191}
192
193// Tests LoadTimingInfo in the case a new socket is used and a PAC script is
194// used.
195void TestLoadTimingNotReusedWithPac(const net::LoadTimingInfo& load_timing_info,
196 int connect_timing_flags) {
197 EXPECT_FALSE(load_timing_info.socket_reused);
198 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
199
200 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
201 EXPECT_LE(load_timing_info.proxy_resolve_start,
202 load_timing_info.proxy_resolve_end);
203 EXPECT_LE(load_timing_info.proxy_resolve_end,
204 load_timing_info.connect_timing.connect_start);
205 net::ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
206 connect_timing_flags);
207 EXPECT_LE(load_timing_info.connect_timing.connect_end,
208 load_timing_info.send_start);
209
210 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20211
[email protected]3b23a222013-05-15 21:33:25212 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20213 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
214 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25215 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25216}
217
Adam Rice425cf122015-01-19 06:18:24218void AddWebSocketHeaders(net::HttpRequestHeaders* headers) {
219 headers->SetHeader("Connection", "Upgrade");
220 headers->SetHeader("Upgrade", "websocket");
221 headers->SetHeader("Origin", "http://www.google.com");
222 headers->SetHeader("Sec-WebSocket-Version", "13");
223 headers->SetHeader("Sec-WebSocket-Key", "dGhlIHNhbXBsZSBub25jZQ==");
224}
225
[email protected]13c8a092010-07-29 06:15:44226} // namespace
227
[email protected]89ceba9a2009-03-21 03:46:06228namespace net {
229
[email protected]448d4ca52012-03-04 04:12:23230namespace {
231
[email protected]c6bf8152012-12-02 07:43:34232HttpNetworkSession* CreateSession(SpdySessionDependencies* session_deps) {
233 return SpdySessionDependencies::SpdyCreateSession(session_deps);
[email protected]e8d536192008-10-17 22:21:14234}
235
[email protected]448d4ca52012-03-04 04:12:23236} // namespace
237
[email protected]23e482282013-06-14 16:08:02238class HttpNetworkTransactionTest
239 : public PlatformTest,
240 public ::testing::WithParamInterface<NextProto> {
[email protected]483fa202013-05-14 01:07:03241 public:
[email protected]23e482282013-06-14 16:08:02242 virtual ~HttpNetworkTransactionTest() {
[email protected]483fa202013-05-14 01:07:03243 // Important to restore the per-pool limit first, since the pool limit must
244 // always be greater than group limit, and the tests reduce both limits.
245 ClientSocketPoolManager::set_max_sockets_per_pool(
246 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
247 ClientSocketPoolManager::set_max_sockets_per_group(
248 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
249 }
250
[email protected]e3ceb682011-06-28 23:55:46251 protected:
[email protected]23e482282013-06-14 16:08:02252 HttpNetworkTransactionTest()
253 : spdy_util_(GetParam()),
254 session_deps_(GetParam()),
[email protected]483fa202013-05-14 01:07:03255 old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
256 HttpNetworkSession::NORMAL_SOCKET_POOL)),
257 old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
258 HttpNetworkSession::NORMAL_SOCKET_POOL)) {
259 }
[email protected]bb88e1d32013-05-03 23:11:07260
[email protected]e3ceb682011-06-28 23:55:46261 struct SimpleGetHelperResult {
262 int rv;
263 std::string status_line;
264 std::string response_data;
[email protected]b8015c42013-12-24 15:18:19265 int64 totalReceivedBytes;
[email protected]58e32bb2013-01-21 18:23:25266 LoadTimingInfo load_timing_info;
[email protected]e3ceb682011-06-28 23:55:46267 };
268
dcheng67be2b1f2014-10-27 21:47:29269 void SetUp() override {
[email protected]0b0bf032010-09-21 18:08:50270 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:34271 base::MessageLoop::current()->RunUntilIdle();
[email protected]2ff8b312010-04-26 22:20:54272 }
273
dcheng67be2b1f2014-10-27 21:47:29274 void TearDown() override {
[email protected]0b0bf032010-09-21 18:08:50275 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:34276 base::MessageLoop::current()->RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09277 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:34278 base::MessageLoop::current()->RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09279 PlatformTest::TearDown();
[email protected]0b0bf032010-09-21 18:08:50280 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:34281 base::MessageLoop::current()->RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09282 }
283
bnc33b8cef42014-11-19 17:30:38284 const char* GetAlternateProtocolFromParam() {
285 return
286 AlternateProtocolToString(AlternateProtocolFromNextProto(GetParam()));
287 }
288
[email protected]8a0fc822013-06-27 20:52:43289 // This is the expected return from a current server advertising SPDY.
290 std::string GetAlternateProtocolHttpHeader() {
bnc33b8cef42014-11-19 17:30:38291 return std::string("Alternate-Protocol: 443:") +
292 GetAlternateProtocolFromParam() + "\r\n\r\n";
[email protected]8a0fc822013-06-27 20:52:43293 }
294
[email protected]202965992011-12-07 23:04:51295 // Either |write_failure| specifies a write failure or |read_failure|
296 // specifies a read failure when using a reused socket. In either case, the
297 // failure should cause the network transaction to resend the request, and the
298 // other argument should be NULL.
299 void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
300 const MockRead* read_failure);
initial.commit586acc5fe2008-07-26 22:42:52301
[email protected]a34f61ee2014-03-18 20:59:49302 // Either |write_failure| specifies a write failure or |read_failure|
303 // specifies a read failure when using a reused socket. In either case, the
304 // failure should cause the network transaction to resend the request, and the
305 // other argument should be NULL.
306 void PreconnectErrorResendRequestTest(const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:10307 const MockRead* read_failure,
308 bool use_spdy);
[email protected]a34f61ee2014-03-18 20:59:49309
[email protected]5a60c8b2011-10-19 20:14:29310 SimpleGetHelperResult SimpleGetHelperForData(StaticSocketDataProvider* data[],
311 size_t data_count) {
[email protected]ff007e162009-05-23 09:13:15312 SimpleGetHelperResult out;
initial.commit586acc5fe2008-07-26 22:42:52313
[email protected]ff007e162009-05-23 09:13:15314 HttpRequestInfo request;
315 request.method = "GET";
316 request.url = GURL("http://www.google.com/");
317 request.load_flags = 0;
initial.commit586acc5fe2008-07-26 22:42:52318
[email protected]58e32bb2013-01-21 18:23:25319 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:07320 session_deps_.net_log = log.bound().net_log();
[email protected]3fe8d2f82013-10-17 08:56:07321 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:27322 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:41323 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:27324
[email protected]5a60c8b2011-10-19 20:14:29325 for (size_t i = 0; i < data_count; ++i) {
[email protected]bb88e1d32013-05-03 23:11:07326 session_deps_.socket_factory->AddSocketDataProvider(data[i]);
[email protected]5a60c8b2011-10-19 20:14:29327 }
initial.commit586acc5fe2008-07-26 22:42:52328
[email protected]49639fa2011-12-20 23:22:41329 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52330
[email protected]c47c0372014-03-12 23:07:02331 EXPECT_TRUE(log.bound().IsLogging());
[email protected]49639fa2011-12-20 23:22:41332 int rv = trans->Start(&request, callback.callback(), log.bound());
[email protected]ff007e162009-05-23 09:13:15333 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:52334
[email protected]ff007e162009-05-23 09:13:15335 out.rv = callback.WaitForResult();
[email protected]58e32bb2013-01-21 18:23:25336
337 // Even in the failure cases that use this function, connections are always
338 // successfully established before the error.
339 EXPECT_TRUE(trans->GetLoadTimingInfo(&out.load_timing_info));
340 TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
341
[email protected]ff007e162009-05-23 09:13:15342 if (out.rv != OK)
343 return out;
344
345 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50346 // Can't use ASSERT_* inside helper functions like this, so
347 // return an error.
[email protected]90499482013-06-01 00:39:50348 if (response == NULL || response->headers.get() == NULL) {
[email protected]fe2255a2011-09-20 19:37:50349 out.rv = ERR_UNEXPECTED;
350 return out;
351 }
[email protected]ff007e162009-05-23 09:13:15352 out.status_line = response->headers->GetStatusLine();
353
[email protected]80a09a82012-11-16 17:40:06354 EXPECT_EQ("127.0.0.1", response->socket_address.host());
355 EXPECT_EQ(80, response->socket_address.port());
[email protected]6d81b482011-02-22 19:47:19356
[email protected]ff007e162009-05-23 09:13:15357 rv = ReadTransaction(trans.get(), &out.response_data);
358 EXPECT_EQ(OK, rv);
[email protected]b2fcd0e2010-12-01 15:19:40359
[email protected]f3da152d2012-06-02 01:00:57360 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:40361 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:39362 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:40363 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
[email protected]169d0012010-05-10 23:20:12364 NetLog::PHASE_NONE);
[email protected]dbb83db2010-05-11 18:13:39365 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:40366 entries, pos,
[email protected]dbb83db2010-05-11 18:13:39367 NetLog::TYPE_HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
368 NetLog::PHASE_NONE);
[email protected]ff007e162009-05-23 09:13:15369
[email protected]f3da152d2012-06-02 01:00:57370 std::string line;
371 EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
372 EXPECT_EQ("GET / HTTP/1.1\r\n", line);
373
[email protected]79e1fd62013-06-20 06:50:04374 HttpRequestHeaders request_headers;
375 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
376 std::string value;
377 EXPECT_TRUE(request_headers.GetHeader("Host", &value));
378 EXPECT_EQ("www.google.com", value);
379 EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
380 EXPECT_EQ("keep-alive", value);
381
382 std::string response_headers;
383 EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
384 EXPECT_EQ("['Host: www.google.com','Connection: keep-alive']",
385 response_headers);
[email protected]3deb9a52010-11-11 00:24:40386
[email protected]b8015c42013-12-24 15:18:19387 out.totalReceivedBytes = trans->GetTotalReceivedBytes();
[email protected]aecfbf22008-10-16 02:02:47388 return out;
[email protected]ff007e162009-05-23 09:13:15389 }
initial.commit586acc5fe2008-07-26 22:42:52390
[email protected]5a60c8b2011-10-19 20:14:29391 SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[],
392 size_t reads_count) {
393 StaticSocketDataProvider reads(data_reads, reads_count, NULL, 0);
394 StaticSocketDataProvider* data[] = { &reads };
395 return SimpleGetHelperForData(data, 1);
396 }
397
[email protected]b8015c42013-12-24 15:18:19398 int64 ReadsSize(MockRead data_reads[], size_t reads_count) {
399 int64 size = 0;
400 for (size_t i = 0; i < reads_count; ++i)
401 size += data_reads[i].data_len;
402 return size;
403 }
404
[email protected]ff007e162009-05-23 09:13:15405 void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
406 int expected_status);
initial.commit586acc5fe2008-07-26 22:42:52407
[email protected]ff007e162009-05-23 09:13:15408 void ConnectStatusHelper(const MockRead& status);
[email protected]bb88e1d32013-05-03 23:11:07409
410 void BypassHostCacheOnRefreshHelper(int load_flags);
411
412 void CheckErrorIsPassedBack(int error, IoMode mode);
413
[email protected]4bd46222013-05-14 19:32:23414 SpdyTestUtil spdy_util_;
[email protected]bb88e1d32013-05-03 23:11:07415 SpdySessionDependencies session_deps_;
[email protected]483fa202013-05-14 01:07:03416
417 // Original socket limits. Some tests set these. Safest to always restore
418 // them once each test has been run.
419 int old_max_group_sockets_;
420 int old_max_pool_sockets_;
[email protected]ff007e162009-05-23 09:13:15421};
[email protected]231d5a32008-09-13 00:45:27422
[email protected]23e482282013-06-14 16:08:02423INSTANTIATE_TEST_CASE_P(
424 NextProto,
425 HttpNetworkTransactionTest,
bnc33b8cef42014-11-19 17:30:38426 testing::Values(kProtoSPDY31, kProtoSPDY4_14, kProtoSPDY4_15));
[email protected]23e482282013-06-14 16:08:02427
[email protected]448d4ca52012-03-04 04:12:23428namespace {
429
[email protected]1826a402014-01-08 15:40:48430class BeforeNetworkStartHandler {
431 public:
432 explicit BeforeNetworkStartHandler(bool defer)
433 : defer_on_before_network_start_(defer),
434 observed_before_network_start_(false) {}
435
436 void OnBeforeNetworkStart(bool* defer) {
437 *defer = defer_on_before_network_start_;
438 observed_before_network_start_ = true;
439 }
440
441 bool observed_before_network_start() const {
442 return observed_before_network_start_;
443 }
444
445 private:
446 const bool defer_on_before_network_start_;
447 bool observed_before_network_start_;
448
449 DISALLOW_COPY_AND_ASSIGN(BeforeNetworkStartHandler);
450};
451
[email protected]597a1ab2014-06-26 08:12:27452class BeforeProxyHeadersSentHandler {
453 public:
454 BeforeProxyHeadersSentHandler()
455 : observed_before_proxy_headers_sent_(false) {}
456
[email protected]1252d42f2014-07-01 21:20:20457 void OnBeforeProxyHeadersSent(const ProxyInfo& proxy_info,
458 HttpRequestHeaders* request_headers) {
[email protected]597a1ab2014-06-26 08:12:27459 observed_before_proxy_headers_sent_ = true;
460 observed_proxy_server_uri_ = proxy_info.proxy_server().ToURI();
461 }
462
463 bool observed_before_proxy_headers_sent() const {
464 return observed_before_proxy_headers_sent_;
465 }
466
467 std::string observed_proxy_server_uri() const {
468 return observed_proxy_server_uri_;
469 }
470
471 private:
472 bool observed_before_proxy_headers_sent_;
473 std::string observed_proxy_server_uri_;
474
475 DISALLOW_COPY_AND_ASSIGN(BeforeProxyHeadersSentHandler);
476};
477
[email protected]15a5ccf82008-10-23 19:57:43478// Fill |str| with a long header list that consumes >= |size| bytes.
479void FillLargeHeadersString(std::string* str, int size) {
thestig9d3bb0c2015-01-24 00:49:51480 const char row[] =
[email protected]4ddaf2502008-10-23 18:26:19481 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
482 const int sizeof_row = strlen(row);
483 const int num_rows = static_cast<int>(
484 ceil(static_cast<float>(size) / sizeof_row));
485 const int sizeof_data = num_rows * sizeof_row;
486 DCHECK(sizeof_data >= size);
[email protected]15a5ccf82008-10-23 19:57:43487 str->reserve(sizeof_data);
[email protected]372d34a2008-11-05 21:30:51488
[email protected]4ddaf2502008-10-23 18:26:19489 for (int i = 0; i < num_rows; ++i)
[email protected]15a5ccf82008-10-23 19:57:43490 str->append(row, sizeof_row);
[email protected]4ddaf2502008-10-23 18:26:19491}
492
[email protected]385a4672009-03-11 22:21:29493// Alternative functions that eliminate randomness and dependency on the local
494// host name so that the generated NTLM messages are reproducible.
[email protected]fe2bc6a2009-03-23 16:52:20495void MockGenerateRandom1(uint8* output, size_t n) {
[email protected]385a4672009-03-11 22:21:29496 static const uint8 bytes[] = {
497 0x55, 0x29, 0x66, 0x26, 0x6b, 0x9c, 0x73, 0x54
498 };
499 static size_t current_byte = 0;
500 for (size_t i = 0; i < n; ++i) {
501 output[i] = bytes[current_byte++];
502 current_byte %= arraysize(bytes);
503 }
504}
505
[email protected]fe2bc6a2009-03-23 16:52:20506void MockGenerateRandom2(uint8* output, size_t n) {
[email protected]385a4672009-03-11 22:21:29507 static const uint8 bytes[] = {
508 0x96, 0x79, 0x85, 0xe7, 0x49, 0x93, 0x70, 0xa1,
509 0x4e, 0xe7, 0x87, 0x45, 0x31, 0x5b, 0xd3, 0x1f
510 };
511 static size_t current_byte = 0;
512 for (size_t i = 0; i < n; ++i) {
513 output[i] = bytes[current_byte++];
514 current_byte %= arraysize(bytes);
515 }
516}
517
[email protected]fe2bc6a2009-03-23 16:52:20518std::string MockGetHostName() {
519 return "WTC-WIN7";
[email protected]385a4672009-03-11 22:21:29520}
521
[email protected]e60e47a2010-07-14 03:37:18522template<typename ParentPool>
523class CaptureGroupNameSocketPool : public ParentPool {
[email protected]04e5be32009-06-26 20:00:31524 public:
[email protected]9e1bdd32011-02-03 21:48:34525 CaptureGroupNameSocketPool(HostResolver* host_resolver,
526 CertVerifier* cert_verifier);
[email protected]e60e47a2010-07-14 03:37:18527
[email protected]d80a4322009-08-14 07:07:49528 const std::string last_group_name_received() const {
529 return last_group_name_;
530 }
531
dmichaeld6e570d2014-12-18 22:30:57532 int RequestSocket(const std::string& group_name,
533 const void* socket_params,
534 RequestPriority priority,
535 ClientSocketHandle* handle,
536 const CompletionCallback& callback,
537 const BoundNetLog& net_log) override {
[email protected]04e5be32009-06-26 20:00:31538 last_group_name_ = group_name;
539 return ERR_IO_PENDING;
540 }
dmichaeld6e570d2014-12-18 22:30:57541 void CancelRequest(const std::string& group_name,
542 ClientSocketHandle* handle) override {}
543 void ReleaseSocket(const std::string& group_name,
544 scoped_ptr<StreamSocket> socket,
545 int id) override {}
546 void CloseIdleSockets() override {}
547 int IdleSocketCount() const override { return 0; }
548 int IdleSocketCountInGroup(const std::string& group_name) const override {
[email protected]04e5be32009-06-26 20:00:31549 return 0;
550 }
dmichaeld6e570d2014-12-18 22:30:57551 LoadState GetLoadState(const std::string& group_name,
552 const ClientSocketHandle* handle) const override {
[email protected]04e5be32009-06-26 20:00:31553 return LOAD_STATE_IDLE;
554 }
dmichaeld6e570d2014-12-18 22:30:57555 base::TimeDelta ConnectionTimeout() const override {
[email protected]a796bcec2010-03-22 17:17:26556 return base::TimeDelta();
557 }
[email protected]d80a4322009-08-14 07:07:49558
559 private:
[email protected]04e5be32009-06-26 20:00:31560 std::string last_group_name_;
561};
562
[email protected]ab739042011-04-07 15:22:28563typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
564CaptureGroupNameTransportSocketPool;
[email protected]e772db3f2010-07-12 18:11:13565typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
566CaptureGroupNameHttpProxySocketPool;
[email protected]2d731a32010-04-29 01:04:06567typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
[email protected]2227c692010-05-04 15:36:11568CaptureGroupNameSOCKSSocketPool;
[email protected]e60e47a2010-07-14 03:37:18569typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
570CaptureGroupNameSSLSocketPool;
571
572template<typename ParentPool>
573CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34574 HostResolver* host_resolver,
575 CertVerifier* /* cert_verifier */)
576 : ParentPool(0, 0, NULL, host_resolver, NULL, NULL) {}
[email protected]e60e47a2010-07-14 03:37:18577
hashimoto0d3e4fb2015-01-09 05:02:50578template <>
[email protected]2df19bb2010-08-25 20:13:46579CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21580 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34581 CertVerifier* /* cert_verifier */)
hashimotodae13b02015-01-15 04:28:21582 : HttpProxyClientSocketPool(0, 0, NULL, NULL, NULL, NULL) {
hashimoto0d3e4fb2015-01-09 05:02:50583}
[email protected]2df19bb2010-08-25 20:13:46584
[email protected]007b3f82013-04-09 08:46:45585template <>
[email protected]e60e47a2010-07-14 03:37:18586CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21587 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34588 CertVerifier* cert_verifier)
[email protected]007b3f82013-04-09 08:46:45589 : SSLClientSocketPool(0,
590 0,
591 NULL,
[email protected]007b3f82013-04-09 08:46:45592 cert_verifier,
593 NULL,
594 NULL,
[email protected]284303b62013-11-28 15:11:54595 NULL,
eranm6571b2b2014-12-03 15:53:23596 NULL,
[email protected]007b3f82013-04-09 08:46:45597 std::string(),
598 NULL,
599 NULL,
600 NULL,
601 NULL,
602 NULL,
[email protected]8e458552014-08-05 00:02:15603 false,
604 NULL) {
605}
[email protected]2227c692010-05-04 15:36:11606
[email protected]231d5a32008-09-13 00:45:27607//-----------------------------------------------------------------------------
608
[email protected]79cb5c12011-09-12 13:12:04609// Helper functions for validating that AuthChallengeInfo's are correctly
610// configured for common cases.
611bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
612 if (!auth_challenge)
613 return false;
614 EXPECT_FALSE(auth_challenge->is_proxy);
615 EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString());
616 EXPECT_EQ("MyRealm1", auth_challenge->realm);
617 EXPECT_EQ("basic", auth_challenge->scheme);
618 return true;
619}
620
621bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
622 if (!auth_challenge)
623 return false;
624 EXPECT_TRUE(auth_challenge->is_proxy);
625 EXPECT_EQ("myproxy:70", auth_challenge->challenger.ToString());
626 EXPECT_EQ("MyRealm1", auth_challenge->realm);
627 EXPECT_EQ("basic", auth_challenge->scheme);
628 return true;
629}
630
631bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
632 if (!auth_challenge)
633 return false;
634 EXPECT_FALSE(auth_challenge->is_proxy);
635 EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString());
636 EXPECT_EQ("digestive", auth_challenge->realm);
637 EXPECT_EQ("digest", auth_challenge->scheme);
638 return true;
639}
640
641bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
642 if (!auth_challenge)
643 return false;
644 EXPECT_FALSE(auth_challenge->is_proxy);
645 EXPECT_EQ("172.22.68.17:80", auth_challenge->challenger.ToString());
646 EXPECT_EQ(std::string(), auth_challenge->realm);
647 EXPECT_EQ("ntlm", auth_challenge->scheme);
648 return true;
649}
650
[email protected]448d4ca52012-03-04 04:12:23651} // namespace
652
[email protected]23e482282013-06-14 16:08:02653TEST_P(HttpNetworkTransactionTest, Basic) {
[email protected]3fe8d2f82013-10-17 08:56:07654 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:40655 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:41656 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]231d5a32008-09-13 00:45:27657}
658
[email protected]23e482282013-06-14 16:08:02659TEST_P(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27660 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35661 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
662 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06663 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27664 };
[email protected]31a2bfe2010-02-09 08:03:39665 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
666 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42667 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27668 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
669 EXPECT_EQ("hello world", out.response_data);
[email protected]b8015c42013-12-24 15:18:19670 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
671 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27672}
673
674// Response with no status line.
[email protected]23e482282013-06-14 16:08:02675TEST_P(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27676 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35677 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06678 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27679 };
[email protected]31a2bfe2010-02-09 08:03:39680 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
681 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42682 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27683 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
684 EXPECT_EQ("hello world", out.response_data);
[email protected]b8015c42013-12-24 15:18:19685 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
686 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27687}
688
689// Allow up to 4 bytes of junk to precede status line.
[email protected]23e482282013-06-14 16:08:02690TEST_P(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27691 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35692 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06693 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27694 };
[email protected]31a2bfe2010-02-09 08:03:39695 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
696 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42697 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27698 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
699 EXPECT_EQ("DATA", out.response_data);
[email protected]b8015c42013-12-24 15:18:19700 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
701 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27702}
703
704// Allow up to 4 bytes of junk to precede status line.
[email protected]23e482282013-06-14 16:08:02705TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27706 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35707 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06708 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27709 };
[email protected]31a2bfe2010-02-09 08:03:39710 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
711 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42712 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27713 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
714 EXPECT_EQ("DATA", out.response_data);
[email protected]b8015c42013-12-24 15:18:19715 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
716 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27717}
718
719// Beyond 4 bytes of slop and it should fail to find a status line.
[email protected]23e482282013-06-14 16:08:02720TEST_P(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27721 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35722 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06723 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27724 };
[email protected]31a2bfe2010-02-09 08:03:39725 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
726 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42727 EXPECT_EQ(OK, out.rv);
[email protected]3d2a59b2008-09-26 19:44:25728 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
729 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
[email protected]b8015c42013-12-24 15:18:19730 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
731 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27732}
733
734// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
[email protected]23e482282013-06-14 16:08:02735TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27736 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35737 MockRead("\n"),
738 MockRead("\n"),
739 MockRead("Q"),
740 MockRead("J"),
741 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06742 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27743 };
[email protected]31a2bfe2010-02-09 08:03:39744 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
745 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42746 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27747 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
748 EXPECT_EQ("DATA", out.response_data);
[email protected]b8015c42013-12-24 15:18:19749 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
750 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27751}
752
753// Close the connection before enough bytes to have a status line.
[email protected]23e482282013-06-14 16:08:02754TEST_P(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:27755 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35756 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:06757 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27758 };
[email protected]31a2bfe2010-02-09 08:03:39759 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
760 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42761 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27762 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
763 EXPECT_EQ("HTT", out.response_data);
[email protected]b8015c42013-12-24 15:18:19764 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
765 EXPECT_EQ(reads_size, out.totalReceivedBytes);
initial.commit586acc5fe2008-07-26 22:42:52766}
767
[email protected]f9d44aa2008-09-23 23:57:17768// Simulate a 204 response, lacking a Content-Length header, sent over a
769// persistent connection. The response should still terminate since a 204
770// cannot have a response body.
[email protected]23e482282013-06-14 16:08:02771TEST_P(HttpNetworkTransactionTest, StopsReading204) {
[email protected]b8015c42013-12-24 15:18:19772 char junk[] = "junk";
[email protected]f9d44aa2008-09-23 23:57:17773 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35774 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
[email protected]b8015c42013-12-24 15:18:19775 MockRead(junk), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:06776 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:17777 };
[email protected]31a2bfe2010-02-09 08:03:39778 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
779 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42780 EXPECT_EQ(OK, out.rv);
[email protected]f9d44aa2008-09-23 23:57:17781 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
782 EXPECT_EQ("", out.response_data);
[email protected]b8015c42013-12-24 15:18:19783 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
784 int64 response_size = reads_size - strlen(junk);
785 EXPECT_EQ(response_size, out.totalReceivedBytes);
[email protected]f9d44aa2008-09-23 23:57:17786}
787
[email protected]0877e3d2009-10-17 22:29:57788// A simple request using chunked encoding with some extra data after.
[email protected]23e482282013-06-14 16:08:02789TEST_P(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]b8015c42013-12-24 15:18:19790 std::string final_chunk = "0\r\n\r\n";
791 std::string extra_data = "HTTP/1.1 200 OK\r\n";
792 std::string last_read = final_chunk + extra_data;
[email protected]0877e3d2009-10-17 22:29:57793 MockRead data_reads[] = {
794 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
795 MockRead("5\r\nHello\r\n"),
796 MockRead("1\r\n"),
797 MockRead(" \r\n"),
798 MockRead("5\r\nworld\r\n"),
[email protected]b8015c42013-12-24 15:18:19799 MockRead(last_read.data()),
[email protected]8ddf8322012-02-23 18:08:06800 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:57801 };
[email protected]31a2bfe2010-02-09 08:03:39802 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
803 arraysize(data_reads));
[email protected]0877e3d2009-10-17 22:29:57804 EXPECT_EQ(OK, out.rv);
805 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
806 EXPECT_EQ("Hello world", out.response_data);
[email protected]b8015c42013-12-24 15:18:19807 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
808 int64 response_size = reads_size - extra_data.size();
809 EXPECT_EQ(response_size, out.totalReceivedBytes);
[email protected]0877e3d2009-10-17 22:29:57810}
811
[email protected]9fe44f52010-09-23 18:36:00812// Next tests deal with http://crbug.com/56344.
813
[email protected]23e482282013-06-14 16:08:02814TEST_P(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00815 MultipleContentLengthHeadersNoTransferEncoding) {
816 MockRead data_reads[] = {
817 MockRead("HTTP/1.1 200 OK\r\n"),
818 MockRead("Content-Length: 10\r\n"),
819 MockRead("Content-Length: 5\r\n\r\n"),
820 };
821 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
822 arraysize(data_reads));
823 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
824}
825
[email protected]23e482282013-06-14 16:08:02826TEST_P(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04827 DuplicateContentLengthHeadersNoTransferEncoding) {
828 MockRead data_reads[] = {
829 MockRead("HTTP/1.1 200 OK\r\n"),
830 MockRead("Content-Length: 5\r\n"),
831 MockRead("Content-Length: 5\r\n\r\n"),
832 MockRead("Hello"),
833 };
834 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
835 arraysize(data_reads));
836 EXPECT_EQ(OK, out.rv);
837 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
838 EXPECT_EQ("Hello", out.response_data);
839}
840
[email protected]23e482282013-06-14 16:08:02841TEST_P(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04842 ComplexContentLengthHeadersNoTransferEncoding) {
843 // More than 2 dupes.
844 {
845 MockRead data_reads[] = {
846 MockRead("HTTP/1.1 200 OK\r\n"),
847 MockRead("Content-Length: 5\r\n"),
848 MockRead("Content-Length: 5\r\n"),
849 MockRead("Content-Length: 5\r\n\r\n"),
850 MockRead("Hello"),
851 };
852 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
853 arraysize(data_reads));
854 EXPECT_EQ(OK, out.rv);
855 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
856 EXPECT_EQ("Hello", out.response_data);
857 }
858 // HTTP/1.0
859 {
860 MockRead data_reads[] = {
861 MockRead("HTTP/1.0 200 OK\r\n"),
862 MockRead("Content-Length: 5\r\n"),
863 MockRead("Content-Length: 5\r\n"),
864 MockRead("Content-Length: 5\r\n\r\n"),
865 MockRead("Hello"),
866 };
867 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
868 arraysize(data_reads));
869 EXPECT_EQ(OK, out.rv);
870 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
871 EXPECT_EQ("Hello", out.response_data);
872 }
873 // 2 dupes and one mismatched.
874 {
875 MockRead data_reads[] = {
876 MockRead("HTTP/1.1 200 OK\r\n"),
877 MockRead("Content-Length: 10\r\n"),
878 MockRead("Content-Length: 10\r\n"),
879 MockRead("Content-Length: 5\r\n\r\n"),
880 };
881 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
882 arraysize(data_reads));
883 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
884 }
885}
886
[email protected]23e482282013-06-14 16:08:02887TEST_P(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00888 MultipleContentLengthHeadersTransferEncoding) {
889 MockRead data_reads[] = {
890 MockRead("HTTP/1.1 200 OK\r\n"),
891 MockRead("Content-Length: 666\r\n"),
892 MockRead("Content-Length: 1337\r\n"),
893 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
894 MockRead("5\r\nHello\r\n"),
895 MockRead("1\r\n"),
896 MockRead(" \r\n"),
897 MockRead("5\r\nworld\r\n"),
898 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:06899 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:00900 };
901 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
902 arraysize(data_reads));
903 EXPECT_EQ(OK, out.rv);
904 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
905 EXPECT_EQ("Hello world", out.response_data);
906}
907
[email protected]1628fe92011-10-04 23:04:55908// Next tests deal with http://crbug.com/98895.
909
910// Checks that a single Content-Disposition header results in no error.
[email protected]23e482282013-06-14 16:08:02911TEST_P(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:55912 MockRead data_reads[] = {
913 MockRead("HTTP/1.1 200 OK\r\n"),
914 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
915 MockRead("Content-Length: 5\r\n\r\n"),
916 MockRead("Hello"),
917 };
918 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
919 arraysize(data_reads));
920 EXPECT_EQ(OK, out.rv);
921 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
922 EXPECT_EQ("Hello", out.response_data);
923}
924
[email protected]54a9c6e52012-03-21 20:10:59925// Checks that two identical Content-Disposition headers result in no error.
[email protected]23e482282013-06-14 16:08:02926TEST_P(HttpNetworkTransactionTest,
[email protected]54a9c6e52012-03-21 20:10:59927 TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:55928 MockRead data_reads[] = {
929 MockRead("HTTP/1.1 200 OK\r\n"),
930 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
931 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
932 MockRead("Content-Length: 5\r\n\r\n"),
933 MockRead("Hello"),
934 };
935 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
936 arraysize(data_reads));
[email protected]54a9c6e52012-03-21 20:10:59937 EXPECT_EQ(OK, out.rv);
938 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
939 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:55940}
941
942// Checks that two distinct Content-Disposition headers result in an error.
[email protected]23e482282013-06-14 16:08:02943TEST_P(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:55944 MockRead data_reads[] = {
945 MockRead("HTTP/1.1 200 OK\r\n"),
946 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
947 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
948 MockRead("Content-Length: 5\r\n\r\n"),
949 MockRead("Hello"),
950 };
951 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
952 arraysize(data_reads));
953 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION, out.rv);
954}
955
[email protected]54a9c6e52012-03-21 20:10:59956// Checks that two identical Location headers result in no error.
957// Also tests Location header behavior.
[email protected]23e482282013-06-14 16:08:02958TEST_P(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:55959 MockRead data_reads[] = {
960 MockRead("HTTP/1.1 302 Redirect\r\n"),
961 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:59962 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:55963 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:06964 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:55965 };
966
967 HttpRequestInfo request;
968 request.method = "GET";
969 request.url = GURL("http://redirect.com/");
970 request.load_flags = 0;
971
[email protected]3fe8d2f82013-10-17 08:56:07972 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1628fe92011-10-04 23:04:55973 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:41974 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]1628fe92011-10-04 23:04:55975
976 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:07977 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:55978
[email protected]49639fa2011-12-20 23:22:41979 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:55980
[email protected]49639fa2011-12-20 23:22:41981 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1628fe92011-10-04 23:04:55982 EXPECT_EQ(ERR_IO_PENDING, rv);
983
984 EXPECT_EQ(OK, callback.WaitForResult());
985
986 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]90499482013-06-01 00:39:50987 ASSERT_TRUE(response != NULL && response->headers.get() != NULL);
[email protected]1628fe92011-10-04 23:04:55988 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
989 std::string url;
990 EXPECT_TRUE(response->headers->IsRedirect(&url));
991 EXPECT_EQ("http://good.com/", url);
[email protected]d8fc4722014-06-13 13:17:15992 EXPECT_TRUE(response->proxy_server.IsEmpty());
[email protected]1628fe92011-10-04 23:04:55993}
994
[email protected]1628fe92011-10-04 23:04:55995// Checks that two distinct Location headers result in an error.
[email protected]23e482282013-06-14 16:08:02996TEST_P(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:55997 MockRead data_reads[] = {
998 MockRead("HTTP/1.1 302 Redirect\r\n"),
999 MockRead("Location: http://good.com/\r\n"),
1000 MockRead("Location: http://evil.com/\r\n"),
1001 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061002 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551003 };
1004 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1005 arraysize(data_reads));
1006 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION, out.rv);
1007}
1008
[email protected]ef0faf2e72009-03-05 23:27:231009// Do a request using the HEAD method. Verify that we don't try to read the
1010// message body (since HEAD has none).
[email protected]23e482282013-06-14 16:08:021011TEST_P(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:421012 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:231013 request.method = "HEAD";
1014 request.url = GURL("http://www.google.com/");
1015 request.load_flags = 0;
1016
[email protected]3fe8d2f82013-10-17 08:56:071017 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271018 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411019 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]597a1ab2014-06-26 08:12:271020 BeforeProxyHeadersSentHandler proxy_headers_handler;
1021 trans->SetBeforeProxyHeadersSentCallback(
1022 base::Bind(&BeforeProxyHeadersSentHandler::OnBeforeProxyHeadersSent,
1023 base::Unretained(&proxy_headers_handler)));
[email protected]cb9bf6ca2011-01-28 13:15:271024
[email protected]ef0faf2e72009-03-05 23:27:231025 MockWrite data_writes1[] = {
1026 MockWrite("HEAD / HTTP/1.1\r\n"
1027 "Host: www.google.com\r\n"
1028 "Connection: keep-alive\r\n"
1029 "Content-Length: 0\r\n\r\n"),
1030 };
1031 MockRead data_reads1[] = {
1032 MockRead("HTTP/1.1 404 Not Found\r\n"),
1033 MockRead("Server: Blah\r\n"),
1034 MockRead("Content-Length: 1234\r\n\r\n"),
1035
1036 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:061037 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]ef0faf2e72009-03-05 23:27:231038 };
1039
[email protected]31a2bfe2010-02-09 08:03:391040 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1041 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:071042 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:231043
[email protected]49639fa2011-12-20 23:22:411044 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:231045
[email protected]49639fa2011-12-20 23:22:411046 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421047 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]ef0faf2e72009-03-05 23:27:231048
1049 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421050 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:231051
[email protected]1c773ea12009-04-28 19:58:421052 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501053 ASSERT_TRUE(response != NULL);
[email protected]ef0faf2e72009-03-05 23:27:231054
1055 // Check that the headers got parsed.
[email protected]90499482013-06-01 00:39:501056 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]ef0faf2e72009-03-05 23:27:231057 EXPECT_EQ(1234, response->headers->GetContentLength());
1058 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
[email protected]d8fc4722014-06-13 13:17:151059 EXPECT_TRUE(response->proxy_server.IsEmpty());
[email protected]597a1ab2014-06-26 08:12:271060 EXPECT_FALSE(proxy_headers_handler.observed_before_proxy_headers_sent());
[email protected]ef0faf2e72009-03-05 23:27:231061
1062 std::string server_header;
1063 void* iter = NULL;
1064 bool has_server_header = response->headers->EnumerateHeader(
1065 &iter, "Server", &server_header);
1066 EXPECT_TRUE(has_server_header);
1067 EXPECT_EQ("Blah", server_header);
1068
1069 // Reading should give EOF right away, since there is no message body
1070 // (despite non-zero content-length).
1071 std::string response_data;
1072 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421073 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:231074 EXPECT_EQ("", response_data);
1075}
1076
[email protected]23e482282013-06-14 16:08:021077TEST_P(HttpNetworkTransactionTest, ReuseConnection) {
[email protected]bb88e1d32013-05-03 23:11:071078 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:521079
1080 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351081 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1082 MockRead("hello"),
1083 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1084 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061085 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521086 };
[email protected]31a2bfe2010-02-09 08:03:391087 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071088 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521089
[email protected]0b0bf032010-09-21 18:08:501090 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521091 "hello", "world"
1092 };
1093
1094 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:421095 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521096 request.method = "GET";
1097 request.url = GURL("http://www.google.com/");
1098 request.load_flags = 0;
1099
[email protected]262eec82013-03-19 21:01:361100 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501101 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271102
[email protected]49639fa2011-12-20 23:22:411103 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521104
[email protected]49639fa2011-12-20 23:22:411105 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421106 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521107
1108 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421109 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521110
[email protected]1c773ea12009-04-28 19:58:421111 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501112 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521113
[email protected]90499482013-06-01 00:39:501114 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251115 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]d8fc4722014-06-13 13:17:151116 EXPECT_TRUE(response->proxy_server.IsEmpty());
initial.commit586acc5fe2008-07-26 22:42:521117
1118 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571119 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421120 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251121 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521122 }
1123}
1124
[email protected]23e482282013-06-14 16:08:021125TEST_P(HttpNetworkTransactionTest, Ignores100) {
[email protected]b2d26cfd2012-12-11 10:36:061126 ScopedVector<UploadElementReader> element_readers;
1127 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:071128 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:271129
[email protected]1c773ea12009-04-28 19:58:421130 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521131 request.method = "POST";
1132 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271133 request.upload_data_stream = &upload_data_stream;
initial.commit586acc5fe2008-07-26 22:42:521134 request.load_flags = 0;
1135
[email protected]3fe8d2f82013-10-17 08:56:071136 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271137 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411138 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271139
initial.commit586acc5fe2008-07-26 22:42:521140 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351141 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1142 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1143 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061144 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521145 };
[email protected]31a2bfe2010-02-09 08:03:391146 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071147 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521148
[email protected]49639fa2011-12-20 23:22:411149 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521150
[email protected]49639fa2011-12-20 23:22:411151 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421152 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521153
1154 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421155 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521156
[email protected]1c773ea12009-04-28 19:58:421157 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501158 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521159
[email protected]90499482013-06-01 00:39:501160 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251161 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521162
1163 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571164 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421165 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251166 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521167}
1168
[email protected]3a2d3662009-03-27 03:49:141169// This test is almost the same as Ignores100 above, but the response contains
1170// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571171// HTTP/1.1 and the two status headers are read in one read.
[email protected]23e482282013-06-14 16:08:021172TEST_P(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421173 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141174 request.method = "GET";
1175 request.url = GURL("http://www.foo.com/");
1176 request.load_flags = 0;
1177
[email protected]3fe8d2f82013-10-17 08:56:071178 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271179 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411180 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271181
[email protected]3a2d3662009-03-27 03:49:141182 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571183 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1184 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141185 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061186 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141187 };
[email protected]31a2bfe2010-02-09 08:03:391188 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071189 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141190
[email protected]49639fa2011-12-20 23:22:411191 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141192
[email protected]49639fa2011-12-20 23:22:411193 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421194 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3a2d3662009-03-27 03:49:141195
1196 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421197 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:141198
[email protected]1c773ea12009-04-28 19:58:421199 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501200 ASSERT_TRUE(response != NULL);
[email protected]3a2d3662009-03-27 03:49:141201
[email protected]90499482013-06-01 00:39:501202 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3a2d3662009-03-27 03:49:141203 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1204
1205 std::string response_data;
1206 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421207 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:141208 EXPECT_EQ("hello world", response_data);
1209}
1210
[email protected]23e482282013-06-14 16:08:021211TEST_P(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
[email protected]ee9410e72010-01-07 01:42:381212 HttpRequestInfo request;
1213 request.method = "POST";
1214 request.url = GURL("http://www.foo.com/");
1215 request.load_flags = 0;
1216
[email protected]3fe8d2f82013-10-17 08:56:071217 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271218 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411219 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271220
[email protected]ee9410e72010-01-07 01:42:381221 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061222 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1223 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381224 };
[email protected]31a2bfe2010-02-09 08:03:391225 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071226 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381227
[email protected]49639fa2011-12-20 23:22:411228 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381229
[email protected]49639fa2011-12-20 23:22:411230 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]ee9410e72010-01-07 01:42:381231 EXPECT_EQ(ERR_IO_PENDING, rv);
1232
1233 rv = callback.WaitForResult();
1234 EXPECT_EQ(OK, rv);
1235
1236 std::string response_data;
1237 rv = ReadTransaction(trans.get(), &response_data);
1238 EXPECT_EQ(OK, rv);
1239 EXPECT_EQ("", response_data);
1240}
1241
[email protected]23e482282013-06-14 16:08:021242TEST_P(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381243 HttpRequestInfo request;
1244 request.method = "POST";
1245 request.url = GURL("http://www.foo.com/");
1246 request.load_flags = 0;
1247
[email protected]3fe8d2f82013-10-17 08:56:071248 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271249 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411250 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271251
[email protected]ee9410e72010-01-07 01:42:381252 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061253 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381254 };
[email protected]31a2bfe2010-02-09 08:03:391255 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071256 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381257
[email protected]49639fa2011-12-20 23:22:411258 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381259
[email protected]49639fa2011-12-20 23:22:411260 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]ee9410e72010-01-07 01:42:381261 EXPECT_EQ(ERR_IO_PENDING, rv);
1262
1263 rv = callback.WaitForResult();
1264 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
1265}
1266
[email protected]23e482282013-06-14 16:08:021267void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511268 const MockWrite* write_failure,
1269 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421270 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521271 request.method = "GET";
1272 request.url = GURL("http://www.foo.com/");
1273 request.load_flags = 0;
1274
[email protected]58e32bb2013-01-21 18:23:251275 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071276 session_deps_.net_log = &net_log;
1277 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271278
[email protected]202965992011-12-07 23:04:511279 // Written data for successfully sending both requests.
1280 MockWrite data1_writes[] = {
1281 MockWrite("GET / HTTP/1.1\r\n"
1282 "Host: www.foo.com\r\n"
1283 "Connection: keep-alive\r\n\r\n"),
1284 MockWrite("GET / HTTP/1.1\r\n"
1285 "Host: www.foo.com\r\n"
1286 "Connection: keep-alive\r\n\r\n")
1287 };
1288
1289 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521290 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351291 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1292 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061293 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521294 };
[email protected]202965992011-12-07 23:04:511295
1296 if (write_failure) {
[email protected]a34f61ee2014-03-18 20:59:491297 ASSERT_FALSE(read_failure);
[email protected]202965992011-12-07 23:04:511298 data1_writes[1] = *write_failure;
1299 } else {
1300 ASSERT_TRUE(read_failure);
1301 data1_reads[2] = *read_failure;
1302 }
1303
1304 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
1305 data1_writes, arraysize(data1_writes));
[email protected]bb88e1d32013-05-03 23:11:071306 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521307
1308 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351309 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1310 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061311 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521312 };
[email protected]31a2bfe2010-02-09 08:03:391313 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071314 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521315
thestig9d3bb0c2015-01-24 00:49:511316 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521317 "hello", "world"
1318 };
1319
[email protected]58e32bb2013-01-21 18:23:251320 uint32 first_socket_log_id = NetLog::Source::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521321 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411322 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521323
[email protected]262eec82013-03-19 21:01:361324 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501325 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
initial.commit586acc5fe2008-07-26 22:42:521326
[email protected]49639fa2011-12-20 23:22:411327 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421328 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521329
1330 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421331 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521332
[email protected]58e32bb2013-01-21 18:23:251333 LoadTimingInfo load_timing_info;
1334 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1335 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1336 if (i == 0) {
1337 first_socket_log_id = load_timing_info.socket_log_id;
1338 } else {
1339 // The second request should be using a new socket.
1340 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1341 }
1342
[email protected]1c773ea12009-04-28 19:58:421343 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501344 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521345
[email protected]90499482013-06-01 00:39:501346 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251347 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521348
1349 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571350 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421351 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251352 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521353 }
1354}
[email protected]3d2a59b2008-09-26 19:44:251355
[email protected]a34f61ee2014-03-18 20:59:491356void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1357 const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:101358 const MockRead* read_failure,
1359 bool use_spdy) {
[email protected]a34f61ee2014-03-18 20:59:491360 HttpRequestInfo request;
1361 request.method = "GET";
[email protected]09356c652014-03-25 15:36:101362 request.url = GURL("https://www.foo.com/");
[email protected]a34f61ee2014-03-18 20:59:491363 request.load_flags = 0;
1364
1365 CapturingNetLog net_log;
1366 session_deps_.net_log = &net_log;
1367 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1368
[email protected]09356c652014-03-25 15:36:101369 SSLSocketDataProvider ssl1(ASYNC, OK);
1370 SSLSocketDataProvider ssl2(ASYNC, OK);
1371 if (use_spdy) {
1372 ssl1.SetNextProto(GetParam());
1373 ssl2.SetNextProto(GetParam());
1374 }
1375 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1376 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]a34f61ee2014-03-18 20:59:491377
[email protected]09356c652014-03-25 15:36:101378 // SPDY versions of the request and response.
1379 scoped_ptr<SpdyFrame> spdy_request(spdy_util_.ConstructSpdyGet(
1380 request.url.spec().c_str(), false, 1, DEFAULT_PRIORITY));
1381 scoped_ptr<SpdyFrame> spdy_response(
1382 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
1383 scoped_ptr<SpdyFrame> spdy_data(
1384 spdy_util_.ConstructSpdyBodyFrame(1, "hello", 5, true));
[email protected]a34f61ee2014-03-18 20:59:491385
[email protected]09356c652014-03-25 15:36:101386 // HTTP/1.1 versions of the request and response.
1387 const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1388 "Host: www.foo.com\r\n"
1389 "Connection: keep-alive\r\n\r\n";
1390 const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1391 const char kHttpData[] = "hello";
1392
1393 std::vector<MockRead> data1_reads;
1394 std::vector<MockWrite> data1_writes;
[email protected]a34f61ee2014-03-18 20:59:491395 if (write_failure) {
1396 ASSERT_FALSE(read_failure);
[email protected]09356c652014-03-25 15:36:101397 data1_writes.push_back(*write_failure);
1398 data1_reads.push_back(MockRead(ASYNC, OK));
[email protected]a34f61ee2014-03-18 20:59:491399 } else {
1400 ASSERT_TRUE(read_failure);
[email protected]09356c652014-03-25 15:36:101401 if (use_spdy) {
1402 data1_writes.push_back(CreateMockWrite(*spdy_request));
1403 } else {
1404 data1_writes.push_back(MockWrite(kHttpRequest));
1405 }
1406 data1_reads.push_back(*read_failure);
[email protected]a34f61ee2014-03-18 20:59:491407 }
1408
[email protected]09356c652014-03-25 15:36:101409 StaticSocketDataProvider data1(&data1_reads[0], data1_reads.size(),
1410 &data1_writes[0], data1_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491411 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1412
[email protected]09356c652014-03-25 15:36:101413 std::vector<MockRead> data2_reads;
1414 std::vector<MockWrite> data2_writes;
1415
1416 if (use_spdy) {
1417 data2_writes.push_back(CreateMockWrite(*spdy_request, 0, ASYNC));
1418
1419 data2_reads.push_back(CreateMockRead(*spdy_response, 1, ASYNC));
1420 data2_reads.push_back(CreateMockRead(*spdy_data, 2, ASYNC));
1421 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1422 } else {
1423 data2_writes.push_back(
1424 MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1425
1426 data2_reads.push_back(
1427 MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1428 data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1429 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1430 }
1431 OrderedSocketData data2(&data2_reads[0], data2_reads.size(),
1432 &data2_writes[0], data2_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491433 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1434
1435 // Preconnect a socket.
1436 net::SSLConfig ssl_config;
1437 session->ssl_config_service()->GetSSLConfig(&ssl_config);
[email protected]d7599122014-05-24 03:37:231438 session->GetNextProtos(&ssl_config.next_protos);
[email protected]a34f61ee2014-03-18 20:59:491439 session->http_stream_factory()->PreconnectStreams(
1440 1, request, DEFAULT_PRIORITY, ssl_config, ssl_config);
1441 // Wait for the preconnect to complete.
1442 // TODO(davidben): Some way to wait for an idle socket count might be handy.
1443 base::RunLoop().RunUntilIdle();
[email protected]09356c652014-03-25 15:36:101444 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]a34f61ee2014-03-18 20:59:491445
1446 // Make the request.
1447 TestCompletionCallback callback;
1448
1449 scoped_ptr<HttpTransaction> trans(
1450 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1451
1452 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1453 EXPECT_EQ(ERR_IO_PENDING, rv);
1454
1455 rv = callback.WaitForResult();
1456 EXPECT_EQ(OK, rv);
1457
1458 LoadTimingInfo load_timing_info;
1459 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
[email protected]09356c652014-03-25 15:36:101460 TestLoadTimingNotReused(
1461 load_timing_info,
1462 CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]a34f61ee2014-03-18 20:59:491463
1464 const HttpResponseInfo* response = trans->GetResponseInfo();
1465 ASSERT_TRUE(response != NULL);
1466
1467 EXPECT_TRUE(response->headers.get() != NULL);
1468 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1469
1470 std::string response_data;
1471 rv = ReadTransaction(trans.get(), &response_data);
1472 EXPECT_EQ(OK, rv);
[email protected]09356c652014-03-25 15:36:101473 EXPECT_EQ(kHttpData, response_data);
[email protected]a34f61ee2014-03-18 20:59:491474}
1475
[email protected]23e482282013-06-14 16:08:021476TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:231477 KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061478 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]202965992011-12-07 23:04:511479 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1480}
1481
[email protected]23e482282013-06-14 16:08:021482TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061483 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]202965992011-12-07 23:04:511484 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251485}
1486
[email protected]23e482282013-06-14 16:08:021487TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061488 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]202965992011-12-07 23:04:511489 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251490}
1491
[email protected]d58ceea82014-06-04 10:55:541492// Make sure that on a 408 response (Request Timeout), the request is retried,
1493// if the socket was a reused keep alive socket.
1494TEST_P(HttpNetworkTransactionTest, KeepAlive408) {
1495 MockRead read_failure(SYNCHRONOUS,
1496 "HTTP/1.1 408 Request Timeout\r\n"
1497 "Connection: Keep-Alive\r\n"
1498 "Content-Length: 6\r\n\r\n"
1499 "Pickle");
1500 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1501}
1502
[email protected]a34f61ee2014-03-18 20:59:491503TEST_P(HttpNetworkTransactionTest,
1504 PreconnectErrorNotConnectedOnWrite) {
1505 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]09356c652014-03-25 15:36:101506 PreconnectErrorResendRequestTest(&write_failure, NULL, false);
[email protected]a34f61ee2014-03-18 20:59:491507}
1508
1509TEST_P(HttpNetworkTransactionTest, PreconnectErrorReset) {
1510 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]09356c652014-03-25 15:36:101511 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
[email protected]a34f61ee2014-03-18 20:59:491512}
1513
1514TEST_P(HttpNetworkTransactionTest, PreconnectErrorEOF) {
1515 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]09356c652014-03-25 15:36:101516 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1517}
1518
1519TEST_P(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
1520 MockRead read_failure(ASYNC, OK); // EOF
1521 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1522}
1523
[email protected]d58ceea82014-06-04 10:55:541524// Make sure that on a 408 response (Request Timeout), the request is retried,
1525// if the socket was a preconnected (UNUSED_IDLE) socket.
1526TEST_P(HttpNetworkTransactionTest, RetryOnIdle408) {
1527 MockRead read_failure(SYNCHRONOUS,
1528 "HTTP/1.1 408 Request Timeout\r\n"
1529 "Connection: Keep-Alive\r\n"
1530 "Content-Length: 6\r\n\r\n"
1531 "Pickle");
1532 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1533 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1534}
1535
[email protected]09356c652014-03-25 15:36:101536TEST_P(HttpNetworkTransactionTest,
1537 SpdyPreconnectErrorNotConnectedOnWrite) {
1538 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1539 PreconnectErrorResendRequestTest(&write_failure, NULL, true);
1540}
1541
1542TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
1543 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1544 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1545}
1546
1547TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
1548 MockRead read_failure(SYNCHRONOUS, OK); // EOF
1549 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1550}
1551
1552TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
1553 MockRead read_failure(ASYNC, OK); // EOF
1554 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
[email protected]a34f61ee2014-03-18 20:59:491555}
1556
[email protected]23e482282013-06-14 16:08:021557TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:421558 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:251559 request.method = "GET";
1560 request.url = GURL("http://www.google.com/");
1561 request.load_flags = 0;
1562
[email protected]3fe8d2f82013-10-17 08:56:071563 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271564 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411565 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271566
[email protected]3d2a59b2008-09-26 19:44:251567 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061568 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:351569 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1570 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061571 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251572 };
[email protected]31a2bfe2010-02-09 08:03:391573 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071574 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:251575
[email protected]49639fa2011-12-20 23:22:411576 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:251577
[email protected]49639fa2011-12-20 23:22:411578 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421579 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3d2a59b2008-09-26 19:44:251580
1581 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421582 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]3d2a59b2008-09-26 19:44:251583
[email protected]1c773ea12009-04-28 19:58:421584 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]3d2a59b2008-09-26 19:44:251585 EXPECT_TRUE(response == NULL);
[email protected]3d2a59b2008-09-26 19:44:251586}
1587
1588// What do various browsers do when the server closes a non-keepalive
1589// connection without sending any response header or body?
1590//
1591// IE7: error page
1592// Safari 3.1.2 (Windows): error page
1593// Firefox 3.0.1: blank page
1594// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:421595// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1596// Us: error page (EMPTY_RESPONSE)
[email protected]23e482282013-06-14 16:08:021597TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:251598 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061599 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:351600 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1601 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061602 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251603 };
[email protected]31a2bfe2010-02-09 08:03:391604 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1605 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:421606 EXPECT_EQ(ERR_EMPTY_RESPONSE, out.rv);
[email protected]3d2a59b2008-09-26 19:44:251607}
[email protected]038e9a32008-10-08 22:40:161608
[email protected]1826a402014-01-08 15:40:481609// Test that network access can be deferred and resumed.
1610TEST_P(HttpNetworkTransactionTest, ThrottleBeforeNetworkStart) {
1611 HttpRequestInfo request;
1612 request.method = "GET";
1613 request.url = GURL("http://www.google.com/");
1614 request.load_flags = 0;
1615
1616 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1617 scoped_ptr<HttpTransaction> trans(
1618 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1619
1620 // Defer on OnBeforeNetworkStart.
1621 BeforeNetworkStartHandler net_start_handler(true); // defer
1622 trans->SetBeforeNetworkStartCallback(
1623 base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
1624 base::Unretained(&net_start_handler)));
1625
1626 MockRead data_reads[] = {
1627 MockRead("HTTP/1.0 200 OK\r\n"),
1628 MockRead("Content-Length: 5\r\n\r\n"),
1629 MockRead("hello"),
1630 MockRead(SYNCHRONOUS, 0),
1631 };
1632 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1633 session_deps_.socket_factory->AddSocketDataProvider(&data);
1634
1635 TestCompletionCallback callback;
1636
1637 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1638 EXPECT_EQ(ERR_IO_PENDING, rv);
1639 base::MessageLoop::current()->RunUntilIdle();
1640
1641 // Should have deferred for network start.
1642 EXPECT_TRUE(net_start_handler.observed_before_network_start());
1643 EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
1644 EXPECT_TRUE(trans->GetResponseInfo() == NULL);
1645
1646 trans->ResumeNetworkStart();
1647 rv = callback.WaitForResult();
1648 EXPECT_EQ(OK, rv);
1649 EXPECT_TRUE(trans->GetResponseInfo() != NULL);
1650
1651 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
1652 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
1653 if (rv == ERR_IO_PENDING)
1654 rv = callback.WaitForResult();
1655 EXPECT_EQ(5, rv);
1656 trans.reset();
1657}
1658
1659// Test that network use can be deferred and canceled.
1660TEST_P(HttpNetworkTransactionTest, ThrottleAndCancelBeforeNetworkStart) {
1661 HttpRequestInfo request;
1662 request.method = "GET";
1663 request.url = GURL("http://www.google.com/");
1664 request.load_flags = 0;
1665
1666 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1667 scoped_ptr<HttpTransaction> trans(
1668 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1669
1670 // Defer on OnBeforeNetworkStart.
1671 BeforeNetworkStartHandler net_start_handler(true); // defer
1672 trans->SetBeforeNetworkStartCallback(
1673 base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
1674 base::Unretained(&net_start_handler)));
1675
1676 TestCompletionCallback callback;
1677
1678 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1679 EXPECT_EQ(ERR_IO_PENDING, rv);
1680 base::MessageLoop::current()->RunUntilIdle();
1681
1682 // Should have deferred for network start.
1683 EXPECT_TRUE(net_start_handler.observed_before_network_start());
1684 EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
1685 EXPECT_TRUE(trans->GetResponseInfo() == NULL);
1686}
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";
1695 request.url = GURL("http://www.google.com/");
1696 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";
1736 request.url = GURL("http://www.google.com/");
1737 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
[email protected]58e32bb2013-01-21 18:23:251779 CapturingNetLog 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";
1885 request.url = GURL("http://www.google.com/");
1886 request.load_flags = 0;
1887
[email protected]58e32bb2013-01-21 18:23:251888 CapturingNetLog 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[] = {
1895 MockWrite("GET / HTTP/1.1\r\n"
1896 "Host: www.google.com\r\n"
1897 "Connection: keep-alive\r\n\r\n"),
1898 };
1899
[email protected]038e9a32008-10-08 22:40:161900 MockRead data_reads1[] = {
1901 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
1902 // Give a couple authenticate options (only the middle one is actually
1903 // supported).
[email protected]22927ad2009-09-21 19:56:191904 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:161905 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1906 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
1907 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1908 // Large content-length -- won't matter, as connection will be reset.
1909 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061910 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:161911 };
1912
1913 // After calling trans->RestartWithAuth(), this is the request we should
1914 // be issuing -- the final header line contains the credentials.
1915 MockWrite data_writes2[] = {
1916 MockWrite("GET / HTTP/1.1\r\n"
1917 "Host: www.google.com\r\n"
1918 "Connection: keep-alive\r\n"
1919 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1920 };
1921
1922 // Lastly, the server responds with the actual content.
1923 MockRead data_reads2[] = {
1924 MockRead("HTTP/1.0 200 OK\r\n"),
1925 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1926 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061927 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:161928 };
1929
[email protected]31a2bfe2010-02-09 08:03:391930 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1931 data_writes1, arraysize(data_writes1));
1932 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1933 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:071934 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1935 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:161936
[email protected]49639fa2011-12-20 23:22:411937 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:161938
[email protected]49639fa2011-12-20 23:22:411939 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421940 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:161941
1942 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421943 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:161944
[email protected]58e32bb2013-01-21 18:23:251945 LoadTimingInfo load_timing_info1;
1946 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
1947 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
1948
[email protected]b8015c42013-12-24 15:18:191949 int64 reads_size1 = ReadsSize(data_reads1, arraysize(data_reads1));
1950 EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
1951
[email protected]1c773ea12009-04-28 19:58:421952 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501953 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:041954 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:161955
[email protected]49639fa2011-12-20 23:22:411956 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:161957
[email protected]49639fa2011-12-20 23:22:411958 rv = trans->RestartWithAuth(
1959 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:421960 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:161961
1962 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421963 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:161964
[email protected]58e32bb2013-01-21 18:23:251965 LoadTimingInfo load_timing_info2;
1966 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
1967 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
1968 // The load timing after restart should have a new socket ID, and times after
1969 // those of the first load timing.
1970 EXPECT_LE(load_timing_info1.receive_headers_end,
1971 load_timing_info2.connect_timing.connect_start);
1972 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
1973
[email protected]b8015c42013-12-24 15:18:191974 int64 reads_size2 = ReadsSize(data_reads2, arraysize(data_reads2));
1975 EXPECT_EQ(reads_size1 + reads_size2, trans->GetTotalReceivedBytes());
1976
[email protected]038e9a32008-10-08 22:40:161977 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501978 ASSERT_TRUE(response != NULL);
[email protected]038e9a32008-10-08 22:40:161979 EXPECT_TRUE(response->auth_challenge.get() == NULL);
1980 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:161981}
1982
[email protected]23e482282013-06-14 16:08:021983TEST_P(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:461984 HttpRequestInfo request;
1985 request.method = "GET";
1986 request.url = GURL("http://www.google.com/");
1987 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
1988
[email protected]3fe8d2f82013-10-17 08:56:071989 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271990 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411991 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271992
[email protected]861fcd52009-08-26 02:33:461993 MockWrite data_writes[] = {
1994 MockWrite("GET / HTTP/1.1\r\n"
1995 "Host: www.google.com\r\n"
1996 "Connection: keep-alive\r\n\r\n"),
1997 };
1998
1999 MockRead data_reads[] = {
2000 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2001 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2002 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2003 // Large content-length -- won't matter, as connection will be reset.
2004 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062005 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:462006 };
2007
[email protected]31a2bfe2010-02-09 08:03:392008 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2009 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072010 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:412011 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:462012
[email protected]49639fa2011-12-20 23:22:412013 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]861fcd52009-08-26 02:33:462014 EXPECT_EQ(ERR_IO_PENDING, rv);
2015
2016 rv = callback.WaitForResult();
2017 EXPECT_EQ(0, rv);
2018
[email protected]b8015c42013-12-24 15:18:192019 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
2020 EXPECT_EQ(reads_size, trans->GetTotalReceivedBytes());
2021
[email protected]861fcd52009-08-26 02:33:462022 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502023 ASSERT_TRUE(response != NULL);
[email protected]861fcd52009-08-26 02:33:462024 EXPECT_TRUE(response->auth_challenge.get() == NULL);
2025}
2026
[email protected]2d2697f92009-02-18 21:00:322027// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2028// connection.
[email protected]23e482282013-06-14 16:08:022029TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
[email protected]1c773ea12009-04-28 19:58:422030 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322031 request.method = "GET";
2032 request.url = GURL("http://www.google.com/");
2033 request.load_flags = 0;
2034
[email protected]58e32bb2013-01-21 18:23:252035 CapturingNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072036 session_deps_.net_log = &log;
2037 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272038
[email protected]2d2697f92009-02-18 21:00:322039 MockWrite data_writes1[] = {
2040 MockWrite("GET / HTTP/1.1\r\n"
2041 "Host: www.google.com\r\n"
2042 "Connection: keep-alive\r\n\r\n"),
2043
2044 // After calling trans->RestartWithAuth(), this is the request we should
2045 // be issuing -- the final header line contains the credentials.
2046 MockWrite("GET / HTTP/1.1\r\n"
2047 "Host: www.google.com\r\n"
2048 "Connection: keep-alive\r\n"
2049 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2050 };
2051
2052 MockRead data_reads1[] = {
2053 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2054 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2055 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2056 MockRead("Content-Length: 14\r\n\r\n"),
2057 MockRead("Unauthorized\r\n"),
2058
2059 // Lastly, the server responds with the actual content.
2060 MockRead("HTTP/1.1 200 OK\r\n"),
2061 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502062 MockRead("Content-Length: 5\r\n\r\n"),
2063 MockRead("Hello"),
[email protected]2d2697f92009-02-18 21:00:322064 };
2065
[email protected]2d0a4f92011-05-05 16:38:462066 // If there is a regression where we disconnect a Keep-Alive
2067 // connection during an auth roundtrip, we'll end up reading this.
2068 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062069 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462070 };
2071
[email protected]31a2bfe2010-02-09 08:03:392072 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2073 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462074 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2075 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072076 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2077 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322078
[email protected]49639fa2011-12-20 23:22:412079 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322080
[email protected]262eec82013-03-19 21:01:362081 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502082 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412083 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422084 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322085
2086 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422087 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322088
[email protected]58e32bb2013-01-21 18:23:252089 LoadTimingInfo load_timing_info1;
2090 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
2091 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2092
[email protected]1c773ea12009-04-28 19:58:422093 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502094 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042095 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322096
[email protected]49639fa2011-12-20 23:22:412097 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322098
[email protected]49639fa2011-12-20 23:22:412099 rv = trans->RestartWithAuth(
2100 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422101 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322102
2103 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422104 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322105
[email protected]58e32bb2013-01-21 18:23:252106 LoadTimingInfo load_timing_info2;
2107 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
2108 TestLoadTimingReused(load_timing_info2);
2109 // The load timing after restart should have the same socket ID, and times
2110 // those of the first load timing.
2111 EXPECT_LE(load_timing_info1.receive_headers_end,
2112 load_timing_info2.send_start);
2113 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2114
[email protected]2d2697f92009-02-18 21:00:322115 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502116 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322117 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502118 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]b8015c42013-12-24 15:18:192119
2120 std::string response_data;
2121 rv = ReadTransaction(trans.get(), &response_data);
2122 EXPECT_EQ(OK, rv);
2123 int64 reads_size1 = ReadsSize(data_reads1, arraysize(data_reads1));
2124 EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
[email protected]2d2697f92009-02-18 21:00:322125}
2126
2127// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2128// connection and with no response body to drain.
[email protected]23e482282013-06-14 16:08:022129TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:422130 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322131 request.method = "GET";
2132 request.url = GURL("http://www.google.com/");
2133 request.load_flags = 0;
2134
[email protected]bb88e1d32013-05-03 23:11:072135 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272136
[email protected]2d2697f92009-02-18 21:00:322137 MockWrite data_writes1[] = {
2138 MockWrite("GET / HTTP/1.1\r\n"
2139 "Host: www.google.com\r\n"
2140 "Connection: keep-alive\r\n\r\n"),
2141
2142 // After calling trans->RestartWithAuth(), this is the request we should
2143 // be issuing -- the final header line contains the credentials.
2144 MockWrite("GET / HTTP/1.1\r\n"
2145 "Host: www.google.com\r\n"
2146 "Connection: keep-alive\r\n"
2147 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2148 };
2149
[email protected]2d2697f92009-02-18 21:00:322150 MockRead data_reads1[] = {
2151 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2152 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:312153 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:322154
2155 // Lastly, the server responds with the actual content.
2156 MockRead("HTTP/1.1 200 OK\r\n"),
2157 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502158 MockRead("Content-Length: 5\r\n\r\n"),
2159 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322160 };
2161
[email protected]2d0a4f92011-05-05 16:38:462162 // An incorrect reconnect would cause this to be read.
2163 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062164 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462165 };
2166
[email protected]31a2bfe2010-02-09 08:03:392167 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2168 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462169 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2170 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072171 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2172 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322173
[email protected]49639fa2011-12-20 23:22:412174 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322175
[email protected]262eec82013-03-19 21:01:362176 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502177 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412178 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422179 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322180
2181 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422182 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322183
[email protected]1c773ea12009-04-28 19:58:422184 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502185 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042186 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322187
[email protected]49639fa2011-12-20 23:22:412188 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322189
[email protected]49639fa2011-12-20 23:22:412190 rv = trans->RestartWithAuth(
2191 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422192 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322193
2194 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422195 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322196
2197 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502198 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322199 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502200 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322201}
2202
2203// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2204// connection and with a large response body to drain.
[email protected]23e482282013-06-14 16:08:022205TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:422206 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322207 request.method = "GET";
2208 request.url = GURL("http://www.google.com/");
2209 request.load_flags = 0;
2210
[email protected]bb88e1d32013-05-03 23:11:072211 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272212
[email protected]2d2697f92009-02-18 21:00:322213 MockWrite data_writes1[] = {
2214 MockWrite("GET / HTTP/1.1\r\n"
2215 "Host: www.google.com\r\n"
2216 "Connection: keep-alive\r\n\r\n"),
2217
2218 // After calling trans->RestartWithAuth(), this is the request we should
2219 // be issuing -- the final header line contains the credentials.
2220 MockWrite("GET / HTTP/1.1\r\n"
2221 "Host: www.google.com\r\n"
2222 "Connection: keep-alive\r\n"
2223 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2224 };
2225
2226 // Respond with 5 kb of response body.
2227 std::string large_body_string("Unauthorized");
2228 large_body_string.append(5 * 1024, ' ');
2229 large_body_string.append("\r\n");
2230
2231 MockRead data_reads1[] = {
2232 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2233 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2234 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2235 // 5134 = 12 + 5 * 1024 + 2
2236 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062237 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:322238
2239 // Lastly, the server responds with the actual content.
2240 MockRead("HTTP/1.1 200 OK\r\n"),
2241 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502242 MockRead("Content-Length: 5\r\n\r\n"),
2243 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322244 };
2245
[email protected]2d0a4f92011-05-05 16:38:462246 // An incorrect reconnect would cause this to be read.
2247 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062248 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462249 };
2250
[email protected]31a2bfe2010-02-09 08:03:392251 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2252 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462253 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2254 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072255 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2256 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322257
[email protected]49639fa2011-12-20 23:22:412258 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322259
[email protected]262eec82013-03-19 21:01:362260 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502261 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412262 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422263 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322264
2265 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422266 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322267
[email protected]1c773ea12009-04-28 19:58:422268 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502269 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042270 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322271
[email protected]49639fa2011-12-20 23:22:412272 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322273
[email protected]49639fa2011-12-20 23:22:412274 rv = trans->RestartWithAuth(
2275 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422276 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322277
2278 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422279 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322280
2281 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502282 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322283 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502284 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322285}
2286
2287// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:312288// connection, but the server gets impatient and closes the connection.
[email protected]23e482282013-06-14 16:08:022289TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:312290 HttpRequestInfo request;
2291 request.method = "GET";
2292 request.url = GURL("http://www.google.com/");
2293 request.load_flags = 0;
2294
[email protected]bb88e1d32013-05-03 23:11:072295 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272296
[email protected]11203f012009-11-12 23:02:312297 MockWrite data_writes1[] = {
2298 MockWrite("GET / HTTP/1.1\r\n"
2299 "Host: www.google.com\r\n"
2300 "Connection: keep-alive\r\n\r\n"),
2301 // This simulates the seemingly successful write to a closed connection
2302 // if the bug is not fixed.
2303 MockWrite("GET / HTTP/1.1\r\n"
2304 "Host: www.google.com\r\n"
2305 "Connection: keep-alive\r\n"
2306 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2307 };
2308
2309 MockRead data_reads1[] = {
2310 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2311 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2312 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2313 MockRead("Content-Length: 14\r\n\r\n"),
2314 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:062315 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:312316 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:062317 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:312318 };
2319
2320 // After calling trans->RestartWithAuth(), this is the request we should
2321 // be issuing -- the final header line contains the credentials.
2322 MockWrite data_writes2[] = {
2323 MockWrite("GET / HTTP/1.1\r\n"
2324 "Host: www.google.com\r\n"
2325 "Connection: keep-alive\r\n"
2326 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2327 };
2328
2329 // Lastly, the server responds with the actual content.
2330 MockRead data_reads2[] = {
2331 MockRead("HTTP/1.1 200 OK\r\n"),
2332 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502333 MockRead("Content-Length: 5\r\n\r\n"),
2334 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:312335 };
2336
[email protected]31a2bfe2010-02-09 08:03:392337 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2338 data_writes1, arraysize(data_writes1));
2339 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2340 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072341 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2342 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:312343
[email protected]49639fa2011-12-20 23:22:412344 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:312345
[email protected]262eec82013-03-19 21:01:362346 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502347 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412348 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]11203f012009-11-12 23:02:312349 EXPECT_EQ(ERR_IO_PENDING, rv);
2350
2351 rv = callback1.WaitForResult();
2352 EXPECT_EQ(OK, rv);
2353
2354 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502355 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042356 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:312357
[email protected]49639fa2011-12-20 23:22:412358 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:312359
[email protected]49639fa2011-12-20 23:22:412360 rv = trans->RestartWithAuth(
2361 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]11203f012009-11-12 23:02:312362 EXPECT_EQ(ERR_IO_PENDING, rv);
2363
2364 rv = callback2.WaitForResult();
2365 EXPECT_EQ(OK, rv);
2366
2367 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502368 ASSERT_TRUE(response != NULL);
[email protected]11203f012009-11-12 23:02:312369 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502370 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:312371}
2372
[email protected]394816e92010-08-03 07:38:592373// Test the request-challenge-retry sequence for basic auth, over a connection
2374// that requires a restart when setting up an SSL tunnel.
ttuttle34f63b52015-03-05 04:33:012375TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
2376 HttpRequestInfo request;
2377 request.method = "GET";
2378 request.url = GURL("https://www.google.com/");
2379 // when the no authentication data flag is set.
2380 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
2381
2382 // Configure against proxy server "myproxy:70".
2383 session_deps_.proxy_service.reset(
2384 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
2385 CapturingBoundNetLog log;
2386 session_deps_.net_log = log.bound().net_log();
2387 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2388
2389 // Since we have proxy, should try to establish tunnel.
2390 MockWrite data_writes1[] = {
2391 MockWrite(
2392 "CONNECT www.google.com:443 HTTP/1.1\r\n"
2393 "Host: www.google.com\r\n"
2394 "Proxy-Connection: keep-alive\r\n\r\n"),
2395
2396 // After calling trans->RestartWithAuth(), this is the request we should
2397 // be issuing -- the final header line contains the credentials.
2398 MockWrite(
2399 "CONNECT www.google.com:443 HTTP/1.1\r\n"
2400 "Host: www.google.com\r\n"
2401 "Proxy-Connection: keep-alive\r\n"
2402 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2403
2404 MockWrite(
2405 "GET / HTTP/1.1\r\n"
2406 "Host: www.google.com\r\n"
2407 "Connection: keep-alive\r\n\r\n"),
2408 };
2409
2410 // The proxy responds to the connect with a 407, using a persistent
2411 // connection.
2412 MockRead data_reads1[] = {
2413 // No credentials.
2414 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
2415 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
2416
2417 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
2418
2419 MockRead("HTTP/1.1 200 OK\r\n"),
2420 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2421 MockRead("Content-Length: 5\r\n\r\n"),
2422 MockRead(SYNCHRONOUS, "hello"),
2423 };
2424
2425 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2426 data_writes1, arraysize(data_writes1));
2427 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2428 SSLSocketDataProvider ssl(ASYNC, OK);
2429 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
2430
2431 TestCompletionCallback callback1;
2432
2433 scoped_ptr<HttpTransaction> trans(
2434 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2435
2436 int rv = trans->Start(&request, callback1.callback(), log.bound());
2437 EXPECT_EQ(ERR_IO_PENDING, rv);
2438
2439 rv = callback1.WaitForResult();
2440 EXPECT_EQ(OK, rv);
2441 net::CapturingNetLog::CapturedEntryList entries;
2442 log.GetEntries(&entries);
2443 size_t pos = ExpectLogContainsSomewhere(
2444 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
2445 NetLog::PHASE_NONE);
2446 ExpectLogContainsSomewhere(
2447 entries, pos, NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2448 NetLog::PHASE_NONE);
2449
2450 const HttpResponseInfo* response = trans->GetResponseInfo();
2451 ASSERT_TRUE(response != NULL);
2452 EXPECT_FALSE(response->headers->IsKeepAlive());
2453 ASSERT_FALSE(response->headers.get() == NULL);
2454 EXPECT_EQ(407, response->headers->response_code());
2455 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
2456 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2457
2458 LoadTimingInfo load_timing_info;
2459 // CONNECT requests and responses are handled at the connect job level, so
2460 // the transaction does not yet have a connection.
2461 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
2462
2463 TestCompletionCallback callback2;
2464
2465 rv =
2466 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
2467 EXPECT_EQ(ERR_IO_PENDING, rv);
2468
2469 rv = callback2.WaitForResult();
2470 EXPECT_EQ(OK, rv);
2471
2472 response = trans->GetResponseInfo();
2473 ASSERT_TRUE(response != NULL);
2474
2475 EXPECT_TRUE(response->headers->IsKeepAlive());
2476 EXPECT_EQ(200, response->headers->response_code());
2477 EXPECT_EQ(5, response->headers->GetContentLength());
2478 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2479
2480 // The password prompt info should not be set.
2481 EXPECT_TRUE(response->auth_challenge.get() == NULL);
2482
2483 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2484 TestLoadTimingNotReusedWithPac(load_timing_info,
2485 CONNECT_TIMING_HAS_SSL_TIMES);
2486
2487 trans.reset();
2488 session->CloseAllConnections();
2489}
2490
2491// Test the request-challenge-retry sequence for basic auth, over a connection
2492// that requires a restart when setting up an SSL tunnel.
2493TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) {
[email protected]394816e92010-08-03 07:38:592494 HttpRequestInfo request;
2495 request.method = "GET";
2496 request.url = GURL("https://www.google.com/");
2497 // when the no authentication data flag is set.
2498 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
2499
[email protected]cb9bf6ca2011-01-28 13:15:272500 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072501 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:202502 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
[email protected]333bdf62012-06-08 22:57:292503 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072504 session_deps_.net_log = log.bound().net_log();
2505 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272506
[email protected]394816e92010-08-03 07:38:592507 // Since we have proxy, should try to establish tunnel.
2508 MockWrite data_writes1[] = {
2509 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2510 "Host: www.google.com\r\n"
2511 "Proxy-Connection: keep-alive\r\n\r\n"),
2512
2513 // After calling trans->RestartWithAuth(), this is the request we should
2514 // be issuing -- the final header line contains the credentials.
2515 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2516 "Host: www.google.com\r\n"
2517 "Proxy-Connection: keep-alive\r\n"
2518 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2519
2520 MockWrite("GET / HTTP/1.1\r\n"
2521 "Host: www.google.com\r\n"
2522 "Connection: keep-alive\r\n\r\n"),
2523 };
2524
2525 // The proxy responds to the connect with a 407, using a persistent
2526 // connection.
2527 MockRead data_reads1[] = {
2528 // No credentials.
2529 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2530 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2531 MockRead("Proxy-Connection: close\r\n\r\n"),
2532
2533 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2534
2535 MockRead("HTTP/1.1 200 OK\r\n"),
2536 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502537 MockRead("Content-Length: 5\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062538 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:592539 };
2540
2541 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2542 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072543 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:062544 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072545 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:592546
[email protected]49639fa2011-12-20 23:22:412547 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:592548
[email protected]262eec82013-03-19 21:01:362549 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502550 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:502551
[email protected]49639fa2011-12-20 23:22:412552 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]394816e92010-08-03 07:38:592553 EXPECT_EQ(ERR_IO_PENDING, rv);
2554
2555 rv = callback1.WaitForResult();
2556 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:572557 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:402558 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:592559 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402560 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]394816e92010-08-03 07:38:592561 NetLog::PHASE_NONE);
2562 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402563 entries, pos,
[email protected]394816e92010-08-03 07:38:592564 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2565 NetLog::PHASE_NONE);
2566
2567 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502568 ASSERT_TRUE(response != NULL);
ttuttle34f63b52015-03-05 04:33:012569 EXPECT_FALSE(response->headers->IsKeepAlive());
[email protected]90499482013-06-01 00:39:502570 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]394816e92010-08-03 07:38:592571 EXPECT_EQ(407, response->headers->response_code());
2572 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042573 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:592574
[email protected]029c83b62013-01-24 05:28:202575 LoadTimingInfo load_timing_info;
2576 // CONNECT requests and responses are handled at the connect job level, so
2577 // the transaction does not yet have a connection.
2578 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
2579
[email protected]49639fa2011-12-20 23:22:412580 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:592581
[email protected]49639fa2011-12-20 23:22:412582 rv = trans->RestartWithAuth(
2583 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]394816e92010-08-03 07:38:592584 EXPECT_EQ(ERR_IO_PENDING, rv);
2585
2586 rv = callback2.WaitForResult();
2587 EXPECT_EQ(OK, rv);
2588
2589 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502590 ASSERT_TRUE(response != NULL);
[email protected]394816e92010-08-03 07:38:592591
2592 EXPECT_TRUE(response->headers->IsKeepAlive());
2593 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:502594 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:592595 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2596
2597 // The password prompt info should not be set.
2598 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502599
[email protected]029c83b62013-01-24 05:28:202600 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2601 TestLoadTimingNotReusedWithPac(load_timing_info,
2602 CONNECT_TIMING_HAS_SSL_TIMES);
2603
[email protected]0b0bf032010-09-21 18:08:502604 trans.reset();
[email protected]102e27c2011-02-23 01:01:312605 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:592606}
2607
[email protected]11203f012009-11-12 23:02:312608// Test the request-challenge-retry sequence for basic auth, over a keep-alive
ttuttle34f63b52015-03-05 04:33:012609// proxy connection with HTTP/1.0 responses, when setting up an SSL tunnel.
2610TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
2611 HttpRequestInfo request;
2612 request.method = "GET";
2613 request.url = GURL("https://www.google.com/");
2614 // Ensure that proxy authentication is attempted even
2615 // when the no authentication data flag is set.
2616 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
2617
2618 // Configure against proxy server "myproxy:70".
2619 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
2620 CapturingBoundNetLog log;
2621 session_deps_.net_log = log.bound().net_log();
2622 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2623
2624 scoped_ptr<HttpTransaction> trans(
2625 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2626
2627 // Since we have proxy, should try to establish tunnel.
2628 MockWrite data_writes1[] = {
2629 MockWrite(
2630 "CONNECT www.google.com:443 HTTP/1.1\r\n"
2631 "Host: www.google.com\r\n"
2632 "Proxy-Connection: keep-alive\r\n\r\n"),
2633
2634 // After calling trans->RestartWithAuth(), this is the request we should
2635 // be issuing -- the final header line contains the credentials.
2636 MockWrite(
2637 "CONNECT www.google.com:443 HTTP/1.1\r\n"
2638 "Host: www.google.com\r\n"
2639 "Proxy-Connection: keep-alive\r\n"
2640 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
2641 };
2642
2643 // The proxy responds to the connect with a 407, using a persistent
2644 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
2645 MockRead data_reads1[] = {
2646 // No credentials.
2647 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
2648 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2649 MockRead("Proxy-Connection: keep-alive\r\n"),
2650 MockRead("Content-Length: 10\r\n\r\n"),
2651 MockRead("0123456789"),
2652
2653 // Wrong credentials (wrong password).
2654 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
2655 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2656 MockRead("Proxy-Connection: keep-alive\r\n"),
2657 MockRead("Content-Length: 10\r\n\r\n"),
2658 // No response body because the test stops reading here.
2659 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
2660 };
2661
2662 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2663 data_writes1, arraysize(data_writes1));
2664 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2665
2666 TestCompletionCallback callback1;
2667
2668 int rv = trans->Start(&request, callback1.callback(), log.bound());
2669 EXPECT_EQ(ERR_IO_PENDING, rv);
2670
2671 rv = callback1.WaitForResult();
2672 EXPECT_EQ(OK, rv);
2673 net::CapturingNetLog::CapturedEntryList entries;
2674 log.GetEntries(&entries);
2675 size_t pos = ExpectLogContainsSomewhere(
2676 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
2677 NetLog::PHASE_NONE);
2678 ExpectLogContainsSomewhere(
2679 entries, pos, NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2680 NetLog::PHASE_NONE);
2681
2682 const HttpResponseInfo* response = trans->GetResponseInfo();
2683 ASSERT_TRUE(response);
2684 ASSERT_TRUE(response->headers);
2685 EXPECT_TRUE(response->headers->IsKeepAlive());
2686 EXPECT_EQ(407, response->headers->response_code());
2687 EXPECT_EQ(10, response->headers->GetContentLength());
2688 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
2689 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2690
2691 TestCompletionCallback callback2;
2692
2693 // Wrong password (should be "bar").
2694 rv =
2695 trans->RestartWithAuth(AuthCredentials(kFoo, kBaz), callback2.callback());
2696 EXPECT_EQ(ERR_IO_PENDING, rv);
2697
2698 rv = callback2.WaitForResult();
2699 EXPECT_EQ(OK, rv);
2700
2701 response = trans->GetResponseInfo();
2702 ASSERT_TRUE(response);
2703 ASSERT_TRUE(response->headers);
2704 EXPECT_TRUE(response->headers->IsKeepAlive());
2705 EXPECT_EQ(407, response->headers->response_code());
2706 EXPECT_EQ(10, response->headers->GetContentLength());
2707 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
2708 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2709
2710 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
2711 // out of scope.
2712 session->CloseAllConnections();
2713}
2714
2715// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2716// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel.
2717TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
[email protected]cb9bf6ca2011-01-28 13:15:272718 HttpRequestInfo request;
2719 request.method = "GET";
2720 request.url = GURL("https://www.google.com/");
2721 // Ensure that proxy authentication is attempted even
2722 // when the no authentication data flag is set.
2723 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
2724
[email protected]2d2697f92009-02-18 21:00:322725 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072726 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]333bdf62012-06-08 22:57:292727 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072728 session_deps_.net_log = log.bound().net_log();
2729 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:322730
[email protected]262eec82013-03-19 21:01:362731 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502732 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d2697f92009-02-18 21:00:322733
[email protected]2d2697f92009-02-18 21:00:322734 // Since we have proxy, should try to establish tunnel.
2735 MockWrite data_writes1[] = {
2736 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:452737 "Host: www.google.com\r\n"
2738 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322739
2740 // After calling trans->RestartWithAuth(), this is the request we should
2741 // be issuing -- the final header line contains the credentials.
2742 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2743 "Host: www.google.com\r\n"
[email protected]e44de5d2009-06-05 20:12:452744 "Proxy-Connection: keep-alive\r\n"
[email protected]2d2697f92009-02-18 21:00:322745 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
2746 };
2747
2748 // The proxy responds to the connect with a 407, using a persistent
2749 // connection.
2750 MockRead data_reads1[] = {
2751 // No credentials.
2752 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2753 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2754 MockRead("Content-Length: 10\r\n\r\n"),
2755 MockRead("0123456789"),
2756
2757 // Wrong credentials (wrong password).
2758 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2759 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2760 MockRead("Content-Length: 10\r\n\r\n"),
2761 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:062762 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]2d2697f92009-02-18 21:00:322763 };
2764
[email protected]31a2bfe2010-02-09 08:03:392765 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2766 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072767 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d2697f92009-02-18 21:00:322768
[email protected]49639fa2011-12-20 23:22:412769 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322770
[email protected]49639fa2011-12-20 23:22:412771 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]1c773ea12009-04-28 19:58:422772 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322773
2774 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422775 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:572776 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:402777 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:392778 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402779 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]dbb83db2010-05-11 18:13:392780 NetLog::PHASE_NONE);
2781 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402782 entries, pos,
[email protected]dbb83db2010-05-11 18:13:392783 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2784 NetLog::PHASE_NONE);
[email protected]2d2697f92009-02-18 21:00:322785
[email protected]1c773ea12009-04-28 19:58:422786 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:242787 ASSERT_TRUE(response);
2788 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:322789 EXPECT_TRUE(response->headers->IsKeepAlive());
2790 EXPECT_EQ(407, response->headers->response_code());
ttuttle34f63b52015-03-05 04:33:012791 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422792 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042793 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322794
[email protected]49639fa2011-12-20 23:22:412795 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322796
2797 // Wrong password (should be "bar").
[email protected]49639fa2011-12-20 23:22:412798 rv = trans->RestartWithAuth(
2799 AuthCredentials(kFoo, kBaz), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422800 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322801
2802 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422803 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322804
2805 response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:242806 ASSERT_TRUE(response);
2807 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:322808 EXPECT_TRUE(response->headers->IsKeepAlive());
2809 EXPECT_EQ(407, response->headers->response_code());
ttuttle34f63b52015-03-05 04:33:012810 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422811 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042812 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]e772db3f2010-07-12 18:11:132813
[email protected]e60e47a2010-07-14 03:37:182814 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
2815 // out of scope.
[email protected]102e27c2011-02-23 01:01:312816 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:322817}
2818
[email protected]a8e9b162009-03-12 00:06:442819// Test that we don't read the response body when we fail to establish a tunnel,
2820// even if the user cancels the proxy's auth attempt.
[email protected]23e482282013-06-14 16:08:022821TEST_P(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:272822 HttpRequestInfo request;
2823 request.method = "GET";
2824 request.url = GURL("https://www.google.com/");
2825 request.load_flags = 0;
2826
[email protected]a8e9b162009-03-12 00:06:442827 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072828 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]a8e9b162009-03-12 00:06:442829
[email protected]bb88e1d32013-05-03 23:11:072830 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:442831
[email protected]262eec82013-03-19 21:01:362832 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502833 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]a8e9b162009-03-12 00:06:442834
[email protected]a8e9b162009-03-12 00:06:442835 // Since we have proxy, should try to establish tunnel.
2836 MockWrite data_writes[] = {
2837 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:452838 "Host: www.google.com\r\n"
2839 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:442840 };
2841
2842 // The proxy responds to the connect with a 407.
2843 MockRead data_reads[] = {
ttuttle7933c112015-01-06 00:55:242844 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2845 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2846 MockRead("Content-Length: 10\r\n\r\n"),
2847 MockRead("0123456789"), // Should not be reached.
2848 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]a8e9b162009-03-12 00:06:442849 };
2850
[email protected]31a2bfe2010-02-09 08:03:392851 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2852 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072853 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:442854
[email protected]49639fa2011-12-20 23:22:412855 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:442856
[email protected]49639fa2011-12-20 23:22:412857 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422858 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a8e9b162009-03-12 00:06:442859
2860 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422861 EXPECT_EQ(OK, rv);
[email protected]a8e9b162009-03-12 00:06:442862
[email protected]1c773ea12009-04-28 19:58:422863 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:242864 ASSERT_TRUE(response);
2865 ASSERT_TRUE(response->headers);
[email protected]a8e9b162009-03-12 00:06:442866 EXPECT_TRUE(response->headers->IsKeepAlive());
2867 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:422868 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:442869
2870 std::string response_data;
2871 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:422872 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]e60e47a2010-07-14 03:37:182873
2874 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:312875 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:442876}
2877
ttuttle7933c112015-01-06 00:55:242878// Test that we don't pass extraneous headers from the proxy's response to the
2879// caller when the proxy responds to CONNECT with 407.
2880TEST_P(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
2881 HttpRequestInfo request;
2882 request.method = "GET";
2883 request.url = GURL("https://www.google.com/");
2884 request.load_flags = 0;
2885
2886 // Configure against proxy server "myproxy:70".
2887 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
2888
2889 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2890
2891 scoped_ptr<HttpTransaction> trans(
2892 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2893
2894 // Since we have proxy, should try to establish tunnel.
2895 MockWrite data_writes[] = {
2896 MockWrite(
2897 "CONNECT www.google.com:443 HTTP/1.1\r\n"
2898 "Host: www.google.com\r\n"
2899 "Proxy-Connection: keep-alive\r\n\r\n"),
2900 };
2901
2902 // The proxy responds to the connect with a 407.
2903 MockRead data_reads[] = {
2904 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2905 MockRead("X-Foo: bar\r\n"),
2906 MockRead("Set-Cookie: foo=bar\r\n"),
2907 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2908 MockRead("Content-Length: 10\r\n\r\n"),
2909 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
2910 };
2911
2912 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
2913 arraysize(data_writes));
2914 session_deps_.socket_factory->AddSocketDataProvider(&data);
2915
2916 TestCompletionCallback callback;
2917
2918 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
2919 EXPECT_EQ(ERR_IO_PENDING, rv);
2920
2921 rv = callback.WaitForResult();
2922 EXPECT_EQ(OK, rv);
2923
2924 const HttpResponseInfo* response = trans->GetResponseInfo();
2925 ASSERT_TRUE(response);
2926 ASSERT_TRUE(response->headers);
2927 EXPECT_TRUE(response->headers->IsKeepAlive());
2928 EXPECT_EQ(407, response->headers->response_code());
2929 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2930 EXPECT_FALSE(response->headers->HasHeader("X-Foo"));
2931 EXPECT_FALSE(response->headers->HasHeader("Set-Cookie"));
2932
2933 std::string response_data;
2934 rv = ReadTransaction(trans.get(), &response_data);
2935 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
2936
2937 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
2938 session->CloseAllConnections();
2939}
2940
[email protected]8fdbcd22010-05-05 02:54:522941// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
2942// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
[email protected]23e482282013-06-14 16:08:022943TEST_P(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:522944 HttpRequestInfo request;
2945 request.method = "GET";
2946 request.url = GURL("http://www.google.com/");
2947 request.load_flags = 0;
2948
[email protected]cb9bf6ca2011-01-28 13:15:272949 // We are using a DIRECT connection (i.e. no proxy) for this session.
[email protected]3fe8d2f82013-10-17 08:56:072950 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272951 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:412952 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:272953
[email protected]8fdbcd22010-05-05 02:54:522954 MockWrite data_writes1[] = {
2955 MockWrite("GET / HTTP/1.1\r\n"
2956 "Host: www.google.com\r\n"
2957 "Connection: keep-alive\r\n\r\n"),
2958 };
2959
2960 MockRead data_reads1[] = {
2961 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
2962 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2963 // Large content-length -- won't matter, as connection will be reset.
2964 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062965 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:522966 };
2967
2968 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2969 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072970 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:522971
[email protected]49639fa2011-12-20 23:22:412972 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:522973
[email protected]49639fa2011-12-20 23:22:412974 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]8fdbcd22010-05-05 02:54:522975 EXPECT_EQ(ERR_IO_PENDING, rv);
2976
2977 rv = callback.WaitForResult();
2978 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
2979}
2980
[email protected]7a67a8152010-11-05 18:31:102981// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
2982// through a non-authenticating proxy. The request should fail with
2983// ERR_UNEXPECTED_PROXY_AUTH.
2984// Note that it is impossible to detect if an HTTP server returns a 407 through
2985// a non-authenticating proxy - there is nothing to indicate whether the
2986// response came from the proxy or the server, so it is treated as if the proxy
2987// issued the challenge.
[email protected]23e482282013-06-14 16:08:022988TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:232989 HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:272990 HttpRequestInfo request;
2991 request.method = "GET";
2992 request.url = GURL("https://www.google.com/");
2993
[email protected]bb88e1d32013-05-03 23:11:072994 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]333bdf62012-06-08 22:57:292995 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072996 session_deps_.net_log = log.bound().net_log();
2997 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:102998
[email protected]7a67a8152010-11-05 18:31:102999 // Since we have proxy, should try to establish tunnel.
3000 MockWrite data_writes1[] = {
3001 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
3002 "Host: www.google.com\r\n"
3003 "Proxy-Connection: keep-alive\r\n\r\n"),
3004
3005 MockWrite("GET / HTTP/1.1\r\n"
3006 "Host: www.google.com\r\n"
3007 "Connection: keep-alive\r\n\r\n"),
3008 };
3009
3010 MockRead data_reads1[] = {
3011 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3012
3013 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
3014 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3015 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:063016 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:103017 };
3018
3019 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3020 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073021 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063022 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073023 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:103024
[email protected]49639fa2011-12-20 23:22:413025 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:103026
[email protected]262eec82013-03-19 21:01:363027 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503028 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a67a8152010-11-05 18:31:103029
[email protected]49639fa2011-12-20 23:22:413030 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7a67a8152010-11-05 18:31:103031 EXPECT_EQ(ERR_IO_PENDING, rv);
3032
3033 rv = callback1.WaitForResult();
3034 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
[email protected]f3da152d2012-06-02 01:00:573035 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:403036 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:103037 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403038 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]7a67a8152010-11-05 18:31:103039 NetLog::PHASE_NONE);
3040 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403041 entries, pos,
[email protected]7a67a8152010-11-05 18:31:103042 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3043 NetLog::PHASE_NONE);
3044}
[email protected]2df19bb2010-08-25 20:13:463045
[email protected]029c83b62013-01-24 05:28:203046// Test the load timing for HTTPS requests with an HTTP proxy.
[email protected]23e482282013-06-14 16:08:023047TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:203048 HttpRequestInfo request1;
3049 request1.method = "GET";
3050 request1.url = GURL("https://www.google.com/1");
3051
3052 HttpRequestInfo request2;
3053 request2.method = "GET";
3054 request2.url = GURL("https://www.google.com/2");
3055
3056 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073057 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:203058 ProxyService::CreateFixed("PROXY myproxy:70"));
3059 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073060 session_deps_.net_log = log.bound().net_log();
3061 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:203062
3063 // Since we have proxy, should try to establish tunnel.
3064 MockWrite data_writes1[] = {
3065 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
3066 "Host: www.google.com\r\n"
3067 "Proxy-Connection: keep-alive\r\n\r\n"),
3068
3069 MockWrite("GET /1 HTTP/1.1\r\n"
3070 "Host: www.google.com\r\n"
3071 "Connection: keep-alive\r\n\r\n"),
3072
3073 MockWrite("GET /2 HTTP/1.1\r\n"
3074 "Host: www.google.com\r\n"
3075 "Connection: keep-alive\r\n\r\n"),
3076 };
3077
3078 // The proxy responds to the connect with a 407, using a persistent
3079 // connection.
3080 MockRead data_reads1[] = {
3081 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3082
3083 MockRead("HTTP/1.1 200 OK\r\n"),
3084 MockRead("Content-Length: 1\r\n\r\n"),
3085 MockRead(SYNCHRONOUS, "1"),
3086
3087 MockRead("HTTP/1.1 200 OK\r\n"),
3088 MockRead("Content-Length: 2\r\n\r\n"),
3089 MockRead(SYNCHRONOUS, "22"),
3090 };
3091
3092 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3093 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073094 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:203095 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073096 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:203097
3098 TestCompletionCallback callback1;
[email protected]262eec82013-03-19 21:01:363099 scoped_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:503100 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:203101
3102 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
3103 EXPECT_EQ(ERR_IO_PENDING, rv);
3104
3105 rv = callback1.WaitForResult();
3106 EXPECT_EQ(OK, rv);
3107
3108 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
3109 ASSERT_TRUE(response1 != NULL);
[email protected]90499482013-06-01 00:39:503110 ASSERT_TRUE(response1->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:203111 EXPECT_EQ(1, response1->headers->GetContentLength());
3112
3113 LoadTimingInfo load_timing_info1;
3114 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
3115 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
3116
3117 trans1.reset();
3118
3119 TestCompletionCallback callback2;
[email protected]262eec82013-03-19 21:01:363120 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503121 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:203122
3123 rv = trans2->Start(&request2, callback2.callback(), log.bound());
3124 EXPECT_EQ(ERR_IO_PENDING, rv);
3125
3126 rv = callback2.WaitForResult();
3127 EXPECT_EQ(OK, rv);
3128
3129 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
3130 ASSERT_TRUE(response2 != NULL);
[email protected]90499482013-06-01 00:39:503131 ASSERT_TRUE(response2->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:203132 EXPECT_EQ(2, response2->headers->GetContentLength());
3133
3134 LoadTimingInfo load_timing_info2;
3135 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3136 TestLoadTimingReused(load_timing_info2);
3137
3138 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
3139
3140 trans2.reset();
3141 session->CloseAllConnections();
3142}
3143
3144// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
[email protected]23e482282013-06-14 16:08:023145TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:203146 HttpRequestInfo request1;
3147 request1.method = "GET";
3148 request1.url = GURL("https://www.google.com/1");
3149
3150 HttpRequestInfo request2;
3151 request2.method = "GET";
3152 request2.url = GURL("https://www.google.com/2");
3153
3154 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073155 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:203156 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
3157 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073158 session_deps_.net_log = log.bound().net_log();
3159 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:203160
3161 // Since we have proxy, should try to establish tunnel.
3162 MockWrite data_writes1[] = {
3163 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
3164 "Host: www.google.com\r\n"
3165 "Proxy-Connection: keep-alive\r\n\r\n"),
3166
3167 MockWrite("GET /1 HTTP/1.1\r\n"
3168 "Host: www.google.com\r\n"
3169 "Connection: keep-alive\r\n\r\n"),
3170
3171 MockWrite("GET /2 HTTP/1.1\r\n"
3172 "Host: www.google.com\r\n"
3173 "Connection: keep-alive\r\n\r\n"),
3174 };
3175
3176 // The proxy responds to the connect with a 407, using a persistent
3177 // connection.
3178 MockRead data_reads1[] = {
3179 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3180
3181 MockRead("HTTP/1.1 200 OK\r\n"),
3182 MockRead("Content-Length: 1\r\n\r\n"),
3183 MockRead(SYNCHRONOUS, "1"),
3184
3185 MockRead("HTTP/1.1 200 OK\r\n"),
3186 MockRead("Content-Length: 2\r\n\r\n"),
3187 MockRead(SYNCHRONOUS, "22"),
3188 };
3189
3190 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3191 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073192 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:203193 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073194 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:203195
3196 TestCompletionCallback callback1;
[email protected]262eec82013-03-19 21:01:363197 scoped_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:503198 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:203199
3200 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
3201 EXPECT_EQ(ERR_IO_PENDING, rv);
3202
3203 rv = callback1.WaitForResult();
3204 EXPECT_EQ(OK, rv);
3205
3206 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
3207 ASSERT_TRUE(response1 != NULL);
[email protected]90499482013-06-01 00:39:503208 ASSERT_TRUE(response1->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:203209 EXPECT_EQ(1, response1->headers->GetContentLength());
3210
3211 LoadTimingInfo load_timing_info1;
3212 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
3213 TestLoadTimingNotReusedWithPac(load_timing_info1,
3214 CONNECT_TIMING_HAS_SSL_TIMES);
3215
3216 trans1.reset();
3217
3218 TestCompletionCallback callback2;
[email protected]262eec82013-03-19 21:01:363219 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503220 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:203221
3222 rv = trans2->Start(&request2, callback2.callback(), log.bound());
3223 EXPECT_EQ(ERR_IO_PENDING, rv);
3224
3225 rv = callback2.WaitForResult();
3226 EXPECT_EQ(OK, rv);
3227
3228 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
3229 ASSERT_TRUE(response2 != NULL);
[email protected]90499482013-06-01 00:39:503230 ASSERT_TRUE(response2->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:203231 EXPECT_EQ(2, response2->headers->GetContentLength());
3232
3233 LoadTimingInfo load_timing_info2;
3234 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3235 TestLoadTimingReusedWithPac(load_timing_info2);
3236
3237 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
3238
3239 trans2.reset();
3240 session->CloseAllConnections();
3241}
3242
[email protected]2df19bb2010-08-25 20:13:463243// Test a simple get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023244TEST_P(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:273245 HttpRequestInfo request;
3246 request.method = "GET";
3247 request.url = GURL("http://www.google.com/");
3248
[email protected]2df19bb2010-08-25 20:13:463249 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073250 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113251 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:293252 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073253 session_deps_.net_log = log.bound().net_log();
3254 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:463255
[email protected]2df19bb2010-08-25 20:13:463256 // Since we have proxy, should use full url
3257 MockWrite data_writes1[] = {
3258 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
3259 "Host: www.google.com\r\n"
3260 "Proxy-Connection: keep-alive\r\n\r\n"),
3261 };
3262
3263 MockRead data_reads1[] = {
3264 MockRead("HTTP/1.1 200 OK\r\n"),
3265 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3266 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063267 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:463268 };
3269
3270 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3271 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073272 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063273 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073274 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:463275
[email protected]49639fa2011-12-20 23:22:413276 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:463277
[email protected]262eec82013-03-19 21:01:363278 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503279 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503280
[email protected]49639fa2011-12-20 23:22:413281 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:463282 EXPECT_EQ(ERR_IO_PENDING, rv);
3283
3284 rv = callback1.WaitForResult();
3285 EXPECT_EQ(OK, rv);
3286
[email protected]58e32bb2013-01-21 18:23:253287 LoadTimingInfo load_timing_info;
3288 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3289 TestLoadTimingNotReused(load_timing_info,
3290 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3291
[email protected]2df19bb2010-08-25 20:13:463292 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503293 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:463294
3295 EXPECT_TRUE(response->headers->IsKeepAlive());
3296 EXPECT_EQ(200, response->headers->response_code());
3297 EXPECT_EQ(100, response->headers->GetContentLength());
3298 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3299
3300 // The password prompt info should not be set.
3301 EXPECT_TRUE(response->auth_challenge.get() == NULL);
3302}
3303
[email protected]7642b5ae2010-09-01 20:55:173304// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023305TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:273306 HttpRequestInfo request;
3307 request.method = "GET";
3308 request.url = GURL("http://www.google.com/");
3309 request.load_flags = 0;
3310
[email protected]7642b5ae2010-09-01 20:55:173311 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073312 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113313 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:293314 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073315 session_deps_.net_log = log.bound().net_log();
3316 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:173317
[email protected]7642b5ae2010-09-01 20:55:173318 // fetch http://www.google.com/ via SPDY
[email protected]cdf8f7e72013-05-23 10:56:463319 scoped_ptr<SpdyFrame> req(
3320 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]7642b5ae2010-09-01 20:55:173321 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
3322
[email protected]23e482282013-06-14 16:08:023323 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3324 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:173325 MockRead spdy_reads[] = {
3326 CreateMockRead(*resp),
3327 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:063328 MockRead(ASYNC, 0, 0),
[email protected]7642b5ae2010-09-01 20:55:173329 };
3330
[email protected]dd54bd82012-07-19 23:44:573331 DelayedSocketData spdy_data(
3332 1, // wait for one write to finish before reading.
3333 spdy_reads, arraysize(spdy_reads),
3334 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073335 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:173336
[email protected]8ddf8322012-02-23 18:08:063337 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023338 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073339 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:173340
[email protected]49639fa2011-12-20 23:22:413341 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:173342
[email protected]262eec82013-03-19 21:01:363343 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503344 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503345
[email protected]49639fa2011-12-20 23:22:413346 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7642b5ae2010-09-01 20:55:173347 EXPECT_EQ(ERR_IO_PENDING, rv);
3348
3349 rv = callback1.WaitForResult();
3350 EXPECT_EQ(OK, rv);
3351
[email protected]58e32bb2013-01-21 18:23:253352 LoadTimingInfo load_timing_info;
3353 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3354 TestLoadTimingNotReused(load_timing_info,
3355 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3356
[email protected]7642b5ae2010-09-01 20:55:173357 const HttpResponseInfo* response = trans->GetResponseInfo();
3358 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503359 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]7642b5ae2010-09-01 20:55:173360 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3361
3362 std::string response_data;
3363 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:233364 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:173365}
3366
[email protected]1c173852014-06-19 12:51:503367// Verifies that a session which races and wins against the owning transaction
3368// (completing prior to host resolution), doesn't fail the transaction.
3369// Regression test for crbug.com/334413.
3370TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
3371 HttpRequestInfo request;
3372 request.method = "GET";
3373 request.url = GURL("http://www.google.com/");
3374 request.load_flags = 0;
3375
3376 // Configure SPDY proxy server "proxy:70".
3377 session_deps_.proxy_service.reset(
3378 ProxyService::CreateFixed("https://proxy:70"));
3379 CapturingBoundNetLog log;
3380 session_deps_.net_log = log.bound().net_log();
3381 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3382
3383 // Fetch http://www.google.com/ through the SPDY proxy.
3384 scoped_ptr<SpdyFrame> req(
3385 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
3386 MockWrite spdy_writes[] = {CreateMockWrite(*req)};
3387
3388 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3389 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
3390 MockRead spdy_reads[] = {
3391 CreateMockRead(*resp), CreateMockRead(*data), MockRead(ASYNC, 0, 0),
3392 };
3393
3394 DelayedSocketData spdy_data(
3395 1, // wait for one write to finish before reading.
3396 spdy_reads,
3397 arraysize(spdy_reads),
3398 spdy_writes,
3399 arraysize(spdy_writes));
3400 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
3401
3402 SSLSocketDataProvider ssl(ASYNC, OK);
3403 ssl.SetNextProto(GetParam());
3404 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3405
3406 TestCompletionCallback callback1;
3407
3408 scoped_ptr<HttpTransaction> trans(
3409 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3410
3411 // Stall the hostname resolution begun by the transaction.
3412 session_deps_.host_resolver->set_synchronous_mode(false);
3413 session_deps_.host_resolver->set_ondemand_mode(true);
3414
3415 int rv = trans->Start(&request, callback1.callback(), log.bound());
3416 EXPECT_EQ(ERR_IO_PENDING, rv);
3417
3418 // Race a session to the proxy, which completes first.
3419 session_deps_.host_resolver->set_ondemand_mode(false);
3420 SpdySessionKey key(
3421 HostPortPair("proxy", 70), ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
3422 base::WeakPtr<SpdySession> spdy_session =
3423 CreateSecureSpdySession(session, key, log.bound());
3424
3425 // Unstall the resolution begun by the transaction.
3426 session_deps_.host_resolver->set_ondemand_mode(true);
3427 session_deps_.host_resolver->ResolveAllPending();
3428
3429 EXPECT_FALSE(callback1.have_result());
3430 rv = callback1.WaitForResult();
3431 EXPECT_EQ(OK, rv);
3432
3433 const HttpResponseInfo* response = trans->GetResponseInfo();
3434 ASSERT_TRUE(response != NULL);
3435 ASSERT_TRUE(response->headers.get() != NULL);
3436 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3437
3438 std::string response_data;
3439 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
3440 EXPECT_EQ(kUploadData, response_data);
3441}
3442
[email protected]dc7bd1c52010-11-12 00:01:133443// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023444TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:273445 HttpRequestInfo request;
3446 request.method = "GET";
3447 request.url = GURL("http://www.google.com/");
3448 request.load_flags = 0;
3449
[email protected]79cb5c12011-09-12 13:12:043450 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073451 session_deps_.proxy_service.reset(
[email protected]79cb5c12011-09-12 13:12:043452 ProxyService::CreateFixed("https://myproxy:70"));
[email protected]333bdf62012-06-08 22:57:293453 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073454 session_deps_.net_log = log.bound().net_log();
3455 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:133456
[email protected]dc7bd1c52010-11-12 00:01:133457 // The first request will be a bare GET, the second request will be a
3458 // GET with a Proxy-Authorization header.
[email protected]ff98d7f02012-03-22 21:44:193459 scoped_ptr<SpdyFrame> req_get(
[email protected]cdf8f7e72013-05-23 10:56:463460 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]dc7bd1c52010-11-12 00:01:133461 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:463462 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:133463 };
[email protected]ff98d7f02012-03-22 21:44:193464 scoped_ptr<SpdyFrame> req_get_authorization(
[email protected]cdf8f7e72013-05-23 10:56:463465 spdy_util_.ConstructSpdyGet(kExtraAuthorizationHeaders,
3466 arraysize(kExtraAuthorizationHeaders) / 2,
3467 false,
3468 3,
3469 LOWEST,
3470 false));
[email protected]dc7bd1c52010-11-12 00:01:133471 MockWrite spdy_writes[] = {
3472 CreateMockWrite(*req_get, 1),
3473 CreateMockWrite(*req_get_authorization, 4),
3474 };
3475
3476 // The first response is a 407 proxy authentication challenge, and the second
3477 // response will be a 200 response since the second request includes a valid
3478 // Authorization header.
3479 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:463480 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:133481 };
[email protected]ff98d7f02012-03-22 21:44:193482 scoped_ptr<SpdyFrame> resp_authentication(
[email protected]23e482282013-06-14 16:08:023483 spdy_util_.ConstructSpdySynReplyError(
[email protected]dc7bd1c52010-11-12 00:01:133484 "407 Proxy Authentication Required",
3485 kExtraAuthenticationHeaders, arraysize(kExtraAuthenticationHeaders)/2,
3486 1));
[email protected]ff98d7f02012-03-22 21:44:193487 scoped_ptr<SpdyFrame> body_authentication(
[email protected]23e482282013-06-14 16:08:023488 spdy_util_.ConstructSpdyBodyFrame(1, true));
3489 scoped_ptr<SpdyFrame> resp_data(
3490 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
3491 scoped_ptr<SpdyFrame> body_data(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:133492 MockRead spdy_reads[] = {
3493 CreateMockRead(*resp_authentication, 2),
3494 CreateMockRead(*body_authentication, 3),
3495 CreateMockRead(*resp_data, 5),
3496 CreateMockRead(*body_data, 6),
[email protected]8ddf8322012-02-23 18:08:063497 MockRead(ASYNC, 0, 7),
[email protected]dc7bd1c52010-11-12 00:01:133498 };
3499
[email protected]dd54bd82012-07-19 23:44:573500 OrderedSocketData data(
3501 spdy_reads, arraysize(spdy_reads),
3502 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073503 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:133504
[email protected]8ddf8322012-02-23 18:08:063505 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023506 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073507 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:133508
[email protected]49639fa2011-12-20 23:22:413509 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:133510
[email protected]262eec82013-03-19 21:01:363511 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503512 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]dc7bd1c52010-11-12 00:01:133513
[email protected]49639fa2011-12-20 23:22:413514 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]dc7bd1c52010-11-12 00:01:133515 EXPECT_EQ(ERR_IO_PENDING, rv);
3516
3517 rv = callback1.WaitForResult();
3518 EXPECT_EQ(OK, rv);
3519
3520 const HttpResponseInfo* const response = trans->GetResponseInfo();
3521
3522 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503523 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]dc7bd1c52010-11-12 00:01:133524 EXPECT_EQ(407, response->headers->response_code());
3525 EXPECT_TRUE(response->was_fetched_via_spdy);
[email protected]79cb5c12011-09-12 13:12:043526 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:133527
[email protected]49639fa2011-12-20 23:22:413528 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:133529
[email protected]49639fa2011-12-20 23:22:413530 rv = trans->RestartWithAuth(
3531 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]dc7bd1c52010-11-12 00:01:133532 EXPECT_EQ(ERR_IO_PENDING, rv);
3533
3534 rv = callback2.WaitForResult();
3535 EXPECT_EQ(OK, rv);
3536
3537 const HttpResponseInfo* const response_restart = trans->GetResponseInfo();
3538
3539 ASSERT_TRUE(response_restart != NULL);
[email protected]90499482013-06-01 00:39:503540 ASSERT_TRUE(response_restart->headers.get() != NULL);
[email protected]dc7bd1c52010-11-12 00:01:133541 EXPECT_EQ(200, response_restart->headers->response_code());
3542 // The password prompt info should not be set.
3543 EXPECT_TRUE(response_restart->auth_challenge.get() == NULL);
3544}
3545
[email protected]d9da5fe2010-10-13 22:37:163546// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
[email protected]23e482282013-06-14 16:08:023547TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:273548 HttpRequestInfo request;
3549 request.method = "GET";
3550 request.url = GURL("https://www.google.com/");
3551 request.load_flags = 0;
3552
[email protected]d9da5fe2010-10-13 22:37:163553 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073554 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113555 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:293556 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073557 session_deps_.net_log = log.bound().net_log();
3558 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:163559
[email protected]262eec82013-03-19 21:01:363560 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503561 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:163562
[email protected]d9da5fe2010-10-13 22:37:163563 // CONNECT to www.google.com:443 via SPDY
lgarrona91df87f2014-12-05 00:51:343564 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(
3565 NULL, 0, 1, LOWEST, HostPortPair("www.google.com", 443)));
[email protected]d9da5fe2010-10-13 22:37:163566 // fetch https://www.google.com/ via HTTP
3567
3568 const char get[] = "GET / HTTP/1.1\r\n"
3569 "Host: www.google.com\r\n"
3570 "Connection: keep-alive\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:193571 scoped_ptr<SpdyFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:023572 spdy_util_.ConstructSpdyBodyFrame(1, get, strlen(get), false));
3573 scoped_ptr<SpdyFrame> conn_resp(
3574 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:163575 const char resp[] = "HTTP/1.1 200 OK\r\n"
3576 "Content-Length: 10\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:193577 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:023578 spdy_util_.ConstructSpdyBodyFrame(1, resp, strlen(resp), false));
[email protected]ff98d7f02012-03-22 21:44:193579 scoped_ptr<SpdyFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:023580 spdy_util_.ConstructSpdyBodyFrame(1, "1234567890", 10, false));
[email protected]ff98d7f02012-03-22 21:44:193581 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203582 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
[email protected]8d2f7012012-02-16 00:08:043583
3584 MockWrite spdy_writes[] = {
3585 CreateMockWrite(*connect, 1),
3586 CreateMockWrite(*wrapped_get, 3),
[email protected]cdf8f7e72013-05-23 10:56:463587 CreateMockWrite(*window_update, 5),
[email protected]8d2f7012012-02-16 00:08:043588 };
3589
[email protected]d9da5fe2010-10-13 22:37:163590 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:063591 CreateMockRead(*conn_resp, 2, ASYNC),
3592 CreateMockRead(*wrapped_get_resp, 4, ASYNC),
3593 CreateMockRead(*wrapped_body, 6, ASYNC),
3594 CreateMockRead(*wrapped_body, 7, ASYNC),
3595 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:163596 };
3597
[email protected]dd54bd82012-07-19 23:44:573598 OrderedSocketData spdy_data(
3599 spdy_reads, arraysize(spdy_reads),
3600 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073601 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163602
[email protected]8ddf8322012-02-23 18:08:063603 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023604 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073605 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063606 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]d9da5fe2010-10-13 22:37:163607 ssl2.was_npn_negotiated = false;
[email protected]8e3c78cb2012-03-31 03:58:463608 ssl2.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:073609 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163610
[email protected]49639fa2011-12-20 23:22:413611 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163612
[email protected]49639fa2011-12-20 23:22:413613 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163614 EXPECT_EQ(ERR_IO_PENDING, rv);
3615
3616 rv = callback1.WaitForResult();
3617 EXPECT_EQ(OK, rv);
3618
[email protected]58e32bb2013-01-21 18:23:253619 LoadTimingInfo load_timing_info;
3620 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3621 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3622
[email protected]d9da5fe2010-10-13 22:37:163623 const HttpResponseInfo* response = trans->GetResponseInfo();
3624 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503625 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d9da5fe2010-10-13 22:37:163626 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3627
3628 std::string response_data;
3629 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
3630 EXPECT_EQ("1234567890", response_data);
3631}
3632
3633// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
[email protected]23e482282013-06-14 16:08:023634TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
[email protected]cb9bf6ca2011-01-28 13:15:273635 HttpRequestInfo request;
3636 request.method = "GET";
3637 request.url = GURL("https://www.google.com/");
3638 request.load_flags = 0;
3639
[email protected]d9da5fe2010-10-13 22:37:163640 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073641 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113642 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:293643 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073644 session_deps_.net_log = log.bound().net_log();
3645 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:163646
[email protected]262eec82013-03-19 21:01:363647 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503648 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:163649
[email protected]d9da5fe2010-10-13 22:37:163650 // CONNECT to www.google.com:443 via SPDY
lgarrona91df87f2014-12-05 00:51:343651 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(
3652 NULL, 0, 1, LOWEST, HostPortPair("www.google.com", 443)));
[email protected]d9da5fe2010-10-13 22:37:163653 // fetch https://www.google.com/ via SPDY
thestig9d3bb0c2015-01-24 00:49:513654 const char kMyUrl[] = "https://www.google.com/";
[email protected]cdf8f7e72013-05-23 10:56:463655 scoped_ptr<SpdyFrame> get(
3656 spdy_util_.ConstructSpdyGet(kMyUrl, false, 1, LOWEST));
[email protected]23e482282013-06-14 16:08:023657 scoped_ptr<SpdyFrame> wrapped_get(
3658 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
3659 scoped_ptr<SpdyFrame> conn_resp(
3660 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3661 scoped_ptr<SpdyFrame> get_resp(
3662 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]ff98d7f02012-03-22 21:44:193663 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:023664 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
3665 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
3666 scoped_ptr<SpdyFrame> wrapped_body(
3667 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
[email protected]ff98d7f02012-03-22 21:44:193668 scoped_ptr<SpdyFrame> window_update_get_resp(
[email protected]c10b20852013-05-15 21:29:203669 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
[email protected]ff98d7f02012-03-22 21:44:193670 scoped_ptr<SpdyFrame> window_update_body(
[email protected]c10b20852013-05-15 21:29:203671 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body->size()));
[email protected]8d2f7012012-02-16 00:08:043672
3673 MockWrite spdy_writes[] = {
3674 CreateMockWrite(*connect, 1),
3675 CreateMockWrite(*wrapped_get, 3),
3676 CreateMockWrite(*window_update_get_resp, 5),
3677 CreateMockWrite(*window_update_body, 7),
3678 };
3679
[email protected]d9da5fe2010-10-13 22:37:163680 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:063681 CreateMockRead(*conn_resp, 2, ASYNC),
3682 CreateMockRead(*wrapped_get_resp, 4, ASYNC),
3683 CreateMockRead(*wrapped_body, 6, ASYNC),
3684 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:163685 };
3686
[email protected]dd54bd82012-07-19 23:44:573687 OrderedSocketData spdy_data(
3688 spdy_reads, arraysize(spdy_reads),
3689 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073690 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163691
[email protected]8ddf8322012-02-23 18:08:063692 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023693 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073694 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063695 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023696 ssl2.SetNextProto(GetParam());
3697 ssl2.protocol_negotiated = GetParam();
[email protected]bb88e1d32013-05-03 23:11:073698 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163699
[email protected]49639fa2011-12-20 23:22:413700 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163701
[email protected]49639fa2011-12-20 23:22:413702 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163703 EXPECT_EQ(ERR_IO_PENDING, rv);
3704
3705 rv = callback1.WaitForResult();
3706 EXPECT_EQ(OK, rv);
3707
[email protected]58e32bb2013-01-21 18:23:253708 LoadTimingInfo load_timing_info;
3709 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3710 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3711
[email protected]d9da5fe2010-10-13 22:37:163712 const HttpResponseInfo* response = trans->GetResponseInfo();
3713 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503714 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d9da5fe2010-10-13 22:37:163715 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3716
3717 std::string response_data;
3718 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:233719 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:163720}
3721
3722// Test a SPDY CONNECT failure through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023723TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:273724 HttpRequestInfo request;
3725 request.method = "GET";
3726 request.url = GURL("https://www.google.com/");
3727 request.load_flags = 0;
3728
[email protected]d9da5fe2010-10-13 22:37:163729 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073730 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113731 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:293732 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073733 session_deps_.net_log = log.bound().net_log();
3734 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:163735
[email protected]262eec82013-03-19 21:01:363736 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503737 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:163738
[email protected]d9da5fe2010-10-13 22:37:163739 // CONNECT to www.google.com:443 via SPDY
lgarrona91df87f2014-12-05 00:51:343740 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(
3741 NULL, 0, 1, LOWEST, HostPortPair("www.google.com", 443)));
[email protected]c10b20852013-05-15 21:29:203742 scoped_ptr<SpdyFrame> get(
3743 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:163744
3745 MockWrite spdy_writes[] = {
3746 CreateMockWrite(*connect, 1),
3747 CreateMockWrite(*get, 3),
3748 };
3749
[email protected]23e482282013-06-14 16:08:023750 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdySynReplyError(1));
3751 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:163752 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:063753 CreateMockRead(*resp, 2, ASYNC),
3754 MockRead(ASYNC, 0, 4),
[email protected]d9da5fe2010-10-13 22:37:163755 };
3756
[email protected]dd54bd82012-07-19 23:44:573757 OrderedSocketData spdy_data(
3758 spdy_reads, arraysize(spdy_reads),
3759 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073760 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163761
[email protected]8ddf8322012-02-23 18:08:063762 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023763 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073764 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063765 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023766 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073767 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163768
[email protected]49639fa2011-12-20 23:22:413769 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163770
[email protected]49639fa2011-12-20 23:22:413771 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163772 EXPECT_EQ(ERR_IO_PENDING, rv);
3773
3774 rv = callback1.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:173775 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]d9da5fe2010-10-13 22:37:163776
[email protected]4eddbc732012-08-09 05:40:173777 // TODO(ttuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:163778}
3779
[email protected]f6c63db52013-02-02 00:35:223780// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
3781// HTTPS Proxy to different servers.
[email protected]23e482282013-06-14 16:08:023782TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:223783 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
3784 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073785 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:223786 "https://proxy:70"));
3787 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073788 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:223789 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:073790 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:223791
3792 HttpRequestInfo request1;
3793 request1.method = "GET";
3794 request1.url = GURL("https://www.google.com/");
3795 request1.load_flags = 0;
3796
3797 HttpRequestInfo request2;
3798 request2.method = "GET";
3799 request2.url = GURL("https://news.google.com/");
3800 request2.load_flags = 0;
3801
3802 // CONNECT to www.google.com:443 via SPDY.
lgarrona91df87f2014-12-05 00:51:343803 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(
3804 NULL, 0, 1, LOWEST, HostPortPair("www.google.com", 443)));
[email protected]23e482282013-06-14 16:08:023805 scoped_ptr<SpdyFrame> conn_resp1(
3806 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:223807
3808 // Fetch https://www.google.com/ via HTTP.
3809 const char get1[] = "GET / HTTP/1.1\r\n"
3810 "Host: www.google.com\r\n"
3811 "Connection: keep-alive\r\n\r\n";
3812 scoped_ptr<SpdyFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:023813 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:223814 const char resp1[] = "HTTP/1.1 200 OK\r\n"
3815 "Content-Length: 1\r\n\r\n";
3816 scoped_ptr<SpdyFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:023817 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
3818 scoped_ptr<SpdyFrame> wrapped_body1(
3819 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
[email protected]f6c63db52013-02-02 00:35:223820 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203821 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:223822
3823 // CONNECT to news.google.com:443 via SPDY.
[email protected]745aa9c2014-06-27 02:21:293824 SpdyHeaderBlock connect2_block;
3825 connect2_block[spdy_util_.GetMethodKey()] = "CONNECT";
3826 connect2_block[spdy_util_.GetPathKey()] = "news.google.com:443";
3827 connect2_block[spdy_util_.GetHostKey()] = "news.google.com";
3828 spdy_util_.MaybeAddVersionHeader(&connect2_block);
[email protected]f6c63db52013-02-02 00:35:223829 scoped_ptr<SpdyFrame> connect2(
[email protected]745aa9c2014-06-27 02:21:293830 spdy_util_.ConstructSpdySyn(3, connect2_block, LOWEST, false, false));
[email protected]601e03f12014-04-06 16:26:393831
[email protected]23e482282013-06-14 16:08:023832 scoped_ptr<SpdyFrame> conn_resp2(
3833 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:223834
3835 // Fetch https://news.google.com/ via HTTP.
3836 const char get2[] = "GET / HTTP/1.1\r\n"
3837 "Host: news.google.com\r\n"
3838 "Connection: keep-alive\r\n\r\n";
3839 scoped_ptr<SpdyFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:023840 spdy_util_.ConstructSpdyBodyFrame(3, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:223841 const char resp2[] = "HTTP/1.1 200 OK\r\n"
3842 "Content-Length: 2\r\n\r\n";
3843 scoped_ptr<SpdyFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:023844 spdy_util_.ConstructSpdyBodyFrame(3, resp2, strlen(resp2), false));
[email protected]f6c63db52013-02-02 00:35:223845 scoped_ptr<SpdyFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:023846 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:223847
3848 MockWrite spdy_writes[] = {
3849 CreateMockWrite(*connect1, 0),
3850 CreateMockWrite(*wrapped_get1, 2),
3851 CreateMockWrite(*connect2, 5),
3852 CreateMockWrite(*wrapped_get2, 7),
3853 };
3854
3855 MockRead spdy_reads[] = {
3856 CreateMockRead(*conn_resp1, 1, ASYNC),
3857 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
3858 CreateMockRead(*wrapped_body1, 4, ASYNC),
3859 CreateMockRead(*conn_resp2, 6, ASYNC),
3860 CreateMockRead(*wrapped_get_resp2, 8, ASYNC),
3861 CreateMockRead(*wrapped_body2, 9, ASYNC),
3862 MockRead(ASYNC, 0, 10),
3863 };
3864
3865 DeterministicSocketData spdy_data(
3866 spdy_reads, arraysize(spdy_reads),
3867 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073868 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:223869
3870 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023871 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073872 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:223873 SSLSocketDataProvider ssl2(ASYNC, OK);
3874 ssl2.was_npn_negotiated = false;
3875 ssl2.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:073876 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:223877 SSLSocketDataProvider ssl3(ASYNC, OK);
3878 ssl3.was_npn_negotiated = false;
3879 ssl3.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:073880 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:223881
3882 TestCompletionCallback callback;
3883
[email protected]262eec82013-03-19 21:01:363884 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503885 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223886 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
3887 EXPECT_EQ(ERR_IO_PENDING, rv);
3888 // The first connect and request, each of their responses, and the body.
3889 spdy_data.RunFor(5);
3890
3891 rv = callback.WaitForResult();
3892 EXPECT_EQ(OK, rv);
3893
3894 LoadTimingInfo load_timing_info;
3895 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3896 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3897
3898 const HttpResponseInfo* response = trans->GetResponseInfo();
3899 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503900 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:223901 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3902
3903 std::string response_data;
3904 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
[email protected]90499482013-06-01 00:39:503905 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223906
[email protected]262eec82013-03-19 21:01:363907 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503908 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223909 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
3910 EXPECT_EQ(ERR_IO_PENDING, rv);
3911
3912 // The second connect and request, each of their responses, and the body.
3913 spdy_data.RunFor(5);
3914 rv = callback.WaitForResult();
3915 EXPECT_EQ(OK, rv);
3916
3917 LoadTimingInfo load_timing_info2;
3918 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3919 // Even though the SPDY connection is reused, a new tunnelled connection has
3920 // to be created, so the socket's load timing looks like a fresh connection.
3921 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
3922
3923 // The requests should have different IDs, since they each are using their own
3924 // separate stream.
3925 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
3926
[email protected]90499482013-06-01 00:39:503927 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223928}
3929
3930// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
3931// HTTPS Proxy to the same server.
[email protected]23e482282013-06-14 16:08:023932TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:223933 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
3934 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073935 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:223936 "https://proxy:70"));
3937 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073938 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:223939 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:073940 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:223941
3942 HttpRequestInfo request1;
3943 request1.method = "GET";
3944 request1.url = GURL("https://www.google.com/");
3945 request1.load_flags = 0;
3946
3947 HttpRequestInfo request2;
3948 request2.method = "GET";
3949 request2.url = GURL("https://www.google.com/2");
3950 request2.load_flags = 0;
3951
3952 // CONNECT to www.google.com:443 via SPDY.
lgarrona91df87f2014-12-05 00:51:343953 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(
3954 NULL, 0, 1, LOWEST, HostPortPair("www.google.com", 443)));
[email protected]23e482282013-06-14 16:08:023955 scoped_ptr<SpdyFrame> conn_resp1(
3956 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:223957
3958 // Fetch https://www.google.com/ via HTTP.
3959 const char get1[] = "GET / HTTP/1.1\r\n"
3960 "Host: www.google.com\r\n"
3961 "Connection: keep-alive\r\n\r\n";
3962 scoped_ptr<SpdyFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:023963 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:223964 const char resp1[] = "HTTP/1.1 200 OK\r\n"
3965 "Content-Length: 1\r\n\r\n";
3966 scoped_ptr<SpdyFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:023967 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
3968 scoped_ptr<SpdyFrame> wrapped_body1(
3969 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
[email protected]f6c63db52013-02-02 00:35:223970 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203971 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:223972
3973 // Fetch https://www.google.com/2 via HTTP.
3974 const char get2[] = "GET /2 HTTP/1.1\r\n"
3975 "Host: www.google.com\r\n"
3976 "Connection: keep-alive\r\n\r\n";
3977 scoped_ptr<SpdyFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:023978 spdy_util_.ConstructSpdyBodyFrame(1, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:223979 const char resp2[] = "HTTP/1.1 200 OK\r\n"
3980 "Content-Length: 2\r\n\r\n";
3981 scoped_ptr<SpdyFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:023982 spdy_util_.ConstructSpdyBodyFrame(1, resp2, strlen(resp2), false));
[email protected]f6c63db52013-02-02 00:35:223983 scoped_ptr<SpdyFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:023984 spdy_util_.ConstructSpdyBodyFrame(1, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:223985
3986 MockWrite spdy_writes[] = {
3987 CreateMockWrite(*connect1, 0),
3988 CreateMockWrite(*wrapped_get1, 2),
3989 CreateMockWrite(*wrapped_get2, 5),
3990 };
3991
3992 MockRead spdy_reads[] = {
3993 CreateMockRead(*conn_resp1, 1, ASYNC),
3994 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
3995 CreateMockRead(*wrapped_body1, 4, ASYNC),
3996 CreateMockRead(*wrapped_get_resp2, 6, ASYNC),
3997 CreateMockRead(*wrapped_body2, 7, ASYNC),
3998 MockRead(ASYNC, 0, 8),
3999 };
4000
4001 DeterministicSocketData spdy_data(
4002 spdy_reads, arraysize(spdy_reads),
4003 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074004 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:224005
4006 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:024007 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:074008 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:224009 SSLSocketDataProvider ssl2(ASYNC, OK);
4010 ssl2.was_npn_negotiated = false;
4011 ssl2.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:074012 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:224013
4014 TestCompletionCallback callback;
4015
[email protected]262eec82013-03-19 21:01:364016 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504017 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224018 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
4019 EXPECT_EQ(ERR_IO_PENDING, rv);
4020 // The first connect and request, each of their responses, and the body.
4021 spdy_data.RunFor(5);
4022
4023 rv = callback.WaitForResult();
4024 EXPECT_EQ(OK, rv);
4025
4026 LoadTimingInfo load_timing_info;
4027 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4028 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
4029
4030 const HttpResponseInfo* response = trans->GetResponseInfo();
4031 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504032 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:224033 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4034
4035 std::string response_data;
4036 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
[email protected]90499482013-06-01 00:39:504037 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:224038 trans.reset();
4039
[email protected]262eec82013-03-19 21:01:364040 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:504041 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224042 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
4043 EXPECT_EQ(ERR_IO_PENDING, rv);
4044
4045 // The second request, response, and body. There should not be a second
4046 // connect.
4047 spdy_data.RunFor(3);
4048 rv = callback.WaitForResult();
4049 EXPECT_EQ(OK, rv);
4050
4051 LoadTimingInfo load_timing_info2;
4052 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4053 TestLoadTimingReused(load_timing_info2);
4054
4055 // The requests should have the same ID.
4056 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
4057
[email protected]90499482013-06-01 00:39:504058 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:224059}
4060
4061// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
4062// Proxy to different servers.
[email protected]23e482282013-06-14 16:08:024063TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:224064 HttpsProxySpdyLoadTimingTwoHttpRequests) {
4065 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:074066 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:224067 "https://proxy:70"));
4068 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074069 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:224070 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:074071 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:224072
4073 HttpRequestInfo request1;
4074 request1.method = "GET";
4075 request1.url = GURL("http://www.google.com/");
4076 request1.load_flags = 0;
4077
4078 HttpRequestInfo request2;
4079 request2.method = "GET";
4080 request2.url = GURL("http://news.google.com/");
4081 request2.load_flags = 0;
4082
4083 // http://www.google.com/
[email protected]23e482282013-06-14 16:08:024084 scoped_ptr<SpdyHeaderBlock> headers(
4085 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/"));
[email protected]745aa9c2014-06-27 02:21:294086 scoped_ptr<SpdyFrame> get1(
4087 spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, false, true));
[email protected]23e482282013-06-14 16:08:024088 scoped_ptr<SpdyFrame> get_resp1(
4089 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
4090 scoped_ptr<SpdyFrame> body1(
4091 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, true));
[email protected]f6c63db52013-02-02 00:35:224092
4093 // http://news.google.com/
[email protected]23e482282013-06-14 16:08:024094 scoped_ptr<SpdyHeaderBlock> headers2(
4095 spdy_util_.ConstructGetHeaderBlockForProxy("http://news.google.com/"));
[email protected]745aa9c2014-06-27 02:21:294096 scoped_ptr<SpdyFrame> get2(
4097 spdy_util_.ConstructSpdySyn(3, *headers2, LOWEST, false, true));
[email protected]23e482282013-06-14 16:08:024098 scoped_ptr<SpdyFrame> get_resp2(
4099 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
4100 scoped_ptr<SpdyFrame> body2(
4101 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, true));
[email protected]f6c63db52013-02-02 00:35:224102
4103 MockWrite spdy_writes[] = {
4104 CreateMockWrite(*get1, 0),
4105 CreateMockWrite(*get2, 3),
4106 };
4107
4108 MockRead spdy_reads[] = {
4109 CreateMockRead(*get_resp1, 1, ASYNC),
4110 CreateMockRead(*body1, 2, ASYNC),
4111 CreateMockRead(*get_resp2, 4, ASYNC),
4112 CreateMockRead(*body2, 5, ASYNC),
4113 MockRead(ASYNC, 0, 6),
4114 };
4115
4116 DeterministicSocketData spdy_data(
4117 spdy_reads, arraysize(spdy_reads),
4118 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074119 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:224120
4121 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:024122 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:074123 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:224124
4125 TestCompletionCallback callback;
4126
[email protected]262eec82013-03-19 21:01:364127 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504128 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224129 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
4130 EXPECT_EQ(ERR_IO_PENDING, rv);
4131 spdy_data.RunFor(2);
4132
4133 rv = callback.WaitForResult();
4134 EXPECT_EQ(OK, rv);
4135
4136 LoadTimingInfo load_timing_info;
4137 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4138 TestLoadTimingNotReused(load_timing_info,
4139 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4140
4141 const HttpResponseInfo* response = trans->GetResponseInfo();
4142 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504143 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:224144 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4145
4146 std::string response_data;
4147 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
[email protected]90499482013-06-01 00:39:504148 EXPECT_EQ(ERR_IO_PENDING, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:224149 spdy_data.RunFor(1);
4150 EXPECT_EQ(1, callback.WaitForResult());
4151 // Delete the first request, so the second one can reuse the socket.
4152 trans.reset();
4153
[email protected]262eec82013-03-19 21:01:364154 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:504155 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224156 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
4157 EXPECT_EQ(ERR_IO_PENDING, rv);
4158
4159 spdy_data.RunFor(2);
4160 rv = callback.WaitForResult();
4161 EXPECT_EQ(OK, rv);
4162
4163 LoadTimingInfo load_timing_info2;
4164 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4165 TestLoadTimingReused(load_timing_info2);
4166
4167 // The requests should have the same ID.
4168 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
4169
[email protected]90499482013-06-01 00:39:504170 EXPECT_EQ(ERR_IO_PENDING, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:224171 spdy_data.RunFor(1);
4172 EXPECT_EQ(2, callback.WaitForResult());
4173}
4174
[email protected]2df19bb2010-08-25 20:13:464175// Test the challenge-response-retry sequence through an HTTPS Proxy
[email protected]23e482282013-06-14 16:08:024176TEST_P(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:464177 HttpRequestInfo request;
4178 request.method = "GET";
4179 request.url = GURL("http://www.google.com/");
4180 // when the no authentication data flag is set.
4181 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
4182
[email protected]79cb5c12011-09-12 13:12:044183 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:074184 session_deps_.proxy_service.reset(
[email protected]79cb5c12011-09-12 13:12:044185 ProxyService::CreateFixed("https://myproxy:70"));
[email protected]333bdf62012-06-08 22:57:294186 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074187 session_deps_.net_log = log.bound().net_log();
4188 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274189
[email protected]2df19bb2010-08-25 20:13:464190 // Since we have proxy, should use full url
4191 MockWrite data_writes1[] = {
4192 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
4193 "Host: www.google.com\r\n"
4194 "Proxy-Connection: keep-alive\r\n\r\n"),
4195
4196 // After calling trans->RestartWithAuth(), this is the request we should
4197 // be issuing -- the final header line contains the credentials.
4198 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
4199 "Host: www.google.com\r\n"
4200 "Proxy-Connection: keep-alive\r\n"
4201 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
4202 };
4203
4204 // The proxy responds to the GET with a 407, using a persistent
4205 // connection.
4206 MockRead data_reads1[] = {
4207 // No credentials.
4208 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4209 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4210 MockRead("Proxy-Connection: keep-alive\r\n"),
4211 MockRead("Content-Length: 0\r\n\r\n"),
4212
4213 MockRead("HTTP/1.1 200 OK\r\n"),
4214 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4215 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064216 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:464217 };
4218
4219 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4220 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074221 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:064222 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074223 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:464224
[email protected]49639fa2011-12-20 23:22:414225 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:464226
[email protected]262eec82013-03-19 21:01:364227 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504228 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504229
[email protected]49639fa2011-12-20 23:22:414230 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:464231 EXPECT_EQ(ERR_IO_PENDING, rv);
4232
4233 rv = callback1.WaitForResult();
4234 EXPECT_EQ(OK, rv);
4235
[email protected]58e32bb2013-01-21 18:23:254236 LoadTimingInfo load_timing_info;
4237 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4238 TestLoadTimingNotReused(load_timing_info,
4239 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4240
[email protected]2df19bb2010-08-25 20:13:464241 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504242 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504243 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]2df19bb2010-08-25 20:13:464244 EXPECT_EQ(407, response->headers->response_code());
4245 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:044246 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:464247
[email protected]49639fa2011-12-20 23:22:414248 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:464249
[email protected]49639fa2011-12-20 23:22:414250 rv = trans->RestartWithAuth(
4251 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]2df19bb2010-08-25 20:13:464252 EXPECT_EQ(ERR_IO_PENDING, rv);
4253
4254 rv = callback2.WaitForResult();
4255 EXPECT_EQ(OK, rv);
4256
[email protected]58e32bb2013-01-21 18:23:254257 load_timing_info = LoadTimingInfo();
4258 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4259 // Retrying with HTTP AUTH is considered to be reusing a socket.
4260 TestLoadTimingReused(load_timing_info);
4261
[email protected]2df19bb2010-08-25 20:13:464262 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504263 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:464264
4265 EXPECT_TRUE(response->headers->IsKeepAlive());
4266 EXPECT_EQ(200, response->headers->response_code());
4267 EXPECT_EQ(100, response->headers->GetContentLength());
4268 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4269
4270 // The password prompt info should not be set.
4271 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4272}
4273
[email protected]23e482282013-06-14 16:08:024274void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:084275 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:424276 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:084277 request.method = "GET";
4278 request.url = GURL("https://www.google.com/");
4279 request.load_flags = 0;
4280
[email protected]cb9bf6ca2011-01-28 13:15:274281 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:074282 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]bb88e1d32013-05-03 23:11:074283 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274284
[email protected]c744cf22009-02-27 07:28:084285 // Since we have proxy, should try to establish tunnel.
4286 MockWrite data_writes[] = {
4287 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:454288 "Host: www.google.com\r\n"
4289 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:084290 };
4291
4292 MockRead data_reads[] = {
4293 status,
4294 MockRead("Content-Length: 10\r\n\r\n"),
4295 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:064296 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]c744cf22009-02-27 07:28:084297 };
4298
[email protected]31a2bfe2010-02-09 08:03:394299 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
4300 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:074301 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:084302
[email protected]49639fa2011-12-20 23:22:414303 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:084304
[email protected]262eec82013-03-19 21:01:364305 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504306 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504307
[email protected]49639fa2011-12-20 23:22:414308 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424309 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]c744cf22009-02-27 07:28:084310
4311 rv = callback.WaitForResult();
4312 EXPECT_EQ(expected_status, rv);
4313}
4314
[email protected]23e482282013-06-14 16:08:024315void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:234316 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:084317 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:424318 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:084319}
4320
[email protected]23e482282013-06-14 16:08:024321TEST_P(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:084322 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
4323}
4324
[email protected]23e482282013-06-14 16:08:024325TEST_P(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:084326 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
4327}
4328
[email protected]23e482282013-06-14 16:08:024329TEST_P(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:084330 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
4331}
4332
[email protected]23e482282013-06-14 16:08:024333TEST_P(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:084334 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
4335}
4336
[email protected]23e482282013-06-14 16:08:024337TEST_P(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:084338 ConnectStatusHelper(
4339 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
4340}
4341
[email protected]23e482282013-06-14 16:08:024342TEST_P(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:084343 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
4344}
4345
[email protected]23e482282013-06-14 16:08:024346TEST_P(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:084347 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
4348}
4349
[email protected]23e482282013-06-14 16:08:024350TEST_P(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:084351 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
4352}
4353
[email protected]23e482282013-06-14 16:08:024354TEST_P(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:084355 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
4356}
4357
[email protected]23e482282013-06-14 16:08:024358TEST_P(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:084359 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
4360}
4361
[email protected]23e482282013-06-14 16:08:024362TEST_P(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:084363 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
4364}
4365
[email protected]23e482282013-06-14 16:08:024366TEST_P(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:084367 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
4368}
4369
[email protected]23e482282013-06-14 16:08:024370TEST_P(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:084371 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
4372}
4373
[email protected]23e482282013-06-14 16:08:024374TEST_P(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:084375 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
4376}
4377
[email protected]23e482282013-06-14 16:08:024378TEST_P(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:084379 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
4380}
4381
[email protected]23e482282013-06-14 16:08:024382TEST_P(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:084383 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
4384}
4385
[email protected]0a17aab32014-04-24 03:32:374386TEST_P(HttpNetworkTransactionTest, ConnectStatus308) {
4387 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
4388}
4389
[email protected]23e482282013-06-14 16:08:024390TEST_P(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:084391 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
4392}
4393
[email protected]23e482282013-06-14 16:08:024394TEST_P(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:084395 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
4396}
4397
[email protected]23e482282013-06-14 16:08:024398TEST_P(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:084399 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
4400}
4401
[email protected]23e482282013-06-14 16:08:024402TEST_P(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:084403 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
4404}
4405
[email protected]23e482282013-06-14 16:08:024406TEST_P(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:084407 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
4408}
4409
[email protected]23e482282013-06-14 16:08:024410TEST_P(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:084411 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
4412}
4413
[email protected]23e482282013-06-14 16:08:024414TEST_P(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:084415 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
4416}
4417
[email protected]23e482282013-06-14 16:08:024418TEST_P(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:084419 ConnectStatusHelperWithExpectedStatus(
4420 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:544421 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:084422}
4423
[email protected]23e482282013-06-14 16:08:024424TEST_P(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:084425 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
4426}
4427
[email protected]23e482282013-06-14 16:08:024428TEST_P(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:084429 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
4430}
4431
[email protected]23e482282013-06-14 16:08:024432TEST_P(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:084433 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
4434}
4435
[email protected]23e482282013-06-14 16:08:024436TEST_P(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:084437 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
4438}
4439
[email protected]23e482282013-06-14 16:08:024440TEST_P(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:084441 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
4442}
4443
[email protected]23e482282013-06-14 16:08:024444TEST_P(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:084445 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
4446}
4447
[email protected]23e482282013-06-14 16:08:024448TEST_P(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:084449 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
4450}
4451
[email protected]23e482282013-06-14 16:08:024452TEST_P(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:084453 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
4454}
4455
[email protected]23e482282013-06-14 16:08:024456TEST_P(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:084457 ConnectStatusHelper(
4458 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
4459}
4460
[email protected]23e482282013-06-14 16:08:024461TEST_P(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:084462 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
4463}
4464
[email protected]23e482282013-06-14 16:08:024465TEST_P(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:084466 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
4467}
4468
[email protected]23e482282013-06-14 16:08:024469TEST_P(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:084470 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
4471}
4472
[email protected]23e482282013-06-14 16:08:024473TEST_P(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:084474 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
4475}
4476
[email protected]23e482282013-06-14 16:08:024477TEST_P(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:084478 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
4479}
4480
[email protected]23e482282013-06-14 16:08:024481TEST_P(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:084482 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
4483}
4484
[email protected]23e482282013-06-14 16:08:024485TEST_P(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:084486 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
4487}
4488
[email protected]038e9a32008-10-08 22:40:164489// Test the flow when both the proxy server AND origin server require
4490// authentication. Again, this uses basic auth for both since that is
4491// the simplest to mock.
[email protected]23e482282013-06-14 16:08:024492TEST_P(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:274493 HttpRequestInfo request;
4494 request.method = "GET";
4495 request.url = GURL("http://www.google.com/");
4496 request.load_flags = 0;
4497
[email protected]038e9a32008-10-08 22:40:164498 // Configure against proxy server "myproxy:70".
[email protected]3fe8d2f82013-10-17 08:56:074499 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
4500 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4501
4502 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:414503 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]038e9a32008-10-08 22:40:164504
[email protected]f9ee6b52008-11-08 06:46:234505 MockWrite data_writes1[] = {
4506 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
4507 "Host: www.google.com\r\n"
4508 "Proxy-Connection: keep-alive\r\n\r\n"),
4509 };
4510
[email protected]038e9a32008-10-08 22:40:164511 MockRead data_reads1[] = {
4512 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
4513 // Give a couple authenticate options (only the middle one is actually
4514 // supported).
[email protected]22927ad2009-09-21 19:56:194515 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:164516 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4517 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
4518 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4519 // Large content-length -- won't matter, as connection will be reset.
4520 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064521 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:164522 };
4523
4524 // After calling trans->RestartWithAuth() the first time, this is the
4525 // request we should be issuing -- the final header line contains the
4526 // proxy's credentials.
4527 MockWrite data_writes2[] = {
4528 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
4529 "Host: www.google.com\r\n"
4530 "Proxy-Connection: keep-alive\r\n"
4531 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
4532 };
4533
4534 // Now the proxy server lets the request pass through to origin server.
4535 // The origin server responds with a 401.
4536 MockRead data_reads2[] = {
4537 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4538 // Note: We are using the same realm-name as the proxy server. This is
4539 // completely valid, as realms are unique across hosts.
4540 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4541 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4542 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064543 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:164544 };
4545
4546 // After calling trans->RestartWithAuth() the second time, we should send
4547 // the credentials for both the proxy and origin server.
4548 MockWrite data_writes3[] = {
4549 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
4550 "Host: www.google.com\r\n"
4551 "Proxy-Connection: keep-alive\r\n"
4552 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
4553 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
4554 };
4555
4556 // Lastly we get the desired content.
4557 MockRead data_reads3[] = {
4558 MockRead("HTTP/1.0 200 OK\r\n"),
4559 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4560 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064561 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:164562 };
4563
[email protected]31a2bfe2010-02-09 08:03:394564 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4565 data_writes1, arraysize(data_writes1));
4566 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4567 data_writes2, arraysize(data_writes2));
4568 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4569 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:074570 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4571 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4572 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:164573
[email protected]49639fa2011-12-20 23:22:414574 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:164575
[email protected]49639fa2011-12-20 23:22:414576 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424577 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:164578
4579 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424580 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:164581
[email protected]1c773ea12009-04-28 19:58:424582 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504583 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044584 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:164585
[email protected]49639fa2011-12-20 23:22:414586 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:164587
[email protected]49639fa2011-12-20 23:22:414588 rv = trans->RestartWithAuth(
4589 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:424590 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:164591
4592 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424593 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:164594
4595 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504596 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044597 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:164598
[email protected]49639fa2011-12-20 23:22:414599 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:164600
[email protected]49639fa2011-12-20 23:22:414601 rv = trans->RestartWithAuth(
4602 AuthCredentials(kFoo2, kBar2), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424603 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:164604
4605 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424606 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:164607
4608 response = trans->GetResponseInfo();
4609 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4610 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:164611}
[email protected]4ddaf2502008-10-23 18:26:194612
[email protected]ea9dc9a2009-09-05 00:43:324613// For the NTLM implementation using SSPI, we skip the NTLM tests since we
4614// can't hook into its internals to cause it to generate predictable NTLM
4615// authorization headers.
4616#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:294617// The NTLM authentication unit tests were generated by capturing the HTTP
4618// requests and responses using Fiddler 2 and inspecting the generated random
4619// bytes in the debugger.
4620
4621// Enter the correct password and authenticate successfully.
[email protected]23e482282013-06-14 16:08:024622TEST_P(HttpNetworkTransactionTest, NTLMAuth1) {
[email protected]1c773ea12009-04-28 19:58:424623 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:244624 request.method = "GET";
4625 request.url = GURL("http://172.22.68.17/kids/login.aspx");
[email protected]2217aa22013-10-11 03:03:544626
4627 // Ensure load is not disrupted by flags which suppress behaviour specific
4628 // to other auth schemes.
4629 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:244630
[email protected]cb9bf6ca2011-01-28 13:15:274631 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
4632 MockGetHostName);
[email protected]bb88e1d32013-05-03 23:11:074633 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274634
[email protected]3f918782009-02-28 01:29:244635 MockWrite data_writes1[] = {
4636 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4637 "Host: 172.22.68.17\r\n"
4638 "Connection: keep-alive\r\n\r\n"),
4639 };
4640
4641 MockRead data_reads1[] = {
4642 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:044643 // Negotiate and NTLM are often requested together. However, we only want
4644 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
4645 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:244646 MockRead("WWW-Authenticate: NTLM\r\n"),
4647 MockRead("Connection: close\r\n"),
4648 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364649 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:244650 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064651 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]3f918782009-02-28 01:29:244652 };
4653
4654 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:224655 // After restarting with a null identity, this is the
[email protected]3f918782009-02-28 01:29:244656 // request we should be issuing -- the final header line contains a Type
4657 // 1 message.
4658 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4659 "Host: 172.22.68.17\r\n"
4660 "Connection: keep-alive\r\n"
4661 "Authorization: NTLM "
4662 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4663
4664 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4665 // (the credentials for the origin server). The second request continues
4666 // on the same connection.
4667 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4668 "Host: 172.22.68.17\r\n"
4669 "Connection: keep-alive\r\n"
[email protected]385a4672009-03-11 22:21:294670 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4671 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4672 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
4673 "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
4674 "ahlhx5I=\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:244675 };
4676
4677 MockRead data_reads2[] = {
4678 // The origin server responds with a Type 2 message.
4679 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4680 MockRead("WWW-Authenticate: NTLM "
[email protected]385a4672009-03-11 22:21:294681 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
[email protected]3f918782009-02-28 01:29:244682 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4683 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4684 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4685 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4686 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4687 "BtAAAAAAA=\r\n"),
4688 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364689 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:244690 MockRead("You are not authorized to view this page\r\n"),
4691
4692 // Lastly we get the desired content.
4693 MockRead("HTTP/1.1 200 OK\r\n"),
4694 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
4695 MockRead("Content-Length: 13\r\n\r\n"),
4696 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:064697 MockRead(SYNCHRONOUS, OK),
[email protected]3f918782009-02-28 01:29:244698 };
4699
[email protected]31a2bfe2010-02-09 08:03:394700 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4701 data_writes1, arraysize(data_writes1));
4702 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4703 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:074704 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4705 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:244706
[email protected]49639fa2011-12-20 23:22:414707 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:244708
[email protected]262eec82013-03-19 21:01:364709 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504710 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504711
[email protected]49639fa2011-12-20 23:22:414712 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424713 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:244714
4715 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424716 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:244717
[email protected]0757e7702009-03-27 04:00:224718 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4719
[email protected]1c773ea12009-04-28 19:58:424720 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:044721 ASSERT_FALSE(response == NULL);
4722 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:244723
[email protected]49639fa2011-12-20 23:22:414724 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:254725
[email protected]f3cf9802011-10-28 18:44:584726 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:414727 callback2.callback());
[email protected]10af5fe72011-01-31 16:17:254728 EXPECT_EQ(ERR_IO_PENDING, rv);
4729
4730 rv = callback2.WaitForResult();
4731 EXPECT_EQ(OK, rv);
4732
4733 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4734
4735 response = trans->GetResponseInfo();
4736 ASSERT_TRUE(response != NULL);
[email protected]10af5fe72011-01-31 16:17:254737 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4738
[email protected]49639fa2011-12-20 23:22:414739 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:244740
[email protected]49639fa2011-12-20 23:22:414741 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424742 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:244743
[email protected]0757e7702009-03-27 04:00:224744 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424745 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:244746
4747 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504748 ASSERT_TRUE(response != NULL);
[email protected]3f918782009-02-28 01:29:244749 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4750 EXPECT_EQ(13, response->headers->GetContentLength());
4751}
4752
[email protected]385a4672009-03-11 22:21:294753// Enter a wrong password, and then the correct one.
[email protected]23e482282013-06-14 16:08:024754TEST_P(HttpNetworkTransactionTest, NTLMAuth2) {
[email protected]1c773ea12009-04-28 19:58:424755 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:294756 request.method = "GET";
4757 request.url = GURL("http://172.22.68.17/kids/login.aspx");
4758 request.load_flags = 0;
4759
[email protected]cb9bf6ca2011-01-28 13:15:274760 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
4761 MockGetHostName);
[email protected]bb88e1d32013-05-03 23:11:074762 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274763
[email protected]385a4672009-03-11 22:21:294764 MockWrite data_writes1[] = {
4765 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4766 "Host: 172.22.68.17\r\n"
4767 "Connection: keep-alive\r\n\r\n"),
4768 };
4769
4770 MockRead data_reads1[] = {
4771 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:044772 // Negotiate and NTLM are often requested together. However, we only want
4773 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
4774 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:294775 MockRead("WWW-Authenticate: NTLM\r\n"),
4776 MockRead("Connection: close\r\n"),
4777 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364778 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294779 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064780 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:294781 };
4782
4783 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:224784 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:294785 // request we should be issuing -- the final header line contains a Type
4786 // 1 message.
4787 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4788 "Host: 172.22.68.17\r\n"
4789 "Connection: keep-alive\r\n"
4790 "Authorization: NTLM "
4791 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4792
4793 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4794 // (the credentials for the origin server). The second request continues
4795 // on the same connection.
4796 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4797 "Host: 172.22.68.17\r\n"
4798 "Connection: keep-alive\r\n"
4799 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4800 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4801 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
4802 "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
4803 "4Ww7b7E=\r\n\r\n"),
4804 };
4805
4806 MockRead data_reads2[] = {
4807 // The origin server responds with a Type 2 message.
4808 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4809 MockRead("WWW-Authenticate: NTLM "
4810 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
4811 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4812 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4813 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4814 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4815 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4816 "BtAAAAAAA=\r\n"),
4817 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364818 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294819 MockRead("You are not authorized to view this page\r\n"),
4820
4821 // Wrong password.
4822 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]385a4672009-03-11 22:21:294823 MockRead("WWW-Authenticate: NTLM\r\n"),
4824 MockRead("Connection: close\r\n"),
4825 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364826 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294827 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064828 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:294829 };
4830
4831 MockWrite data_writes3[] = {
[email protected]0757e7702009-03-27 04:00:224832 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:294833 // request we should be issuing -- the final header line contains a Type
4834 // 1 message.
4835 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4836 "Host: 172.22.68.17\r\n"
4837 "Connection: keep-alive\r\n"
4838 "Authorization: NTLM "
4839 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4840
4841 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4842 // (the credentials for the origin server). The second request continues
4843 // on the same connection.
4844 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4845 "Host: 172.22.68.17\r\n"
4846 "Connection: keep-alive\r\n"
4847 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4848 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4849 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
4850 "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
4851 "+4MUm7c=\r\n\r\n"),
4852 };
4853
4854 MockRead data_reads3[] = {
4855 // The origin server responds with a Type 2 message.
4856 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4857 MockRead("WWW-Authenticate: NTLM "
4858 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
4859 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4860 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4861 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4862 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4863 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4864 "BtAAAAAAA=\r\n"),
4865 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364866 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294867 MockRead("You are not authorized to view this page\r\n"),
4868
4869 // Lastly we get the desired content.
4870 MockRead("HTTP/1.1 200 OK\r\n"),
4871 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
4872 MockRead("Content-Length: 13\r\n\r\n"),
4873 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:064874 MockRead(SYNCHRONOUS, OK),
[email protected]385a4672009-03-11 22:21:294875 };
4876
[email protected]31a2bfe2010-02-09 08:03:394877 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4878 data_writes1, arraysize(data_writes1));
4879 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4880 data_writes2, arraysize(data_writes2));
4881 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4882 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:074883 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4884 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4885 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:294886
[email protected]49639fa2011-12-20 23:22:414887 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:294888
[email protected]262eec82013-03-19 21:01:364889 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504890 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504891
[email protected]49639fa2011-12-20 23:22:414892 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424893 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:294894
4895 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424896 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:294897
[email protected]0757e7702009-03-27 04:00:224898 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:294899
[email protected]1c773ea12009-04-28 19:58:424900 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504901 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044902 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:294903
[email protected]49639fa2011-12-20 23:22:414904 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:294905
[email protected]0757e7702009-03-27 04:00:224906 // Enter the wrong password.
[email protected]f3cf9802011-10-28 18:44:584907 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword),
[email protected]49639fa2011-12-20 23:22:414908 callback2.callback());
[email protected]1c773ea12009-04-28 19:58:424909 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:294910
[email protected]10af5fe72011-01-31 16:17:254911 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424912 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:294913
[email protected]0757e7702009-03-27 04:00:224914 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:414915 TestCompletionCallback callback3;
4916 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424917 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]10af5fe72011-01-31 16:17:254918 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424919 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:224920 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4921
4922 response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:044923 ASSERT_FALSE(response == NULL);
4924 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:224925
[email protected]49639fa2011-12-20 23:22:414926 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:224927
4928 // Now enter the right password.
[email protected]f3cf9802011-10-28 18:44:584929 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:414930 callback4.callback());
[email protected]10af5fe72011-01-31 16:17:254931 EXPECT_EQ(ERR_IO_PENDING, rv);
4932
4933 rv = callback4.WaitForResult();
4934 EXPECT_EQ(OK, rv);
4935
4936 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4937
[email protected]49639fa2011-12-20 23:22:414938 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:254939
4940 // One more roundtrip
[email protected]49639fa2011-12-20 23:22:414941 rv = trans->RestartWithAuth(AuthCredentials(), callback5.callback());
[email protected]1c773ea12009-04-28 19:58:424942 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:224943
4944 rv = callback5.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424945 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:224946
[email protected]385a4672009-03-11 22:21:294947 response = trans->GetResponseInfo();
4948 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4949 EXPECT_EQ(13, response->headers->GetContentLength());
4950}
[email protected]ea9dc9a2009-09-05 00:43:324951#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:294952
[email protected]4ddaf2502008-10-23 18:26:194953// Test reading a server response which has only headers, and no body.
4954// After some maximum number of bytes is consumed, the transaction should
4955// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
[email protected]23e482282013-06-14 16:08:024956TEST_P(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:424957 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:194958 request.method = "GET";
4959 request.url = GURL("http://www.google.com/");
4960 request.load_flags = 0;
4961
[email protected]3fe8d2f82013-10-17 08:56:074962 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274963 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:414964 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:274965
[email protected]b75b7b2f2009-10-06 00:54:534966 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:434967 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:534968 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:194969
4970 MockRead data_reads[] = {
4971 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:064972 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:194973 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:064974 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:194975 };
[email protected]31a2bfe2010-02-09 08:03:394976 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:074977 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:194978
[email protected]49639fa2011-12-20 23:22:414979 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:194980
[email protected]49639fa2011-12-20 23:22:414981 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424982 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]4ddaf2502008-10-23 18:26:194983
4984 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424985 EXPECT_EQ(ERR_RESPONSE_HEADERS_TOO_BIG, rv);
[email protected]4ddaf2502008-10-23 18:26:194986
[email protected]1c773ea12009-04-28 19:58:424987 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]4ddaf2502008-10-23 18:26:194988 EXPECT_TRUE(response == NULL);
4989}
[email protected]f4e426b2008-11-05 00:24:494990
4991// Make sure that we don't try to reuse a TCPClientSocket when failing to
4992// establish tunnel.
4993// http://code.google.com/p/chromium/issues/detail?id=3772
[email protected]23e482282013-06-14 16:08:024994TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:234995 DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:274996 HttpRequestInfo request;
4997 request.method = "GET";
4998 request.url = GURL("https://www.google.com/");
4999 request.load_flags = 0;
5000
[email protected]f4e426b2008-11-05 00:24:495001 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:075002 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]db8f44c2008-12-13 04:52:015003
[email protected]bb88e1d32013-05-03 23:11:075004 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:495005
[email protected]262eec82013-03-19 21:01:365006 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505007 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f4e426b2008-11-05 00:24:495008
[email protected]f4e426b2008-11-05 00:24:495009 // Since we have proxy, should try to establish tunnel.
5010 MockWrite data_writes1[] = {
5011 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:455012 "Host: www.google.com\r\n"
5013 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:495014 };
5015
[email protected]77848d12008-11-14 00:00:225016 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:495017 // connection. Usually a proxy would return 501 (not implemented),
5018 // or 200 (tunnel established).
5019 MockRead data_reads1[] = {
5020 MockRead("HTTP/1.1 404 Not Found\r\n"),
5021 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065022 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]f4e426b2008-11-05 00:24:495023 };
5024
[email protected]31a2bfe2010-02-09 08:03:395025 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5026 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075027 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:495028
[email protected]49639fa2011-12-20 23:22:415029 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:495030
[email protected]49639fa2011-12-20 23:22:415031 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425032 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f4e426b2008-11-05 00:24:495033
5034 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425035 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]f4e426b2008-11-05 00:24:495036
[email protected]1c773ea12009-04-28 19:58:425037 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]c744cf22009-02-27 07:28:085038 EXPECT_TRUE(response == NULL);
[email protected]f4e426b2008-11-05 00:24:495039
[email protected]b4404c02009-04-10 16:38:525040 // Empty the current queue. This is necessary because idle sockets are
5041 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345042 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:525043
[email protected]f4e426b2008-11-05 00:24:495044 // We now check to make sure the TCPClientSocket was not added back to
5045 // the pool.
[email protected]90499482013-06-01 00:39:505046 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:495047 trans.reset();
[email protected]2da659e2013-05-23 20:51:345048 base::MessageLoop::current()->RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:495049 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:505050 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:495051}
[email protected]372d34a2008-11-05 21:30:515052
[email protected]1b157c02009-04-21 01:55:405053// Make sure that we recycle a socket after reading all of the response body.
[email protected]23e482282013-06-14 16:08:025054TEST_P(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:425055 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:405056 request.method = "GET";
5057 request.url = GURL("http://www.google.com/");
5058 request.load_flags = 0;
5059
[email protected]bb88e1d32013-05-03 23:11:075060 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275061
[email protected]262eec82013-03-19 21:01:365062 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505063 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275064
[email protected]1b157c02009-04-21 01:55:405065 MockRead data_reads[] = {
5066 // A part of the response body is received with the response headers.
5067 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
5068 // The rest of the response body is received in two parts.
5069 MockRead("lo"),
5070 MockRead(" world"),
5071 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:065072 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:405073 };
5074
[email protected]31a2bfe2010-02-09 08:03:395075 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:075076 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:405077
[email protected]49639fa2011-12-20 23:22:415078 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:405079
[email protected]49639fa2011-12-20 23:22:415080 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425081 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]1b157c02009-04-21 01:55:405082
5083 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425084 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:405085
[email protected]1c773ea12009-04-28 19:58:425086 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505087 ASSERT_TRUE(response != NULL);
[email protected]1b157c02009-04-21 01:55:405088
[email protected]90499482013-06-01 00:39:505089 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]1b157c02009-04-21 01:55:405090 std::string status_line = response->headers->GetStatusLine();
5091 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
5092
[email protected]90499482013-06-01 00:39:505093 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:405094
5095 std::string response_data;
5096 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:425097 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:405098 EXPECT_EQ("hello world", response_data);
5099
5100 // Empty the current queue. This is necessary because idle sockets are
5101 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345102 base::MessageLoop::current()->RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:405103
5104 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505105 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:405106}
5107
[email protected]76a505b2010-08-25 06:23:005108// Make sure that we recycle a SSL socket after reading all of the response
5109// body.
[email protected]23e482282013-06-14 16:08:025110TEST_P(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:005111 HttpRequestInfo request;
5112 request.method = "GET";
5113 request.url = GURL("https://www.google.com/");
5114 request.load_flags = 0;
5115
5116 MockWrite data_writes[] = {
5117 MockWrite("GET / HTTP/1.1\r\n"
5118 "Host: www.google.com\r\n"
5119 "Connection: keep-alive\r\n\r\n"),
5120 };
5121
5122 MockRead data_reads[] = {
5123 MockRead("HTTP/1.1 200 OK\r\n"),
5124 MockRead("Content-Length: 11\r\n\r\n"),
5125 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:065126 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:005127 };
5128
[email protected]8ddf8322012-02-23 18:08:065129 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075130 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:005131
5132 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5133 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:075134 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:005135
[email protected]49639fa2011-12-20 23:22:415136 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:005137
[email protected]bb88e1d32013-05-03 23:11:075138 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:365139 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505140 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:005141
[email protected]49639fa2011-12-20 23:22:415142 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:005143
5144 EXPECT_EQ(ERR_IO_PENDING, rv);
5145 EXPECT_EQ(OK, callback.WaitForResult());
5146
5147 const HttpResponseInfo* response = trans->GetResponseInfo();
5148 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:505149 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:005150 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5151
[email protected]90499482013-06-01 00:39:505152 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005153
5154 std::string response_data;
5155 rv = ReadTransaction(trans.get(), &response_data);
5156 EXPECT_EQ(OK, rv);
5157 EXPECT_EQ("hello world", response_data);
5158
5159 // Empty the current queue. This is necessary because idle sockets are
5160 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345161 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:005162
5163 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505164 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005165}
5166
5167// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
5168// from the pool and make sure that we recover okay.
[email protected]23e482282013-06-14 16:08:025169TEST_P(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:005170 HttpRequestInfo request;
5171 request.method = "GET";
5172 request.url = GURL("https://www.google.com/");
5173 request.load_flags = 0;
5174
5175 MockWrite data_writes[] = {
5176 MockWrite("GET / HTTP/1.1\r\n"
5177 "Host: www.google.com\r\n"
5178 "Connection: keep-alive\r\n\r\n"),
5179 MockWrite("GET / HTTP/1.1\r\n"
5180 "Host: www.google.com\r\n"
5181 "Connection: keep-alive\r\n\r\n"),
5182 };
5183
5184 MockRead data_reads[] = {
5185 MockRead("HTTP/1.1 200 OK\r\n"),
5186 MockRead("Content-Length: 11\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065187 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:005188 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:065189 MockRead(ASYNC, 0, 0) // EOF
[email protected]76a505b2010-08-25 06:23:005190 };
5191
[email protected]8ddf8322012-02-23 18:08:065192 SSLSocketDataProvider ssl(ASYNC, OK);
5193 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075194 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5195 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:005196
5197 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5198 data_writes, arraysize(data_writes));
5199 StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
5200 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:075201 session_deps_.socket_factory->AddSocketDataProvider(&data);
5202 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:005203
[email protected]49639fa2011-12-20 23:22:415204 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:005205
[email protected]bb88e1d32013-05-03 23:11:075206 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:365207 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505208 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:005209
[email protected]49639fa2011-12-20 23:22:415210 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:005211
5212 EXPECT_EQ(ERR_IO_PENDING, rv);
5213 EXPECT_EQ(OK, callback.WaitForResult());
5214
5215 const HttpResponseInfo* response = trans->GetResponseInfo();
5216 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:505217 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:005218 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5219
[email protected]90499482013-06-01 00:39:505220 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005221
5222 std::string response_data;
5223 rv = ReadTransaction(trans.get(), &response_data);
5224 EXPECT_EQ(OK, rv);
5225 EXPECT_EQ("hello world", response_data);
5226
5227 // Empty the current queue. This is necessary because idle sockets are
5228 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345229 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:005230
5231 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505232 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005233
5234 // Now start the second transaction, which should reuse the previous socket.
5235
[email protected]90499482013-06-01 00:39:505236 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:005237
[email protected]49639fa2011-12-20 23:22:415238 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:005239
5240 EXPECT_EQ(ERR_IO_PENDING, rv);
5241 EXPECT_EQ(OK, callback.WaitForResult());
5242
5243 response = trans->GetResponseInfo();
5244 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:505245 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:005246 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5247
[email protected]90499482013-06-01 00:39:505248 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005249
5250 rv = ReadTransaction(trans.get(), &response_data);
5251 EXPECT_EQ(OK, rv);
5252 EXPECT_EQ("hello world", response_data);
5253
5254 // Empty the current queue. This is necessary because idle sockets are
5255 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345256 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:005257
5258 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505259 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005260}
5261
[email protected]b4404c02009-04-10 16:38:525262// Make sure that we recycle a socket after a zero-length response.
5263// http://crbug.com/9880
[email protected]23e482282013-06-14 16:08:025264TEST_P(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:425265 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:525266 request.method = "GET";
5267 request.url = GURL("http://www.google.com/csi?v=3&s=web&action=&"
5268 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
5269 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
5270 "rt=prt.2642,ol.2649,xjs.2951");
5271 request.load_flags = 0;
5272
[email protected]bb88e1d32013-05-03 23:11:075273 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275274
[email protected]262eec82013-03-19 21:01:365275 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505276 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275277
[email protected]b4404c02009-04-10 16:38:525278 MockRead data_reads[] = {
5279 MockRead("HTTP/1.1 204 No Content\r\n"
5280 "Content-Length: 0\r\n"
5281 "Content-Type: text/html\r\n\r\n"),
5282 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:065283 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:525284 };
5285
[email protected]31a2bfe2010-02-09 08:03:395286 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:075287 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:525288
[email protected]49639fa2011-12-20 23:22:415289 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:525290
[email protected]49639fa2011-12-20 23:22:415291 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425292 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]b4404c02009-04-10 16:38:525293
5294 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425295 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:525296
[email protected]1c773ea12009-04-28 19:58:425297 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505298 ASSERT_TRUE(response != NULL);
[email protected]b4404c02009-04-10 16:38:525299
[email protected]90499482013-06-01 00:39:505300 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]b4404c02009-04-10 16:38:525301 std::string status_line = response->headers->GetStatusLine();
5302 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
5303
[email protected]90499482013-06-01 00:39:505304 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:525305
5306 std::string response_data;
5307 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:425308 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:525309 EXPECT_EQ("", response_data);
5310
5311 // Empty the current queue. This is necessary because idle sockets are
5312 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345313 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:525314
5315 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505316 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:525317}
5318
[email protected]23e482282013-06-14 16:08:025319TEST_P(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
[email protected]b2d26cfd2012-12-11 10:36:065320 ScopedVector<UploadElementReader> element_readers;
5321 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:075322 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:275323
[email protected]1c773ea12009-04-28 19:58:425324 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:515325 // Transaction 1: a GET request that succeeds. The socket is recycled
5326 // after use.
5327 request[0].method = "GET";
5328 request[0].url = GURL("http://www.google.com/");
5329 request[0].load_flags = 0;
5330 // Transaction 2: a POST request. Reuses the socket kept alive from
5331 // transaction 1. The first attempts fails when writing the POST data.
5332 // This causes the transaction to retry with a new socket. The second
5333 // attempt succeeds.
5334 request[1].method = "POST";
5335 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:275336 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:515337 request[1].load_flags = 0;
5338
[email protected]bb88e1d32013-05-03 23:11:075339 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:515340
5341 // The first socket is used for transaction 1 and the first attempt of
5342 // transaction 2.
5343
5344 // The response of transaction 1.
5345 MockRead data_reads1[] = {
5346 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
5347 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:065348 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:515349 };
5350 // The mock write results of transaction 1 and the first attempt of
5351 // transaction 2.
5352 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:065353 MockWrite(SYNCHRONOUS, 64), // GET
5354 MockWrite(SYNCHRONOUS, 93), // POST
5355 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:515356 };
[email protected]31a2bfe2010-02-09 08:03:395357 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5358 data_writes1, arraysize(data_writes1));
[email protected]372d34a2008-11-05 21:30:515359
5360 // The second socket is used for the second attempt of transaction 2.
5361
5362 // The response of transaction 2.
5363 MockRead data_reads2[] = {
5364 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
5365 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:065366 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:515367 };
5368 // The mock write results of the second attempt of transaction 2.
5369 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:065370 MockWrite(SYNCHRONOUS, 93), // POST
5371 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:515372 };
[email protected]31a2bfe2010-02-09 08:03:395373 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5374 data_writes2, arraysize(data_writes2));
[email protected]372d34a2008-11-05 21:30:515375
[email protected]bb88e1d32013-05-03 23:11:075376 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5377 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:515378
thestig9d3bb0c2015-01-24 00:49:515379 const char* const kExpectedResponseData[] = {
[email protected]372d34a2008-11-05 21:30:515380 "hello world", "welcome"
5381 };
5382
5383 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:425384 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505385 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]372d34a2008-11-05 21:30:515386
[email protected]49639fa2011-12-20 23:22:415387 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:515388
[email protected]49639fa2011-12-20 23:22:415389 int rv = trans->Start(&request[i], callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425390 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]372d34a2008-11-05 21:30:515391
5392 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425393 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:515394
[email protected]1c773ea12009-04-28 19:58:425395 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505396 ASSERT_TRUE(response != NULL);
[email protected]372d34a2008-11-05 21:30:515397
[email protected]90499482013-06-01 00:39:505398 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]372d34a2008-11-05 21:30:515399 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5400
5401 std::string response_data;
5402 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:425403 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:515404 EXPECT_EQ(kExpectedResponseData[i], response_data);
5405 }
5406}
[email protected]f9ee6b52008-11-08 06:46:235407
5408// Test the request-challenge-retry sequence for basic auth when there is
5409// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:165410// it fails the identity from the URL is used to answer the challenge.
[email protected]23e482282013-06-14 16:08:025411TEST_P(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:425412 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235413 request.method = "GET";
[email protected]a97cca42009-08-14 01:00:295414 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:415415 request.load_flags = LOAD_NORMAL;
[email protected]a97cca42009-08-14 01:00:295416
[email protected]3fe8d2f82013-10-17 08:56:075417 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275418 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415419 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275420
[email protected]a97cca42009-08-14 01:00:295421 // The password contains an escaped character -- for this test to pass it
5422 // will need to be unescaped by HttpNetworkTransaction.
5423 EXPECT_EQ("b%40r", request.url.password());
5424
[email protected]f9ee6b52008-11-08 06:46:235425 MockWrite data_writes1[] = {
5426 MockWrite("GET / HTTP/1.1\r\n"
5427 "Host: www.google.com\r\n"
5428 "Connection: keep-alive\r\n\r\n"),
5429 };
5430
5431 MockRead data_reads1[] = {
5432 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5433 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5434 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065435 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235436 };
5437
[email protected]2262e3a2012-05-22 16:08:165438 // After the challenge above, the transaction will be restarted using the
5439 // identity from the url (foo, b@r) to answer the challenge.
5440 MockWrite data_writes2[] = {
5441 MockWrite("GET / HTTP/1.1\r\n"
5442 "Host: www.google.com\r\n"
5443 "Connection: keep-alive\r\n"
5444 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
5445 };
5446
5447 MockRead data_reads2[] = {
5448 MockRead("HTTP/1.0 200 OK\r\n"),
5449 MockRead("Content-Length: 100\r\n\r\n"),
5450 MockRead(SYNCHRONOUS, OK),
5451 };
5452
[email protected]31a2bfe2010-02-09 08:03:395453 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5454 data_writes1, arraysize(data_writes1));
[email protected]2262e3a2012-05-22 16:08:165455 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5456 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075457 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5458 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235459
[email protected]49639fa2011-12-20 23:22:415460 TestCompletionCallback callback1;
[email protected]49639fa2011-12-20 23:22:415461 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425462 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235463 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425464 EXPECT_EQ(OK, rv);
[email protected]2262e3a2012-05-22 16:08:165465 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5466
5467 TestCompletionCallback callback2;
5468 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
5469 EXPECT_EQ(ERR_IO_PENDING, rv);
5470 rv = callback2.WaitForResult();
5471 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225472 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5473
[email protected]2262e3a2012-05-22 16:08:165474 const HttpResponseInfo* response = trans->GetResponseInfo();
5475 ASSERT_TRUE(response != NULL);
5476
5477 // There is no challenge info, since the identity in URL worked.
5478 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5479
5480 EXPECT_EQ(100, response->headers->GetContentLength());
5481
5482 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:345483 base::MessageLoop::current()->RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:165484}
5485
5486// Test the request-challenge-retry sequence for basic auth when there is an
5487// incorrect identity in the URL. The identity from the URL should be used only
5488// once.
[email protected]23e482282013-06-14 16:08:025489TEST_P(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:165490 HttpRequestInfo request;
5491 request.method = "GET";
5492 // Note: the URL has a username:password in it. The password "baz" is
5493 // wrong (should be "bar").
5494 request.url = GURL("http://foo:[email protected]/");
5495
5496 request.load_flags = LOAD_NORMAL;
5497
[email protected]3fe8d2f82013-10-17 08:56:075498 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2262e3a2012-05-22 16:08:165499 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415500 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2262e3a2012-05-22 16:08:165501
5502 MockWrite data_writes1[] = {
5503 MockWrite("GET / HTTP/1.1\r\n"
5504 "Host: www.google.com\r\n"
5505 "Connection: keep-alive\r\n\r\n"),
5506 };
5507
5508 MockRead data_reads1[] = {
5509 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5510 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5511 MockRead("Content-Length: 10\r\n\r\n"),
5512 MockRead(SYNCHRONOUS, ERR_FAILED),
5513 };
5514
5515 // After the challenge above, the transaction will be restarted using the
5516 // identity from the url (foo, baz) to answer the challenge.
5517 MockWrite data_writes2[] = {
5518 MockWrite("GET / HTTP/1.1\r\n"
5519 "Host: www.google.com\r\n"
5520 "Connection: keep-alive\r\n"
5521 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
5522 };
5523
5524 MockRead data_reads2[] = {
5525 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5526 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5527 MockRead("Content-Length: 10\r\n\r\n"),
5528 MockRead(SYNCHRONOUS, ERR_FAILED),
5529 };
5530
5531 // After the challenge above, the transaction will be restarted using the
5532 // identity supplied by the user (foo, bar) to answer the challenge.
5533 MockWrite data_writes3[] = {
5534 MockWrite("GET / HTTP/1.1\r\n"
5535 "Host: www.google.com\r\n"
5536 "Connection: keep-alive\r\n"
5537 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5538 };
5539
5540 MockRead data_reads3[] = {
5541 MockRead("HTTP/1.0 200 OK\r\n"),
5542 MockRead("Content-Length: 100\r\n\r\n"),
5543 MockRead(SYNCHRONOUS, OK),
5544 };
5545
5546 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5547 data_writes1, arraysize(data_writes1));
5548 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5549 data_writes2, arraysize(data_writes2));
5550 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5551 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075552 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5553 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5554 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:165555
5556 TestCompletionCallback callback1;
5557
5558 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5559 EXPECT_EQ(ERR_IO_PENDING, rv);
5560
5561 rv = callback1.WaitForResult();
5562 EXPECT_EQ(OK, rv);
5563
5564 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5565 TestCompletionCallback callback2;
5566 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
5567 EXPECT_EQ(ERR_IO_PENDING, rv);
5568 rv = callback2.WaitForResult();
5569 EXPECT_EQ(OK, rv);
5570 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5571
5572 const HttpResponseInfo* response = trans->GetResponseInfo();
5573 ASSERT_TRUE(response != NULL);
5574 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
5575
5576 TestCompletionCallback callback3;
5577 rv = trans->RestartWithAuth(
5578 AuthCredentials(kFoo, kBar), callback3.callback());
5579 EXPECT_EQ(ERR_IO_PENDING, rv);
5580 rv = callback3.WaitForResult();
5581 EXPECT_EQ(OK, rv);
5582 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5583
5584 response = trans->GetResponseInfo();
5585 ASSERT_TRUE(response != NULL);
5586
5587 // There is no challenge info, since the identity worked.
5588 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5589
5590 EXPECT_EQ(100, response->headers->GetContentLength());
5591
[email protected]ea9dc9a2009-09-05 00:43:325592 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:345593 base::MessageLoop::current()->RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:325594}
5595
[email protected]2217aa22013-10-11 03:03:545596
5597// Test the request-challenge-retry sequence for basic auth when there is a
5598// correct identity in the URL, but its use is being suppressed. The identity
5599// from the URL should never be used.
5600TEST_P(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
5601 HttpRequestInfo request;
5602 request.method = "GET";
5603 request.url = GURL("http://foo:[email protected]/");
5604 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
5605
[email protected]3fe8d2f82013-10-17 08:56:075606 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2217aa22013-10-11 03:03:545607 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415608 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2217aa22013-10-11 03:03:545609
5610 MockWrite data_writes1[] = {
5611 MockWrite("GET / HTTP/1.1\r\n"
5612 "Host: www.google.com\r\n"
5613 "Connection: keep-alive\r\n\r\n"),
5614 };
5615
5616 MockRead data_reads1[] = {
5617 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5618 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5619 MockRead("Content-Length: 10\r\n\r\n"),
5620 MockRead(SYNCHRONOUS, ERR_FAILED),
5621 };
5622
5623 // After the challenge above, the transaction will be restarted using the
5624 // identity supplied by the user, not the one in the URL, to answer the
5625 // challenge.
5626 MockWrite data_writes3[] = {
5627 MockWrite("GET / HTTP/1.1\r\n"
5628 "Host: www.google.com\r\n"
5629 "Connection: keep-alive\r\n"
5630 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5631 };
5632
5633 MockRead data_reads3[] = {
5634 MockRead("HTTP/1.0 200 OK\r\n"),
5635 MockRead("Content-Length: 100\r\n\r\n"),
5636 MockRead(SYNCHRONOUS, OK),
5637 };
5638
5639 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5640 data_writes1, arraysize(data_writes1));
5641 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5642 data_writes3, arraysize(data_writes3));
5643 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5644 session_deps_.socket_factory->AddSocketDataProvider(&data3);
5645
5646 TestCompletionCallback callback1;
5647 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5648 EXPECT_EQ(ERR_IO_PENDING, rv);
5649 rv = callback1.WaitForResult();
5650 EXPECT_EQ(OK, rv);
5651 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5652
5653 const HttpResponseInfo* response = trans->GetResponseInfo();
5654 ASSERT_TRUE(response != NULL);
5655 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
5656
5657 TestCompletionCallback callback3;
5658 rv = trans->RestartWithAuth(
5659 AuthCredentials(kFoo, kBar), callback3.callback());
5660 EXPECT_EQ(ERR_IO_PENDING, rv);
5661 rv = callback3.WaitForResult();
5662 EXPECT_EQ(OK, rv);
5663 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5664
5665 response = trans->GetResponseInfo();
5666 ASSERT_TRUE(response != NULL);
5667
5668 // There is no challenge info, since the identity worked.
5669 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5670 EXPECT_EQ(100, response->headers->GetContentLength());
5671
5672 // Empty the current queue.
5673 base::MessageLoop::current()->RunUntilIdle();
5674}
5675
[email protected]f9ee6b52008-11-08 06:46:235676// Test that previously tried username/passwords for a realm get re-used.
[email protected]23e482282013-06-14 16:08:025677TEST_P(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
[email protected]bb88e1d32013-05-03 23:11:075678 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:235679
5680 // Transaction 1: authenticate (foo, bar) on MyRealm1
5681 {
[email protected]1c773ea12009-04-28 19:58:425682 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235683 request.method = "GET";
5684 request.url = GURL("http://www.google.com/x/y/z");
5685 request.load_flags = 0;
5686
[email protected]262eec82013-03-19 21:01:365687 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505688 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275689
[email protected]f9ee6b52008-11-08 06:46:235690 MockWrite data_writes1[] = {
5691 MockWrite("GET /x/y/z HTTP/1.1\r\n"
5692 "Host: www.google.com\r\n"
5693 "Connection: keep-alive\r\n\r\n"),
5694 };
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[] = {
5705 MockWrite("GET /x/y/z HTTP/1.1\r\n"
5706 "Host: www.google.com\r\n"
5707 "Connection: keep-alive\r\n"
5708 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5709 };
5710
5711 // Sever accepts the authorization.
5712 MockRead data_reads2[] = {
5713 MockRead("HTTP/1.0 200 OK\r\n"),
5714 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065715 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235716 };
5717
[email protected]31a2bfe2010-02-09 08:03:395718 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5719 data_writes1, arraysize(data_writes1));
5720 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5721 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075722 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5723 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235724
[email protected]49639fa2011-12-20 23:22:415725 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235726
[email protected]49639fa2011-12-20 23:22:415727 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425728 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235729
5730 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425731 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235732
[email protected]1c773ea12009-04-28 19:58:425733 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505734 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045735 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:235736
[email protected]49639fa2011-12-20 23:22:415737 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:235738
[email protected]49639fa2011-12-20 23:22:415739 rv = trans->RestartWithAuth(
5740 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425741 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235742
5743 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425744 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235745
5746 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505747 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235748 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5749 EXPECT_EQ(100, response->headers->GetContentLength());
5750 }
5751
5752 // ------------------------------------------------------------------------
5753
5754 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
5755 {
[email protected]1c773ea12009-04-28 19:58:425756 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235757 request.method = "GET";
5758 // Note that Transaction 1 was at /x/y/z, so this is in the same
5759 // protection space as MyRealm1.
5760 request.url = GURL("http://www.google.com/x/y/a/b");
5761 request.load_flags = 0;
5762
[email protected]262eec82013-03-19 21:01:365763 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505764 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275765
[email protected]f9ee6b52008-11-08 06:46:235766 MockWrite data_writes1[] = {
5767 MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
5768 "Host: www.google.com\r\n"
5769 "Connection: keep-alive\r\n"
5770 // Send preemptive authorization for MyRealm1
5771 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5772 };
5773
5774 // The server didn't like the preemptive authorization, and
5775 // challenges us for a different realm (MyRealm2).
5776 MockRead data_reads1[] = {
5777 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5778 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
5779 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065780 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235781 };
5782
5783 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
5784 MockWrite data_writes2[] = {
5785 MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
5786 "Host: www.google.com\r\n"
5787 "Connection: keep-alive\r\n"
5788 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
5789 };
5790
5791 // Sever accepts the authorization.
5792 MockRead data_reads2[] = {
5793 MockRead("HTTP/1.0 200 OK\r\n"),
5794 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065795 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235796 };
5797
[email protected]31a2bfe2010-02-09 08:03:395798 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5799 data_writes1, arraysize(data_writes1));
5800 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5801 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075802 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5803 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235804
[email protected]49639fa2011-12-20 23:22:415805 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235806
[email protected]49639fa2011-12-20 23:22:415807 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425808 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235809
5810 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425811 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235812
[email protected]1c773ea12009-04-28 19:58:425813 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505814 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045815 ASSERT_TRUE(response->auth_challenge.get());
5816 EXPECT_FALSE(response->auth_challenge->is_proxy);
5817 EXPECT_EQ("www.google.com:80",
5818 response->auth_challenge->challenger.ToString());
5819 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
5820 EXPECT_EQ("basic", response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:235821
[email protected]49639fa2011-12-20 23:22:415822 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:235823
[email protected]49639fa2011-12-20 23:22:415824 rv = trans->RestartWithAuth(
5825 AuthCredentials(kFoo2, kBar2), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425826 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235827
5828 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425829 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235830
5831 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505832 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235833 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5834 EXPECT_EQ(100, response->headers->GetContentLength());
5835 }
5836
5837 // ------------------------------------------------------------------------
5838
5839 // Transaction 3: Resend a request in MyRealm's protection space --
5840 // succeed with preemptive authorization.
5841 {
[email protected]1c773ea12009-04-28 19:58:425842 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235843 request.method = "GET";
5844 request.url = GURL("http://www.google.com/x/y/z2");
5845 request.load_flags = 0;
5846
[email protected]262eec82013-03-19 21:01:365847 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505848 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275849
[email protected]f9ee6b52008-11-08 06:46:235850 MockWrite data_writes1[] = {
5851 MockWrite("GET /x/y/z2 HTTP/1.1\r\n"
5852 "Host: www.google.com\r\n"
5853 "Connection: keep-alive\r\n"
5854 // The authorization for MyRealm1 gets sent preemptively
5855 // (since the url is in the same protection space)
5856 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5857 };
5858
5859 // Sever accepts the preemptive authorization
5860 MockRead data_reads1[] = {
5861 MockRead("HTTP/1.0 200 OK\r\n"),
5862 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065863 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235864 };
5865
[email protected]31a2bfe2010-02-09 08:03:395866 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5867 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075868 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:235869
[email protected]49639fa2011-12-20 23:22:415870 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235871
[email protected]49639fa2011-12-20 23:22:415872 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425873 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235874
5875 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425876 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235877
[email protected]1c773ea12009-04-28 19:58:425878 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505879 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235880
5881 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5882 EXPECT_EQ(100, response->headers->GetContentLength());
5883 }
5884
5885 // ------------------------------------------------------------------------
5886
5887 // Transaction 4: request another URL in MyRealm (however the
5888 // url is not known to belong to the protection space, so no pre-auth).
5889 {
[email protected]1c773ea12009-04-28 19:58:425890 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235891 request.method = "GET";
5892 request.url = GURL("http://www.google.com/x/1");
5893 request.load_flags = 0;
5894
[email protected]262eec82013-03-19 21:01:365895 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505896 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275897
[email protected]f9ee6b52008-11-08 06:46:235898 MockWrite data_writes1[] = {
5899 MockWrite("GET /x/1 HTTP/1.1\r\n"
5900 "Host: www.google.com\r\n"
5901 "Connection: keep-alive\r\n\r\n"),
5902 };
5903
5904 MockRead data_reads1[] = {
5905 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5906 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5907 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065908 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235909 };
5910
5911 // Resend with authorization from MyRealm's cache.
5912 MockWrite data_writes2[] = {
5913 MockWrite("GET /x/1 HTTP/1.1\r\n"
5914 "Host: www.google.com\r\n"
5915 "Connection: keep-alive\r\n"
5916 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5917 };
5918
5919 // Sever accepts the authorization.
5920 MockRead data_reads2[] = {
5921 MockRead("HTTP/1.0 200 OK\r\n"),
5922 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065923 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235924 };
5925
[email protected]31a2bfe2010-02-09 08:03:395926 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5927 data_writes1, arraysize(data_writes1));
5928 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5929 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075930 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5931 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235932
[email protected]49639fa2011-12-20 23:22:415933 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235934
[email protected]49639fa2011-12-20 23:22:415935 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425936 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235937
5938 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425939 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235940
[email protected]0757e7702009-03-27 04:00:225941 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:415942 TestCompletionCallback callback2;
5943 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425944 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:225945 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425946 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225947 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5948
[email protected]1c773ea12009-04-28 19:58:425949 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505950 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235951 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5952 EXPECT_EQ(100, response->headers->GetContentLength());
5953 }
5954
5955 // ------------------------------------------------------------------------
5956
5957 // Transaction 5: request a URL in MyRealm, but the server rejects the
5958 // cached identity. Should invalidate and re-prompt.
5959 {
[email protected]1c773ea12009-04-28 19:58:425960 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235961 request.method = "GET";
5962 request.url = GURL("http://www.google.com/p/q/t");
5963 request.load_flags = 0;
5964
[email protected]262eec82013-03-19 21:01:365965 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505966 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275967
[email protected]f9ee6b52008-11-08 06:46:235968 MockWrite data_writes1[] = {
5969 MockWrite("GET /p/q/t HTTP/1.1\r\n"
5970 "Host: www.google.com\r\n"
5971 "Connection: keep-alive\r\n\r\n"),
5972 };
5973
5974 MockRead data_reads1[] = {
5975 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5976 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5977 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065978 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235979 };
5980
5981 // Resend with authorization from cache for MyRealm.
5982 MockWrite data_writes2[] = {
5983 MockWrite("GET /p/q/t HTTP/1.1\r\n"
5984 "Host: www.google.com\r\n"
5985 "Connection: keep-alive\r\n"
5986 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5987 };
5988
5989 // Sever rejects the authorization.
5990 MockRead data_reads2[] = {
5991 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5992 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5993 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065994 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235995 };
5996
5997 // At this point we should prompt for new credentials for MyRealm.
5998 // Restart with username=foo3, password=foo4.
5999 MockWrite data_writes3[] = {
6000 MockWrite("GET /p/q/t HTTP/1.1\r\n"
6001 "Host: www.google.com\r\n"
6002 "Connection: keep-alive\r\n"
6003 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
6004 };
6005
6006 // Sever accepts the authorization.
6007 MockRead data_reads3[] = {
6008 MockRead("HTTP/1.0 200 OK\r\n"),
6009 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066010 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:236011 };
6012
[email protected]31a2bfe2010-02-09 08:03:396013 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6014 data_writes1, arraysize(data_writes1));
6015 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6016 data_writes2, arraysize(data_writes2));
6017 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6018 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076019 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6020 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6021 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:236022
[email protected]49639fa2011-12-20 23:22:416023 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:236024
[email protected]49639fa2011-12-20 23:22:416025 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426026 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236027
6028 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426029 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236030
[email protected]0757e7702009-03-27 04:00:226031 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:416032 TestCompletionCallback callback2;
6033 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:426034 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:226035 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426036 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:226037 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6038
[email protected]1c773ea12009-04-28 19:58:426039 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506040 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:046041 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:236042
[email protected]49639fa2011-12-20 23:22:416043 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:236044
[email protected]49639fa2011-12-20 23:22:416045 rv = trans->RestartWithAuth(
6046 AuthCredentials(kFoo3, kBar3), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:426047 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236048
[email protected]0757e7702009-03-27 04:00:226049 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426050 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236051
6052 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506053 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:236054 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6055 EXPECT_EQ(100, response->headers->GetContentLength());
6056 }
6057}
[email protected]89ceba9a2009-03-21 03:46:066058
[email protected]3c32c5f2010-05-18 15:18:126059// Tests that nonce count increments when multiple auth attempts
6060// are started with the same nonce.
[email protected]23e482282013-06-14 16:08:026061TEST_P(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:446062 HttpAuthHandlerDigest::Factory* digest_factory =
6063 new HttpAuthHandlerDigest::Factory();
6064 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
6065 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
6066 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:076067 session_deps_.http_auth_handler_factory.reset(digest_factory);
6068 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:126069
6070 // Transaction 1: authenticate (foo, bar) on MyRealm1
6071 {
[email protected]3c32c5f2010-05-18 15:18:126072 HttpRequestInfo request;
6073 request.method = "GET";
6074 request.url = GURL("http://www.google.com/x/y/z");
6075 request.load_flags = 0;
6076
[email protected]262eec82013-03-19 21:01:366077 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506078 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276079
[email protected]3c32c5f2010-05-18 15:18:126080 MockWrite data_writes1[] = {
6081 MockWrite("GET /x/y/z HTTP/1.1\r\n"
6082 "Host: www.google.com\r\n"
6083 "Connection: keep-alive\r\n\r\n"),
6084 };
6085
6086 MockRead data_reads1[] = {
6087 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6088 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
6089 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066090 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:126091 };
6092
6093 // Resend with authorization (username=foo, password=bar)
6094 MockWrite data_writes2[] = {
6095 MockWrite("GET /x/y/z HTTP/1.1\r\n"
6096 "Host: www.google.com\r\n"
6097 "Connection: keep-alive\r\n"
6098 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
6099 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
6100 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
6101 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
6102 };
6103
6104 // Sever accepts the authorization.
6105 MockRead data_reads2[] = {
6106 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:066107 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:126108 };
6109
6110 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6111 data_writes1, arraysize(data_writes1));
6112 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6113 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076114 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6115 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:126116
[email protected]49639fa2011-12-20 23:22:416117 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:126118
[email protected]49639fa2011-12-20 23:22:416119 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:126120 EXPECT_EQ(ERR_IO_PENDING, rv);
6121
6122 rv = callback1.WaitForResult();
6123 EXPECT_EQ(OK, rv);
6124
6125 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506126 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:046127 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:126128
[email protected]49639fa2011-12-20 23:22:416129 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:126130
[email protected]49639fa2011-12-20 23:22:416131 rv = trans->RestartWithAuth(
6132 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]3c32c5f2010-05-18 15:18:126133 EXPECT_EQ(ERR_IO_PENDING, rv);
6134
6135 rv = callback2.WaitForResult();
6136 EXPECT_EQ(OK, rv);
6137
6138 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506139 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:126140 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6141 }
6142
6143 // ------------------------------------------------------------------------
6144
6145 // Transaction 2: Request another resource in digestive's protection space.
6146 // This will preemptively add an Authorization header which should have an
6147 // "nc" value of 2 (as compared to 1 in the first use.
6148 {
[email protected]3c32c5f2010-05-18 15:18:126149 HttpRequestInfo request;
6150 request.method = "GET";
6151 // Note that Transaction 1 was at /x/y/z, so this is in the same
6152 // protection space as digest.
6153 request.url = GURL("http://www.google.com/x/y/a/b");
6154 request.load_flags = 0;
6155
[email protected]262eec82013-03-19 21:01:366156 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506157 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276158
[email protected]3c32c5f2010-05-18 15:18:126159 MockWrite data_writes1[] = {
6160 MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
6161 "Host: www.google.com\r\n"
6162 "Connection: keep-alive\r\n"
6163 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
6164 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
6165 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
6166 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
6167 };
6168
6169 // Sever accepts the authorization.
6170 MockRead data_reads1[] = {
6171 MockRead("HTTP/1.0 200 OK\r\n"),
6172 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066173 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:126174 };
6175
6176 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6177 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:076178 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:126179
[email protected]49639fa2011-12-20 23:22:416180 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:126181
[email protected]49639fa2011-12-20 23:22:416182 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:126183 EXPECT_EQ(ERR_IO_PENDING, rv);
6184
6185 rv = callback1.WaitForResult();
6186 EXPECT_EQ(OK, rv);
6187
6188 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506189 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:126190 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6191 }
6192}
6193
[email protected]89ceba9a2009-03-21 03:46:066194// Test the ResetStateForRestart() private method.
[email protected]23e482282013-06-14 16:08:026195TEST_P(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:066196 // Create a transaction (the dependencies aren't important).
[email protected]3fe8d2f82013-10-17 08:56:076197 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:406198 scoped_ptr<HttpNetworkTransaction> trans(
dcheng48459ac22014-08-26 00:46:416199 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]89ceba9a2009-03-21 03:46:066200
6201 // Setup some state (which we expect ResetStateForRestart() will clear).
[email protected]89ceba9a2009-03-21 03:46:066202 trans->read_buf_ = new IOBuffer(15);
6203 trans->read_buf_len_ = 15;
[email protected]b94f92d2010-10-27 16:45:206204 trans->request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:066205
6206 // Setup state in response_
[email protected]a7e41312009-12-16 23:18:146207 HttpResponseInfo* response = &trans->response_;
[email protected]0877e3d2009-10-17 22:29:576208 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:086209 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:576210 response->response_time = base::Time::Now();
6211 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:066212
6213 { // Setup state for response_.vary_data
6214 HttpRequestInfo request;
6215 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
6216 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:276217 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:436218 request.extra_headers.SetHeader("Foo", "1");
6219 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:506220 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:066221 }
6222
6223 // Cause the above state to be reset.
6224 trans->ResetStateForRestart();
6225
6226 // Verify that the state that needed to be reset, has been reset.
[email protected]9b6fee12009-09-29 18:13:076227 EXPECT_TRUE(trans->read_buf_.get() == NULL);
[email protected]89ceba9a2009-03-21 03:46:066228 EXPECT_EQ(0, trans->read_buf_len_);
[email protected]b94f92d2010-10-27 16:45:206229 EXPECT_TRUE(trans->request_headers_.IsEmpty());
[email protected]0877e3d2009-10-17 22:29:576230 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6231 EXPECT_TRUE(response->headers.get() == NULL);
[email protected]34f40942010-10-04 00:34:046232 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:086233 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:576234 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:066235}
6236
[email protected]bacff652009-03-31 17:50:336237// Test HTTPS connections to a site with a bad certificate
[email protected]23e482282013-06-14 16:08:026238TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:336239 HttpRequestInfo request;
6240 request.method = "GET";
6241 request.url = GURL("https://www.google.com/");
6242 request.load_flags = 0;
6243
[email protected]3fe8d2f82013-10-17 08:56:076244 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276245 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416246 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276247
[email protected]bacff652009-03-31 17:50:336248 MockWrite data_writes[] = {
6249 MockWrite("GET / HTTP/1.1\r\n"
6250 "Host: www.google.com\r\n"
6251 "Connection: keep-alive\r\n\r\n"),
6252 };
6253
6254 MockRead data_reads[] = {
6255 MockRead("HTTP/1.0 200 OK\r\n"),
6256 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6257 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066258 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:336259 };
6260
[email protected]5ecc992a42009-11-11 01:41:596261 StaticSocketDataProvider ssl_bad_certificate;
[email protected]31a2bfe2010-02-09 08:03:396262 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6263 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066264 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
6265 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:336266
[email protected]bb88e1d32013-05-03 23:11:076267 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
6268 session_deps_.socket_factory->AddSocketDataProvider(&data);
6269 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
6270 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:336271
[email protected]49639fa2011-12-20 23:22:416272 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:336273
[email protected]49639fa2011-12-20 23:22:416274 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:336275 EXPECT_EQ(ERR_IO_PENDING, rv);
6276
6277 rv = callback.WaitForResult();
6278 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
6279
[email protected]49639fa2011-12-20 23:22:416280 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:336281 EXPECT_EQ(ERR_IO_PENDING, rv);
6282
6283 rv = callback.WaitForResult();
6284 EXPECT_EQ(OK, rv);
6285
6286 const HttpResponseInfo* response = trans->GetResponseInfo();
6287
[email protected]fe2255a2011-09-20 19:37:506288 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:336289 EXPECT_EQ(100, response->headers->GetContentLength());
6290}
6291
6292// Test HTTPS connections to a site with a bad certificate, going through a
6293// proxy
[email protected]23e482282013-06-14 16:08:026294TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
[email protected]bb88e1d32013-05-03 23:11:076295 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]bacff652009-03-31 17:50:336296
6297 HttpRequestInfo request;
6298 request.method = "GET";
6299 request.url = GURL("https://www.google.com/");
6300 request.load_flags = 0;
6301
6302 MockWrite proxy_writes[] = {
6303 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:456304 "Host: www.google.com\r\n"
6305 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:336306 };
6307
6308 MockRead proxy_reads[] = {
6309 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066310 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:336311 };
6312
6313 MockWrite data_writes[] = {
6314 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:456315 "Host: www.google.com\r\n"
6316 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:336317 MockWrite("GET / HTTP/1.1\r\n"
6318 "Host: www.google.com\r\n"
6319 "Connection: keep-alive\r\n\r\n"),
6320 };
6321
6322 MockRead data_reads[] = {
6323 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
6324 MockRead("HTTP/1.0 200 OK\r\n"),
6325 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6326 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066327 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:336328 };
6329
[email protected]31a2bfe2010-02-09 08:03:396330 StaticSocketDataProvider ssl_bad_certificate(
6331 proxy_reads, arraysize(proxy_reads),
6332 proxy_writes, arraysize(proxy_writes));
6333 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6334 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066335 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
6336 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:336337
[email protected]bb88e1d32013-05-03 23:11:076338 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
6339 session_deps_.socket_factory->AddSocketDataProvider(&data);
6340 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
6341 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:336342
[email protected]49639fa2011-12-20 23:22:416343 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:336344
6345 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:076346 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:336347
[email protected]3fe8d2f82013-10-17 08:56:076348 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:406349 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416350 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bacff652009-03-31 17:50:336351
[email protected]49639fa2011-12-20 23:22:416352 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:336353 EXPECT_EQ(ERR_IO_PENDING, rv);
6354
6355 rv = callback.WaitForResult();
6356 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
6357
[email protected]49639fa2011-12-20 23:22:416358 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:336359 EXPECT_EQ(ERR_IO_PENDING, rv);
6360
6361 rv = callback.WaitForResult();
6362 EXPECT_EQ(OK, rv);
6363
6364 const HttpResponseInfo* response = trans->GetResponseInfo();
6365
[email protected]fe2255a2011-09-20 19:37:506366 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:336367 EXPECT_EQ(100, response->headers->GetContentLength());
6368 }
6369}
6370
[email protected]2df19bb2010-08-25 20:13:466371
6372// Test HTTPS connections to a site, going through an HTTPS proxy
[email protected]23e482282013-06-14 16:08:026373TEST_P(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076374 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206375 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
6376 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076377 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:466378
6379 HttpRequestInfo request;
6380 request.method = "GET";
6381 request.url = GURL("https://www.google.com/");
6382 request.load_flags = 0;
6383
6384 MockWrite data_writes[] = {
6385 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6386 "Host: www.google.com\r\n"
6387 "Proxy-Connection: keep-alive\r\n\r\n"),
6388 MockWrite("GET / HTTP/1.1\r\n"
6389 "Host: www.google.com\r\n"
6390 "Connection: keep-alive\r\n\r\n"),
6391 };
6392
6393 MockRead data_reads[] = {
6394 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
6395 MockRead("HTTP/1.1 200 OK\r\n"),
6396 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6397 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066398 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:466399 };
6400
6401 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6402 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066403 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
6404 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:466405
[email protected]bb88e1d32013-05-03 23:11:076406 session_deps_.socket_factory->AddSocketDataProvider(&data);
6407 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
6408 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:466409
[email protected]49639fa2011-12-20 23:22:416410 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:466411
[email protected]3fe8d2f82013-10-17 08:56:076412 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:466413 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416414 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2df19bb2010-08-25 20:13:466415
[email protected]49639fa2011-12-20 23:22:416416 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:466417 EXPECT_EQ(ERR_IO_PENDING, rv);
6418
6419 rv = callback.WaitForResult();
6420 EXPECT_EQ(OK, rv);
6421 const HttpResponseInfo* response = trans->GetResponseInfo();
6422
[email protected]fe2255a2011-09-20 19:37:506423 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:466424
6425 EXPECT_TRUE(response->headers->IsKeepAlive());
6426 EXPECT_EQ(200, response->headers->response_code());
6427 EXPECT_EQ(100, response->headers->GetContentLength());
6428 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:206429
6430 LoadTimingInfo load_timing_info;
6431 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6432 TestLoadTimingNotReusedWithPac(load_timing_info,
6433 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:466434}
6435
[email protected]511f6f52010-12-17 03:58:296436// Test an HTTPS Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:026437TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076438 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206439 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
6440 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076441 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:296442
6443 HttpRequestInfo request;
6444 request.method = "GET";
6445 request.url = GURL("https://www.google.com/");
6446 request.load_flags = 0;
6447
6448 MockWrite data_writes[] = {
6449 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6450 "Host: www.google.com\r\n"
6451 "Proxy-Connection: keep-alive\r\n\r\n"),
6452 };
6453
6454 MockRead data_reads[] = {
6455 MockRead("HTTP/1.1 302 Redirect\r\n"),
6456 MockRead("Location: http://login.example.com/\r\n"),
6457 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066458 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:296459 };
6460
6461 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6462 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066463 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:296464
[email protected]bb88e1d32013-05-03 23:11:076465 session_deps_.socket_factory->AddSocketDataProvider(&data);
6466 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296467
[email protected]49639fa2011-12-20 23:22:416468 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296469
[email protected]3fe8d2f82013-10-17 08:56:076470 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296471 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416472 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:296473
[email protected]49639fa2011-12-20 23:22:416474 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296475 EXPECT_EQ(ERR_IO_PENDING, rv);
6476
6477 rv = callback.WaitForResult();
6478 EXPECT_EQ(OK, rv);
6479 const HttpResponseInfo* response = trans->GetResponseInfo();
6480
[email protected]fe2255a2011-09-20 19:37:506481 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:296482
6483 EXPECT_EQ(302, response->headers->response_code());
6484 std::string url;
6485 EXPECT_TRUE(response->headers->IsRedirect(&url));
6486 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:206487
6488 // In the case of redirects from proxies, HttpNetworkTransaction returns
6489 // timing for the proxy connection instead of the connection to the host,
6490 // and no send / receive times.
6491 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
6492 LoadTimingInfo load_timing_info;
6493 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6494
6495 EXPECT_FALSE(load_timing_info.socket_reused);
6496 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
6497
6498 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
6499 EXPECT_LE(load_timing_info.proxy_resolve_start,
6500 load_timing_info.proxy_resolve_end);
6501 EXPECT_LE(load_timing_info.proxy_resolve_end,
6502 load_timing_info.connect_timing.connect_start);
6503 ExpectConnectTimingHasTimes(
6504 load_timing_info.connect_timing,
6505 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
6506
6507 EXPECT_TRUE(load_timing_info.send_start.is_null());
6508 EXPECT_TRUE(load_timing_info.send_end.is_null());
6509 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:296510}
6511
6512// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:026513TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
[email protected]bb88e1d32013-05-03 23:11:076514 session_deps_.proxy_service.reset(
[email protected]511f6f52010-12-17 03:58:296515 ProxyService::CreateFixed("https://proxy:70"));
6516
6517 HttpRequestInfo request;
6518 request.method = "GET";
6519 request.url = GURL("https://www.google.com/");
6520 request.load_flags = 0;
6521
lgarrona91df87f2014-12-05 00:51:346522 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(
6523 NULL, 0, 1, LOWEST, HostPortPair("www.google.com", 443)));
[email protected]c10b20852013-05-15 21:29:206524 scoped_ptr<SpdyFrame> goaway(
6525 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:296526 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:066527 CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
[email protected]57d2dfa2013-06-24 06:04:126528 CreateMockWrite(*goaway.get(), 3, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:296529 };
6530
6531 static const char* const kExtraHeaders[] = {
6532 "location",
6533 "http://login.example.com/",
6534 };
[email protected]ff98d7f02012-03-22 21:44:196535 scoped_ptr<SpdyFrame> resp(
[email protected]23e482282013-06-14 16:08:026536 spdy_util_.ConstructSpdySynReplyError("302 Redirect", kExtraHeaders,
[email protected]511f6f52010-12-17 03:58:296537 arraysize(kExtraHeaders)/2, 1));
6538 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:066539 CreateMockRead(*resp.get(), 1, SYNCHRONOUS),
6540 MockRead(ASYNC, 0, 2), // EOF
[email protected]511f6f52010-12-17 03:58:296541 };
6542
[email protected]dd54bd82012-07-19 23:44:576543 DelayedSocketData data(
6544 1, // wait for one write to finish before reading.
6545 data_reads, arraysize(data_reads),
6546 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066547 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]23e482282013-06-14 16:08:026548 proxy_ssl.SetNextProto(GetParam());
[email protected]511f6f52010-12-17 03:58:296549
[email protected]bb88e1d32013-05-03 23:11:076550 session_deps_.socket_factory->AddSocketDataProvider(&data);
6551 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296552
[email protected]49639fa2011-12-20 23:22:416553 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296554
[email protected]3fe8d2f82013-10-17 08:56:076555 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296556 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416557 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:296558
[email protected]49639fa2011-12-20 23:22:416559 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296560 EXPECT_EQ(ERR_IO_PENDING, rv);
6561
6562 rv = callback.WaitForResult();
6563 EXPECT_EQ(OK, rv);
6564 const HttpResponseInfo* response = trans->GetResponseInfo();
6565
[email protected]fe2255a2011-09-20 19:37:506566 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:296567
6568 EXPECT_EQ(302, response->headers->response_code());
6569 std::string url;
6570 EXPECT_TRUE(response->headers->IsRedirect(&url));
6571 EXPECT_EQ("http://login.example.com/", url);
6572}
6573
[email protected]4eddbc732012-08-09 05:40:176574// Test that an HTTPS proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:026575TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:176576 ErrorResponseToHttpsConnectViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076577 session_deps_.proxy_service.reset(
[email protected]511f6f52010-12-17 03:58:296578 ProxyService::CreateFixed("https://proxy:70"));
6579
6580 HttpRequestInfo request;
6581 request.method = "GET";
6582 request.url = GURL("https://www.google.com/");
6583 request.load_flags = 0;
6584
6585 MockWrite data_writes[] = {
6586 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6587 "Host: www.google.com\r\n"
6588 "Proxy-Connection: keep-alive\r\n\r\n"),
6589 };
6590
6591 MockRead data_reads[] = {
6592 MockRead("HTTP/1.1 404 Not Found\r\n"),
6593 MockRead("Content-Length: 23\r\n\r\n"),
6594 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:066595 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:296596 };
6597
6598 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6599 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066600 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:296601
[email protected]bb88e1d32013-05-03 23:11:076602 session_deps_.socket_factory->AddSocketDataProvider(&data);
6603 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296604
[email protected]49639fa2011-12-20 23:22:416605 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296606
[email protected]3fe8d2f82013-10-17 08:56:076607 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296608 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416609 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:296610
[email protected]49639fa2011-12-20 23:22:416611 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296612 EXPECT_EQ(ERR_IO_PENDING, rv);
6613
6614 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:176615 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:296616
[email protected]4eddbc732012-08-09 05:40:176617 // TODO(ttuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:296618}
6619
[email protected]4eddbc732012-08-09 05:40:176620// Test that a SPDY proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:026621TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:176622 ErrorResponseToHttpsConnectViaSpdyProxy) {
[email protected]bb88e1d32013-05-03 23:11:076623 session_deps_.proxy_service.reset(
6624 ProxyService::CreateFixed("https://proxy:70"));
[email protected]511f6f52010-12-17 03:58:296625
6626 HttpRequestInfo request;
6627 request.method = "GET";
6628 request.url = GURL("https://www.google.com/");
6629 request.load_flags = 0;
6630
lgarrona91df87f2014-12-05 00:51:346631 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(
6632 NULL, 0, 1, LOWEST, HostPortPair("www.google.com", 443)));
[email protected]c10b20852013-05-15 21:29:206633 scoped_ptr<SpdyFrame> rst(
6634 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:296635 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:066636 CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
[email protected]4eddbc732012-08-09 05:40:176637 CreateMockWrite(*rst.get(), 3, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:296638 };
6639
6640 static const char* const kExtraHeaders[] = {
6641 "location",
6642 "http://login.example.com/",
6643 };
[email protected]ff98d7f02012-03-22 21:44:196644 scoped_ptr<SpdyFrame> resp(
[email protected]23e482282013-06-14 16:08:026645 spdy_util_.ConstructSpdySynReplyError("404 Not Found", kExtraHeaders,
[email protected]511f6f52010-12-17 03:58:296646 arraysize(kExtraHeaders)/2, 1));
[email protected]ff98d7f02012-03-22 21:44:196647 scoped_ptr<SpdyFrame> body(
[email protected]23e482282013-06-14 16:08:026648 spdy_util_.ConstructSpdyBodyFrame(
6649 1, "The host does not exist", 23, true));
[email protected]511f6f52010-12-17 03:58:296650 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:066651 CreateMockRead(*resp.get(), 1, SYNCHRONOUS),
6652 CreateMockRead(*body.get(), 2, SYNCHRONOUS),
[email protected]4eddbc732012-08-09 05:40:176653 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:296654 };
6655
[email protected]dd54bd82012-07-19 23:44:576656 DelayedSocketData data(
6657 1, // wait for one write to finish before reading.
6658 data_reads, arraysize(data_reads),
6659 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066660 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]23e482282013-06-14 16:08:026661 proxy_ssl.SetNextProto(GetParam());
[email protected]511f6f52010-12-17 03:58:296662
[email protected]bb88e1d32013-05-03 23:11:076663 session_deps_.socket_factory->AddSocketDataProvider(&data);
6664 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296665
[email protected]49639fa2011-12-20 23:22:416666 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296667
[email protected]3fe8d2f82013-10-17 08:56:076668 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296669 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416670 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:296671
[email protected]49639fa2011-12-20 23:22:416672 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296673 EXPECT_EQ(ERR_IO_PENDING, rv);
6674
6675 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:176676 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:296677
[email protected]4eddbc732012-08-09 05:40:176678 // TODO(ttuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:296679}
6680
[email protected]0c5fb722012-02-28 11:50:356681// Test the request-challenge-retry sequence for basic auth, through
6682// a SPDY proxy over a single SPDY session.
[email protected]23e482282013-06-14 16:08:026683TEST_P(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:356684 HttpRequestInfo request;
6685 request.method = "GET";
6686 request.url = GURL("https://www.google.com/");
6687 // when the no authentication data flag is set.
6688 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
6689
6690 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076691 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206692 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
[email protected]333bdf62012-06-08 22:57:296693 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076694 session_deps_.net_log = log.bound().net_log();
6695 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:356696
6697 // Since we have proxy, should try to establish tunnel.
lgarrona91df87f2014-12-05 00:51:346698 scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyConnect(
6699 NULL, 0, 1, LOWEST, HostPortPair("www.google.com", 443)));
[email protected]c10b20852013-05-15 21:29:206700 scoped_ptr<SpdyFrame> rst(
6701 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]0c5fb722012-02-28 11:50:356702
6703 // After calling trans->RestartWithAuth(), this is the request we should
6704 // be issuing -- the final header line contains the credentials.
6705 const char* const kAuthCredentials[] = {
6706 "proxy-authorization", "Basic Zm9vOmJhcg==",
6707 };
[email protected]fba2dbde2013-05-24 16:09:016708 scoped_ptr<SpdyFrame> connect2(spdy_util_.ConstructSpdyConnect(
lgarrona91df87f2014-12-05 00:51:346709 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST,
6710 HostPortPair("www.google.com", 443)));
[email protected]0c5fb722012-02-28 11:50:356711 // fetch https://www.google.com/ via HTTP
6712 const char get[] = "GET / HTTP/1.1\r\n"
6713 "Host: www.google.com\r\n"
6714 "Connection: keep-alive\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:196715 scoped_ptr<SpdyFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:026716 spdy_util_.ConstructSpdyBodyFrame(3, get, strlen(get), false));
[email protected]0c5fb722012-02-28 11:50:356717
6718 MockWrite spdy_writes[] = {
[email protected]3d7c43f2012-07-10 21:26:206719 CreateMockWrite(*req, 1, ASYNC),
[email protected]c92f4b4542012-07-26 23:53:216720 CreateMockWrite(*rst, 4, ASYNC),
6721 CreateMockWrite(*connect2, 5),
[email protected]3d7c43f2012-07-10 21:26:206722 CreateMockWrite(*wrapped_get, 8),
[email protected]0c5fb722012-02-28 11:50:356723 };
6724
6725 // The proxy responds to the connect with a 407, using a persistent
6726 // connection.
thestig9d3bb0c2015-01-24 00:49:516727 const char kAuthStatus[] = "407";
[email protected]0c5fb722012-02-28 11:50:356728 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:356729 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
6730 };
[email protected]745aa9c2014-06-27 02:21:296731 scoped_ptr<SpdyFrame> conn_auth_resp(spdy_util_.ConstructSpdySynReplyError(
6732 kAuthStatus, kAuthChallenge, arraysize(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:356733
[email protected]23e482282013-06-14 16:08:026734 scoped_ptr<SpdyFrame> conn_resp(
6735 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:356736 const char resp[] = "HTTP/1.1 200 OK\r\n"
6737 "Content-Length: 5\r\n\r\n";
6738
[email protected]ff98d7f02012-03-22 21:44:196739 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:026740 spdy_util_.ConstructSpdyBodyFrame(3, resp, strlen(resp), false));
[email protected]ff98d7f02012-03-22 21:44:196741 scoped_ptr<SpdyFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:026742 spdy_util_.ConstructSpdyBodyFrame(3, "hello", 5, false));
[email protected]0c5fb722012-02-28 11:50:356743 MockRead spdy_reads[] = {
[email protected]3d7c43f2012-07-10 21:26:206744 CreateMockRead(*conn_auth_resp, 2, ASYNC),
6745 CreateMockRead(*conn_resp, 6, ASYNC),
6746 CreateMockRead(*wrapped_get_resp, 9, ASYNC),
6747 CreateMockRead(*wrapped_body, 10, ASYNC),
6748 MockRead(ASYNC, OK, 11), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:356749 };
6750
[email protected]dd54bd82012-07-19 23:44:576751 OrderedSocketData spdy_data(
6752 spdy_reads, arraysize(spdy_reads),
6753 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:076754 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:356755 // Negotiate SPDY to the proxy
6756 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:026757 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:076758 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:356759 // Vanilla SSL to the server
6760 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076761 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:356762
6763 TestCompletionCallback callback1;
6764
[email protected]262eec82013-03-19 21:01:366765 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506766 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0c5fb722012-02-28 11:50:356767
6768 int rv = trans->Start(&request, callback1.callback(), log.bound());
6769 EXPECT_EQ(ERR_IO_PENDING, rv);
6770
6771 rv = callback1.WaitForResult();
6772 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:576773 net::CapturingNetLog::CapturedEntryList entries;
[email protected]0c5fb722012-02-28 11:50:356774 log.GetEntries(&entries);
6775 size_t pos = ExpectLogContainsSomewhere(
6776 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
6777 NetLog::PHASE_NONE);
6778 ExpectLogContainsSomewhere(
6779 entries, pos,
6780 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
6781 NetLog::PHASE_NONE);
6782
6783 const HttpResponseInfo* response = trans->GetResponseInfo();
6784 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:506785 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]0c5fb722012-02-28 11:50:356786 EXPECT_EQ(407, response->headers->response_code());
6787 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6788 EXPECT_TRUE(response->auth_challenge.get() != NULL);
6789 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
6790
6791 TestCompletionCallback callback2;
6792
6793 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
6794 callback2.callback());
6795 EXPECT_EQ(ERR_IO_PENDING, rv);
6796
6797 rv = callback2.WaitForResult();
6798 EXPECT_EQ(OK, rv);
6799
6800 response = trans->GetResponseInfo();
6801 ASSERT_TRUE(response != NULL);
6802
6803 EXPECT_TRUE(response->headers->IsKeepAlive());
6804 EXPECT_EQ(200, response->headers->response_code());
6805 EXPECT_EQ(5, response->headers->GetContentLength());
6806 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6807
6808 // The password prompt info should not be set.
6809 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6810
[email protected]029c83b62013-01-24 05:28:206811 LoadTimingInfo load_timing_info;
6812 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6813 TestLoadTimingNotReusedWithPac(load_timing_info,
6814 CONNECT_TIMING_HAS_SSL_TIMES);
6815
[email protected]0c5fb722012-02-28 11:50:356816 trans.reset();
6817 session->CloseAllConnections();
6818}
6819
[email protected]7c6f7ba2012-04-03 04:09:296820// Test that an explicitly trusted SPDY proxy can push a resource from an
6821// origin that is different from that of its associated resource.
[email protected]23e482282013-06-14 16:08:026822TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPush) {
[email protected]7c6f7ba2012-04-03 04:09:296823 HttpRequestInfo request;
6824 HttpRequestInfo push_request;
6825
[email protected]7c6f7ba2012-04-03 04:09:296826 request.method = "GET";
6827 request.url = GURL("http://www.google.com/");
6828 push_request.method = "GET";
6829 push_request.url = GURL("http://www.another-origin.com/foo.dat");
6830
[email protected]7c6f7ba2012-04-03 04:09:296831 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076832 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206833 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
[email protected]333bdf62012-06-08 22:57:296834 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076835 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:506836
6837 // Enable cross-origin push.
[email protected]bb88e1d32013-05-03 23:11:076838 session_deps_.trusted_spdy_proxy = "myproxy:70";
[email protected]61b4efc2012-04-27 18:12:506839
[email protected]bb88e1d32013-05-03 23:11:076840 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:296841
[email protected]cdf8f7e72013-05-23 10:56:466842 scoped_ptr<SpdyFrame> stream1_syn(
6843 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]7c6f7ba2012-04-03 04:09:296844
6845 MockWrite spdy_writes[] = {
[email protected]cdf8f7e72013-05-23 10:56:466846 CreateMockWrite(*stream1_syn, 1, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:296847 };
6848
6849 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026850 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:296851
6852 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026853 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:296854
6855 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026856 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
[email protected]7c6f7ba2012-04-03 04:09:296857 0,
6858 2,
6859 1,
6860 "http://www.another-origin.com/foo.dat"));
[email protected]8a0fc822013-06-27 20:52:436861 const char kPushedData[] = "pushed";
6862 scoped_ptr<SpdyFrame> stream2_body(
6863 spdy_util_.ConstructSpdyBodyFrame(
6864 2, kPushedData, strlen(kPushedData), true));
[email protected]7c6f7ba2012-04-03 04:09:296865
6866 MockRead spdy_reads[] = {
6867 CreateMockRead(*stream1_reply, 2, ASYNC),
6868 CreateMockRead(*stream2_syn, 3, ASYNC),
6869 CreateMockRead(*stream1_body, 4, ASYNC),
[email protected]8a0fc822013-06-27 20:52:436870 CreateMockRead(*stream2_body, 5, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:296871 MockRead(ASYNC, ERR_IO_PENDING, 6), // Force a pause
6872 };
6873
[email protected]dd54bd82012-07-19 23:44:576874 OrderedSocketData spdy_data(
6875 spdy_reads, arraysize(spdy_reads),
6876 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:076877 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:296878 // Negotiate SPDY to the proxy
6879 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:026880 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:076881 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:296882
[email protected]262eec82013-03-19 21:01:366883 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506884 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7c6f7ba2012-04-03 04:09:296885 TestCompletionCallback callback;
6886 int rv = trans->Start(&request, callback.callback(), log.bound());
6887 EXPECT_EQ(ERR_IO_PENDING, rv);
6888
6889 rv = callback.WaitForResult();
6890 EXPECT_EQ(OK, rv);
6891 const HttpResponseInfo* response = trans->GetResponseInfo();
6892
[email protected]262eec82013-03-19 21:01:366893 scoped_ptr<HttpTransaction> push_trans(
[email protected]90499482013-06-01 00:39:506894 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
6895 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
[email protected]7c6f7ba2012-04-03 04:09:296896 EXPECT_EQ(ERR_IO_PENDING, rv);
6897
6898 rv = callback.WaitForResult();
6899 EXPECT_EQ(OK, rv);
6900 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
6901
6902 ASSERT_TRUE(response != NULL);
6903 EXPECT_TRUE(response->headers->IsKeepAlive());
6904
6905 EXPECT_EQ(200, response->headers->response_code());
6906 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6907
6908 std::string response_data;
6909 rv = ReadTransaction(trans.get(), &response_data);
6910 EXPECT_EQ(OK, rv);
6911 EXPECT_EQ("hello!", response_data);
6912
[email protected]029c83b62013-01-24 05:28:206913 LoadTimingInfo load_timing_info;
6914 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6915 TestLoadTimingNotReusedWithPac(load_timing_info,
6916 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6917
[email protected]7c6f7ba2012-04-03 04:09:296918 // Verify the pushed stream.
[email protected]90499482013-06-01 00:39:506919 EXPECT_TRUE(push_response->headers.get() != NULL);
[email protected]7c6f7ba2012-04-03 04:09:296920 EXPECT_EQ(200, push_response->headers->response_code());
6921
6922 rv = ReadTransaction(push_trans.get(), &response_data);
6923 EXPECT_EQ(OK, rv);
6924 EXPECT_EQ("pushed", response_data);
6925
[email protected]029c83b62013-01-24 05:28:206926 LoadTimingInfo push_load_timing_info;
6927 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
6928 TestLoadTimingReusedWithPac(push_load_timing_info);
6929 // The transactions should share a socket ID, despite being for different
6930 // origins.
6931 EXPECT_EQ(load_timing_info.socket_log_id,
6932 push_load_timing_info.socket_log_id);
6933
[email protected]7c6f7ba2012-04-03 04:09:296934 trans.reset();
6935 push_trans.reset();
6936 session->CloseAllConnections();
6937}
6938
[email protected]8c843192012-04-05 07:15:006939// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
[email protected]23e482282013-06-14 16:08:026940TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
[email protected]8c843192012-04-05 07:15:006941 HttpRequestInfo request;
6942
6943 request.method = "GET";
6944 request.url = GURL("http://www.google.com/");
6945
[email protected]8c843192012-04-05 07:15:006946 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076947 session_deps_.proxy_service.reset(
[email protected]8c843192012-04-05 07:15:006948 ProxyService::CreateFixed("https://myproxy:70"));
[email protected]333bdf62012-06-08 22:57:296949 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076950 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:506951
6952 // Enable cross-origin push.
[email protected]bb88e1d32013-05-03 23:11:076953 session_deps_.trusted_spdy_proxy = "myproxy:70";
[email protected]61b4efc2012-04-27 18:12:506954
[email protected]bb88e1d32013-05-03 23:11:076955 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:006956
[email protected]cdf8f7e72013-05-23 10:56:466957 scoped_ptr<SpdyFrame> stream1_syn(
6958 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]8c843192012-04-05 07:15:006959
6960 scoped_ptr<SpdyFrame> push_rst(
[email protected]c10b20852013-05-15 21:29:206961 spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:006962
6963 MockWrite spdy_writes[] = {
6964 CreateMockWrite(*stream1_syn, 1, ASYNC),
6965 CreateMockWrite(*push_rst, 4),
6966 };
6967
6968 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026969 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:006970
6971 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026972 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8c843192012-04-05 07:15:006973
6974 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026975 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
[email protected]8c843192012-04-05 07:15:006976 0,
6977 2,
6978 1,
6979 "https://www.another-origin.com/foo.dat"));
6980
6981 MockRead spdy_reads[] = {
6982 CreateMockRead(*stream1_reply, 2, ASYNC),
6983 CreateMockRead(*stream2_syn, 3, ASYNC),
6984 CreateMockRead(*stream1_body, 5, ASYNC),
6985 MockRead(ASYNC, ERR_IO_PENDING, 6), // Force a pause
6986 };
6987
[email protected]dd54bd82012-07-19 23:44:576988 OrderedSocketData spdy_data(
6989 spdy_reads, arraysize(spdy_reads),
6990 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:076991 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:006992 // Negotiate SPDY to the proxy
6993 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:026994 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:076995 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:006996
[email protected]262eec82013-03-19 21:01:366997 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506998 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c843192012-04-05 07:15:006999 TestCompletionCallback callback;
7000 int rv = trans->Start(&request, callback.callback(), log.bound());
7001 EXPECT_EQ(ERR_IO_PENDING, rv);
7002
7003 rv = callback.WaitForResult();
7004 EXPECT_EQ(OK, rv);
7005 const HttpResponseInfo* response = trans->GetResponseInfo();
7006
7007 ASSERT_TRUE(response != NULL);
7008 EXPECT_TRUE(response->headers->IsKeepAlive());
7009
7010 EXPECT_EQ(200, response->headers->response_code());
7011 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
7012
7013 std::string response_data;
7014 rv = ReadTransaction(trans.get(), &response_data);
7015 EXPECT_EQ(OK, rv);
7016 EXPECT_EQ("hello!", response_data);
7017
7018 trans.reset();
7019 session->CloseAllConnections();
7020}
7021
[email protected]2df19bb2010-08-25 20:13:467022// Test HTTPS connections to a site with a bad certificate, going through an
7023// HTTPS proxy
[email protected]23e482282013-06-14 16:08:027024TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:077025 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:117026 "https://proxy:70"));
[email protected]2df19bb2010-08-25 20:13:467027
7028 HttpRequestInfo request;
7029 request.method = "GET";
7030 request.url = GURL("https://www.google.com/");
7031 request.load_flags = 0;
7032
7033 // Attempt to fetch the URL from a server with a bad cert
7034 MockWrite bad_cert_writes[] = {
7035 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
7036 "Host: www.google.com\r\n"
7037 "Proxy-Connection: keep-alive\r\n\r\n"),
7038 };
7039
7040 MockRead bad_cert_reads[] = {
7041 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067042 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:467043 };
7044
7045 // Attempt to fetch the URL with a good cert
7046 MockWrite good_data_writes[] = {
7047 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
7048 "Host: www.google.com\r\n"
7049 "Proxy-Connection: keep-alive\r\n\r\n"),
7050 MockWrite("GET / HTTP/1.1\r\n"
7051 "Host: www.google.com\r\n"
7052 "Connection: keep-alive\r\n\r\n"),
7053 };
7054
7055 MockRead good_cert_reads[] = {
7056 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
7057 MockRead("HTTP/1.0 200 OK\r\n"),
7058 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7059 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067060 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:467061 };
7062
7063 StaticSocketDataProvider ssl_bad_certificate(
7064 bad_cert_reads, arraysize(bad_cert_reads),
7065 bad_cert_writes, arraysize(bad_cert_writes));
7066 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
7067 good_data_writes, arraysize(good_data_writes));
[email protected]8ddf8322012-02-23 18:08:067068 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
7069 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:467070
7071 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:077072 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7073 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
7074 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:467075
7076 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:077077 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7078 session_deps_.socket_factory->AddSocketDataProvider(&data);
7079 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:467080
[email protected]49639fa2011-12-20 23:22:417081 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:467082
[email protected]3fe8d2f82013-10-17 08:56:077083 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:467084 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417085 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2df19bb2010-08-25 20:13:467086
[email protected]49639fa2011-12-20 23:22:417087 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:467088 EXPECT_EQ(ERR_IO_PENDING, rv);
7089
7090 rv = callback.WaitForResult();
7091 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
7092
[email protected]49639fa2011-12-20 23:22:417093 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]2df19bb2010-08-25 20:13:467094 EXPECT_EQ(ERR_IO_PENDING, rv);
7095
7096 rv = callback.WaitForResult();
7097 EXPECT_EQ(OK, rv);
7098
7099 const HttpResponseInfo* response = trans->GetResponseInfo();
7100
[email protected]fe2255a2011-09-20 19:37:507101 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:467102 EXPECT_EQ(100, response->headers->GetContentLength());
7103}
7104
[email protected]23e482282013-06-14 16:08:027105TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:427106 HttpRequestInfo request;
7107 request.method = "GET";
7108 request.url = GURL("http://www.google.com/");
[email protected]8c76ae22010-04-20 22:15:437109 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
7110 "Chromium Ultra Awesome X Edition");
[email protected]1c773ea12009-04-28 19:58:427111
[email protected]3fe8d2f82013-10-17 08:56:077112 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277113 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417114 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277115
[email protected]1c773ea12009-04-28 19:58:427116 MockWrite data_writes[] = {
7117 MockWrite("GET / HTTP/1.1\r\n"
7118 "Host: www.google.com\r\n"
7119 "Connection: keep-alive\r\n"
7120 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
7121 };
7122
7123 // Lastly, the server responds with the actual content.
7124 MockRead data_reads[] = {
7125 MockRead("HTTP/1.0 200 OK\r\n"),
7126 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7127 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067128 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427129 };
7130
[email protected]31a2bfe2010-02-09 08:03:397131 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7132 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077133 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427134
[email protected]49639fa2011-12-20 23:22:417135 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427136
[email protected]49639fa2011-12-20 23:22:417137 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427138 EXPECT_EQ(ERR_IO_PENDING, rv);
7139
7140 rv = callback.WaitForResult();
7141 EXPECT_EQ(OK, rv);
7142}
7143
[email protected]23e482282013-06-14 16:08:027144TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:297145 HttpRequestInfo request;
7146 request.method = "GET";
7147 request.url = GURL("https://www.google.com/");
7148 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
7149 "Chromium Ultra Awesome X Edition");
7150
[email protected]bb88e1d32013-05-03 23:11:077151 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]3fe8d2f82013-10-17 08:56:077152 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277153 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417154 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277155
[email protected]da81f132010-08-18 23:39:297156 MockWrite data_writes[] = {
7157 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
7158 "Host: www.google.com\r\n"
7159 "Proxy-Connection: keep-alive\r\n"
7160 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
7161 };
7162 MockRead data_reads[] = {
7163 // Return an error, so the transaction stops here (this test isn't
7164 // interested in the rest).
7165 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
7166 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7167 MockRead("Proxy-Connection: close\r\n\r\n"),
7168 };
7169
7170 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7171 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077172 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:297173
[email protected]49639fa2011-12-20 23:22:417174 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:297175
[email protected]49639fa2011-12-20 23:22:417176 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]da81f132010-08-18 23:39:297177 EXPECT_EQ(ERR_IO_PENDING, rv);
7178
7179 rv = callback.WaitForResult();
7180 EXPECT_EQ(OK, rv);
7181}
7182
[email protected]23e482282013-06-14 16:08:027183TEST_P(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:427184 HttpRequestInfo request;
7185 request.method = "GET";
7186 request.url = GURL("http://www.google.com/");
7187 request.load_flags = 0;
[email protected]c10450102011-06-27 09:06:167188 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
7189 "http://the.previous.site.com/");
[email protected]1c773ea12009-04-28 19:58:427190
[email protected]3fe8d2f82013-10-17 08:56:077191 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277192 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417193 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277194
[email protected]1c773ea12009-04-28 19:58:427195 MockWrite data_writes[] = {
7196 MockWrite("GET / HTTP/1.1\r\n"
7197 "Host: www.google.com\r\n"
7198 "Connection: keep-alive\r\n"
7199 "Referer: http://the.previous.site.com/\r\n\r\n"),
7200 };
7201
7202 // Lastly, the server responds with the actual content.
7203 MockRead data_reads[] = {
7204 MockRead("HTTP/1.0 200 OK\r\n"),
7205 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7206 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067207 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427208 };
7209
[email protected]31a2bfe2010-02-09 08:03:397210 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7211 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077212 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427213
[email protected]49639fa2011-12-20 23:22:417214 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427215
[email protected]49639fa2011-12-20 23:22:417216 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427217 EXPECT_EQ(ERR_IO_PENDING, rv);
7218
7219 rv = callback.WaitForResult();
7220 EXPECT_EQ(OK, rv);
7221}
7222
[email protected]23e482282013-06-14 16:08:027223TEST_P(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:427224 HttpRequestInfo request;
7225 request.method = "POST";
7226 request.url = GURL("http://www.google.com/");
7227
[email protected]3fe8d2f82013-10-17 08:56:077228 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277229 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417230 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277231
[email protected]1c773ea12009-04-28 19:58:427232 MockWrite data_writes[] = {
7233 MockWrite("POST / HTTP/1.1\r\n"
7234 "Host: www.google.com\r\n"
7235 "Connection: keep-alive\r\n"
7236 "Content-Length: 0\r\n\r\n"),
7237 };
7238
7239 // Lastly, the server responds with the actual content.
7240 MockRead data_reads[] = {
7241 MockRead("HTTP/1.0 200 OK\r\n"),
7242 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7243 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067244 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427245 };
7246
[email protected]31a2bfe2010-02-09 08:03:397247 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7248 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077249 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427250
[email protected]49639fa2011-12-20 23:22:417251 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427252
[email protected]49639fa2011-12-20 23:22:417253 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427254 EXPECT_EQ(ERR_IO_PENDING, rv);
7255
7256 rv = callback.WaitForResult();
7257 EXPECT_EQ(OK, rv);
7258}
7259
[email protected]23e482282013-06-14 16:08:027260TEST_P(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:427261 HttpRequestInfo request;
7262 request.method = "PUT";
7263 request.url = GURL("http://www.google.com/");
7264
[email protected]3fe8d2f82013-10-17 08:56:077265 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277266 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417267 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277268
[email protected]1c773ea12009-04-28 19:58:427269 MockWrite data_writes[] = {
7270 MockWrite("PUT / HTTP/1.1\r\n"
7271 "Host: www.google.com\r\n"
7272 "Connection: keep-alive\r\n"
7273 "Content-Length: 0\r\n\r\n"),
7274 };
7275
7276 // Lastly, the server responds with the actual content.
7277 MockRead data_reads[] = {
7278 MockRead("HTTP/1.0 200 OK\r\n"),
7279 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7280 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067281 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427282 };
7283
[email protected]31a2bfe2010-02-09 08:03:397284 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7285 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077286 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427287
[email protected]49639fa2011-12-20 23:22:417288 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427289
[email protected]49639fa2011-12-20 23:22:417290 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427291 EXPECT_EQ(ERR_IO_PENDING, rv);
7292
7293 rv = callback.WaitForResult();
7294 EXPECT_EQ(OK, rv);
7295}
7296
[email protected]23e482282013-06-14 16:08:027297TEST_P(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:427298 HttpRequestInfo request;
7299 request.method = "HEAD";
7300 request.url = GURL("http://www.google.com/");
7301
[email protected]3fe8d2f82013-10-17 08:56:077302 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277303 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417304 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277305
[email protected]1c773ea12009-04-28 19:58:427306 MockWrite data_writes[] = {
7307 MockWrite("HEAD / HTTP/1.1\r\n"
7308 "Host: www.google.com\r\n"
7309 "Connection: keep-alive\r\n"
7310 "Content-Length: 0\r\n\r\n"),
7311 };
7312
7313 // Lastly, the server responds with the actual content.
7314 MockRead data_reads[] = {
7315 MockRead("HTTP/1.0 200 OK\r\n"),
7316 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7317 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067318 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427319 };
7320
[email protected]31a2bfe2010-02-09 08:03:397321 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7322 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077323 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427324
[email protected]49639fa2011-12-20 23:22:417325 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427326
[email protected]49639fa2011-12-20 23:22:417327 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427328 EXPECT_EQ(ERR_IO_PENDING, rv);
7329
7330 rv = callback.WaitForResult();
7331 EXPECT_EQ(OK, rv);
7332}
7333
[email protected]23e482282013-06-14 16:08:027334TEST_P(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:427335 HttpRequestInfo request;
7336 request.method = "GET";
7337 request.url = GURL("http://www.google.com/");
7338 request.load_flags = LOAD_BYPASS_CACHE;
7339
[email protected]3fe8d2f82013-10-17 08:56:077340 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277341 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417342 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277343
[email protected]1c773ea12009-04-28 19:58:427344 MockWrite data_writes[] = {
7345 MockWrite("GET / HTTP/1.1\r\n"
7346 "Host: www.google.com\r\n"
7347 "Connection: keep-alive\r\n"
7348 "Pragma: no-cache\r\n"
7349 "Cache-Control: no-cache\r\n\r\n"),
7350 };
7351
7352 // Lastly, the server responds with the actual content.
7353 MockRead data_reads[] = {
7354 MockRead("HTTP/1.0 200 OK\r\n"),
7355 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7356 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067357 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427358 };
7359
[email protected]31a2bfe2010-02-09 08:03:397360 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7361 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077362 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427363
[email protected]49639fa2011-12-20 23:22:417364 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427365
[email protected]49639fa2011-12-20 23:22:417366 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427367 EXPECT_EQ(ERR_IO_PENDING, rv);
7368
7369 rv = callback.WaitForResult();
7370 EXPECT_EQ(OK, rv);
7371}
7372
[email protected]23e482282013-06-14 16:08:027373TEST_P(HttpNetworkTransactionTest,
[email protected]1c773ea12009-04-28 19:58:427374 BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:427375 HttpRequestInfo request;
7376 request.method = "GET";
7377 request.url = GURL("http://www.google.com/");
7378 request.load_flags = LOAD_VALIDATE_CACHE;
7379
[email protected]3fe8d2f82013-10-17 08:56:077380 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277381 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417382 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277383
[email protected]1c773ea12009-04-28 19:58:427384 MockWrite data_writes[] = {
7385 MockWrite("GET / HTTP/1.1\r\n"
7386 "Host: www.google.com\r\n"
7387 "Connection: keep-alive\r\n"
7388 "Cache-Control: max-age=0\r\n\r\n"),
7389 };
7390
7391 // Lastly, the server responds with the actual content.
7392 MockRead data_reads[] = {
7393 MockRead("HTTP/1.0 200 OK\r\n"),
7394 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7395 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067396 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427397 };
7398
[email protected]31a2bfe2010-02-09 08:03:397399 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7400 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077401 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427402
[email protected]49639fa2011-12-20 23:22:417403 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427404
[email protected]49639fa2011-12-20 23:22:417405 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427406 EXPECT_EQ(ERR_IO_PENDING, rv);
7407
7408 rv = callback.WaitForResult();
7409 EXPECT_EQ(OK, rv);
7410}
7411
[email protected]23e482282013-06-14 16:08:027412TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:427413 HttpRequestInfo request;
7414 request.method = "GET";
7415 request.url = GURL("http://www.google.com/");
[email protected]8c76ae22010-04-20 22:15:437416 request.extra_headers.SetHeader("FooHeader", "Bar");
[email protected]1c773ea12009-04-28 19:58:427417
[email protected]3fe8d2f82013-10-17 08:56:077418 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277419 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417420 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277421
[email protected]1c773ea12009-04-28 19:58:427422 MockWrite data_writes[] = {
7423 MockWrite("GET / HTTP/1.1\r\n"
7424 "Host: www.google.com\r\n"
7425 "Connection: keep-alive\r\n"
7426 "FooHeader: Bar\r\n\r\n"),
7427 };
7428
7429 // Lastly, the server responds with the actual content.
7430 MockRead data_reads[] = {
7431 MockRead("HTTP/1.0 200 OK\r\n"),
7432 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7433 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067434 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427435 };
7436
[email protected]31a2bfe2010-02-09 08:03:397437 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7438 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077439 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427440
[email protected]49639fa2011-12-20 23:22:417441 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427442
[email protected]49639fa2011-12-20 23:22:417443 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427444 EXPECT_EQ(ERR_IO_PENDING, rv);
7445
7446 rv = callback.WaitForResult();
7447 EXPECT_EQ(OK, rv);
7448}
7449
[email protected]23e482282013-06-14 16:08:027450TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:477451 HttpRequestInfo request;
7452 request.method = "GET";
7453 request.url = GURL("http://www.google.com/");
[email protected]8c76ae22010-04-20 22:15:437454 request.extra_headers.SetHeader("referer", "www.foo.com");
7455 request.extra_headers.SetHeader("hEllo", "Kitty");
7456 request.extra_headers.SetHeader("FoO", "bar");
[email protected]270c6412010-03-29 22:02:477457
[email protected]3fe8d2f82013-10-17 08:56:077458 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277459 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417460 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277461
[email protected]270c6412010-03-29 22:02:477462 MockWrite data_writes[] = {
7463 MockWrite("GET / HTTP/1.1\r\n"
7464 "Host: www.google.com\r\n"
7465 "Connection: keep-alive\r\n"
[email protected]c10450102011-06-27 09:06:167466 "referer: www.foo.com\r\n"
[email protected]270c6412010-03-29 22:02:477467 "hEllo: Kitty\r\n"
7468 "FoO: bar\r\n\r\n"),
7469 };
7470
7471 // Lastly, the server responds with the actual content.
7472 MockRead data_reads[] = {
7473 MockRead("HTTP/1.0 200 OK\r\n"),
7474 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7475 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067476 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:477477 };
7478
7479 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7480 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077481 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:477482
[email protected]49639fa2011-12-20 23:22:417483 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:477484
[email protected]49639fa2011-12-20 23:22:417485 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]270c6412010-03-29 22:02:477486 EXPECT_EQ(ERR_IO_PENDING, rv);
7487
7488 rv = callback.WaitForResult();
7489 EXPECT_EQ(OK, rv);
7490}
7491
[email protected]23e482282013-06-14 16:08:027492TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277493 HttpRequestInfo request;
7494 request.method = "GET";
7495 request.url = GURL("http://www.google.com/");
7496 request.load_flags = 0;
7497
[email protected]bb88e1d32013-05-03 23:11:077498 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207499 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
7500 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077501 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:027502
[email protected]3fe8d2f82013-10-17 08:56:077503 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3cd17242009-06-23 02:59:027504 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417505 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3cd17242009-06-23 02:59:027506
[email protected]3cd17242009-06-23 02:59:027507 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
7508 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7509
7510 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:067511 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
[email protected]3cd17242009-06-23 02:59:027512 MockWrite("GET / HTTP/1.1\r\n"
7513 "Host: www.google.com\r\n"
7514 "Connection: keep-alive\r\n\r\n")
7515 };
7516
7517 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:067518 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:027519 MockRead("HTTP/1.0 200 OK\r\n"),
7520 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7521 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067522 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:027523 };
7524
[email protected]31a2bfe2010-02-09 08:03:397525 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7526 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077527 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:027528
[email protected]49639fa2011-12-20 23:22:417529 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:027530
[email protected]49639fa2011-12-20 23:22:417531 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:027532 EXPECT_EQ(ERR_IO_PENDING, rv);
7533
7534 rv = callback.WaitForResult();
7535 EXPECT_EQ(OK, rv);
7536
7537 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507538 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:027539
[email protected]029c83b62013-01-24 05:28:207540 LoadTimingInfo load_timing_info;
7541 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7542 TestLoadTimingNotReusedWithPac(load_timing_info,
7543 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7544
[email protected]3cd17242009-06-23 02:59:027545 std::string response_text;
7546 rv = ReadTransaction(trans.get(), &response_text);
7547 EXPECT_EQ(OK, rv);
7548 EXPECT_EQ("Payload", response_text);
7549}
7550
[email protected]23e482282013-06-14 16:08:027551TEST_P(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277552 HttpRequestInfo request;
7553 request.method = "GET";
7554 request.url = GURL("https://www.google.com/");
7555 request.load_flags = 0;
7556
[email protected]bb88e1d32013-05-03 23:11:077557 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207558 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
7559 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077560 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:027561
[email protected]3fe8d2f82013-10-17 08:56:077562 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3cd17242009-06-23 02:59:027563 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417564 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3cd17242009-06-23 02:59:027565
[email protected]3cd17242009-06-23 02:59:027566 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
7567 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7568
7569 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:067570 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
[email protected]e0c27be2009-07-15 13:09:357571 arraysize(write_buffer)),
[email protected]3cd17242009-06-23 02:59:027572 MockWrite("GET / HTTP/1.1\r\n"
7573 "Host: www.google.com\r\n"
7574 "Connection: keep-alive\r\n\r\n")
7575 };
7576
7577 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:017578 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
7579 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:357580 MockRead("HTTP/1.0 200 OK\r\n"),
7581 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7582 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067583 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:357584 };
7585
[email protected]31a2bfe2010-02-09 08:03:397586 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7587 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077588 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:357589
[email protected]8ddf8322012-02-23 18:08:067590 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077591 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:357592
[email protected]49639fa2011-12-20 23:22:417593 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:357594
[email protected]49639fa2011-12-20 23:22:417595 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:357596 EXPECT_EQ(ERR_IO_PENDING, rv);
7597
7598 rv = callback.WaitForResult();
7599 EXPECT_EQ(OK, rv);
7600
[email protected]029c83b62013-01-24 05:28:207601 LoadTimingInfo load_timing_info;
7602 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7603 TestLoadTimingNotReusedWithPac(load_timing_info,
7604 CONNECT_TIMING_HAS_SSL_TIMES);
7605
[email protected]e0c27be2009-07-15 13:09:357606 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507607 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:357608
7609 std::string response_text;
7610 rv = ReadTransaction(trans.get(), &response_text);
7611 EXPECT_EQ(OK, rv);
7612 EXPECT_EQ("Payload", response_text);
7613}
7614
[email protected]23e482282013-06-14 16:08:027615TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:207616 HttpRequestInfo request;
7617 request.method = "GET";
7618 request.url = GURL("http://www.google.com/");
7619 request.load_flags = 0;
7620
[email protected]bb88e1d32013-05-03 23:11:077621 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207622 ProxyService::CreateFixed("socks4://myproxy:1080"));
7623 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077624 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:207625
[email protected]3fe8d2f82013-10-17 08:56:077626 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:207627 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417628 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:207629
7630 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
7631 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7632
7633 MockWrite data_writes[] = {
7634 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
7635 MockWrite("GET / HTTP/1.1\r\n"
7636 "Host: www.google.com\r\n"
7637 "Connection: keep-alive\r\n\r\n")
7638 };
7639
7640 MockRead data_reads[] = {
7641 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
7642 MockRead("HTTP/1.0 200 OK\r\n"),
7643 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7644 MockRead("Payload"),
7645 MockRead(SYNCHRONOUS, OK)
7646 };
7647
7648 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7649 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077650 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:207651
7652 TestCompletionCallback callback;
7653
7654 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7655 EXPECT_EQ(ERR_IO_PENDING, rv);
7656
7657 rv = callback.WaitForResult();
7658 EXPECT_EQ(OK, rv);
7659
7660 const HttpResponseInfo* response = trans->GetResponseInfo();
7661 ASSERT_TRUE(response != NULL);
7662
7663 LoadTimingInfo load_timing_info;
7664 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7665 TestLoadTimingNotReused(load_timing_info,
7666 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7667
7668 std::string response_text;
7669 rv = ReadTransaction(trans.get(), &response_text);
7670 EXPECT_EQ(OK, rv);
7671 EXPECT_EQ("Payload", response_text);
7672}
7673
[email protected]23e482282013-06-14 16:08:027674TEST_P(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277675 HttpRequestInfo request;
7676 request.method = "GET";
7677 request.url = GURL("http://www.google.com/");
7678 request.load_flags = 0;
7679
[email protected]bb88e1d32013-05-03 23:11:077680 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207681 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
7682 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077683 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:357684
[email protected]3fe8d2f82013-10-17 08:56:077685 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e0c27be2009-07-15 13:09:357686 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417687 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]e0c27be2009-07-15 13:09:357688
[email protected]e0c27be2009-07-15 13:09:357689 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
7690 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:377691 const char kSOCKS5OkRequest[] = {
7692 0x05, // Version
7693 0x01, // Command (CONNECT)
7694 0x00, // Reserved.
7695 0x03, // Address type (DOMAINNAME).
7696 0x0E, // Length of domain (14)
7697 // Domain string:
7698 'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
7699 0x00, 0x50, // 16-bit port (80)
7700 };
[email protected]e0c27be2009-07-15 13:09:357701 const char kSOCKS5OkResponse[] =
7702 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
7703
7704 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:067705 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
7706 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
[email protected]e0c27be2009-07-15 13:09:357707 MockWrite("GET / HTTP/1.1\r\n"
7708 "Host: www.google.com\r\n"
7709 "Connection: keep-alive\r\n\r\n")
7710 };
7711
7712 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:017713 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
7714 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:357715 MockRead("HTTP/1.0 200 OK\r\n"),
7716 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7717 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067718 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:357719 };
7720
[email protected]31a2bfe2010-02-09 08:03:397721 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7722 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077723 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:357724
[email protected]49639fa2011-12-20 23:22:417725 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:357726
[email protected]49639fa2011-12-20 23:22:417727 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:357728 EXPECT_EQ(ERR_IO_PENDING, rv);
7729
7730 rv = callback.WaitForResult();
7731 EXPECT_EQ(OK, rv);
7732
7733 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507734 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:357735
[email protected]029c83b62013-01-24 05:28:207736 LoadTimingInfo load_timing_info;
7737 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7738 TestLoadTimingNotReusedWithPac(load_timing_info,
7739 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7740
[email protected]e0c27be2009-07-15 13:09:357741 std::string response_text;
7742 rv = ReadTransaction(trans.get(), &response_text);
7743 EXPECT_EQ(OK, rv);
7744 EXPECT_EQ("Payload", response_text);
7745}
7746
[email protected]23e482282013-06-14 16:08:027747TEST_P(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277748 HttpRequestInfo request;
7749 request.method = "GET";
7750 request.url = GURL("https://www.google.com/");
7751 request.load_flags = 0;
7752
[email protected]bb88e1d32013-05-03 23:11:077753 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207754 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
7755 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077756 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:357757
[email protected]3fe8d2f82013-10-17 08:56:077758 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e0c27be2009-07-15 13:09:357759 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417760 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]e0c27be2009-07-15 13:09:357761
[email protected]e0c27be2009-07-15 13:09:357762 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
7763 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:377764 const unsigned char kSOCKS5OkRequest[] = {
7765 0x05, // Version
7766 0x01, // Command (CONNECT)
7767 0x00, // Reserved.
7768 0x03, // Address type (DOMAINNAME).
7769 0x0E, // Length of domain (14)
7770 // Domain string:
7771 'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
7772 0x01, 0xBB, // 16-bit port (443)
7773 };
7774
[email protected]e0c27be2009-07-15 13:09:357775 const char kSOCKS5OkResponse[] =
7776 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
7777
7778 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:067779 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
7780 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
[email protected]e0c27be2009-07-15 13:09:357781 arraysize(kSOCKS5OkRequest)),
7782 MockWrite("GET / HTTP/1.1\r\n"
7783 "Host: www.google.com\r\n"
7784 "Connection: keep-alive\r\n\r\n")
7785 };
7786
7787 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:017788 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
7789 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:027790 MockRead("HTTP/1.0 200 OK\r\n"),
7791 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7792 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067793 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:027794 };
7795
[email protected]31a2bfe2010-02-09 08:03:397796 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7797 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077798 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:027799
[email protected]8ddf8322012-02-23 18:08:067800 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077801 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:027802
[email protected]49639fa2011-12-20 23:22:417803 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:027804
[email protected]49639fa2011-12-20 23:22:417805 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:027806 EXPECT_EQ(ERR_IO_PENDING, rv);
7807
7808 rv = callback.WaitForResult();
7809 EXPECT_EQ(OK, rv);
7810
7811 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507812 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:027813
[email protected]029c83b62013-01-24 05:28:207814 LoadTimingInfo load_timing_info;
7815 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7816 TestLoadTimingNotReusedWithPac(load_timing_info,
7817 CONNECT_TIMING_HAS_SSL_TIMES);
7818
[email protected]3cd17242009-06-23 02:59:027819 std::string response_text;
7820 rv = ReadTransaction(trans.get(), &response_text);
7821 EXPECT_EQ(OK, rv);
7822 EXPECT_EQ("Payload", response_text);
7823}
7824
[email protected]448d4ca52012-03-04 04:12:237825namespace {
7826
[email protected]04e5be32009-06-26 20:00:317827// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:067828
7829struct GroupNameTest {
7830 std::string proxy_server;
7831 std::string url;
7832 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:187833 bool ssl;
[email protected]2d731a32010-04-29 01:04:067834};
7835
7836scoped_refptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]8a0fc822013-06-27 20:52:437837 NextProto next_proto,
[email protected]bb88e1d32013-05-03 23:11:077838 SpdySessionDependencies* session_deps_) {
7839 scoped_refptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:067840
[email protected]30d4c022013-07-18 22:58:167841 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:537842 session->http_server_properties();
7843 http_server_properties->SetAlternateProtocol(
[email protected]2d731a32010-04-29 01:04:067844 HostPortPair("host.with.alternate", 80), 443,
bnc1102b552015-01-30 20:11:017845 AlternateProtocolFromNextProto(next_proto), 1.0);
[email protected]2d731a32010-04-29 01:04:067846
7847 return session;
7848}
7849
7850int GroupNameTransactionHelper(
7851 const std::string& url,
7852 const scoped_refptr<HttpNetworkSession>& session) {
[email protected]2d731a32010-04-29 01:04:067853 HttpRequestInfo request;
7854 request.method = "GET";
7855 request.url = GURL(url);
7856 request.load_flags = 0;
7857
[email protected]262eec82013-03-19 21:01:367858 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507859 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277860
[email protected]49639fa2011-12-20 23:22:417861 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:067862
7863 // We do not complete this request, the dtor will clean the transaction up.
[email protected]49639fa2011-12-20 23:22:417864 return trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d731a32010-04-29 01:04:067865}
7866
[email protected]448d4ca52012-03-04 04:12:237867} // namespace
7868
[email protected]23e482282013-06-14 16:08:027869TEST_P(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:067870 const GroupNameTest tests[] = {
[email protected]04e5be32009-06-26 20:00:317871 {
[email protected]2d731a32010-04-29 01:04:067872 "", // unused
[email protected]04e5be32009-06-26 20:00:317873 "http://www.google.com/direct",
[email protected]2ff8b312010-04-26 22:20:547874 "www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:187875 false,
[email protected]2ff8b312010-04-26 22:20:547876 },
7877 {
[email protected]2d731a32010-04-29 01:04:067878 "", // unused
[email protected]2ff8b312010-04-26 22:20:547879 "http://[2001:1418:13:1::25]/direct",
7880 "[2001:1418:13:1::25]:80",
[email protected]e60e47a2010-07-14 03:37:187881 false,
[email protected]04e5be32009-06-26 20:00:317882 },
[email protected]04e5be32009-06-26 20:00:317883
7884 // SSL Tests
7885 {
[email protected]2d731a32010-04-29 01:04:067886 "", // unused
[email protected]04e5be32009-06-26 20:00:317887 "https://www.google.com/direct_ssl",
[email protected]0e88ad602010-05-04 23:47:027888 "ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:187889 true,
[email protected]04e5be32009-06-26 20:00:317890 },
7891 {
[email protected]2d731a32010-04-29 01:04:067892 "", // unused
7893 "https://[2001:1418:13:1::25]/direct",
[email protected]0e88ad602010-05-04 23:47:027894 "ssl/[2001:1418:13:1::25]:443",
[email protected]e60e47a2010-07-14 03:37:187895 true,
[email protected]04e5be32009-06-26 20:00:317896 },
7897 {
[email protected]2d731a32010-04-29 01:04:067898 "", // unused
[email protected]2ff8b312010-04-26 22:20:547899 "http://host.with.alternate/direct",
[email protected]0e88ad602010-05-04 23:47:027900 "ssl/host.with.alternate:443",
[email protected]e60e47a2010-07-14 03:37:187901 true,
[email protected]2ff8b312010-04-26 22:20:547902 },
[email protected]2d731a32010-04-29 01:04:067903 };
[email protected]2ff8b312010-04-26 22:20:547904
[email protected]d7599122014-05-24 03:37:237905 session_deps_.use_alternate_protocols = true;
[email protected]2d731a32010-04-29 01:04:067906
viettrungluue4a8b882014-10-16 06:17:387907 for (size_t i = 0; i < arraysize(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:077908 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:027909 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:067910 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:437911 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:067912
7913 HttpNetworkSessionPeer peer(session);
[email protected]ab739042011-04-07 15:22:287914 CaptureGroupNameTransportSocketPool* transport_conn_pool =
7915 new CaptureGroupNameTransportSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:137916 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347917 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]831e4a32013-11-14 02:14:447918 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
7919 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:027920 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
7921 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
dchenge3d1ddc2014-10-15 19:30:517922 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]2d731a32010-04-29 01:04:067923
7924 EXPECT_EQ(ERR_IO_PENDING,
7925 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:187926 if (tests[i].ssl)
7927 EXPECT_EQ(tests[i].expected_group_name,
7928 ssl_conn_pool->last_group_name_received());
7929 else
7930 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:287931 transport_conn_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:067932 }
7933
[email protected]2d731a32010-04-29 01:04:067934}
7935
[email protected]23e482282013-06-14 16:08:027936TEST_P(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:067937 const GroupNameTest tests[] = {
7938 {
7939 "http_proxy",
7940 "http://www.google.com/http_proxy_normal",
7941 "www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:187942 false,
[email protected]2d731a32010-04-29 01:04:067943 },
7944
7945 // SSL Tests
7946 {
7947 "http_proxy",
7948 "https://www.google.com/http_connect_ssl",
[email protected]0e88ad602010-05-04 23:47:027949 "ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:187950 true,
[email protected]2d731a32010-04-29 01:04:067951 },
[email protected]af3490e2010-10-16 21:02:297952
[email protected]9faeded92010-04-29 20:03:057953 {
7954 "http_proxy",
7955 "http://host.with.alternate/direct",
[email protected]0e88ad602010-05-04 23:47:027956 "ssl/host.with.alternate:443",
[email protected]e60e47a2010-07-14 03:37:187957 true,
[email protected]9faeded92010-04-29 20:03:057958 },
[email protected]45499252013-01-23 17:12:567959
7960 {
7961 "http_proxy",
7962 "ftp://ftp.google.com/http_proxy_normal",
7963 "ftp/ftp.google.com:21",
7964 false,
7965 },
[email protected]2d731a32010-04-29 01:04:067966 };
7967
[email protected]d7599122014-05-24 03:37:237968 session_deps_.use_alternate_protocols = true;
[email protected]2d731a32010-04-29 01:04:067969
viettrungluue4a8b882014-10-16 06:17:387970 for (size_t i = 0; i < arraysize(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:077971 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:027972 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:067973 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:437974 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:067975
7976 HttpNetworkSessionPeer peer(session);
7977
[email protected]e60e47a2010-07-14 03:37:187978 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:137979 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:347980 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:137981 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347982 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:027983
[email protected]831e4a32013-11-14 02:14:447984 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
7985 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:027986 mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool);
7987 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
dchenge3d1ddc2014-10-15 19:30:517988 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]2d731a32010-04-29 01:04:067989
7990 EXPECT_EQ(ERR_IO_PENDING,
7991 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:187992 if (tests[i].ssl)
7993 EXPECT_EQ(tests[i].expected_group_name,
7994 ssl_conn_pool->last_group_name_received());
7995 else
7996 EXPECT_EQ(tests[i].expected_group_name,
7997 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:067998 }
[email protected]2d731a32010-04-29 01:04:067999}
8000
[email protected]23e482282013-06-14 16:08:028001TEST_P(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:068002 const GroupNameTest tests[] = {
8003 {
8004 "socks4://socks_proxy:1080",
8005 "http://www.google.com/socks4_direct",
8006 "socks4/www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:188007 false,
[email protected]2d731a32010-04-29 01:04:068008 },
8009 {
8010 "socks5://socks_proxy:1080",
8011 "http://www.google.com/socks5_direct",
8012 "socks5/www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:188013 false,
[email protected]2d731a32010-04-29 01:04:068014 },
8015
8016 // SSL Tests
8017 {
8018 "socks4://socks_proxy:1080",
8019 "https://www.google.com/socks4_ssl",
[email protected]0e88ad602010-05-04 23:47:028020 "socks4/ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:188021 true,
[email protected]2d731a32010-04-29 01:04:068022 },
8023 {
8024 "socks5://socks_proxy:1080",
8025 "https://www.google.com/socks5_ssl",
[email protected]0e88ad602010-05-04 23:47:028026 "socks5/ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:188027 true,
[email protected]2d731a32010-04-29 01:04:068028 },
[email protected]af3490e2010-10-16 21:02:298029
[email protected]9faeded92010-04-29 20:03:058030 {
8031 "socks4://socks_proxy:1080",
8032 "http://host.with.alternate/direct",
[email protected]0e88ad602010-05-04 23:47:028033 "socks4/ssl/host.with.alternate:443",
[email protected]e60e47a2010-07-14 03:37:188034 true,
[email protected]9faeded92010-04-29 20:03:058035 },
[email protected]04e5be32009-06-26 20:00:318036 };
8037
[email protected]d7599122014-05-24 03:37:238038 session_deps_.use_alternate_protocols = true;
[email protected]2ff8b312010-04-26 22:20:548039
viettrungluue4a8b882014-10-16 06:17:388040 for (size_t i = 0; i < arraysize(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:078041 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:028042 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:068043 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:438044 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]8b114dd72011-03-25 05:33:028045
[email protected]2d731a32010-04-29 01:04:068046 HttpNetworkSessionPeer peer(session);
[email protected]04e5be32009-06-26 20:00:318047
[email protected]e60e47a2010-07-14 03:37:188048 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:138049 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:348050 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:138051 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:348052 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:028053
[email protected]831e4a32013-11-14 02:14:448054 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
8055 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:028056 mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_conn_pool);
8057 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
dchenge3d1ddc2014-10-15 19:30:518058 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]04e5be32009-06-26 20:00:318059
[email protected]262eec82013-03-19 21:01:368060 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508061 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]04e5be32009-06-26 20:00:318062
[email protected]2d731a32010-04-29 01:04:068063 EXPECT_EQ(ERR_IO_PENDING,
8064 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:188065 if (tests[i].ssl)
8066 EXPECT_EQ(tests[i].expected_group_name,
8067 ssl_conn_pool->last_group_name_received());
8068 else
8069 EXPECT_EQ(tests[i].expected_group_name,
8070 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:318071 }
8072}
8073
[email protected]23e482282013-06-14 16:08:028074TEST_P(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:278075 HttpRequestInfo request;
8076 request.method = "GET";
8077 request.url = GURL("http://www.google.com/");
8078
[email protected]bb88e1d32013-05-03 23:11:078079 session_deps_.proxy_service.reset(
[email protected]81cdfcd2010-10-16 00:49:008080 ProxyService::CreateFixed("myproxy:70;foobar:80"));
[email protected]b59ff372009-07-15 22:04:328081
[email protected]69719062010-01-05 20:09:218082 // This simulates failure resolving all hostnames; that means we will fail
8083 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:078084 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:328085
[email protected]3fe8d2f82013-10-17 08:56:078086 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]9172a982009-06-06 00:30:258087 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418088 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]9172a982009-06-06 00:30:258089
[email protected]49639fa2011-12-20 23:22:418090 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:258091
[email protected]49639fa2011-12-20 23:22:418092 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9172a982009-06-06 00:30:258093 EXPECT_EQ(ERR_IO_PENDING, rv);
8094
[email protected]9172a982009-06-06 00:30:258095 rv = callback.WaitForResult();
[email protected]f7fccee2010-09-16 20:53:018096 EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
[email protected]9172a982009-06-06 00:30:258097}
8098
[email protected]685af592010-05-11 19:31:248099// Base test to make sure that when the load flags for a request specify to
8100// bypass the cache, the DNS cache is not used.
[email protected]23e482282013-06-14 16:08:028101void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
[email protected]bb88e1d32013-05-03 23:11:078102 int load_flags) {
[email protected]cb9bf6ca2011-01-28 13:15:278103 // Issue a request, asking to bypass the cache(s).
8104 HttpRequestInfo request;
8105 request.method = "GET";
8106 request.load_flags = load_flags;
8107 request.url = GURL("http://www.google.com/");
8108
[email protected]a2c2fb92009-07-18 07:31:048109 // Select a host resolver that does caching.
[email protected]bb88e1d32013-05-03 23:11:078110 session_deps_.host_resolver.reset(new MockCachingHostResolver);
[email protected]b59ff372009-07-15 22:04:328111
[email protected]3fe8d2f82013-10-17 08:56:078112 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8113 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418114 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3b9cca42009-06-16 01:08:288115
[email protected]6e78dfb2011-07-28 21:34:478116 // Warm up the host cache so it has an entry for "www.google.com".
[email protected]3b9cca42009-06-16 01:08:288117 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:298118 TestCompletionCallback callback;
[email protected]bb88e1d32013-05-03 23:11:078119 int rv = session_deps_.host_resolver->Resolve(
[email protected]5109c1952013-08-20 18:44:108120 HostResolver::RequestInfo(HostPortPair("www.google.com", 80)),
8121 DEFAULT_PRIORITY,
[email protected]b9823c02013-08-16 21:24:418122 &addrlist,
8123 callback.callback(),
8124 NULL,
8125 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:478126 EXPECT_EQ(ERR_IO_PENDING, rv);
8127 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:288128 EXPECT_EQ(OK, rv);
8129
8130 // Verify that it was added to host cache, by doing a subsequent async lookup
8131 // and confirming it completes synchronously.
[email protected]bb88e1d32013-05-03 23:11:078132 rv = session_deps_.host_resolver->Resolve(
[email protected]5109c1952013-08-20 18:44:108133 HostResolver::RequestInfo(HostPortPair("www.google.com", 80)),
8134 DEFAULT_PRIORITY,
[email protected]b9823c02013-08-16 21:24:418135 &addrlist,
8136 callback.callback(),
8137 NULL,
8138 BoundNetLog());
[email protected]b59ff372009-07-15 22:04:328139 ASSERT_EQ(OK, rv);
[email protected]3b9cca42009-06-16 01:08:288140
8141 // Inject a failure the next time that "www.google.com" is resolved. This way
8142 // we can tell if the next lookup hit the cache, or the "network".
8143 // (cache --> success, "network" --> failure).
[email protected]bb88e1d32013-05-03 23:11:078144 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.google.com");
[email protected]3b9cca42009-06-16 01:08:288145
8146 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
8147 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:068148 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
[email protected]31a2bfe2010-02-09 08:03:398149 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078150 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:288151
[email protected]3b9cca42009-06-16 01:08:288152 // Run the request.
[email protected]49639fa2011-12-20 23:22:418153 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3b9cca42009-06-16 01:08:288154 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:418155 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:288156
8157 // If we bypassed the cache, we would have gotten a failure while resolving
8158 // "www.google.com".
8159 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
8160}
8161
[email protected]685af592010-05-11 19:31:248162// There are multiple load flags that should trigger the host cache bypass.
8163// Test each in isolation:
[email protected]23e482282013-06-14 16:08:028164TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
[email protected]685af592010-05-11 19:31:248165 BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
8166}
8167
[email protected]23e482282013-06-14 16:08:028168TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
[email protected]685af592010-05-11 19:31:248169 BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
8170}
8171
[email protected]23e482282013-06-14 16:08:028172TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
[email protected]685af592010-05-11 19:31:248173 BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
8174}
8175
[email protected]0877e3d2009-10-17 22:29:578176// Make sure we can handle an error when writing the request.
[email protected]23e482282013-06-14 16:08:028177TEST_P(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:578178 HttpRequestInfo request;
8179 request.method = "GET";
8180 request.url = GURL("http://www.foo.com/");
8181 request.load_flags = 0;
8182
8183 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:068184 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:578185 };
[email protected]31a2bfe2010-02-09 08:03:398186 StaticSocketDataProvider data(NULL, 0,
8187 write_failure, arraysize(write_failure));
[email protected]bb88e1d32013-05-03 23:11:078188 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3fe8d2f82013-10-17 08:56:078189 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578190
[email protected]49639fa2011-12-20 23:22:418191 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:578192
8193 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418194 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:578195
[email protected]49639fa2011-12-20 23:22:418196 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578197 EXPECT_EQ(ERR_IO_PENDING, rv);
8198
8199 rv = callback.WaitForResult();
8200 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
8201}
8202
8203// Check that a connection closed after the start of the headers finishes ok.
[email protected]23e482282013-06-14 16:08:028204TEST_P(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:578205 HttpRequestInfo request;
8206 request.method = "GET";
8207 request.url = GURL("http://www.foo.com/");
8208 request.load_flags = 0;
8209
8210 MockRead data_reads[] = {
8211 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:068212 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:578213 };
8214
[email protected]31a2bfe2010-02-09 08:03:398215 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078216 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3fe8d2f82013-10-17 08:56:078217 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578218
[email protected]49639fa2011-12-20 23:22:418219 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:578220
8221 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418222 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:578223
[email protected]49639fa2011-12-20 23:22:418224 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578225 EXPECT_EQ(ERR_IO_PENDING, rv);
8226
8227 rv = callback.WaitForResult();
8228 EXPECT_EQ(OK, rv);
8229
8230 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508231 ASSERT_TRUE(response != NULL);
[email protected]0877e3d2009-10-17 22:29:578232
[email protected]90499482013-06-01 00:39:508233 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]0877e3d2009-10-17 22:29:578234 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
8235
8236 std::string response_data;
8237 rv = ReadTransaction(trans.get(), &response_data);
8238 EXPECT_EQ(OK, rv);
8239 EXPECT_EQ("", response_data);
8240}
8241
8242// Make sure that a dropped connection while draining the body for auth
8243// restart does the right thing.
[email protected]23e482282013-06-14 16:08:028244TEST_P(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:578245 HttpRequestInfo request;
8246 request.method = "GET";
8247 request.url = GURL("http://www.google.com/");
8248 request.load_flags = 0;
8249
8250 MockWrite data_writes1[] = {
8251 MockWrite("GET / HTTP/1.1\r\n"
8252 "Host: www.google.com\r\n"
8253 "Connection: keep-alive\r\n\r\n"),
8254 };
8255
8256 MockRead data_reads1[] = {
8257 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
8258 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8259 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8260 MockRead("Content-Length: 14\r\n\r\n"),
8261 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:068262 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:578263 };
8264
[email protected]31a2bfe2010-02-09 08:03:398265 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8266 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:078267 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:578268
8269 // After calling trans->RestartWithAuth(), this is the request we should
8270 // be issuing -- the final header line contains the credentials.
8271 MockWrite data_writes2[] = {
8272 MockWrite("GET / HTTP/1.1\r\n"
8273 "Host: www.google.com\r\n"
8274 "Connection: keep-alive\r\n"
8275 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
8276 };
8277
8278 // Lastly, the server responds with the actual content.
8279 MockRead data_reads2[] = {
8280 MockRead("HTTP/1.1 200 OK\r\n"),
8281 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8282 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068283 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:578284 };
8285
[email protected]31a2bfe2010-02-09 08:03:398286 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8287 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:078288 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3fe8d2f82013-10-17 08:56:078289 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578290
[email protected]49639fa2011-12-20 23:22:418291 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:578292
[email protected]262eec82013-03-19 21:01:368293 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508294 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:508295
[email protected]49639fa2011-12-20 23:22:418296 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578297 EXPECT_EQ(ERR_IO_PENDING, rv);
8298
8299 rv = callback1.WaitForResult();
8300 EXPECT_EQ(OK, rv);
8301
8302 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508303 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048304 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:578305
[email protected]49639fa2011-12-20 23:22:418306 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:578307
[email protected]49639fa2011-12-20 23:22:418308 rv = trans->RestartWithAuth(
8309 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]0877e3d2009-10-17 22:29:578310 EXPECT_EQ(ERR_IO_PENDING, rv);
8311
8312 rv = callback2.WaitForResult();
8313 EXPECT_EQ(OK, rv);
8314
8315 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508316 ASSERT_TRUE(response != NULL);
[email protected]0877e3d2009-10-17 22:29:578317 EXPECT_TRUE(response->auth_challenge.get() == NULL);
8318 EXPECT_EQ(100, response->headers->GetContentLength());
8319}
8320
8321// Test HTTPS connections going through a proxy that sends extra data.
[email protected]23e482282013-06-14 16:08:028322TEST_P(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
[email protected]bb88e1d32013-05-03 23:11:078323 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]0877e3d2009-10-17 22:29:578324
8325 HttpRequestInfo request;
8326 request.method = "GET";
8327 request.url = GURL("https://www.google.com/");
8328 request.load_flags = 0;
8329
8330 MockRead proxy_reads[] = {
8331 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:068332 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:578333 };
8334
[email protected]31a2bfe2010-02-09 08:03:398335 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
[email protected]8ddf8322012-02-23 18:08:068336 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:578337
[email protected]bb88e1d32013-05-03 23:11:078338 session_deps_.socket_factory->AddSocketDataProvider(&data);
8339 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:578340
[email protected]49639fa2011-12-20 23:22:418341 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:578342
[email protected]bb88e1d32013-05-03 23:11:078343 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:578344
[email protected]3fe8d2f82013-10-17 08:56:078345 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578346 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418347 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:578348
[email protected]49639fa2011-12-20 23:22:418349 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578350 EXPECT_EQ(ERR_IO_PENDING, rv);
8351
8352 rv = callback.WaitForResult();
8353 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
8354}
8355
[email protected]23e482282013-06-14 16:08:028356TEST_P(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:468357 HttpRequestInfo request;
8358 request.method = "GET";
8359 request.url = GURL("http://www.google.com/");
8360 request.load_flags = 0;
8361
[email protected]3fe8d2f82013-10-17 08:56:078362 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:278363 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418364 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278365
[email protected]e22e1362009-11-23 21:31:128366 MockRead data_reads[] = {
8367 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068368 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:128369 };
[email protected]9492e4a2010-02-24 00:58:468370
8371 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078372 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:468373
[email protected]49639fa2011-12-20 23:22:418374 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:468375
[email protected]49639fa2011-12-20 23:22:418376 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9492e4a2010-02-24 00:58:468377 EXPECT_EQ(ERR_IO_PENDING, rv);
8378
8379 EXPECT_EQ(OK, callback.WaitForResult());
8380
8381 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508382 ASSERT_TRUE(response != NULL);
[email protected]9492e4a2010-02-24 00:58:468383
[email protected]90499482013-06-01 00:39:508384 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]9492e4a2010-02-24 00:58:468385 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
8386
8387 std::string response_data;
8388 rv = ReadTransaction(trans.get(), &response_data);
[email protected]5543cbb2012-04-20 16:35:238389 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
[email protected]e22e1362009-11-23 21:31:128390}
8391
[email protected]23e482282013-06-14 16:08:028392TEST_P(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:158393 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:528394 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
[email protected]95d88ffe2010-02-04 21:25:338395 const uint64 kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:218396 UploadFileElementReader::ScopedOverridingContentLengthForTests
8397 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:338398
[email protected]b2d26cfd2012-12-11 10:36:068399 ScopedVector<UploadElementReader> element_readers;
8400 element_readers.push_back(
[email protected]cadac622013-06-11 16:46:368401 new UploadFileElementReader(base::MessageLoopProxy::current().get(),
8402 temp_file_path,
8403 0,
8404 kuint64max,
8405 base::Time()));
mmenkecbc2b712014-10-09 20:29:078406 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:278407
8408 HttpRequestInfo request;
8409 request.method = "POST";
8410 request.url = GURL("http://www.google.com/upload");
8411 request.upload_data_stream = &upload_data_stream;
8412 request.load_flags = 0;
8413
[email protected]3fe8d2f82013-10-17 08:56:078414 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]329b68b2012-11-14 17:54:278415 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418416 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]95d88ffe2010-02-04 21:25:338417
8418 MockRead data_reads[] = {
8419 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
8420 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068421 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:338422 };
[email protected]31a2bfe2010-02-09 08:03:398423 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078424 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:338425
[email protected]49639fa2011-12-20 23:22:418426 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:338427
[email protected]49639fa2011-12-20 23:22:418428 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]95d88ffe2010-02-04 21:25:338429 EXPECT_EQ(ERR_IO_PENDING, rv);
8430
8431 rv = callback.WaitForResult();
8432 EXPECT_EQ(OK, rv);
8433
8434 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508435 ASSERT_TRUE(response != NULL);
[email protected]95d88ffe2010-02-04 21:25:338436
[email protected]90499482013-06-01 00:39:508437 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]95d88ffe2010-02-04 21:25:338438 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
8439
8440 std::string response_data;
8441 rv = ReadTransaction(trans.get(), &response_data);
8442 EXPECT_EQ(OK, rv);
8443 EXPECT_EQ("hello world", response_data);
8444
[email protected]dd3aa792013-07-16 19:10:238445 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:338446}
8447
[email protected]23e482282013-06-14 16:08:028448TEST_P(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:158449 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:528450 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:368451 std::string temp_file_content("Unreadable file.");
[email protected]e5c2a22e2014-03-06 20:42:308452 ASSERT_TRUE(base::WriteFile(temp_file, temp_file_content.c_str(),
[email protected]6624b4622010-03-29 19:58:368453 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:118454 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:368455
[email protected]b2d26cfd2012-12-11 10:36:068456 ScopedVector<UploadElementReader> element_readers;
8457 element_readers.push_back(
[email protected]cadac622013-06-11 16:46:368458 new UploadFileElementReader(base::MessageLoopProxy::current().get(),
8459 temp_file,
8460 0,
8461 kuint64max,
8462 base::Time()));
mmenkecbc2b712014-10-09 20:29:078463 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:278464
8465 HttpRequestInfo request;
8466 request.method = "POST";
8467 request.url = GURL("http://www.google.com/upload");
8468 request.upload_data_stream = &upload_data_stream;
8469 request.load_flags = 0;
8470
[email protected]999dd8c2013-11-12 06:45:548471 // If we try to upload an unreadable file, the transaction should fail.
[email protected]3fe8d2f82013-10-17 08:56:078472 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]329b68b2012-11-14 17:54:278473 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418474 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]6624b4622010-03-29 19:58:368475
[email protected]999dd8c2013-11-12 06:45:548476 StaticSocketDataProvider data(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078477 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:368478
[email protected]49639fa2011-12-20 23:22:418479 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:368480
[email protected]49639fa2011-12-20 23:22:418481 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]6624b4622010-03-29 19:58:368482 EXPECT_EQ(ERR_IO_PENDING, rv);
8483
8484 rv = callback.WaitForResult();
[email protected]999dd8c2013-11-12 06:45:548485 EXPECT_EQ(ERR_ACCESS_DENIED, rv);
[email protected]6624b4622010-03-29 19:58:368486
8487 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]999dd8c2013-11-12 06:45:548488 EXPECT_FALSE(response);
[email protected]6624b4622010-03-29 19:58:368489
[email protected]dd3aa792013-07-16 19:10:238490 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:368491}
8492
[email protected]02cad5d2013-10-02 08:14:038493TEST_P(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
8494 class FakeUploadElementReader : public UploadElementReader {
8495 public:
8496 FakeUploadElementReader() {}
dchengb03027d2014-10-21 12:00:208497 ~FakeUploadElementReader() override {}
[email protected]02cad5d2013-10-02 08:14:038498
8499 const CompletionCallback& callback() const { return callback_; }
8500
8501 // UploadElementReader overrides:
dchengb03027d2014-10-21 12:00:208502 int Init(const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:038503 callback_ = callback;
8504 return ERR_IO_PENDING;
8505 }
dchengb03027d2014-10-21 12:00:208506 uint64 GetContentLength() const override { return 0; }
8507 uint64 BytesRemaining() const override { return 0; }
8508 int Read(IOBuffer* buf,
8509 int buf_length,
8510 const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:038511 return ERR_FAILED;
8512 }
8513
8514 private:
8515 CompletionCallback callback_;
8516 };
8517
8518 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
8519 ScopedVector<UploadElementReader> element_readers;
8520 element_readers.push_back(fake_reader);
mmenkecbc2b712014-10-09 20:29:078521 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02cad5d2013-10-02 08:14:038522
8523 HttpRequestInfo request;
8524 request.method = "POST";
8525 request.url = GURL("http://www.google.com/upload");
8526 request.upload_data_stream = &upload_data_stream;
8527 request.load_flags = 0;
8528
[email protected]3fe8d2f82013-10-17 08:56:078529 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02cad5d2013-10-02 08:14:038530 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418531 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02cad5d2013-10-02 08:14:038532
8533 StaticSocketDataProvider data;
8534 session_deps_.socket_factory->AddSocketDataProvider(&data);
8535
8536 TestCompletionCallback callback;
8537 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8538 EXPECT_EQ(ERR_IO_PENDING, rv);
8539 base::MessageLoop::current()->RunUntilIdle();
8540
8541 // Transaction is pending on request body initialization.
8542 ASSERT_FALSE(fake_reader->callback().is_null());
8543
8544 // Return Init()'s result after the transaction gets destroyed.
8545 trans.reset();
8546 fake_reader->callback().Run(OK); // Should not crash.
8547}
8548
[email protected]aeefc9e82010-02-19 16:18:278549// Tests that changes to Auth realms are treated like auth rejections.
[email protected]23e482282013-06-14 16:08:028550TEST_P(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:278551
8552 HttpRequestInfo request;
8553 request.method = "GET";
8554 request.url = GURL("http://www.google.com/");
8555 request.load_flags = 0;
8556
8557 // First transaction will request a resource and receive a Basic challenge
8558 // with realm="first_realm".
8559 MockWrite data_writes1[] = {
8560 MockWrite("GET / HTTP/1.1\r\n"
8561 "Host: www.google.com\r\n"
8562 "Connection: keep-alive\r\n"
8563 "\r\n"),
8564 };
8565 MockRead data_reads1[] = {
8566 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8567 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
8568 "\r\n"),
8569 };
8570
8571 // After calling trans->RestartWithAuth(), provide an Authentication header
8572 // for first_realm. The server will reject and provide a challenge with
8573 // second_realm.
8574 MockWrite data_writes2[] = {
8575 MockWrite("GET / HTTP/1.1\r\n"
8576 "Host: www.google.com\r\n"
8577 "Connection: keep-alive\r\n"
8578 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
8579 "\r\n"),
8580 };
8581 MockRead data_reads2[] = {
8582 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8583 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
8584 "\r\n"),
8585 };
8586
8587 // This again fails, and goes back to first_realm. Make sure that the
8588 // entry is removed from cache.
8589 MockWrite data_writes3[] = {
8590 MockWrite("GET / HTTP/1.1\r\n"
8591 "Host: www.google.com\r\n"
8592 "Connection: keep-alive\r\n"
8593 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
8594 "\r\n"),
8595 };
8596 MockRead data_reads3[] = {
8597 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8598 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
8599 "\r\n"),
8600 };
8601
8602 // Try one last time (with the correct password) and get the resource.
8603 MockWrite data_writes4[] = {
8604 MockWrite("GET / HTTP/1.1\r\n"
8605 "Host: www.google.com\r\n"
8606 "Connection: keep-alive\r\n"
8607 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
8608 "\r\n"),
8609 };
8610 MockRead data_reads4[] = {
8611 MockRead("HTTP/1.1 200 OK\r\n"
8612 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:508613 "Content-Length: 5\r\n"
8614 "\r\n"
8615 "hello"),
[email protected]aeefc9e82010-02-19 16:18:278616 };
8617
8618 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8619 data_writes1, arraysize(data_writes1));
8620 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8621 data_writes2, arraysize(data_writes2));
8622 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
8623 data_writes3, arraysize(data_writes3));
8624 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
8625 data_writes4, arraysize(data_writes4));
[email protected]bb88e1d32013-05-03 23:11:078626 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8627 session_deps_.socket_factory->AddSocketDataProvider(&data2);
8628 session_deps_.socket_factory->AddSocketDataProvider(&data3);
8629 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:278630
[email protected]49639fa2011-12-20 23:22:418631 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:278632
[email protected]3fe8d2f82013-10-17 08:56:078633 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0b0bf032010-09-21 18:08:508634 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418635 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:508636
[email protected]aeefc9e82010-02-19 16:18:278637 // Issue the first request with Authorize headers. There should be a
8638 // password prompt for first_realm waiting to be filled in after the
8639 // transaction completes.
[email protected]49639fa2011-12-20 23:22:418640 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]aeefc9e82010-02-19 16:18:278641 EXPECT_EQ(ERR_IO_PENDING, rv);
8642 rv = callback1.WaitForResult();
8643 EXPECT_EQ(OK, rv);
8644 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508645 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048646 const AuthChallengeInfo* challenge = response->auth_challenge.get();
8647 ASSERT_FALSE(challenge == NULL);
8648 EXPECT_FALSE(challenge->is_proxy);
8649 EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
8650 EXPECT_EQ("first_realm", challenge->realm);
8651 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278652
8653 // Issue the second request with an incorrect password. There should be a
8654 // password prompt for second_realm waiting to be filled in after the
8655 // transaction completes.
[email protected]49639fa2011-12-20 23:22:418656 TestCompletionCallback callback2;
8657 rv = trans->RestartWithAuth(
8658 AuthCredentials(kFirst, kBaz), callback2.callback());
[email protected]aeefc9e82010-02-19 16:18:278659 EXPECT_EQ(ERR_IO_PENDING, rv);
8660 rv = callback2.WaitForResult();
8661 EXPECT_EQ(OK, rv);
8662 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508663 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048664 challenge = response->auth_challenge.get();
8665 ASSERT_FALSE(challenge == NULL);
8666 EXPECT_FALSE(challenge->is_proxy);
8667 EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
8668 EXPECT_EQ("second_realm", challenge->realm);
8669 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278670
8671 // Issue the third request with another incorrect password. There should be
8672 // a password prompt for first_realm waiting to be filled in. If the password
8673 // prompt is not present, it indicates that the HttpAuthCacheEntry for
8674 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:418675 TestCompletionCallback callback3;
8676 rv = trans->RestartWithAuth(
8677 AuthCredentials(kSecond, kFou), callback3.callback());
[email protected]aeefc9e82010-02-19 16:18:278678 EXPECT_EQ(ERR_IO_PENDING, rv);
8679 rv = callback3.WaitForResult();
8680 EXPECT_EQ(OK, rv);
8681 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508682 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048683 challenge = response->auth_challenge.get();
8684 ASSERT_FALSE(challenge == NULL);
8685 EXPECT_FALSE(challenge->is_proxy);
8686 EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
8687 EXPECT_EQ("first_realm", challenge->realm);
8688 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278689
8690 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:418691 TestCompletionCallback callback4;
8692 rv = trans->RestartWithAuth(
8693 AuthCredentials(kFirst, kBar), callback4.callback());
[email protected]aeefc9e82010-02-19 16:18:278694 EXPECT_EQ(ERR_IO_PENDING, rv);
8695 rv = callback4.WaitForResult();
8696 EXPECT_EQ(OK, rv);
8697 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508698 ASSERT_TRUE(response != NULL);
[email protected]aeefc9e82010-02-19 16:18:278699 EXPECT_TRUE(response->auth_challenge.get() == NULL);
8700}
8701
[email protected]23e482282013-06-14 16:08:028702TEST_P(HttpNetworkTransactionTest, HonorAlternateProtocolHeader) {
[email protected]d7599122014-05-24 03:37:238703 session_deps_.next_protos = SpdyNextProtos();
8704 session_deps_.use_alternate_protocols = true;
[email protected]a2cb8122010-03-10 17:22:428705
[email protected]8a0fc822013-06-27 20:52:438706 std::string alternate_protocol_http_header =
8707 GetAlternateProtocolHttpHeader();
8708
[email protected]564b4912010-03-09 16:30:428709 MockRead data_reads[] = {
8710 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438711 MockRead(alternate_protocol_http_header.c_str()),
[email protected]564b4912010-03-09 16:30:428712 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068713 MockRead(SYNCHRONOUS, OK),
[email protected]564b4912010-03-09 16:30:428714 };
8715
8716 HttpRequestInfo request;
8717 request.method = "GET";
8718 request.url = GURL("http://www.google.com/");
8719 request.load_flags = 0;
8720
8721 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
8722
[email protected]bb88e1d32013-05-03 23:11:078723 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]564b4912010-03-09 16:30:428724
[email protected]49639fa2011-12-20 23:22:418725 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:428726
[email protected]bb88e1d32013-05-03 23:11:078727 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:368728 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508729 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]564b4912010-03-09 16:30:428730
[email protected]49639fa2011-12-20 23:22:418731 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:428732 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]9e743cd2010-03-16 07:03:538733
[email protected]2fbaecf22010-07-22 22:20:358734 HostPortPair http_host_port_pair("www.google.com", 80);
[email protected]9801e3702014-03-07 09:33:558735 HttpServerProperties& http_server_properties =
[email protected]17291a022011-10-10 07:32:538736 *session->http_server_properties();
bnc3c2553312015-02-03 23:12:018737 AlternateProtocolInfo alternate =
8738 http_server_properties.GetAlternateProtocol(http_host_port_pair);
8739 EXPECT_EQ(alternate.protocol, UNINITIALIZED_ALTERNATE_PROTOCOL);
[email protected]564b4912010-03-09 16:30:428740
8741 EXPECT_EQ(OK, callback.WaitForResult());
8742
8743 const HttpResponseInfo* response = trans->GetResponseInfo();
8744 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508745 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:428746 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:538747 EXPECT_FALSE(response->was_fetched_via_spdy);
8748 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]564b4912010-03-09 16:30:428749
8750 std::string response_data;
8751 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8752 EXPECT_EQ("hello world", response_data);
8753
bnc3c2553312015-02-03 23:12:018754 alternate = http_server_properties.GetAlternateProtocol(http_host_port_pair);
8755 EXPECT_EQ(443, alternate.port);
8756 EXPECT_EQ(AlternateProtocolFromNextProto(GetParam()), alternate.protocol);
8757 EXPECT_EQ(1.0, alternate.probability);
[email protected]564b4912010-03-09 16:30:428758}
8759
[email protected]23e482282013-06-14 16:08:028760TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238761 MarkBrokenAlternateProtocolAndFallback) {
[email protected]d7599122014-05-24 03:37:238762 session_deps_.use_alternate_protocols = true;
[email protected]564b4912010-03-09 16:30:428763
8764 HttpRequestInfo request;
8765 request.method = "GET";
8766 request.url = GURL("http://www.google.com/");
8767 request.load_flags = 0;
8768
[email protected]d973e99a2012-02-17 21:02:368769 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:428770 StaticSocketDataProvider first_data;
8771 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078772 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]564b4912010-03-09 16:30:428773
8774 MockRead data_reads[] = {
8775 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8776 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068777 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:428778 };
8779 StaticSocketDataProvider second_data(
8780 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078781 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:428782
[email protected]bb88e1d32013-05-03 23:11:078783 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:428784
[email protected]30d4c022013-07-18 22:58:168785 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538786 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118787 // Port must be < 1024, or the header will be ignored (since initial port was
8788 // port 80 (another restricted port).
[email protected]17291a022011-10-10 07:32:538789 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118790 HostPortPair::FromURL(request.url),
8791 666 /* port is ignored by MockConnect anyway */,
bnc1102b552015-01-30 20:11:018792 AlternateProtocolFromNextProto(GetParam()), 1.0);
[email protected]564b4912010-03-09 16:30:428793
[email protected]262eec82013-03-19 21:01:368794 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508795 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418796 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:428797
[email protected]49639fa2011-12-20 23:22:418798 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:428799 EXPECT_EQ(ERR_IO_PENDING, rv);
8800 EXPECT_EQ(OK, callback.WaitForResult());
8801
8802 const HttpResponseInfo* response = trans->GetResponseInfo();
8803 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508804 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:428805 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8806
8807 std::string response_data;
8808 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8809 EXPECT_EQ("hello world", response_data);
8810
[email protected]287d9412014-07-08 23:01:008811 const AlternateProtocolInfo alternate =
[email protected]17291a022011-10-10 07:32:538812 http_server_properties->GetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118813 HostPortPair::FromURL(request.url));
bnc3c2553312015-02-03 23:12:018814 EXPECT_NE(UNINITIALIZED_ALTERNATE_PROTOCOL, alternate.protocol);
bnccbd55d5f2014-11-06 19:50:408815 EXPECT_TRUE(alternate.is_broken);
[email protected]564b4912010-03-09 16:30:428816}
8817
[email protected]23e482282013-06-14 16:08:028818TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238819 AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:118820 // Ensure that we're not allowed to redirect traffic via an alternate
8821 // protocol to an unrestricted (port >= 1024) when the original traffic was
8822 // on a restricted port (port < 1024). Ensure that we can redirect in all
8823 // other cases.
[email protected]d7599122014-05-24 03:37:238824 session_deps_.use_alternate_protocols = true;
[email protected]3912662a32011-10-04 00:51:118825
8826 HttpRequestInfo restricted_port_request;
8827 restricted_port_request.method = "GET";
8828 restricted_port_request.url = GURL("http://www.google.com:1023/");
8829 restricted_port_request.load_flags = 0;
8830
[email protected]d973e99a2012-02-17 21:02:368831 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118832 StaticSocketDataProvider first_data;
8833 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078834 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118835
8836 MockRead data_reads[] = {
8837 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8838 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068839 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118840 };
8841 StaticSocketDataProvider second_data(
8842 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078843 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118844
[email protected]bb88e1d32013-05-03 23:11:078845 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118846
[email protected]30d4c022013-07-18 22:58:168847 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538848 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118849 const int kUnrestrictedAlternatePort = 1024;
[email protected]17291a022011-10-10 07:32:538850 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118851 HostPortPair::FromURL(restricted_port_request.url),
bnc1102b552015-01-30 20:11:018852 kUnrestrictedAlternatePort, AlternateProtocolFromNextProto(GetParam()),
8853 1.0);
[email protected]3912662a32011-10-04 00:51:118854
[email protected]262eec82013-03-19 21:01:368855 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508856 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418857 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118858
[email protected]49639fa2011-12-20 23:22:418859 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:368860 &restricted_port_request,
8861 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118862 EXPECT_EQ(ERR_IO_PENDING, rv);
8863 // Invalid change to unrestricted port should fail.
8864 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.WaitForResult());
[email protected]c54c6962013-02-01 04:53:198865}
[email protected]3912662a32011-10-04 00:51:118866
[email protected]23e482282013-06-14 16:08:028867TEST_P(HttpNetworkTransactionTest,
[email protected]c54c6962013-02-01 04:53:198868 AlternateProtocolPortRestrictedPermitted) {
8869 // Ensure that we're allowed to redirect traffic via an alternate
8870 // protocol to an unrestricted (port >= 1024) when the original traffic was
8871 // on a restricted port (port < 1024) if we set
8872 // enable_user_alternate_protocol_ports.
8873
[email protected]d7599122014-05-24 03:37:238874 session_deps_.use_alternate_protocols = true;
[email protected]bb88e1d32013-05-03 23:11:078875 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:198876
8877 HttpRequestInfo restricted_port_request;
8878 restricted_port_request.method = "GET";
8879 restricted_port_request.url = GURL("http://www.google.com:1023/");
8880 restricted_port_request.load_flags = 0;
8881
8882 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
8883 StaticSocketDataProvider first_data;
8884 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078885 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:198886
8887 MockRead data_reads[] = {
8888 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8889 MockRead("hello world"),
8890 MockRead(ASYNC, OK),
8891 };
8892 StaticSocketDataProvider second_data(
8893 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078894 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]c54c6962013-02-01 04:53:198895
[email protected]bb88e1d32013-05-03 23:11:078896 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:198897
[email protected]30d4c022013-07-18 22:58:168898 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]c54c6962013-02-01 04:53:198899 session->http_server_properties();
8900 const int kUnrestrictedAlternatePort = 1024;
8901 http_server_properties->SetAlternateProtocol(
8902 HostPortPair::FromURL(restricted_port_request.url),
bnc1102b552015-01-30 20:11:018903 kUnrestrictedAlternatePort, AlternateProtocolFromNextProto(GetParam()),
8904 1.0);
[email protected]c54c6962013-02-01 04:53:198905
[email protected]262eec82013-03-19 21:01:368906 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508907 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]c54c6962013-02-01 04:53:198908 TestCompletionCallback callback;
8909
8910 EXPECT_EQ(ERR_IO_PENDING, trans->Start(
[email protected]262eec82013-03-19 21:01:368911 &restricted_port_request,
8912 callback.callback(), BoundNetLog()));
[email protected]c54c6962013-02-01 04:53:198913 // Change to unrestricted port should succeed.
8914 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:118915}
8916
[email protected]23e482282013-06-14 16:08:028917TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238918 AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:118919 // Ensure that we're not allowed to redirect traffic via an alternate
8920 // protocol to an unrestricted (port >= 1024) when the original traffic was
8921 // on a restricted port (port < 1024). Ensure that we can redirect in all
8922 // other cases.
[email protected]d7599122014-05-24 03:37:238923 session_deps_.use_alternate_protocols = true;
[email protected]3912662a32011-10-04 00:51:118924
8925 HttpRequestInfo restricted_port_request;
8926 restricted_port_request.method = "GET";
8927 restricted_port_request.url = GURL("http://www.google.com:1023/");
8928 restricted_port_request.load_flags = 0;
8929
[email protected]d973e99a2012-02-17 21:02:368930 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118931 StaticSocketDataProvider first_data;
8932 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078933 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118934
8935 MockRead data_reads[] = {
8936 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8937 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068938 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118939 };
8940 StaticSocketDataProvider second_data(
8941 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078942 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118943
[email protected]bb88e1d32013-05-03 23:11:078944 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118945
[email protected]30d4c022013-07-18 22:58:168946 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538947 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118948 const int kRestrictedAlternatePort = 80;
[email protected]17291a022011-10-10 07:32:538949 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118950 HostPortPair::FromURL(restricted_port_request.url),
bnc1102b552015-01-30 20:11:018951 kRestrictedAlternatePort, AlternateProtocolFromNextProto(GetParam()),
8952 1.0);
[email protected]3912662a32011-10-04 00:51:118953
[email protected]262eec82013-03-19 21:01:368954 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508955 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418956 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118957
[email protected]49639fa2011-12-20 23:22:418958 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:368959 &restricted_port_request,
8960 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118961 EXPECT_EQ(ERR_IO_PENDING, rv);
8962 // Valid change to restricted port should pass.
8963 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:118964}
8965
[email protected]23e482282013-06-14 16:08:028966TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238967 AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:118968 // Ensure that we're not allowed to redirect traffic via an alternate
8969 // protocol to an unrestricted (port >= 1024) when the original traffic was
8970 // on a restricted port (port < 1024). Ensure that we can redirect in all
8971 // other cases.
[email protected]d7599122014-05-24 03:37:238972 session_deps_.use_alternate_protocols = true;
[email protected]3912662a32011-10-04 00:51:118973
8974 HttpRequestInfo unrestricted_port_request;
8975 unrestricted_port_request.method = "GET";
8976 unrestricted_port_request.url = GURL("http://www.google.com:1024/");
8977 unrestricted_port_request.load_flags = 0;
8978
[email protected]d973e99a2012-02-17 21:02:368979 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118980 StaticSocketDataProvider first_data;
8981 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078982 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118983
8984 MockRead data_reads[] = {
8985 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8986 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068987 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118988 };
8989 StaticSocketDataProvider second_data(
8990 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078991 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118992
[email protected]bb88e1d32013-05-03 23:11:078993 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118994
[email protected]30d4c022013-07-18 22:58:168995 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538996 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118997 const int kRestrictedAlternatePort = 80;
[email protected]17291a022011-10-10 07:32:538998 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118999 HostPortPair::FromURL(unrestricted_port_request.url),
bnc1102b552015-01-30 20:11:019000 kRestrictedAlternatePort, AlternateProtocolFromNextProto(GetParam()),
9001 1.0);
[email protected]3912662a32011-10-04 00:51:119002
[email protected]262eec82013-03-19 21:01:369003 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509004 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419005 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:119006
[email protected]49639fa2011-12-20 23:22:419007 int rv = trans->Start(
9008 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:119009 EXPECT_EQ(ERR_IO_PENDING, rv);
9010 // Valid change to restricted port should pass.
9011 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:119012}
9013
[email protected]23e482282013-06-14 16:08:029014TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239015 AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:119016 // Ensure that we're not allowed to redirect traffic via an alternate
9017 // protocol to an unrestricted (port >= 1024) when the original traffic was
9018 // on a restricted port (port < 1024). Ensure that we can redirect in all
9019 // other cases.
[email protected]d7599122014-05-24 03:37:239020 session_deps_.use_alternate_protocols = true;
[email protected]3912662a32011-10-04 00:51:119021
9022 HttpRequestInfo unrestricted_port_request;
9023 unrestricted_port_request.method = "GET";
9024 unrestricted_port_request.url = GURL("http://www.google.com:1024/");
9025 unrestricted_port_request.load_flags = 0;
9026
[email protected]d973e99a2012-02-17 21:02:369027 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:119028 StaticSocketDataProvider first_data;
9029 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079030 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:119031
9032 MockRead data_reads[] = {
9033 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9034 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069035 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:119036 };
9037 StaticSocketDataProvider second_data(
9038 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079039 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:119040
[email protected]bb88e1d32013-05-03 23:11:079041 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:119042
[email protected]30d4c022013-07-18 22:58:169043 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:539044 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:119045 const int kUnrestrictedAlternatePort = 1024;
[email protected]17291a022011-10-10 07:32:539046 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:119047 HostPortPair::FromURL(unrestricted_port_request.url),
bnc1102b552015-01-30 20:11:019048 kUnrestrictedAlternatePort, AlternateProtocolFromNextProto(GetParam()),
9049 1.0);
[email protected]3912662a32011-10-04 00:51:119050
[email protected]262eec82013-03-19 21:01:369051 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509052 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419053 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:119054
[email protected]49639fa2011-12-20 23:22:419055 int rv = trans->Start(
9056 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:119057 EXPECT_EQ(ERR_IO_PENDING, rv);
9058 // Valid change to an unrestricted port should pass.
9059 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:119060}
9061
[email protected]d7599122014-05-24 03:37:239062TEST_P(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:029063 // Ensure that we're not allowed to redirect traffic via an alternate
9064 // protocol to an unsafe port, and that we resume the second
9065 // HttpStreamFactoryImpl::Job once the alternate protocol request fails.
[email protected]d7599122014-05-24 03:37:239066 session_deps_.use_alternate_protocols = true;
[email protected]eb6234e2012-01-19 01:50:029067
9068 HttpRequestInfo request;
9069 request.method = "GET";
9070 request.url = GURL("http://www.google.com/");
9071 request.load_flags = 0;
9072
9073 // The alternate protocol request will error out before we attempt to connect,
9074 // so only the standard HTTP request will try to connect.
9075 MockRead data_reads[] = {
9076 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9077 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069078 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:029079 };
9080 StaticSocketDataProvider data(
9081 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079082 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:029083
[email protected]bb88e1d32013-05-03 23:11:079084 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:029085
[email protected]30d4c022013-07-18 22:58:169086 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]eb6234e2012-01-19 01:50:029087 session->http_server_properties();
9088 const int kUnsafePort = 7;
9089 http_server_properties->SetAlternateProtocol(
bnc1102b552015-01-30 20:11:019090 HostPortPair::FromURL(request.url), kUnsafePort,
9091 AlternateProtocolFromNextProto(GetParam()), 1.0);
[email protected]eb6234e2012-01-19 01:50:029092
[email protected]262eec82013-03-19 21:01:369093 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509094 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]eb6234e2012-01-19 01:50:029095 TestCompletionCallback callback;
9096
9097 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9098 EXPECT_EQ(ERR_IO_PENDING, rv);
9099 // The HTTP request should succeed.
9100 EXPECT_EQ(OK, callback.WaitForResult());
9101
9102 // Disable alternate protocol before the asserts.
[email protected]d7599122014-05-24 03:37:239103 // HttpStreamFactory::set_use_alternate_protocols(false);
[email protected]eb6234e2012-01-19 01:50:029104
9105 const HttpResponseInfo* response = trans->GetResponseInfo();
9106 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509107 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]eb6234e2012-01-19 01:50:029108 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9109
9110 std::string response_data;
9111 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9112 EXPECT_EQ("hello world", response_data);
9113}
9114
[email protected]23e482282013-06-14 16:08:029115TEST_P(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]d7599122014-05-24 03:37:239116 session_deps_.use_alternate_protocols = true;
9117 session_deps_.next_protos = SpdyNextProtos();
[email protected]2ff8b312010-04-26 22:20:549118
9119 HttpRequestInfo request;
9120 request.method = "GET";
9121 request.url = GURL("http://www.google.com/");
9122 request.load_flags = 0;
9123
[email protected]8a0fc822013-06-27 20:52:439124 std::string alternate_protocol_http_header =
9125 GetAlternateProtocolHttpHeader();
9126
[email protected]2ff8b312010-04-26 22:20:549127 MockRead data_reads[] = {
9128 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439129 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2ff8b312010-04-26 22:20:549130 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:179131 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
9132 MockRead(ASYNC, OK)
[email protected]2ff8b312010-04-26 22:20:549133 };
9134
9135 StaticSocketDataProvider first_transaction(
9136 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079137 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:549138
[email protected]8ddf8322012-02-23 18:08:069139 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029140 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:079141 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:549142
[email protected]cdf8f7e72013-05-23 10:56:469143 scoped_ptr<SpdyFrame> req(
9144 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]e7f75092010-07-01 22:39:139145 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
[email protected]2ff8b312010-04-26 22:20:549146
[email protected]23e482282013-06-14 16:08:029147 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9148 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:549149 MockRead spdy_reads[] = {
[email protected]e7f75092010-07-01 22:39:139150 CreateMockRead(*resp),
9151 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:069152 MockRead(ASYNC, 0, 0),
[email protected]2ff8b312010-04-26 22:20:549153 };
9154
[email protected]dd54bd82012-07-19 23:44:579155 DelayedSocketData spdy_data(
9156 1, // wait for one write to finish before reading.
9157 spdy_reads, arraysize(spdy_reads),
9158 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079159 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:549160
[email protected]d973e99a2012-02-17 21:02:369161 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559162 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
9163 NULL, 0, NULL, 0);
9164 hanging_non_alternate_protocol_socket.set_connect_data(
9165 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:079166 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:559167 &hanging_non_alternate_protocol_socket);
9168
[email protected]49639fa2011-12-20 23:22:419169 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:549170
[email protected]bb88e1d32013-05-03 23:11:079171 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369172 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509173 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:549174
[email protected]49639fa2011-12-20 23:22:419175 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:549176 EXPECT_EQ(ERR_IO_PENDING, rv);
9177 EXPECT_EQ(OK, callback.WaitForResult());
9178
9179 const HttpResponseInfo* response = trans->GetResponseInfo();
9180 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509181 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:549182 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9183
9184 std::string response_data;
9185 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9186 EXPECT_EQ("hello world", response_data);
9187
[email protected]90499482013-06-01 00:39:509188 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:549189
[email protected]49639fa2011-12-20 23:22:419190 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:549191 EXPECT_EQ(ERR_IO_PENDING, rv);
9192 EXPECT_EQ(OK, callback.WaitForResult());
9193
9194 response = trans->GetResponseInfo();
9195 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509196 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:549197 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539198 EXPECT_TRUE(response->was_fetched_via_spdy);
9199 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:549200
9201 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9202 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:549203}
9204
[email protected]23e482282013-06-14 16:08:029205TEST_P(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]d7599122014-05-24 03:37:239206 session_deps_.use_alternate_protocols = true;
9207 session_deps_.next_protos = SpdyNextProtos();
[email protected]2d6728692011-03-12 01:39:559208
9209 HttpRequestInfo request;
9210 request.method = "GET";
9211 request.url = GURL("http://www.google.com/");
9212 request.load_flags = 0;
9213
[email protected]8a0fc822013-06-27 20:52:439214 std::string alternate_protocol_http_header =
9215 GetAlternateProtocolHttpHeader();
9216
[email protected]2d6728692011-03-12 01:39:559217 MockRead data_reads[] = {
9218 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439219 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2d6728692011-03-12 01:39:559220 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:179221 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:069222 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:559223 };
9224
9225 StaticSocketDataProvider first_transaction(
9226 data_reads, arraysize(data_reads), NULL, 0);
9227 // Socket 1 is the HTTP transaction with the Alternate-Protocol header.
[email protected]bb88e1d32013-05-03 23:11:079228 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:559229
[email protected]d973e99a2012-02-17 21:02:369230 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559231 StaticSocketDataProvider hanging_socket(
9232 NULL, 0, NULL, 0);
9233 hanging_socket.set_connect_data(never_finishing_connect);
9234 // Socket 2 and 3 are the hanging Alternate-Protocol and
9235 // non-Alternate-Protocol jobs from the 2nd transaction.
[email protected]bb88e1d32013-05-03 23:11:079236 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
9237 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
[email protected]2d6728692011-03-12 01:39:559238
[email protected]8ddf8322012-02-23 18:08:069239 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029240 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:079241 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:559242
[email protected]cdf8f7e72013-05-23 10:56:469243 scoped_ptr<SpdyFrame> req1(
9244 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
9245 scoped_ptr<SpdyFrame> req2(
9246 spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
[email protected]2d6728692011-03-12 01:39:559247 MockWrite spdy_writes[] = {
9248 CreateMockWrite(*req1),
9249 CreateMockWrite(*req2),
9250 };
[email protected]23e482282013-06-14 16:08:029251 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9252 scoped_ptr<SpdyFrame> data1(spdy_util_.ConstructSpdyBodyFrame(1, true));
9253 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
9254 scoped_ptr<SpdyFrame> data2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]2d6728692011-03-12 01:39:559255 MockRead spdy_reads[] = {
9256 CreateMockRead(*resp1),
9257 CreateMockRead(*data1),
9258 CreateMockRead(*resp2),
9259 CreateMockRead(*data2),
[email protected]8ddf8322012-02-23 18:08:069260 MockRead(ASYNC, 0, 0),
[email protected]2d6728692011-03-12 01:39:559261 };
9262
[email protected]dd54bd82012-07-19 23:44:579263 DelayedSocketData spdy_data(
9264 2, // wait for writes to finish before reading.
9265 spdy_reads, arraysize(spdy_reads),
9266 spdy_writes, arraysize(spdy_writes));
[email protected]2d6728692011-03-12 01:39:559267 // Socket 4 is the successful Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:079268 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:559269
9270 // Socket 5 is the unsuccessful non-Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:079271 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
[email protected]2d6728692011-03-12 01:39:559272
[email protected]bb88e1d32013-05-03 23:11:079273 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:419274 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:509275 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:559276
[email protected]49639fa2011-12-20 23:22:419277 int rv = trans1.Start(&request, callback1.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559278 EXPECT_EQ(ERR_IO_PENDING, rv);
9279 EXPECT_EQ(OK, callback1.WaitForResult());
9280
9281 const HttpResponseInfo* response = trans1.GetResponseInfo();
9282 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509283 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559284 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9285
9286 std::string response_data;
9287 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
9288 EXPECT_EQ("hello world", response_data);
9289
[email protected]49639fa2011-12-20 23:22:419290 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:509291 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:419292 rv = trans2.Start(&request, callback2.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559293 EXPECT_EQ(ERR_IO_PENDING, rv);
9294
[email protected]49639fa2011-12-20 23:22:419295 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:509296 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:419297 rv = trans3.Start(&request, callback3.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559298 EXPECT_EQ(ERR_IO_PENDING, rv);
9299
9300 EXPECT_EQ(OK, callback2.WaitForResult());
9301 EXPECT_EQ(OK, callback3.WaitForResult());
9302
9303 response = trans2.GetResponseInfo();
9304 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509305 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559306 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9307 EXPECT_TRUE(response->was_fetched_via_spdy);
9308 EXPECT_TRUE(response->was_npn_negotiated);
9309 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
9310 EXPECT_EQ("hello!", response_data);
9311
9312 response = trans3.GetResponseInfo();
9313 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509314 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559315 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9316 EXPECT_TRUE(response->was_fetched_via_spdy);
9317 EXPECT_TRUE(response->was_npn_negotiated);
9318 ASSERT_EQ(OK, ReadTransaction(&trans3, &response_data));
9319 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:559320}
9321
[email protected]23e482282013-06-14 16:08:029322TEST_P(HttpNetworkTransactionTest, StallAlternateProtocolForNpnSpdy) {
[email protected]d7599122014-05-24 03:37:239323 session_deps_.use_alternate_protocols = true;
9324 session_deps_.next_protos = SpdyNextProtos();
[email protected]2d6728692011-03-12 01:39:559325
9326 HttpRequestInfo request;
9327 request.method = "GET";
9328 request.url = GURL("http://www.google.com/");
9329 request.load_flags = 0;
9330
[email protected]8a0fc822013-06-27 20:52:439331 std::string alternate_protocol_http_header =
9332 GetAlternateProtocolHttpHeader();
9333
[email protected]2d6728692011-03-12 01:39:559334 MockRead data_reads[] = {
9335 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439336 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2d6728692011-03-12 01:39:559337 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:179338 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:069339 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:559340 };
9341
9342 StaticSocketDataProvider first_transaction(
9343 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079344 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:559345
[email protected]8ddf8322012-02-23 18:08:069346 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029347 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:079348 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:559349
[email protected]d973e99a2012-02-17 21:02:369350 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559351 StaticSocketDataProvider hanging_alternate_protocol_socket(
9352 NULL, 0, NULL, 0);
9353 hanging_alternate_protocol_socket.set_connect_data(
9354 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:079355 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:559356 &hanging_alternate_protocol_socket);
9357
9358 // 2nd request is just a copy of the first one, over HTTP again.
[email protected]bb88e1d32013-05-03 23:11:079359 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:559360
[email protected]49639fa2011-12-20 23:22:419361 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:559362
[email protected]bb88e1d32013-05-03 23:11:079363 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369364 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509365 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:559366
[email protected]49639fa2011-12-20 23:22:419367 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559368 EXPECT_EQ(ERR_IO_PENDING, rv);
9369 EXPECT_EQ(OK, callback.WaitForResult());
9370
9371 const HttpResponseInfo* response = trans->GetResponseInfo();
9372 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509373 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559374 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9375
9376 std::string response_data;
9377 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9378 EXPECT_EQ("hello world", response_data);
9379
[email protected]90499482013-06-01 00:39:509380 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:559381
[email protected]49639fa2011-12-20 23:22:419382 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559383 EXPECT_EQ(ERR_IO_PENDING, rv);
9384 EXPECT_EQ(OK, callback.WaitForResult());
9385
9386 response = trans->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_FALSE(response->was_fetched_via_spdy);
9391 EXPECT_FALSE(response->was_npn_negotiated);
9392
9393 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9394 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:559395}
9396
[email protected]631f1322010-04-30 17:59:119397class CapturingProxyResolver : public ProxyResolver {
9398 public:
9399 CapturingProxyResolver() : ProxyResolver(false /* expects_pac_bytes */) {}
dchengb03027d2014-10-21 12:00:209400 ~CapturingProxyResolver() override {}
[email protected]631f1322010-04-30 17:59:119401
dchengb03027d2014-10-21 12:00:209402 int GetProxyForURL(const GURL& url,
9403 ProxyInfo* results,
9404 const CompletionCallback& callback,
9405 RequestHandle* request,
9406 const BoundNetLog& net_log) override {
[email protected]fae7669f2010-08-02 21:49:409407 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
9408 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:429409 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:119410 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:429411 return OK;
[email protected]631f1322010-04-30 17:59:119412 }
9413
dchengb03027d2014-10-21 12:00:209414 void CancelRequest(RequestHandle request) override { NOTREACHED(); }
[email protected]631f1322010-04-30 17:59:119415
dchengb03027d2014-10-21 12:00:209416 LoadState GetLoadState(RequestHandle request) const override {
[email protected]f2c971f2011-11-08 00:33:179417 NOTREACHED();
9418 return LOAD_STATE_IDLE;
9419 }
9420
dchengb03027d2014-10-21 12:00:209421 void CancelSetPacScript() override { NOTREACHED(); }
[email protected]1e605472010-12-16 21:41:409422
dchengb03027d2014-10-21 12:00:209423 int SetPacScript(const scoped_refptr<ProxyResolverScriptData>&,
9424 const CompletionCallback& /*callback*/) override {
[email protected]d911f1b2010-05-05 22:39:429425 return OK;
[email protected]631f1322010-04-30 17:59:119426 }
9427
[email protected]24476402010-07-20 20:55:179428 const std::vector<GURL>& resolved() const { return resolved_; }
9429
9430 private:
[email protected]631f1322010-04-30 17:59:119431 std::vector<GURL> resolved_;
9432
9433 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
9434};
9435
[email protected]23e482282013-06-14 16:08:029436TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239437 UseAlternateProtocolForTunneledNpnSpdy) {
[email protected]d7599122014-05-24 03:37:239438 session_deps_.use_alternate_protocols = true;
9439 session_deps_.next_protos = SpdyNextProtos();
[email protected]631f1322010-04-30 17:59:119440
9441 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:429442 proxy_config.set_auto_detect(true);
9443 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:119444
[email protected]631f1322010-04-30 17:59:119445 CapturingProxyResolver* capturing_proxy_resolver =
9446 new CapturingProxyResolver();
[email protected]bb88e1d32013-05-03 23:11:079447 session_deps_.proxy_service.reset(new ProxyService(
[email protected]66761b952010-06-25 21:30:389448 new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver,
9449 NULL));
[email protected]029c83b62013-01-24 05:28:209450 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079451 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:119452
9453 HttpRequestInfo request;
9454 request.method = "GET";
9455 request.url = GURL("http://www.google.com/");
9456 request.load_flags = 0;
9457
[email protected]8a0fc822013-06-27 20:52:439458 std::string alternate_protocol_http_header =
9459 GetAlternateProtocolHttpHeader();
9460
[email protected]631f1322010-04-30 17:59:119461 MockRead data_reads[] = {
9462 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439463 MockRead(alternate_protocol_http_header.c_str()),
[email protected]631f1322010-04-30 17:59:119464 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:179465 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:069466 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:119467 };
9468
9469 StaticSocketDataProvider first_transaction(
9470 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079471 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]631f1322010-04-30 17:59:119472
[email protected]8ddf8322012-02-23 18:08:069473 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029474 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:079475 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]631f1322010-04-30 17:59:119476
[email protected]cdf8f7e72013-05-23 10:56:469477 scoped_ptr<SpdyFrame> req(
9478 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]631f1322010-04-30 17:59:119479 MockWrite spdy_writes[] = {
9480 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
9481 "Host: www.google.com\r\n"
[email protected]d911f1b2010-05-05 22:39:429482 "Proxy-Connection: keep-alive\r\n\r\n"), // 0
[email protected]cdf8f7e72013-05-23 10:56:469483 CreateMockWrite(*req), // 3
[email protected]631f1322010-04-30 17:59:119484 };
9485
[email protected]d911f1b2010-05-05 22:39:429486 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
9487
[email protected]23e482282013-06-14 16:08:029488 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9489 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]631f1322010-04-30 17:59:119490 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:069491 MockRead(ASYNC, kCONNECTResponse, arraysize(kCONNECTResponse) - 1, 1), // 1
[email protected]e7f75092010-07-01 22:39:139492 CreateMockRead(*resp.get(), 4), // 2, 4
9493 CreateMockRead(*data.get(), 4), // 5
[email protected]8ddf8322012-02-23 18:08:069494 MockRead(ASYNC, 0, 0, 4), // 6
[email protected]631f1322010-04-30 17:59:119495 };
9496
[email protected]dd54bd82012-07-19 23:44:579497 OrderedSocketData spdy_data(
9498 spdy_reads, arraysize(spdy_reads),
9499 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079500 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:119501
[email protected]d973e99a2012-02-17 21:02:369502 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559503 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
9504 NULL, 0, NULL, 0);
9505 hanging_non_alternate_protocol_socket.set_connect_data(
9506 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:079507 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:559508 &hanging_non_alternate_protocol_socket);
9509
[email protected]49639fa2011-12-20 23:22:419510 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:119511
[email protected]bb88e1d32013-05-03 23:11:079512 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369513 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509514 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:119515
[email protected]49639fa2011-12-20 23:22:419516 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:119517 EXPECT_EQ(ERR_IO_PENDING, rv);
9518 EXPECT_EQ(OK, callback.WaitForResult());
9519
9520 const HttpResponseInfo* response = trans->GetResponseInfo();
9521 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509522 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]631f1322010-04-30 17:59:119523 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539524 EXPECT_FALSE(response->was_fetched_via_spdy);
9525 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:119526
9527 std::string response_data;
9528 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9529 EXPECT_EQ("hello world", response_data);
9530
[email protected]90499482013-06-01 00:39:509531 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:119532
[email protected]49639fa2011-12-20 23:22:419533 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:119534 EXPECT_EQ(ERR_IO_PENDING, rv);
9535 EXPECT_EQ(OK, callback.WaitForResult());
9536
9537 response = trans->GetResponseInfo();
9538 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509539 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]631f1322010-04-30 17:59:119540 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539541 EXPECT_TRUE(response->was_fetched_via_spdy);
9542 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:119543
9544 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9545 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:559546 ASSERT_EQ(3u, capturing_proxy_resolver->resolved().size());
[email protected]d911f1b2010-05-05 22:39:429547 EXPECT_EQ("http://www.google.com/",
[email protected]631f1322010-04-30 17:59:119548 capturing_proxy_resolver->resolved()[0].spec());
[email protected]d911f1b2010-05-05 22:39:429549 EXPECT_EQ("https://www.google.com/",
9550 capturing_proxy_resolver->resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:119551
[email protected]029c83b62013-01-24 05:28:209552 LoadTimingInfo load_timing_info;
9553 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
9554 TestLoadTimingNotReusedWithPac(load_timing_info,
9555 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:119556}
[email protected]631f1322010-04-30 17:59:119557
[email protected]23e482282013-06-14 16:08:029558TEST_P(HttpNetworkTransactionTest,
[email protected]2ff8b312010-04-26 22:20:549559 UseAlternateProtocolForNpnSpdyWithExistingSpdySession) {
[email protected]d7599122014-05-24 03:37:239560 session_deps_.use_alternate_protocols = true;
9561 session_deps_.next_protos = SpdyNextProtos();
[email protected]2ff8b312010-04-26 22:20:549562
9563 HttpRequestInfo request;
9564 request.method = "GET";
9565 request.url = GURL("http://www.google.com/");
9566 request.load_flags = 0;
9567
[email protected]8a0fc822013-06-27 20:52:439568 std::string alternate_protocol_http_header =
9569 GetAlternateProtocolHttpHeader();
9570
[email protected]2ff8b312010-04-26 22:20:549571 MockRead data_reads[] = {
9572 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439573 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2ff8b312010-04-26 22:20:549574 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069575 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:549576 };
9577
9578 StaticSocketDataProvider first_transaction(
9579 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079580 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:549581
[email protected]8ddf8322012-02-23 18:08:069582 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029583 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:079584 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:549585
[email protected]cdf8f7e72013-05-23 10:56:469586 scoped_ptr<SpdyFrame> req(
9587 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]e7f75092010-07-01 22:39:139588 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
[email protected]2ff8b312010-04-26 22:20:549589
[email protected]23e482282013-06-14 16:08:029590 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9591 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:549592 MockRead spdy_reads[] = {
[email protected]e7f75092010-07-01 22:39:139593 CreateMockRead(*resp),
9594 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:069595 MockRead(ASYNC, 0, 0),
[email protected]2ff8b312010-04-26 22:20:549596 };
9597
[email protected]dd54bd82012-07-19 23:44:579598 DelayedSocketData spdy_data(
9599 1, // wait for one write to finish before reading.
9600 spdy_reads, arraysize(spdy_reads),
9601 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079602 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:549603
[email protected]83039bb2011-12-09 18:43:559604 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:549605
[email protected]bb88e1d32013-05-03 23:11:079606 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:549607
[email protected]262eec82013-03-19 21:01:369608 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509609 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:549610
[email protected]49639fa2011-12-20 23:22:419611 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:549612 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:419613 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:549614
9615 const HttpResponseInfo* response = trans->GetResponseInfo();
9616 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509617 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:549618 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9619
9620 std::string response_data;
9621 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9622 EXPECT_EQ("hello world", response_data);
9623
9624 // Set up an initial SpdySession in the pool to reuse.
[email protected]02b0c342010-09-25 21:09:389625 HostPortPair host_port_pair("www.google.com", 443);
[email protected]e6d017652013-05-17 18:01:409626 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:539627 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:279628 base::WeakPtr<SpdySession> spdy_session =
[email protected]41d64e82013-07-03 22:44:269629 CreateSecureSpdySession(session, key, BoundNetLog());
[email protected]02b0c342010-09-25 21:09:389630
[email protected]90499482013-06-01 00:39:509631 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:549632
[email protected]49639fa2011-12-20 23:22:419633 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:549634 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:419635 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:549636
9637 response = trans->GetResponseInfo();
9638 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509639 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:549640 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539641 EXPECT_TRUE(response->was_fetched_via_spdy);
9642 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:549643
9644 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9645 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:429646}
9647
[email protected]044de0642010-06-17 10:42:159648// GenerateAuthToken is a mighty big test.
9649// It tests all permutation of GenerateAuthToken behavior:
9650// - Synchronous and Asynchronous completion.
9651// - OK or error on completion.
9652// - Direct connection, non-authenticating proxy, and authenticating proxy.
9653// - HTTP or HTTPS backend (to include proxy tunneling).
9654// - Non-authenticating and authenticating backend.
9655//
[email protected]fe3b7dc2012-02-03 19:52:099656// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:159657// problems generating an auth token for an authenticating proxy, we don't
9658// need to test all permutations of the backend server).
9659//
9660// The test proceeds by going over each of the configuration cases, and
9661// potentially running up to three rounds in each of the tests. The TestConfig
9662// specifies both the configuration for the test as well as the expectations
9663// for the results.
[email protected]23e482282013-06-14 16:08:029664TEST_P(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:509665 static const char kServer[] = "http://www.example.com";
9666 static const char kSecureServer[] = "https://www.example.com";
9667 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:159668 const int kAuthErr = ERR_INVALID_AUTH_CREDENTIALS;
9669
9670 enum AuthTiming {
9671 AUTH_NONE,
9672 AUTH_SYNC,
9673 AUTH_ASYNC,
9674 };
9675
9676 const MockWrite kGet(
9677 "GET / HTTP/1.1\r\n"
9678 "Host: www.example.com\r\n"
9679 "Connection: keep-alive\r\n\r\n");
9680 const MockWrite kGetProxy(
9681 "GET http://www.example.com/ HTTP/1.1\r\n"
9682 "Host: www.example.com\r\n"
9683 "Proxy-Connection: keep-alive\r\n\r\n");
9684 const MockWrite kGetAuth(
9685 "GET / HTTP/1.1\r\n"
9686 "Host: www.example.com\r\n"
9687 "Connection: keep-alive\r\n"
9688 "Authorization: auth_token\r\n\r\n");
9689 const MockWrite kGetProxyAuth(
9690 "GET http://www.example.com/ HTTP/1.1\r\n"
9691 "Host: www.example.com\r\n"
9692 "Proxy-Connection: keep-alive\r\n"
9693 "Proxy-Authorization: auth_token\r\n\r\n");
9694 const MockWrite kGetAuthThroughProxy(
9695 "GET http://www.example.com/ HTTP/1.1\r\n"
9696 "Host: www.example.com\r\n"
9697 "Proxy-Connection: keep-alive\r\n"
9698 "Authorization: auth_token\r\n\r\n");
9699 const MockWrite kGetAuthWithProxyAuth(
9700 "GET http://www.example.com/ HTTP/1.1\r\n"
9701 "Host: www.example.com\r\n"
9702 "Proxy-Connection: keep-alive\r\n"
9703 "Proxy-Authorization: auth_token\r\n"
9704 "Authorization: auth_token\r\n\r\n");
9705 const MockWrite kConnect(
9706 "CONNECT www.example.com:443 HTTP/1.1\r\n"
9707 "Host: www.example.com\r\n"
9708 "Proxy-Connection: keep-alive\r\n\r\n");
9709 const MockWrite kConnectProxyAuth(
9710 "CONNECT www.example.com:443 HTTP/1.1\r\n"
9711 "Host: www.example.com\r\n"
9712 "Proxy-Connection: keep-alive\r\n"
9713 "Proxy-Authorization: auth_token\r\n\r\n");
9714
9715 const MockRead kSuccess(
9716 "HTTP/1.1 200 OK\r\n"
9717 "Content-Type: text/html; charset=iso-8859-1\r\n"
9718 "Content-Length: 3\r\n\r\n"
9719 "Yes");
9720 const MockRead kFailure(
9721 "Should not be called.");
9722 const MockRead kServerChallenge(
9723 "HTTP/1.1 401 Unauthorized\r\n"
9724 "WWW-Authenticate: Mock realm=server\r\n"
9725 "Content-Type: text/html; charset=iso-8859-1\r\n"
9726 "Content-Length: 14\r\n\r\n"
9727 "Unauthorized\r\n");
9728 const MockRead kProxyChallenge(
9729 "HTTP/1.1 407 Unauthorized\r\n"
9730 "Proxy-Authenticate: Mock realm=proxy\r\n"
9731 "Proxy-Connection: close\r\n"
9732 "Content-Type: text/html; charset=iso-8859-1\r\n"
9733 "Content-Length: 14\r\n\r\n"
9734 "Unauthorized\r\n");
9735 const MockRead kProxyConnected(
9736 "HTTP/1.1 200 Connection Established\r\n\r\n");
9737
9738 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
9739 // no constructors, but the C++ compiler on Windows warns about
9740 // unspecified data in compound literals. So, moved to using constructors,
9741 // and TestRound's created with the default constructor should not be used.
9742 struct TestRound {
9743 TestRound()
9744 : expected_rv(ERR_UNEXPECTED),
9745 extra_write(NULL),
9746 extra_read(NULL) {
9747 }
9748 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
9749 int expected_rv_arg)
9750 : write(write_arg),
9751 read(read_arg),
9752 expected_rv(expected_rv_arg),
9753 extra_write(NULL),
9754 extra_read(NULL) {
9755 }
9756 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
9757 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:019758 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:159759 : write(write_arg),
9760 read(read_arg),
9761 expected_rv(expected_rv_arg),
9762 extra_write(extra_write_arg),
9763 extra_read(extra_read_arg) {
9764 }
9765 MockWrite write;
9766 MockRead read;
9767 int expected_rv;
9768 const MockWrite* extra_write;
9769 const MockRead* extra_read;
9770 };
9771
9772 static const int kNoSSL = 500;
9773
9774 struct TestConfig {
thestig9d3bb0c2015-01-24 00:49:519775 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:159776 AuthTiming proxy_auth_timing;
9777 int proxy_auth_rv;
thestig9d3bb0c2015-01-24 00:49:519778 const char* const server_url;
[email protected]044de0642010-06-17 10:42:159779 AuthTiming server_auth_timing;
9780 int server_auth_rv;
9781 int num_auth_rounds;
9782 int first_ssl_round;
9783 TestRound rounds[3];
9784 } test_configs[] = {
9785 // Non-authenticating HTTP server with a direct connection.
9786 { NULL, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
9787 { TestRound(kGet, kSuccess, OK)}},
9788 // Authenticating HTTP server with a direct connection.
9789 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
9790 { TestRound(kGet, kServerChallenge, OK),
9791 TestRound(kGetAuth, kSuccess, OK)}},
9792 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
9793 { TestRound(kGet, kServerChallenge, OK),
9794 TestRound(kGetAuth, kFailure, kAuthErr)}},
9795 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
9796 { TestRound(kGet, kServerChallenge, OK),
9797 TestRound(kGetAuth, kSuccess, OK)}},
9798 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
9799 { TestRound(kGet, kServerChallenge, OK),
9800 TestRound(kGetAuth, kFailure, kAuthErr)}},
9801 // Non-authenticating HTTP server through a non-authenticating proxy.
9802 { kProxy, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
9803 { TestRound(kGetProxy, kSuccess, OK)}},
9804 // Authenticating HTTP server through a non-authenticating proxy.
9805 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
9806 { TestRound(kGetProxy, kServerChallenge, OK),
9807 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
9808 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
9809 { TestRound(kGetProxy, kServerChallenge, OK),
9810 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
9811 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
9812 { TestRound(kGetProxy, kServerChallenge, OK),
9813 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
9814 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
9815 { TestRound(kGetProxy, kServerChallenge, OK),
9816 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
9817 // Non-authenticating HTTP server through an authenticating proxy.
9818 { kProxy, AUTH_SYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
9819 { TestRound(kGetProxy, kProxyChallenge, OK),
9820 TestRound(kGetProxyAuth, kSuccess, OK)}},
9821 { kProxy, AUTH_SYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
9822 { TestRound(kGetProxy, kProxyChallenge, OK),
9823 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
9824 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
9825 { TestRound(kGetProxy, kProxyChallenge, OK),
9826 TestRound(kGetProxyAuth, kSuccess, OK)}},
9827 { kProxy, AUTH_ASYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
9828 { TestRound(kGetProxy, kProxyChallenge, OK),
9829 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
9830 // Authenticating HTTP server through an authenticating proxy.
9831 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
9832 { TestRound(kGetProxy, kProxyChallenge, OK),
9833 TestRound(kGetProxyAuth, kServerChallenge, OK),
9834 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9835 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
9836 { TestRound(kGetProxy, kProxyChallenge, OK),
9837 TestRound(kGetProxyAuth, kServerChallenge, OK),
9838 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9839 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
9840 { TestRound(kGetProxy, kProxyChallenge, OK),
9841 TestRound(kGetProxyAuth, kServerChallenge, OK),
9842 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9843 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
9844 { TestRound(kGetProxy, kProxyChallenge, OK),
9845 TestRound(kGetProxyAuth, kServerChallenge, OK),
9846 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9847 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
9848 { TestRound(kGetProxy, kProxyChallenge, OK),
9849 TestRound(kGetProxyAuth, kServerChallenge, OK),
9850 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9851 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
9852 { TestRound(kGetProxy, kProxyChallenge, OK),
9853 TestRound(kGetProxyAuth, kServerChallenge, OK),
9854 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9855 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
9856 { TestRound(kGetProxy, kProxyChallenge, OK),
9857 TestRound(kGetProxyAuth, kServerChallenge, OK),
9858 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9859 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
9860 { TestRound(kGetProxy, kProxyChallenge, OK),
9861 TestRound(kGetProxyAuth, kServerChallenge, OK),
9862 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9863 // Non-authenticating HTTPS server with a direct connection.
9864 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
9865 { TestRound(kGet, kSuccess, OK)}},
9866 // Authenticating HTTPS server with a direct connection.
9867 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
9868 { TestRound(kGet, kServerChallenge, OK),
9869 TestRound(kGetAuth, kSuccess, OK)}},
9870 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
9871 { TestRound(kGet, kServerChallenge, OK),
9872 TestRound(kGetAuth, kFailure, kAuthErr)}},
9873 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
9874 { TestRound(kGet, kServerChallenge, OK),
9875 TestRound(kGetAuth, kSuccess, OK)}},
9876 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
9877 { TestRound(kGet, kServerChallenge, OK),
9878 TestRound(kGetAuth, kFailure, kAuthErr)}},
9879 // Non-authenticating HTTPS server with a non-authenticating proxy.
9880 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
9881 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
9882 // Authenticating HTTPS server through a non-authenticating proxy.
9883 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
9884 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9885 TestRound(kGetAuth, kSuccess, OK)}},
9886 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
9887 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9888 TestRound(kGetAuth, kFailure, kAuthErr)}},
9889 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
9890 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9891 TestRound(kGetAuth, kSuccess, OK)}},
9892 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
9893 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9894 TestRound(kGetAuth, kFailure, kAuthErr)}},
9895 // Non-Authenticating HTTPS server through an authenticating proxy.
9896 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
9897 { TestRound(kConnect, kProxyChallenge, OK),
9898 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
9899 { kProxy, AUTH_SYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
9900 { TestRound(kConnect, kProxyChallenge, OK),
9901 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
9902 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
9903 { TestRound(kConnect, kProxyChallenge, OK),
9904 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
9905 { kProxy, AUTH_ASYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
9906 { TestRound(kConnect, kProxyChallenge, OK),
9907 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
9908 // Authenticating HTTPS server through an authenticating proxy.
9909 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
9910 { TestRound(kConnect, kProxyChallenge, OK),
9911 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9912 &kGet, &kServerChallenge),
9913 TestRound(kGetAuth, kSuccess, OK)}},
9914 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
9915 { TestRound(kConnect, kProxyChallenge, OK),
9916 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9917 &kGet, &kServerChallenge),
9918 TestRound(kGetAuth, kFailure, kAuthErr)}},
9919 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
9920 { TestRound(kConnect, kProxyChallenge, OK),
9921 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9922 &kGet, &kServerChallenge),
9923 TestRound(kGetAuth, kSuccess, OK)}},
9924 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
9925 { TestRound(kConnect, kProxyChallenge, OK),
9926 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9927 &kGet, &kServerChallenge),
9928 TestRound(kGetAuth, kFailure, kAuthErr)}},
9929 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
9930 { TestRound(kConnect, kProxyChallenge, OK),
9931 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9932 &kGet, &kServerChallenge),
9933 TestRound(kGetAuth, kSuccess, OK)}},
9934 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
9935 { TestRound(kConnect, kProxyChallenge, OK),
9936 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9937 &kGet, &kServerChallenge),
9938 TestRound(kGetAuth, kFailure, kAuthErr)}},
9939 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
9940 { TestRound(kConnect, kProxyChallenge, OK),
9941 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9942 &kGet, &kServerChallenge),
9943 TestRound(kGetAuth, kSuccess, OK)}},
9944 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
9945 { TestRound(kConnect, kProxyChallenge, OK),
9946 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9947 &kGet, &kServerChallenge),
9948 TestRound(kGetAuth, kFailure, kAuthErr)}},
9949 };
9950
viettrungluue4a8b882014-10-16 06:17:389951 for (size_t i = 0; i < arraysize(test_configs); ++i) {
[email protected]2d01c262011-08-11 23:07:089952 HttpAuthHandlerMock::Factory* auth_factory(
9953 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:079954 session_deps_.http_auth_handler_factory.reset(auth_factory);
[email protected]044de0642010-06-17 10:42:159955 const TestConfig& test_config = test_configs[i];
[email protected]65d34382010-07-01 18:12:269956
9957 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:159958 if (test_config.proxy_auth_timing != AUTH_NONE) {
[email protected]2d01c262011-08-11 23:07:089959 for (int n = 0; n < 2; n++) {
9960 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
9961 std::string auth_challenge = "Mock realm=proxy";
9962 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:249963 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
9964 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:089965 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
9966 origin, BoundNetLog());
9967 auth_handler->SetGenerateExpectation(
9968 test_config.proxy_auth_timing == AUTH_ASYNC,
9969 test_config.proxy_auth_rv);
9970 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
9971 }
[email protected]044de0642010-06-17 10:42:159972 }
9973 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:009974 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:159975 std::string auth_challenge = "Mock realm=server";
9976 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:249977 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
9978 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:159979 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
9980 origin, BoundNetLog());
9981 auth_handler->SetGenerateExpectation(
9982 test_config.server_auth_timing == AUTH_ASYNC,
9983 test_config.server_auth_rv);
[email protected]2d01c262011-08-11 23:07:089984 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:159985 }
9986 if (test_config.proxy_url) {
[email protected]bb88e1d32013-05-03 23:11:079987 session_deps_.proxy_service.reset(
[email protected]6104ea5d2011-04-27 21:37:129988 ProxyService::CreateFixed(test_config.proxy_url));
[email protected]044de0642010-06-17 10:42:159989 } else {
[email protected]bb88e1d32013-05-03 23:11:079990 session_deps_.proxy_service.reset(ProxyService::CreateDirect());
[email protected]044de0642010-06-17 10:42:159991 }
9992
9993 HttpRequestInfo request;
9994 request.method = "GET";
9995 request.url = GURL(test_config.server_url);
9996 request.load_flags = 0;
9997
[email protected]bb88e1d32013-05-03 23:11:079998 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
dcheng48459ac22014-08-26 00:46:419999 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]044de0642010-06-17 10:42:1510000
10001 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
10002 const TestRound& read_write_round = test_config.rounds[round];
10003
10004 // Set up expected reads and writes.
10005 MockRead reads[2];
10006 reads[0] = read_write_round.read;
10007 size_t length_reads = 1;
10008 if (read_write_round.extra_read) {
10009 reads[1] = *read_write_round.extra_read;
10010 length_reads = 2;
10011 }
10012
10013 MockWrite writes[2];
10014 writes[0] = read_write_round.write;
10015 size_t length_writes = 1;
10016 if (read_write_round.extra_write) {
10017 writes[1] = *read_write_round.extra_write;
10018 length_writes = 2;
10019 }
10020 StaticSocketDataProvider data_provider(
10021 reads, length_reads, writes, length_writes);
[email protected]bb88e1d32013-05-03 23:11:0710022 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]044de0642010-06-17 10:42:1510023
10024 // Add an SSL sequence if necessary.
[email protected]8ddf8322012-02-23 18:08:0610025 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
[email protected]044de0642010-06-17 10:42:1510026 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0710027 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1510028 &ssl_socket_data_provider);
10029
10030 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4110031 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1510032 int rv;
10033 if (round == 0) {
[email protected]49639fa2011-12-20 23:22:4110034 rv = trans.Start(&request, callback.callback(), BoundNetLog());
[email protected]044de0642010-06-17 10:42:1510035 } else {
[email protected]49639fa2011-12-20 23:22:4110036 rv = trans.RestartWithAuth(
10037 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1510038 }
10039 if (rv == ERR_IO_PENDING)
10040 rv = callback.WaitForResult();
10041
10042 // Compare results with expected data.
10043 EXPECT_EQ(read_write_round.expected_rv, rv);
[email protected]0b0bf032010-09-21 18:08:5010044 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]044de0642010-06-17 10:42:1510045 if (read_write_round.expected_rv == OK) {
[email protected]fe2255a2011-09-20 19:37:5010046 ASSERT_TRUE(response != NULL);
[email protected]044de0642010-06-17 10:42:1510047 } else {
10048 EXPECT_TRUE(response == NULL);
10049 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
10050 continue;
10051 }
10052 if (round + 1 < test_config.num_auth_rounds) {
10053 EXPECT_FALSE(response->auth_challenge.get() == NULL);
10054 } else {
10055 EXPECT_TRUE(response->auth_challenge.get() == NULL);
10056 }
10057 }
[email protected]e5ae96a2010-04-14 20:12:4510058 }
10059}
10060
[email protected]23e482282013-06-14 16:08:0210061TEST_P(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1410062 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1410063 HttpAuthHandlerMock::Factory* auth_factory(
10064 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0710065 session_deps_.http_auth_handler_factory.reset(auth_factory);
10066 session_deps_.proxy_service.reset(ProxyService::CreateDirect());
10067 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
10068 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:1410069
10070 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
10071 auth_handler->set_connection_based(true);
10072 std::string auth_challenge = "Mock realm=server";
10073 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2410074 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
10075 auth_challenge.end());
[email protected]c871bce92010-07-15 21:51:1410076 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
10077 origin, BoundNetLog());
[email protected]2d01c262011-08-11 23:07:0810078 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1410079
[email protected]c871bce92010-07-15 21:51:1410080 int rv = OK;
10081 const HttpResponseInfo* response = NULL;
10082 HttpRequestInfo request;
10083 request.method = "GET";
10084 request.url = origin;
10085 request.load_flags = 0;
[email protected]cb9bf6ca2011-01-28 13:15:2710086
[email protected]bb88e1d32013-05-03 23:11:0710087 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1010088
10089 // Use a TCP Socket Pool with only one connection per group. This is used
10090 // to validate that the TCP socket is not released to the pool between
10091 // each round of multi-round authentication.
10092 HttpNetworkSessionPeer session_peer(session);
[email protected]ab739042011-04-07 15:22:2810093 ClientSocketPoolHistograms transport_pool_histograms("SmallTCP");
10094 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:1010095 50, // Max sockets for pool
10096 1, // Max sockets per group
[email protected]ab739042011-04-07 15:22:2810097 &transport_pool_histograms,
[email protected]bb88e1d32013-05-03 23:11:0710098 session_deps_.host_resolver.get(),
10099 session_deps_.socket_factory.get(),
10100 session_deps_.net_log);
[email protected]831e4a32013-11-14 02:14:4410101 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
10102 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:0210103 mock_pool_manager->SetTransportSocketPool(transport_pool);
dchenge3d1ddc2014-10-15 19:30:5110104 session_peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]7ef4cbbb2011-02-06 11:19:1010105
[email protected]262eec82013-03-19 21:01:3610106 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010107 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110108 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1410109
10110 const MockWrite kGet(
10111 "GET / HTTP/1.1\r\n"
10112 "Host: www.example.com\r\n"
10113 "Connection: keep-alive\r\n\r\n");
10114 const MockWrite kGetAuth(
10115 "GET / HTTP/1.1\r\n"
10116 "Host: www.example.com\r\n"
10117 "Connection: keep-alive\r\n"
10118 "Authorization: auth_token\r\n\r\n");
10119
10120 const MockRead kServerChallenge(
10121 "HTTP/1.1 401 Unauthorized\r\n"
10122 "WWW-Authenticate: Mock realm=server\r\n"
10123 "Content-Type: text/html; charset=iso-8859-1\r\n"
10124 "Content-Length: 14\r\n\r\n"
10125 "Unauthorized\r\n");
10126 const MockRead kSuccess(
10127 "HTTP/1.1 200 OK\r\n"
10128 "Content-Type: text/html; charset=iso-8859-1\r\n"
10129 "Content-Length: 3\r\n\r\n"
10130 "Yes");
10131
10132 MockWrite writes[] = {
10133 // First round
10134 kGet,
10135 // Second round
10136 kGetAuth,
10137 // Third round
10138 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3010139 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1010140 kGetAuth,
10141 // Competing request
10142 kGet,
[email protected]c871bce92010-07-15 21:51:1410143 };
10144 MockRead reads[] = {
10145 // First round
10146 kServerChallenge,
10147 // Second round
10148 kServerChallenge,
10149 // Third round
[email protected]eca50e122010-09-11 14:03:3010150 kServerChallenge,
10151 // Fourth round
[email protected]c871bce92010-07-15 21:51:1410152 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1010153 // Competing response
10154 kSuccess,
[email protected]c871bce92010-07-15 21:51:1410155 };
10156 StaticSocketDataProvider data_provider(reads, arraysize(reads),
10157 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:0710158 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1410159
thestig9d3bb0c2015-01-24 00:49:5110160 const char kSocketGroup[] = "www.example.com:80";
[email protected]7ef4cbbb2011-02-06 11:19:1010161
10162 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1410163 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4110164 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]c871bce92010-07-15 21:51:1410165 if (rv == ERR_IO_PENDING)
10166 rv = callback.WaitForResult();
10167 EXPECT_EQ(OK, rv);
10168 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010169 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:1410170 EXPECT_FALSE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2810171 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1410172
[email protected]7ef4cbbb2011-02-06 11:19:1010173 // In between rounds, another request comes in for the same domain.
10174 // It should not be able to grab the TCP socket that trans has already
10175 // claimed.
10176 scoped_ptr<HttpTransaction> trans_compete(
[email protected]90499482013-06-01 00:39:5010177 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110178 TestCompletionCallback callback_compete;
10179 rv = trans_compete->Start(
10180 &request, callback_compete.callback(), BoundNetLog());
[email protected]7ef4cbbb2011-02-06 11:19:1010181 EXPECT_EQ(ERR_IO_PENDING, rv);
10182 // callback_compete.WaitForResult at this point would stall forever,
10183 // since the HttpNetworkTransaction does not release the request back to
10184 // the pool until after authentication completes.
10185
10186 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1410187 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4110188 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1410189 if (rv == ERR_IO_PENDING)
10190 rv = callback.WaitForResult();
10191 EXPECT_EQ(OK, rv);
10192 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010193 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:1410194 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2810195 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1410196
[email protected]7ef4cbbb2011-02-06 11:19:1010197 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1410198 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4110199 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1410200 if (rv == ERR_IO_PENDING)
10201 rv = callback.WaitForResult();
10202 EXPECT_EQ(OK, rv);
10203 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010204 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:1410205 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2810206 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]eca50e122010-09-11 14:03:3010207
[email protected]7ef4cbbb2011-02-06 11:19:1010208 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3010209 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4110210 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3010211 if (rv == ERR_IO_PENDING)
10212 rv = callback.WaitForResult();
10213 EXPECT_EQ(OK, rv);
10214 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010215 ASSERT_TRUE(response != NULL);
[email protected]eca50e122010-09-11 14:03:3010216 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2810217 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1010218
10219 // Read the body since the fourth round was successful. This will also
10220 // release the socket back to the pool.
10221 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
[email protected]90499482013-06-01 00:39:5010222 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1010223 if (rv == ERR_IO_PENDING)
10224 rv = callback.WaitForResult();
10225 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:5010226 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1010227 EXPECT_EQ(0, rv);
10228 // There are still 0 idle sockets, since the trans_compete transaction
10229 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:2810230 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1010231
10232 // The competing request can now finish. Wait for the headers and then
10233 // read the body.
10234 rv = callback_compete.WaitForResult();
10235 EXPECT_EQ(OK, rv);
[email protected]90499482013-06-01 00:39:5010236 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1010237 if (rv == ERR_IO_PENDING)
10238 rv = callback.WaitForResult();
10239 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:5010240 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1010241 EXPECT_EQ(0, rv);
10242
10243 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:2810244 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1410245}
10246
[email protected]65041fa2010-05-21 06:56:5310247// This tests the case that a request is issued via http instead of spdy after
10248// npn is negotiated.
[email protected]23e482282013-06-14 16:08:0210249TEST_P(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]d7599122014-05-24 03:37:2310250 session_deps_.use_alternate_protocols = true;
10251 NextProtoVector next_protos;
[email protected]0ce3af82013-07-22 16:17:1610252 next_protos.push_back(kProtoHTTP11);
[email protected]d7599122014-05-24 03:37:2310253 session_deps_.next_protos = next_protos;
10254
[email protected]65041fa2010-05-21 06:56:5310255 HttpRequestInfo request;
10256 request.method = "GET";
10257 request.url = GURL("https://www.google.com/");
10258 request.load_flags = 0;
10259
10260 MockWrite data_writes[] = {
10261 MockWrite("GET / HTTP/1.1\r\n"
10262 "Host: www.google.com\r\n"
10263 "Connection: keep-alive\r\n\r\n"),
10264 };
10265
[email protected]8a0fc822013-06-27 20:52:4310266 std::string alternate_protocol_http_header =
10267 GetAlternateProtocolHttpHeader();
10268
[email protected]65041fa2010-05-21 06:56:5310269 MockRead data_reads[] = {
10270 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:4310271 MockRead(alternate_protocol_http_header.c_str()),
[email protected]65041fa2010-05-21 06:56:5310272 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610273 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5310274 };
10275
[email protected]8ddf8322012-02-23 18:08:0610276 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]65041fa2010-05-21 06:56:5310277 ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
10278 ssl.next_proto = "http/1.1";
[email protected]8e3c78cb2012-03-31 03:58:4610279 ssl.protocol_negotiated = kProtoHTTP11;
[email protected]65041fa2010-05-21 06:56:5310280
[email protected]bb88e1d32013-05-03 23:11:0710281 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5310282
10283 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
10284 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0710285 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5310286
[email protected]49639fa2011-12-20 23:22:4110287 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5310288
[email protected]bb88e1d32013-05-03 23:11:0710289 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610290 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010291 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]65041fa2010-05-21 06:56:5310292
[email protected]49639fa2011-12-20 23:22:4110293 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]65041fa2010-05-21 06:56:5310294
10295 EXPECT_EQ(ERR_IO_PENDING, rv);
10296 EXPECT_EQ(OK, callback.WaitForResult());
10297
10298 const HttpResponseInfo* response = trans->GetResponseInfo();
10299 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010300 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]65041fa2010-05-21 06:56:5310301 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10302
10303 std::string response_data;
10304 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10305 EXPECT_EQ("hello world", response_data);
10306
10307 EXPECT_FALSE(response->was_fetched_via_spdy);
10308 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]65041fa2010-05-21 06:56:5310309}
[email protected]26ef6582010-06-24 02:30:4710310
[email protected]23e482282013-06-14 16:08:0210311TEST_P(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:4710312 // Simulate the SSL handshake completing with an NPN negotiation
10313 // followed by an immediate server closing of the socket.
10314 // Fix crash: http://crbug.com/46369
[email protected]d7599122014-05-24 03:37:2310315 session_deps_.use_alternate_protocols = true;
10316 session_deps_.next_protos = SpdyNextProtos();
[email protected]26ef6582010-06-24 02:30:4710317
10318 HttpRequestInfo request;
10319 request.method = "GET";
10320 request.url = GURL("https://www.google.com/");
10321 request.load_flags = 0;
10322
[email protected]8ddf8322012-02-23 18:08:0610323 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210324 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710325 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4710326
[email protected]cdf8f7e72013-05-23 10:56:4610327 scoped_ptr<SpdyFrame> req(
10328 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]e7f75092010-07-01 22:39:1310329 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
[email protected]26ef6582010-06-24 02:30:4710330
10331 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0610332 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4710333 };
10334
[email protected]dd54bd82012-07-19 23:44:5710335 DelayedSocketData spdy_data(
10336 0, // don't wait in this case, immediate hangup.
10337 spdy_reads, arraysize(spdy_reads),
10338 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710339 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4710340
[email protected]49639fa2011-12-20 23:22:4110341 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4710342
[email protected]bb88e1d32013-05-03 23:11:0710343 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610344 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010345 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]26ef6582010-06-24 02:30:4710346
[email protected]49639fa2011-12-20 23:22:4110347 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]26ef6582010-06-24 02:30:4710348 EXPECT_EQ(ERR_IO_PENDING, rv);
10349 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult());
[email protected]26ef6582010-06-24 02:30:4710350}
[email protected]65d34382010-07-01 18:12:2610351
[email protected]795cbf82013-07-22 09:37:2710352// A subclass of HttpAuthHandlerMock that records the request URL when
10353// it gets it. This is needed since the auth handler may get destroyed
10354// before we get a chance to query it.
10355class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
10356 public:
10357 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
10358
dchengb03027d2014-10-21 12:00:2010359 ~UrlRecordingHttpAuthHandlerMock() override {}
[email protected]795cbf82013-07-22 09:37:2710360
10361 protected:
dchengb03027d2014-10-21 12:00:2010362 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
10363 const HttpRequestInfo* request,
10364 const CompletionCallback& callback,
10365 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2710366 *url_ = request->url;
10367 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
10368 credentials, request, callback, auth_token);
10369 }
10370
10371 private:
10372 GURL* url_;
10373};
10374
[email protected]23e482282013-06-14 16:08:0210375TEST_P(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) {
[email protected]f45c1ee2010-08-03 00:54:3010376 // This test ensures that the URL passed into the proxy is upgraded
10377 // to https when doing an Alternate Protocol upgrade.
[email protected]d7599122014-05-24 03:37:2310378 session_deps_.use_alternate_protocols = true;
10379 session_deps_.next_protos = SpdyNextProtos();
[email protected]f45c1ee2010-08-03 00:54:3010380
[email protected]bb88e1d32013-05-03 23:11:0710381 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:2010382 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
10383 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710384 session_deps_.net_log = &net_log;
[email protected]795cbf82013-07-22 09:37:2710385 GURL request_url;
10386 {
10387 HttpAuthHandlerMock::Factory* auth_factory =
10388 new HttpAuthHandlerMock::Factory();
10389 UrlRecordingHttpAuthHandlerMock* auth_handler =
10390 new UrlRecordingHttpAuthHandlerMock(&request_url);
10391 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
10392 auth_factory->set_do_init_from_challenge(true);
10393 session_deps_.http_auth_handler_factory.reset(auth_factory);
10394 }
[email protected]f45c1ee2010-08-03 00:54:3010395
10396 HttpRequestInfo request;
10397 request.method = "GET";
10398 request.url = GURL("http://www.google.com");
10399 request.load_flags = 0;
10400
10401 // First round goes unauthenticated through the proxy.
10402 MockWrite data_writes_1[] = {
10403 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
10404 "Host: www.google.com\r\n"
10405 "Proxy-Connection: keep-alive\r\n"
10406 "\r\n"),
10407 };
10408 MockRead data_reads_1[] = {
[email protected]8ddf8322012-02-23 18:08:0610409 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
bnc33b8cef42014-11-19 17:30:3810410 MockRead("HTTP/1.1 200 OK\r\n"),
10411 MockRead("Alternate-Protocol: 443:"),
10412 MockRead(GetAlternateProtocolFromParam()),
10413 MockRead("\r\n"),
10414 MockRead("Proxy-Connection: close\r\n"),
10415 MockRead("\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3010416 };
10417 StaticSocketDataProvider data_1(data_reads_1, arraysize(data_reads_1),
10418 data_writes_1, arraysize(data_writes_1));
10419
10420 // Second round tries to tunnel to www.google.com due to the
10421 // Alternate-Protocol announcement in the first round. It fails due
10422 // to a proxy authentication challenge.
[email protected]394816e92010-08-03 07:38:5910423 // After the failure, a tunnel is established to www.google.com using
10424 // Proxy-Authorization headers. There is then a SPDY request round.
10425 //
[email protected]fe3b7dc2012-02-03 19:52:0910426 // NOTE: Despite the "Proxy-Connection: Close", these are done on the
10427 // same MockTCPClientSocket since the underlying HttpNetworkClientSocket
10428 // does a Disconnect and Connect on the same socket, rather than trying
10429 // to obtain a new one.
10430 //
[email protected]394816e92010-08-03 07:38:5910431 // NOTE: Originally, the proxy response to the second CONNECT request
10432 // simply returned another 407 so the unit test could skip the SSL connection
10433 // establishment and SPDY framing issues. Alas, the
10434 // retry-http-when-alternate-protocol fails logic kicks in, which was more
[email protected]f45c1ee2010-08-03 00:54:3010435 // complicated to set up expectations for than the SPDY session.
[email protected]394816e92010-08-03 07:38:5910436
[email protected]cdf8f7e72013-05-23 10:56:4610437 scoped_ptr<SpdyFrame> req(
10438 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]23e482282013-06-14 16:08:0210439 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10440 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]f45c1ee2010-08-03 00:54:3010441
[email protected]394816e92010-08-03 07:38:5910442 MockWrite data_writes_2[] = {
10443 // First connection attempt without Proxy-Authorization.
10444 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
10445 "Host: www.google.com\r\n"
10446 "Proxy-Connection: keep-alive\r\n"
10447 "\r\n"),
10448
10449 // Second connection attempt with Proxy-Authorization.
[email protected]f45c1ee2010-08-03 00:54:3010450 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
10451 "Host: www.google.com\r\n"
10452 "Proxy-Connection: keep-alive\r\n"
10453 "Proxy-Authorization: auth_token\r\n"
10454 "\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3010455
[email protected]394816e92010-08-03 07:38:5910456 // SPDY request
10457 CreateMockWrite(*req),
[email protected]f45c1ee2010-08-03 00:54:3010458 };
[email protected]394816e92010-08-03 07:38:5910459 const char kRejectConnectResponse[] = ("HTTP/1.1 407 Unauthorized\r\n"
10460 "Proxy-Authenticate: Mock\r\n"
10461 "Proxy-Connection: close\r\n"
10462 "\r\n");
10463 const char kAcceptConnectResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
10464 MockRead data_reads_2[] = {
10465 // First connection attempt fails
[email protected]8ddf8322012-02-23 18:08:0610466 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ, 1),
10467 MockRead(ASYNC, kRejectConnectResponse,
[email protected]394816e92010-08-03 07:38:5910468 arraysize(kRejectConnectResponse) - 1, 1),
10469
10470 // Second connection attempt passes
[email protected]8ddf8322012-02-23 18:08:0610471 MockRead(ASYNC, kAcceptConnectResponse,
[email protected]fe3b7dc2012-02-03 19:52:0910472 arraysize(kAcceptConnectResponse) -1, 4),
[email protected]394816e92010-08-03 07:38:5910473
10474 // SPDY response
[email protected]fe3b7dc2012-02-03 19:52:0910475 CreateMockRead(*resp.get(), 6),
10476 CreateMockRead(*data.get(), 6),
[email protected]8ddf8322012-02-23 18:08:0610477 MockRead(ASYNC, 0, 0, 6),
[email protected]394816e92010-08-03 07:38:5910478 };
[email protected]dd54bd82012-07-19 23:44:5710479 OrderedSocketData data_2(
10480 data_reads_2, arraysize(data_reads_2),
10481 data_writes_2, arraysize(data_writes_2));
[email protected]f45c1ee2010-08-03 00:54:3010482
[email protected]8ddf8322012-02-23 18:08:0610483 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210484 ssl.SetNextProto(GetParam());
[email protected]f45c1ee2010-08-03 00:54:3010485
[email protected]d973e99a2012-02-17 21:02:3610486 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5510487 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
10488 NULL, 0, NULL, 0);
10489 hanging_non_alternate_protocol_socket.set_connect_data(
10490 never_finishing_connect);
10491
[email protected]bb88e1d32013-05-03 23:11:0710492 session_deps_.socket_factory->AddSocketDataProvider(&data_1);
10493 session_deps_.socket_factory->AddSocketDataProvider(&data_2);
10494 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10495 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5510496 &hanging_non_alternate_protocol_socket);
[email protected]bb88e1d32013-05-03 23:11:0710497 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f45c1ee2010-08-03 00:54:3010498
10499 // First round should work and provide the Alternate-Protocol state.
[email protected]49639fa2011-12-20 23:22:4110500 TestCompletionCallback callback_1;
[email protected]262eec82013-03-19 21:01:3610501 scoped_ptr<HttpTransaction> trans_1(
[email protected]90499482013-06-01 00:39:5010502 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110503 int rv = trans_1->Start(&request, callback_1.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:3010504 EXPECT_EQ(ERR_IO_PENDING, rv);
10505 EXPECT_EQ(OK, callback_1.WaitForResult());
10506
10507 // Second round should attempt a tunnel connect and get an auth challenge.
[email protected]49639fa2011-12-20 23:22:4110508 TestCompletionCallback callback_2;
[email protected]262eec82013-03-19 21:01:3610509 scoped_ptr<HttpTransaction> trans_2(
[email protected]90499482013-06-01 00:39:5010510 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110511 rv = trans_2->Start(&request, callback_2.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:3010512 EXPECT_EQ(ERR_IO_PENDING, rv);
10513 EXPECT_EQ(OK, callback_2.WaitForResult());
10514 const HttpResponseInfo* response = trans_2->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010515 ASSERT_TRUE(response != NULL);
[email protected]f45c1ee2010-08-03 00:54:3010516 ASSERT_FALSE(response->auth_challenge.get() == NULL);
10517
10518 // Restart with auth. Tunnel should work and response received.
[email protected]49639fa2011-12-20 23:22:4110519 TestCompletionCallback callback_3;
10520 rv = trans_2->RestartWithAuth(
10521 AuthCredentials(kFoo, kBar), callback_3.callback());
[email protected]f45c1ee2010-08-03 00:54:3010522 EXPECT_EQ(ERR_IO_PENDING, rv);
10523 EXPECT_EQ(OK, callback_3.WaitForResult());
10524
10525 // After all that work, these two lines (or actually, just the scheme) are
10526 // what this test is all about. Make sure it happens correctly.
[email protected]f45c1ee2010-08-03 00:54:3010527 EXPECT_EQ("https", request_url.scheme());
10528 EXPECT_EQ("www.google.com", request_url.host());
10529
[email protected]029c83b62013-01-24 05:28:2010530 LoadTimingInfo load_timing_info;
10531 EXPECT_TRUE(trans_2->GetLoadTimingInfo(&load_timing_info));
10532 TestLoadTimingNotReusedWithPac(load_timing_info,
10533 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]8e6441ca2010-08-19 05:56:3810534}
10535
10536// Test that if we cancel the transaction as the connection is completing, that
10537// everything tears down correctly.
[email protected]23e482282013-06-14 16:08:0210538TEST_P(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3810539 // Setup everything about the connection to complete synchronously, so that
10540 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
10541 // for is the callback from the HttpStreamRequest.
10542 // Then cancel the transaction.
10543 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3610544 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3810545 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0610546 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
10547 MockRead(SYNCHRONOUS, "hello world"),
10548 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3810549 };
10550
[email protected]8e6441ca2010-08-19 05:56:3810551 HttpRequestInfo request;
10552 request.method = "GET";
10553 request.url = GURL("http://www.google.com/");
10554 request.load_flags = 0;
10555
[email protected]bb88e1d32013-05-03 23:11:0710556 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]3fe8d2f82013-10-17 08:56:0710557 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:2710558 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4110559 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:2710560
[email protected]8e6441ca2010-08-19 05:56:3810561 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10562 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710563 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3810564
[email protected]49639fa2011-12-20 23:22:4110565 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3810566
[email protected]333bdf62012-06-08 22:57:2910567 CapturingBoundNetLog log;
[email protected]49639fa2011-12-20 23:22:4110568 int rv = trans->Start(&request, callback.callback(), log.bound());
[email protected]8e6441ca2010-08-19 05:56:3810569 EXPECT_EQ(ERR_IO_PENDING, rv);
10570 trans.reset(); // Cancel the transaction here.
10571
[email protected]2da659e2013-05-23 20:51:3410572 base::MessageLoop::current()->RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3010573}
10574
[email protected]ecab6e052014-05-16 14:58:1210575// Test that if a transaction is cancelled after receiving the headers, the
10576// stream is drained properly and added back to the socket pool. The main
10577// purpose of this test is to make sure that an HttpStreamParser can be read
10578// from after the HttpNetworkTransaction and the objects it owns have been
10579// deleted.
10580// See http://crbug.com/368418
10581TEST_P(HttpNetworkTransactionTest, CancelAfterHeaders) {
10582 MockRead data_reads[] = {
10583 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
10584 MockRead(ASYNC, "Content-Length: 2\r\n"),
10585 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
10586 MockRead(ASYNC, "1"),
10587 // 2 async reads are necessary to trigger a ReadResponseBody call after the
10588 // HttpNetworkTransaction has been deleted.
10589 MockRead(ASYNC, "2"),
10590 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
10591 };
10592 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10593 session_deps_.socket_factory->AddSocketDataProvider(&data);
10594
10595 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10596
10597 {
10598 HttpRequestInfo request;
10599 request.method = "GET";
10600 request.url = GURL("http://www.google.com/");
10601 request.load_flags = 0;
10602
dcheng48459ac22014-08-26 00:46:4110603 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1210604 TestCompletionCallback callback;
10605
10606 int rv = trans.Start(&request, callback.callback(), BoundNetLog());
10607 EXPECT_EQ(ERR_IO_PENDING, rv);
10608 callback.WaitForResult();
10609
10610 const HttpResponseInfo* response = trans.GetResponseInfo();
10611 ASSERT_TRUE(response != NULL);
10612 EXPECT_TRUE(response->headers.get() != NULL);
10613 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10614
10615 // The transaction and HttpRequestInfo are deleted.
10616 }
10617
10618 // Let the HttpResponseBodyDrainer drain the socket.
10619 base::MessageLoop::current()->RunUntilIdle();
10620
10621 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4110622 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1210623}
10624
[email protected]76a505b2010-08-25 06:23:0010625// Test a basic GET request through a proxy.
[email protected]23e482282013-06-14 16:08:0210626TEST_P(HttpNetworkTransactionTest, ProxyGet) {
[email protected]bb88e1d32013-05-03 23:11:0710627 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:2010628 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
[email protected]333bdf62012-06-08 22:57:2910629 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710630 session_deps_.net_log = log.bound().net_log();
10631 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0010632
[email protected]76a505b2010-08-25 06:23:0010633 HttpRequestInfo request;
10634 request.method = "GET";
10635 request.url = GURL("http://www.google.com/");
10636
10637 MockWrite data_writes1[] = {
10638 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
10639 "Host: www.google.com\r\n"
10640 "Proxy-Connection: keep-alive\r\n\r\n"),
10641 };
10642
10643 MockRead data_reads1[] = {
10644 MockRead("HTTP/1.1 200 OK\r\n"),
10645 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10646 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610647 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0010648 };
10649
10650 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10651 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710652 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0010653
[email protected]49639fa2011-12-20 23:22:4110654 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0010655
[email protected]262eec82013-03-19 21:01:3610656 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010657 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]597a1ab2014-06-26 08:12:2710658 BeforeProxyHeadersSentHandler proxy_headers_handler;
10659 trans->SetBeforeProxyHeadersSentCallback(
10660 base::Bind(&BeforeProxyHeadersSentHandler::OnBeforeProxyHeadersSent,
10661 base::Unretained(&proxy_headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5010662
[email protected]49639fa2011-12-20 23:22:4110663 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0010664 EXPECT_EQ(ERR_IO_PENDING, rv);
10665
10666 rv = callback1.WaitForResult();
10667 EXPECT_EQ(OK, rv);
10668
10669 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010670 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:0010671
10672 EXPECT_TRUE(response->headers->IsKeepAlive());
10673 EXPECT_EQ(200, response->headers->response_code());
10674 EXPECT_EQ(100, response->headers->GetContentLength());
10675 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]d8fc4722014-06-13 13:17:1510676 EXPECT_TRUE(
10677 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
[email protected]597a1ab2014-06-26 08:12:2710678 EXPECT_TRUE(proxy_headers_handler.observed_before_proxy_headers_sent());
10679 EXPECT_EQ("myproxy:70", proxy_headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0010680 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2010681
10682 LoadTimingInfo load_timing_info;
10683 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10684 TestLoadTimingNotReusedWithPac(load_timing_info,
10685 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0010686}
10687
10688// Test a basic HTTPS GET request through a proxy.
[email protected]23e482282013-06-14 16:08:0210689TEST_P(HttpNetworkTransactionTest, ProxyTunnelGet) {
[email protected]bb88e1d32013-05-03 23:11:0710690 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:2010691 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
[email protected]333bdf62012-06-08 22:57:2910692 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710693 session_deps_.net_log = log.bound().net_log();
10694 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0010695
[email protected]76a505b2010-08-25 06:23:0010696 HttpRequestInfo request;
10697 request.method = "GET";
10698 request.url = GURL("https://www.google.com/");
10699
10700 // Since we have proxy, should try to establish tunnel.
10701 MockWrite data_writes1[] = {
10702 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
10703 "Host: www.google.com\r\n"
10704 "Proxy-Connection: keep-alive\r\n\r\n"),
10705
10706 MockWrite("GET / HTTP/1.1\r\n"
10707 "Host: www.google.com\r\n"
10708 "Connection: keep-alive\r\n\r\n"),
10709 };
10710
10711 MockRead data_reads1[] = {
10712 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
10713
10714 MockRead("HTTP/1.1 200 OK\r\n"),
10715 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10716 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610717 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0010718 };
10719
10720 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10721 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710722 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0610723 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710724 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0010725
[email protected]49639fa2011-12-20 23:22:4110726 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0010727
[email protected]262eec82013-03-19 21:01:3610728 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010729 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5010730
[email protected]49639fa2011-12-20 23:22:4110731 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0010732 EXPECT_EQ(ERR_IO_PENDING, rv);
10733
10734 rv = callback1.WaitForResult();
10735 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:5710736 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:4010737 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0010738 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010739 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0010740 NetLog::PHASE_NONE);
10741 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010742 entries, pos,
[email protected]76a505b2010-08-25 06:23:0010743 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
10744 NetLog::PHASE_NONE);
10745
10746 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010747 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:0010748
10749 EXPECT_TRUE(response->headers->IsKeepAlive());
10750 EXPECT_EQ(200, response->headers->response_code());
10751 EXPECT_EQ(100, response->headers->GetContentLength());
10752 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10753 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]d8fc4722014-06-13 13:17:1510754 EXPECT_TRUE(
10755 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
[email protected]029c83b62013-01-24 05:28:2010756
10757 LoadTimingInfo load_timing_info;
10758 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10759 TestLoadTimingNotReusedWithPac(load_timing_info,
10760 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0010761}
10762
10763// Test a basic HTTPS GET request through a proxy, but the server hangs up
10764// while establishing the tunnel.
[email protected]23e482282013-06-14 16:08:0210765TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
[email protected]bb88e1d32013-05-03 23:11:0710766 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]333bdf62012-06-08 22:57:2910767 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710768 session_deps_.net_log = log.bound().net_log();
10769 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0010770
[email protected]76a505b2010-08-25 06:23:0010771 HttpRequestInfo request;
10772 request.method = "GET";
10773 request.url = GURL("https://www.google.com/");
10774
10775 // Since we have proxy, should try to establish tunnel.
10776 MockWrite data_writes1[] = {
10777 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
10778 "Host: www.google.com\r\n"
10779 "Proxy-Connection: keep-alive\r\n\r\n"),
10780
10781 MockWrite("GET / HTTP/1.1\r\n"
10782 "Host: www.google.com\r\n"
10783 "Connection: keep-alive\r\n\r\n"),
10784 };
10785
10786 MockRead data_reads1[] = {
[email protected]8ddf8322012-02-23 18:08:0610787 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:0010788 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610789 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0010790 };
10791
10792 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10793 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710794 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0610795 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710796 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0010797
[email protected]49639fa2011-12-20 23:22:4110798 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0010799
[email protected]262eec82013-03-19 21:01:3610800 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010801 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5010802
[email protected]49639fa2011-12-20 23:22:4110803 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0010804 EXPECT_EQ(ERR_IO_PENDING, rv);
10805
10806 rv = callback1.WaitForResult();
10807 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
[email protected]f3da152d2012-06-02 01:00:5710808 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:4010809 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0010810 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010811 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0010812 NetLog::PHASE_NONE);
10813 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010814 entries, pos,
[email protected]76a505b2010-08-25 06:23:0010815 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
10816 NetLog::PHASE_NONE);
10817}
10818
[email protected]749eefa82010-09-13 22:14:0310819// Test for crbug.com/55424.
[email protected]23e482282013-06-14 16:08:0210820TEST_P(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
[email protected]cdf8f7e72013-05-23 10:56:4610821 scoped_ptr<SpdyFrame> req(
10822 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
[email protected]749eefa82010-09-13 22:14:0310823 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
10824
[email protected]23e482282013-06-14 16:08:0210825 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10826 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0310827 MockRead spdy_reads[] = {
10828 CreateMockRead(*resp),
10829 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:0610830 MockRead(ASYNC, 0, 0),
[email protected]749eefa82010-09-13 22:14:0310831 };
10832
[email protected]dd54bd82012-07-19 23:44:5710833 DelayedSocketData spdy_data(
10834 1, // wait for one write to finish before reading.
10835 spdy_reads, arraysize(spdy_reads),
10836 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710837 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0310838
[email protected]8ddf8322012-02-23 18:08:0610839 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210840 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710841 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0310842
[email protected]bb88e1d32013-05-03 23:11:0710843 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0310844
10845 // Set up an initial SpdySession in the pool to reuse.
[email protected]02b0c342010-09-25 21:09:3810846 HostPortPair host_port_pair("www.google.com", 443);
[email protected]e6d017652013-05-17 18:01:4010847 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5310848 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2710849 base::WeakPtr<SpdySession> spdy_session =
[email protected]41d64e82013-07-03 22:44:2610850 CreateInsecureSpdySession(session, key, BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0310851
10852 HttpRequestInfo request;
10853 request.method = "GET";
10854 request.url = GURL("https://www.google.com/");
10855 request.load_flags = 0;
10856
10857 // This is the important line that marks this as a preconnect.
10858 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
10859
[email protected]262eec82013-03-19 21:01:3610860 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010861 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]749eefa82010-09-13 22:14:0310862
[email protected]41d64e82013-07-03 22:44:2610863 TestCompletionCallback callback;
[email protected]49639fa2011-12-20 23:22:4110864 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0310865 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110866 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]749eefa82010-09-13 22:14:0310867}
10868
[email protected]73b8dd222010-11-11 19:55:2410869// Given a net error, cause that error to be returned from the first Write()
10870// call and verify that the HttpTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0210871void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0710872 int error, IoMode mode) {
[email protected]cb9bf6ca2011-01-28 13:15:2710873 net::HttpRequestInfo request_info;
10874 request_info.url = GURL("https://www.example.com/");
10875 request_info.method = "GET";
10876 request_info.load_flags = net::LOAD_NORMAL;
10877
[email protected]8ddf8322012-02-23 18:08:0610878 SSLSocketDataProvider ssl_data(mode, OK);
[email protected]73b8dd222010-11-11 19:55:2410879 net::MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:0610880 net::MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2410881 };
10882 net::StaticSocketDataProvider data(NULL, 0,
10883 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0710884 session_deps_.socket_factory->AddSocketDataProvider(&data);
10885 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2410886
[email protected]bb88e1d32013-05-03 23:11:0710887 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610888 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010889 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]73b8dd222010-11-11 19:55:2410890
[email protected]49639fa2011-12-20 23:22:4110891 TestCompletionCallback callback;
10892 int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
[email protected]73b8dd222010-11-11 19:55:2410893 if (rv == net::ERR_IO_PENDING)
10894 rv = callback.WaitForResult();
10895 ASSERT_EQ(error, rv);
10896}
10897
[email protected]23e482282013-06-14 16:08:0210898TEST_P(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2410899 // Just check a grab bag of cert errors.
10900 static const int kErrors[] = {
10901 ERR_CERT_COMMON_NAME_INVALID,
10902 ERR_CERT_AUTHORITY_INVALID,
10903 ERR_CERT_DATE_INVALID,
10904 };
10905 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0610906 CheckErrorIsPassedBack(kErrors[i], ASYNC);
10907 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2410908 }
10909}
10910
[email protected]bd0b6772011-01-11 19:59:3010911// Ensure that a client certificate is removed from the SSL client auth
10912// cache when:
10913// 1) No proxy is involved.
10914// 2) TLS False Start is disabled.
10915// 3) The initial TLS handshake requests a client certificate.
10916// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0210917TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310918 ClientAuthCertCache_Direct_NoFalseStart) {
[email protected]cb9bf6ca2011-01-28 13:15:2710919 net::HttpRequestInfo request_info;
10920 request_info.url = GURL("https://www.example.com/");
10921 request_info.method = "GET";
10922 request_info.load_flags = net::LOAD_NORMAL;
10923
[email protected]bd0b6772011-01-11 19:59:3010924 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4110925 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3010926
10927 // [ssl_]data1 contains the data for the first SSL handshake. When a
10928 // CertificateRequest is received for the first time, the handshake will
10929 // be aborted to allow the caller to provide a certificate.
[email protected]8ddf8322012-02-23 18:08:0610930 SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3010931 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710932 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
[email protected]bd0b6772011-01-11 19:59:3010933 net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710934 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3010935
10936 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
10937 // False Start is not being used, the result of the SSL handshake will be
10938 // returned as part of the SSLClientSocket::Connect() call. This test
10939 // matches the result of a server sending a handshake_failure alert,
10940 // rather than a Finished message, because it requires a client
10941 // certificate and none was supplied.
[email protected]8ddf8322012-02-23 18:08:0610942 SSLSocketDataProvider ssl_data2(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3010943 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710944 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
[email protected]bd0b6772011-01-11 19:59:3010945 net::StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710946 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3010947
10948 // [ssl_]data3 contains the data for the third SSL handshake. When a
10949 // connection to a server fails during an SSL handshake,
[email protected]80c75f682012-05-26 16:22:1710950 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
10951 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3010952 // of the HttpNetworkTransaction. Because this test failure is due to
10953 // requiring a client certificate, this fallback handshake should also
10954 // fail.
[email protected]8ddf8322012-02-23 18:08:0610955 SSLSocketDataProvider ssl_data3(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3010956 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710957 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
[email protected]bd0b6772011-01-11 19:59:3010958 net::StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710959 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3010960
[email protected]80c75f682012-05-26 16:22:1710961 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
10962 // connection to a server fails during an SSL handshake,
10963 // HttpNetworkTransaction will attempt to fallback to SSLv3 if the previous
10964 // connection was attempted with TLSv1. This is transparent to the caller
10965 // of the HttpNetworkTransaction. Because this test failure is due to
10966 // requiring a client certificate, this fallback handshake should also
10967 // fail.
10968 SSLSocketDataProvider ssl_data4(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
10969 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710970 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
[email protected]80c75f682012-05-26 16:22:1710971 net::StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710972 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1710973
[email protected]7799de12013-05-30 05:52:5110974 // Need one more if TLSv1.2 is enabled.
10975 SSLSocketDataProvider ssl_data5(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
10976 ssl_data5.cert_request_info = cert_request.get();
10977 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
10978 net::StaticSocketDataProvider data5(NULL, 0, NULL, 0);
10979 session_deps_.socket_factory->AddSocketDataProvider(&data5);
10980
[email protected]bb88e1d32013-05-03 23:11:0710981 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610982 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010983 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3010984
[email protected]bd0b6772011-01-11 19:59:3010985 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4110986 TestCompletionCallback callback;
10987 int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
[email protected]bd0b6772011-01-11 19:59:3010988 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10989
10990 // Complete the SSL handshake, which should abort due to requiring a
10991 // client certificate.
10992 rv = callback.WaitForResult();
10993 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
10994
10995 // Indicate that no certificate should be supplied. From the perspective
10996 // of SSLClientCertCache, NULL is just as meaningful as a real
10997 // certificate, so this is the same as supply a
10998 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4110999 rv = trans->RestartWithCertificate(NULL, callback.callback());
[email protected]bd0b6772011-01-11 19:59:3011000 ASSERT_EQ(net::ERR_IO_PENDING, rv);
11001
11002 // Ensure the certificate was added to the client auth cache before
11003 // allowing the connection to continue restarting.
11004 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4111005 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
11006 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3011007 ASSERT_EQ(NULL, client_cert.get());
11008
11009 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1711010 // then consume ssl_data3 and ssl_data4, both of which should also fail.
11011 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3011012 rv = callback.WaitForResult();
11013 ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
11014
11015 // Ensure that the client certificate is removed from the cache on a
11016 // handshake failure.
[email protected]791879c2013-12-17 07:22:4111017 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11018 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3011019}
11020
11021// Ensure that a client certificate is removed from the SSL client auth
11022// cache when:
11023// 1) No proxy is involved.
11024// 2) TLS False Start is enabled.
11025// 3) The initial TLS handshake requests a client certificate.
11026// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0211027TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2311028 ClientAuthCertCache_Direct_FalseStart) {
[email protected]cb9bf6ca2011-01-28 13:15:2711029 net::HttpRequestInfo request_info;
11030 request_info.url = GURL("https://www.example.com/");
11031 request_info.method = "GET";
11032 request_info.load_flags = net::LOAD_NORMAL;
11033
[email protected]bd0b6772011-01-11 19:59:3011034 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4111035 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3011036
11037 // When TLS False Start is used, SSLClientSocket::Connect() calls will
11038 // return successfully after reading up to the peer's Certificate message.
11039 // This is to allow the caller to call SSLClientSocket::Write(), which can
11040 // enqueue application data to be sent in the same packet as the
11041 // ChangeCipherSpec and Finished messages.
11042 // The actual handshake will be finished when SSLClientSocket::Read() is
11043 // called, which expects to process the peer's ChangeCipherSpec and
11044 // Finished messages. If there was an error negotiating with the peer,
11045 // such as due to the peer requiring a client certificate when none was
11046 // supplied, the alert sent by the peer won't be processed until Read() is
11047 // called.
11048
11049 // Like the non-False Start case, when a client certificate is requested by
11050 // the peer, the handshake is aborted during the Connect() call.
11051 // [ssl_]data1 represents the initial SSL handshake with the peer.
[email protected]8ddf8322012-02-23 18:08:0611052 SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3011053 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711054 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
[email protected]bd0b6772011-01-11 19:59:3011055 net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711056 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3011057
11058 // When a client certificate is supplied, Connect() will not be aborted
11059 // when the peer requests the certificate. Instead, the handshake will
11060 // artificially succeed, allowing the caller to write the HTTP request to
11061 // the socket. The handshake messages are not processed until Read() is
11062 // called, which then detects that the handshake was aborted, due to the
11063 // peer sending a handshake_failure because it requires a client
11064 // certificate.
[email protected]8ddf8322012-02-23 18:08:0611065 SSLSocketDataProvider ssl_data2(ASYNC, net::OK);
[email protected]bd0b6772011-01-11 19:59:3011066 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711067 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
[email protected]bd0b6772011-01-11 19:59:3011068 net::MockRead data2_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0611069 net::MockRead(ASYNC /* async */, net::ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3011070 };
11071 net::StaticSocketDataProvider data2(
11072 data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711073 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3011074
11075 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1711076 // the data for the SSL handshake once the TLSv1.1 connection falls back to
11077 // TLSv1. It has the same behaviour as [ssl_]data2.
[email protected]8ddf8322012-02-23 18:08:0611078 SSLSocketDataProvider ssl_data3(ASYNC, net::OK);
[email protected]bd0b6772011-01-11 19:59:3011079 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711080 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
[email protected]bd0b6772011-01-11 19:59:3011081 net::StaticSocketDataProvider data3(
11082 data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711083 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3011084
[email protected]80c75f682012-05-26 16:22:1711085 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
11086 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
11087 SSLSocketDataProvider ssl_data4(ASYNC, net::OK);
11088 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711089 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
[email protected]80c75f682012-05-26 16:22:1711090 net::StaticSocketDataProvider data4(
11091 data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711092 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1711093
[email protected]7799de12013-05-30 05:52:5111094 // Need one more if TLSv1.2 is enabled.
11095 SSLSocketDataProvider ssl_data5(ASYNC, net::OK);
11096 ssl_data5.cert_request_info = cert_request.get();
11097 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
11098 net::StaticSocketDataProvider data5(
11099 data2_reads, arraysize(data2_reads), NULL, 0);
11100 session_deps_.socket_factory->AddSocketDataProvider(&data5);
11101
[email protected]bb88e1d32013-05-03 23:11:0711102 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3611103 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011104 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3011105
[email protected]bd0b6772011-01-11 19:59:3011106 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4111107 TestCompletionCallback callback;
11108 int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
[email protected]bd0b6772011-01-11 19:59:3011109 ASSERT_EQ(net::ERR_IO_PENDING, rv);
11110
11111 // Complete the SSL handshake, which should abort due to requiring a
11112 // client certificate.
11113 rv = callback.WaitForResult();
11114 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
11115
11116 // Indicate that no certificate should be supplied. From the perspective
11117 // of SSLClientCertCache, NULL is just as meaningful as a real
11118 // certificate, so this is the same as supply a
11119 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4111120 rv = trans->RestartWithCertificate(NULL, callback.callback());
[email protected]bd0b6772011-01-11 19:59:3011121 ASSERT_EQ(net::ERR_IO_PENDING, rv);
11122
11123 // Ensure the certificate was added to the client auth cache before
11124 // allowing the connection to continue restarting.
11125 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4111126 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
11127 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3011128 ASSERT_EQ(NULL, client_cert.get());
11129
[email protected]bd0b6772011-01-11 19:59:3011130 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1711131 // then consume ssl_data3 and ssl_data4, both of which should also fail.
11132 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3011133 rv = callback.WaitForResult();
11134 ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
11135
11136 // Ensure that the client certificate is removed from the cache on a
11137 // handshake failure.
[email protected]791879c2013-12-17 07:22:4111138 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11139 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3011140}
11141
[email protected]8c405132011-01-11 22:03:1811142// Ensure that a client certificate is removed from the SSL client auth
11143// cache when:
11144// 1) An HTTPS proxy is involved.
11145// 3) The HTTPS proxy requests a client certificate.
11146// 4) The client supplies an invalid/unacceptable certificate for the
11147// proxy.
11148// The test is repeated twice, first for connecting to an HTTPS endpoint,
11149// then for connecting to an HTTP endpoint.
[email protected]23e482282013-06-14 16:08:0211150TEST_P(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
[email protected]bb88e1d32013-05-03 23:11:0711151 session_deps_.proxy_service.reset(
[email protected]8c405132011-01-11 22:03:1811152 ProxyService::CreateFixed("https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:2911153 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0711154 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1811155
11156 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4111157 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1811158
11159 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
11160 // [ssl_]data[1-3]. Rather than represending the endpoint
11161 // (www.example.com:443), they represent failures with the HTTPS proxy
11162 // (proxy:70).
[email protected]8ddf8322012-02-23 18:08:0611163 SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1811164 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711165 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
[email protected]8c405132011-01-11 22:03:1811166 net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711167 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1811168
[email protected]8ddf8322012-02-23 18:08:0611169 SSLSocketDataProvider ssl_data2(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1811170 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711171 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
[email protected]8c405132011-01-11 22:03:1811172 net::StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711173 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1811174
[email protected]80c75f682012-05-26 16:22:1711175 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
11176#if 0
[email protected]8ddf8322012-02-23 18:08:0611177 SSLSocketDataProvider ssl_data3(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1811178 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711179 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
[email protected]8c405132011-01-11 22:03:1811180 net::StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711181 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1711182#endif
[email protected]8c405132011-01-11 22:03:1811183
11184 net::HttpRequestInfo requests[2];
11185 requests[0].url = GURL("https://www.example.com/");
11186 requests[0].method = "GET";
11187 requests[0].load_flags = net::LOAD_NORMAL;
11188
11189 requests[1].url = GURL("http://www.example.com/");
11190 requests[1].method = "GET";
11191 requests[1].load_flags = net::LOAD_NORMAL;
11192
11193 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0711194 session_deps_.socket_factory->ResetNextMockIndexes();
11195 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c405132011-01-11 22:03:1811196 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5011197 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c405132011-01-11 22:03:1811198
11199 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4111200 TestCompletionCallback callback;
11201 int rv = trans->Start(
11202 &requests[i], callback.callback(), net::BoundNetLog());
[email protected]8c405132011-01-11 22:03:1811203 ASSERT_EQ(net::ERR_IO_PENDING, rv);
11204
11205 // Complete the SSL handshake, which should abort due to requiring a
11206 // client certificate.
11207 rv = callback.WaitForResult();
11208 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
11209
11210 // Indicate that no certificate should be supplied. From the perspective
11211 // of SSLClientCertCache, NULL is just as meaningful as a real
11212 // certificate, so this is the same as supply a
11213 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4111214 rv = trans->RestartWithCertificate(NULL, callback.callback());
[email protected]8c405132011-01-11 22:03:1811215 ASSERT_EQ(net::ERR_IO_PENDING, rv);
11216
11217 // Ensure the certificate was added to the client auth cache before
11218 // allowing the connection to continue restarting.
11219 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4111220 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
11221 HostPortPair("proxy", 70), &client_cert));
[email protected]8c405132011-01-11 22:03:1811222 ASSERT_EQ(NULL, client_cert.get());
11223 // Ensure the certificate was NOT cached for the endpoint. This only
11224 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4111225 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11226 HostPortPair("www.example.com", 443), &client_cert));
[email protected]8c405132011-01-11 22:03:1811227
11228 // Restart the handshake. This will consume ssl_data2, which fails, and
11229 // then consume ssl_data3, which should also fail. The result code is
11230 // checked against what ssl_data3 should return.
11231 rv = callback.WaitForResult();
11232 ASSERT_EQ(net::ERR_PROXY_CONNECTION_FAILED, rv);
11233
11234 // Now that the new handshake has failed, ensure that the client
11235 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4111236 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11237 HostPortPair("proxy", 70), &client_cert));
11238 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11239 HostPortPair("www.example.com", 443), &client_cert));
[email protected]8c405132011-01-11 22:03:1811240 }
11241}
11242
[email protected]23e482282013-06-14 16:08:0211243// Unlike TEST/TEST_F, which are macros that expand to further macros,
11244// TEST_P is a macro that expands directly to code that stringizes the
11245// arguments. As a result, macros passed as parameters (such as prefix
11246// or test_case_name) will not be expanded by the preprocessor. To
11247// work around this, indirect the macro for TEST_P, so that the
11248// pre-processor will expand macros such as MAYBE_test_name before
11249// instantiating the test.
11250#define WRAPPED_TEST_P(test_case_name, test_name) \
11251 TEST_P(test_case_name, test_name)
11252
[email protected]45b170822012-05-04 21:18:1411253// Times out on Win7 dbg(2) bot. http://crbug.com/124776
11254#if defined(OS_WIN)
11255#define MAYBE_UseIPConnectionPooling DISABLED_UseIPConnectionPooling
11256#else
11257#define MAYBE_UseIPConnectionPooling UseIPConnectionPooling
11258#endif
[email protected]23e482282013-06-14 16:08:0211259WRAPPED_TEST_P(HttpNetworkTransactionTest, MAYBE_UseIPConnectionPooling) {
[email protected]d7599122014-05-24 03:37:2311260 session_deps_.use_alternate_protocols = true;
11261 session_deps_.next_protos = SpdyNextProtos();
[email protected]e3ceb682011-06-28 23:55:4611262
11263 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0711264 session_deps_.host_resolver.reset(new MockCachingHostResolver());
11265 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2611266 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
11267 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4611268
[email protected]8ddf8322012-02-23 18:08:0611269 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211270 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711271 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4611272
[email protected]cdf8f7e72013-05-23 10:56:4611273 scoped_ptr<SpdyFrame> host1_req(
11274 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
11275 scoped_ptr<SpdyFrame> host2_req(
11276 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4611277 MockWrite spdy_writes[] = {
11278 CreateMockWrite(*host1_req, 1),
11279 CreateMockWrite(*host2_req, 4),
11280 };
[email protected]23e482282013-06-14 16:08:0211281 scoped_ptr<SpdyFrame> host1_resp(
11282 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11283 scoped_ptr<SpdyFrame> host1_resp_body(
11284 spdy_util_.ConstructSpdyBodyFrame(1, true));
11285 scoped_ptr<SpdyFrame> host2_resp(
11286 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11287 scoped_ptr<SpdyFrame> host2_resp_body(
11288 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4611289 MockRead spdy_reads[] = {
11290 CreateMockRead(*host1_resp, 2),
11291 CreateMockRead(*host1_resp_body, 3),
11292 CreateMockRead(*host2_resp, 5),
11293 CreateMockRead(*host2_resp_body, 6),
[email protected]8ddf8322012-02-23 18:08:0611294 MockRead(ASYNC, 0, 7),
[email protected]e3ceb682011-06-28 23:55:4611295 };
11296
[email protected]d2b5f092012-06-08 23:55:0211297 IPAddressNumber ip;
11298 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
11299 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11300 MockConnect connect(ASYNC, OK, peer_addr);
[email protected]dd54bd82012-07-19 23:44:5711301 OrderedSocketData spdy_data(
11302 connect,
11303 spdy_reads, arraysize(spdy_reads),
11304 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711305 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4611306
[email protected]aa22b242011-11-16 18:58:2911307 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4611308 HttpRequestInfo request1;
11309 request1.method = "GET";
11310 request1.url = GURL("https://www.google.com/");
11311 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011312 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611313
[email protected]49639fa2011-12-20 23:22:4111314 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611315 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111316 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611317
11318 const HttpResponseInfo* response = trans1.GetResponseInfo();
11319 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011320 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611321 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11322
11323 std::string response_data;
11324 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
11325 EXPECT_EQ("hello!", response_data);
11326
11327 // Preload www.gmail.com into HostCache.
11328 HostPortPair host_port("www.gmail.com", 443);
[email protected]5109c1952013-08-20 18:44:1011329 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4611330 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1011331 rv = session_deps_.host_resolver->Resolve(resolve_info,
11332 DEFAULT_PRIORITY,
11333 &ignored,
11334 callback.callback(),
11335 NULL,
11336 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4711337 EXPECT_EQ(ERR_IO_PENDING, rv);
11338 rv = callback.WaitForResult();
11339 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4611340
11341 HttpRequestInfo request2;
11342 request2.method = "GET";
11343 request2.url = GURL("https://www.gmail.com/");
11344 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011345 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611346
[email protected]49639fa2011-12-20 23:22:4111347 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611348 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111349 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611350
11351 response = trans2.GetResponseInfo();
11352 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011353 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611354 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11355 EXPECT_TRUE(response->was_fetched_via_spdy);
11356 EXPECT_TRUE(response->was_npn_negotiated);
11357 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
11358 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4611359}
[email protected]45b170822012-05-04 21:18:1411360#undef MAYBE_UseIPConnectionPooling
[email protected]e3ceb682011-06-28 23:55:4611361
[email protected]23e482282013-06-14 16:08:0211362TEST_P(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d7599122014-05-24 03:37:2311363 session_deps_.use_alternate_protocols = true;
11364 session_deps_.next_protos = SpdyNextProtos();
[email protected]d2b5f092012-06-08 23:55:0211365
11366 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0711367 session_deps_.host_resolver.reset(new MockCachingHostResolver());
11368 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0211369 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
11370 pool_peer.DisableDomainAuthenticationVerification();
11371
11372 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211373 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711374 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]d2b5f092012-06-08 23:55:0211375
[email protected]cdf8f7e72013-05-23 10:56:4611376 scoped_ptr<SpdyFrame> host1_req(
11377 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
11378 scoped_ptr<SpdyFrame> host2_req(
11379 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0211380 MockWrite spdy_writes[] = {
11381 CreateMockWrite(*host1_req, 1),
11382 CreateMockWrite(*host2_req, 4),
11383 };
[email protected]23e482282013-06-14 16:08:0211384 scoped_ptr<SpdyFrame> host1_resp(
11385 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11386 scoped_ptr<SpdyFrame> host1_resp_body(
11387 spdy_util_.ConstructSpdyBodyFrame(1, true));
11388 scoped_ptr<SpdyFrame> host2_resp(
11389 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11390 scoped_ptr<SpdyFrame> host2_resp_body(
11391 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0211392 MockRead spdy_reads[] = {
11393 CreateMockRead(*host1_resp, 2),
11394 CreateMockRead(*host1_resp_body, 3),
11395 CreateMockRead(*host2_resp, 5),
11396 CreateMockRead(*host2_resp_body, 6),
11397 MockRead(ASYNC, 0, 7),
11398 };
11399
11400 IPAddressNumber ip;
11401 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
11402 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11403 MockConnect connect(ASYNC, OK, peer_addr);
[email protected]dd54bd82012-07-19 23:44:5711404 OrderedSocketData spdy_data(
11405 connect,
11406 spdy_reads, arraysize(spdy_reads),
11407 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711408 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0211409
11410 TestCompletionCallback callback;
11411 HttpRequestInfo request1;
11412 request1.method = "GET";
11413 request1.url = GURL("https://www.google.com/");
11414 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011415 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0211416
11417 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
11418 EXPECT_EQ(ERR_IO_PENDING, rv);
11419 EXPECT_EQ(OK, callback.WaitForResult());
11420
11421 const HttpResponseInfo* response = trans1.GetResponseInfo();
11422 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011423 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d2b5f092012-06-08 23:55:0211424 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11425
11426 std::string response_data;
11427 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
11428 EXPECT_EQ("hello!", response_data);
11429
11430 HttpRequestInfo request2;
11431 request2.method = "GET";
11432 request2.url = GURL("https://www.gmail.com/");
11433 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011434 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0211435
11436 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
11437 EXPECT_EQ(ERR_IO_PENDING, rv);
11438 EXPECT_EQ(OK, callback.WaitForResult());
11439
11440 response = trans2.GetResponseInfo();
11441 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011442 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d2b5f092012-06-08 23:55:0211443 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11444 EXPECT_TRUE(response->was_fetched_via_spdy);
11445 EXPECT_TRUE(response->was_npn_negotiated);
11446 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
11447 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0211448}
11449
[email protected]e3ceb682011-06-28 23:55:4611450class OneTimeCachingHostResolver : public net::HostResolver {
11451 public:
11452 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
11453 : host_port_(host_port) {}
dchengb03027d2014-10-21 12:00:2011454 ~OneTimeCachingHostResolver() override {}
[email protected]e3ceb682011-06-28 23:55:4611455
11456 RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); }
11457
11458 // HostResolver methods:
dchengb03027d2014-10-21 12:00:2011459 int Resolve(const RequestInfo& info,
11460 RequestPriority priority,
11461 AddressList* addresses,
11462 const CompletionCallback& callback,
11463 RequestHandle* out_req,
11464 const BoundNetLog& net_log) override {
[email protected]95a214c2011-08-04 21:50:4011465 return host_resolver_.Resolve(
[email protected]5109c1952013-08-20 18:44:1011466 info, priority, addresses, callback, out_req, net_log);
[email protected]95a214c2011-08-04 21:50:4011467 }
11468
dchengb03027d2014-10-21 12:00:2011469 int ResolveFromCache(const RequestInfo& info,
11470 AddressList* addresses,
11471 const BoundNetLog& net_log) override {
[email protected]95a214c2011-08-04 21:50:4011472 int rv = host_resolver_.ResolveFromCache(info, addresses, net_log);
11473 if (rv == OK && info.host_port_pair().Equals(host_port_))
[email protected]98e1cd012011-11-08 15:33:0911474 host_resolver_.GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4611475 return rv;
11476 }
11477
dchengb03027d2014-10-21 12:00:2011478 void CancelRequest(RequestHandle req) override {
[email protected]e3ceb682011-06-28 23:55:4611479 host_resolver_.CancelRequest(req);
11480 }
11481
[email protected]46da33be2011-07-19 21:58:0411482 MockCachingHostResolver* GetMockHostResolver() {
11483 return &host_resolver_;
11484 }
11485
[email protected]e3ceb682011-06-28 23:55:4611486 private:
11487 MockCachingHostResolver host_resolver_;
11488 const HostPortPair host_port_;
11489};
11490
[email protected]45b170822012-05-04 21:18:1411491// Times out on Win7 dbg(2) bot. http://crbug.com/124776
11492#if defined(OS_WIN)
[email protected]bb88e1d32013-05-03 23:11:0711493#define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \
11494 DISABLED_UseIPConnectionPoolingWithHostCacheExpiration
[email protected]45b170822012-05-04 21:18:1411495#else
[email protected]bb88e1d32013-05-03 23:11:0711496#define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \
11497 UseIPConnectionPoolingWithHostCacheExpiration
[email protected]45b170822012-05-04 21:18:1411498#endif
[email protected]23e482282013-06-14 16:08:0211499WRAPPED_TEST_P(HttpNetworkTransactionTest,
11500 MAYBE_UseIPConnectionPoolingWithHostCacheExpiration) {
[email protected]23e482282013-06-14 16:08:0211501// Times out on Win7 dbg(2) bot. http://crbug.com/124776 . (MAYBE_
11502// prefix doesn't work with parametrized tests).
11503#if defined(OS_WIN)
11504 return;
[email protected]88c7b4be2014-03-19 23:04:0111505#else
[email protected]d7599122014-05-24 03:37:2311506 session_deps_.use_alternate_protocols = true;
11507 session_deps_.next_protos = SpdyNextProtos();
[email protected]e3ceb682011-06-28 23:55:4611508
11509 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
[email protected]e3ceb682011-06-28 23:55:4611510 OneTimeCachingHostResolver host_resolver(HostPortPair("www.gmail.com", 443));
[email protected]c6bf8152012-12-02 07:43:3411511 HttpNetworkSession::Params params =
[email protected]bb88e1d32013-05-03 23:11:0711512 SpdySessionDependencies::CreateSessionParams(&session_deps_);
[email protected]e3ceb682011-06-28 23:55:4611513 params.host_resolver = &host_resolver;
[email protected]bb88e1d32013-05-03 23:11:0711514 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2611515 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
11516 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4611517
[email protected]8ddf8322012-02-23 18:08:0611518 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211519 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711520 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4611521
[email protected]cdf8f7e72013-05-23 10:56:4611522 scoped_ptr<SpdyFrame> host1_req(
11523 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
11524 scoped_ptr<SpdyFrame> host2_req(
11525 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4611526 MockWrite spdy_writes[] = {
11527 CreateMockWrite(*host1_req, 1),
11528 CreateMockWrite(*host2_req, 4),
11529 };
[email protected]23e482282013-06-14 16:08:0211530 scoped_ptr<SpdyFrame> host1_resp(
11531 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11532 scoped_ptr<SpdyFrame> host1_resp_body(
11533 spdy_util_.ConstructSpdyBodyFrame(1, true));
11534 scoped_ptr<SpdyFrame> host2_resp(
11535 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11536 scoped_ptr<SpdyFrame> host2_resp_body(
11537 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4611538 MockRead spdy_reads[] = {
11539 CreateMockRead(*host1_resp, 2),
11540 CreateMockRead(*host1_resp_body, 3),
11541 CreateMockRead(*host2_resp, 5),
11542 CreateMockRead(*host2_resp_body, 6),
[email protected]8ddf8322012-02-23 18:08:0611543 MockRead(ASYNC, 0, 7),
[email protected]e3ceb682011-06-28 23:55:4611544 };
11545
[email protected]d2b5f092012-06-08 23:55:0211546 IPAddressNumber ip;
11547 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
11548 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11549 MockConnect connect(ASYNC, OK, peer_addr);
[email protected]dd54bd82012-07-19 23:44:5711550 OrderedSocketData spdy_data(
11551 connect,
11552 spdy_reads, arraysize(spdy_reads),
11553 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711554 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4611555
[email protected]aa22b242011-11-16 18:58:2911556 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4611557 HttpRequestInfo request1;
11558 request1.method = "GET";
11559 request1.url = GURL("https://www.google.com/");
11560 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011561 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611562
[email protected]49639fa2011-12-20 23:22:4111563 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611564 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111565 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611566
11567 const HttpResponseInfo* response = trans1.GetResponseInfo();
11568 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011569 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611570 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11571
11572 std::string response_data;
11573 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
11574 EXPECT_EQ("hello!", response_data);
11575
11576 // Preload cache entries into HostCache.
[email protected]5109c1952013-08-20 18:44:1011577 HostResolver::RequestInfo resolve_info(HostPortPair("www.gmail.com", 443));
[email protected]e3ceb682011-06-28 23:55:4611578 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1011579 rv = host_resolver.Resolve(resolve_info,
11580 DEFAULT_PRIORITY,
11581 &ignored,
11582 callback.callback(),
11583 NULL,
11584 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4711585 EXPECT_EQ(ERR_IO_PENDING, rv);
11586 rv = callback.WaitForResult();
11587 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4611588
11589 HttpRequestInfo request2;
11590 request2.method = "GET";
11591 request2.url = GURL("https://www.gmail.com/");
11592 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011593 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611594
[email protected]49639fa2011-12-20 23:22:4111595 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611596 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111597 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611598
11599 response = trans2.GetResponseInfo();
11600 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011601 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611602 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11603 EXPECT_TRUE(response->was_fetched_via_spdy);
11604 EXPECT_TRUE(response->was_npn_negotiated);
11605 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
11606 EXPECT_EQ("hello!", response_data);
[email protected]88c7b4be2014-03-19 23:04:0111607#endif
[email protected]e3ceb682011-06-28 23:55:4611608}
[email protected]45b170822012-05-04 21:18:1411609#undef MAYBE_UseIPConnectionPoolingWithHostCacheExpiration
[email protected]e3ceb682011-06-28 23:55:4611610
[email protected]23e482282013-06-14 16:08:0211611TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
lgarrona91df87f2014-12-05 00:51:3411612 const std::string https_url = "https://www.google.com:8080/";
11613 const std::string http_url = "http://www.google.com:8080/";
[email protected]8450d722012-07-02 19:14:0411614
11615 // SPDY GET for HTTPS URL
[email protected]cdf8f7e72013-05-23 10:56:4611616 scoped_ptr<SpdyFrame> req1(
11617 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0411618
11619 MockWrite writes1[] = {
11620 CreateMockWrite(*req1, 0),
11621 };
11622
[email protected]23e482282013-06-14 16:08:0211623 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11624 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8450d722012-07-02 19:14:0411625 MockRead reads1[] = {
11626 CreateMockRead(*resp1, 1),
11627 CreateMockRead(*body1, 2),
11628 MockRead(ASYNC, ERR_IO_PENDING, 3)
11629 };
11630
[email protected]dd54bd82012-07-19 23:44:5711631 DelayedSocketData data1(
11632 1, reads1, arraysize(reads1),
11633 writes1, arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0411634 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5711635 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0411636
11637 // HTTP GET for the HTTP URL
11638 MockWrite writes2[] = {
lgarrona91df87f2014-12-05 00:51:3411639 MockWrite(ASYNC, 4,
11640 "GET / HTTP/1.1\r\n"
11641 "Host: www.google.com:8080\r\n"
11642 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0411643 };
11644
11645 MockRead reads2[] = {
11646 MockRead(ASYNC, 5, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
11647 MockRead(ASYNC, 6, "hello"),
11648 MockRead(ASYNC, 7, OK),
11649 };
11650
[email protected]dd54bd82012-07-19 23:44:5711651 DelayedSocketData data2(
11652 1, reads2, arraysize(reads2),
11653 writes2, arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0411654
[email protected]8450d722012-07-02 19:14:0411655 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211656 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711657 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11658 session_deps_.socket_factory->AddSocketDataProvider(&data1);
11659 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0411660
[email protected]bb88e1d32013-05-03 23:11:0711661 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0411662
11663 // Start the first transaction to set up the SpdySession
11664 HttpRequestInfo request1;
11665 request1.method = "GET";
11666 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0411667 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011668 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0411669 TestCompletionCallback callback1;
11670 EXPECT_EQ(ERR_IO_PENDING,
11671 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411672 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411673
11674 EXPECT_EQ(OK, callback1.WaitForResult());
11675 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11676
11677 // Now, start the HTTP request
11678 HttpRequestInfo request2;
11679 request2.method = "GET";
11680 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0411681 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011682 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0411683 TestCompletionCallback callback2;
11684 EXPECT_EQ(ERR_IO_PENDING,
11685 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411686 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411687
11688 EXPECT_EQ(OK, callback2.WaitForResult());
11689 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11690}
11691
[email protected]23e482282013-06-14 16:08:0211692TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
lgarrona91df87f2014-12-05 00:51:3411693 const std::string https_url = "https://www.google.com:8080/";
11694 const std::string http_url = "http://www.google.com:8080/";
[email protected]8450d722012-07-02 19:14:0411695
11696 // SPDY GET for HTTPS URL (through CONNECT tunnel)
lgarrona91df87f2014-12-05 00:51:3411697 const HostPortPair host_port_pair("www.google.com", 8080);
11698 scoped_ptr<SpdyFrame> connect(
11699 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
[email protected]cdf8f7e72013-05-23 10:56:4611700 scoped_ptr<SpdyFrame> req1(
11701 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]23e482282013-06-14 16:08:0211702 scoped_ptr<SpdyFrame> wrapped_req1(
11703 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3911704
11705 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
[email protected]745aa9c2014-06-27 02:21:2911706 SpdyHeaderBlock req2_block;
11707 req2_block[spdy_util_.GetMethodKey()] = "GET";
bnc33b8cef42014-11-19 17:30:3811708 req2_block[spdy_util_.GetPathKey()] = "/";
lgarrona91df87f2014-12-05 00:51:3411709 req2_block[spdy_util_.GetHostKey()] = "www.google.com:8080";
[email protected]745aa9c2014-06-27 02:21:2911710 req2_block[spdy_util_.GetSchemeKey()] = "http";
11711 spdy_util_.MaybeAddVersionHeader(&req2_block);
[email protected]601e03f12014-04-06 16:26:3911712 scoped_ptr<SpdyFrame> req2(
[email protected]745aa9c2014-06-27 02:21:2911713 spdy_util_.ConstructSpdySyn(3, req2_block, MEDIUM, false, true));
[email protected]8450d722012-07-02 19:14:0411714
11715 MockWrite writes1[] = {
11716 CreateMockWrite(*connect, 0),
11717 CreateMockWrite(*wrapped_req1, 2),
11718 CreateMockWrite(*req2, 5),
11719 };
11720
[email protected]23e482282013-06-14 16:08:0211721 scoped_ptr<SpdyFrame> conn_resp(
11722 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11723 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11724 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
11725 scoped_ptr<SpdyFrame> wrapped_resp1(
11726 spdy_util_.ConstructWrappedSpdyFrame(resp1, 1));
11727 scoped_ptr<SpdyFrame> wrapped_body1(
11728 spdy_util_.ConstructWrappedSpdyFrame(body1, 1));
11729 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11730 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]8450d722012-07-02 19:14:0411731 MockRead reads1[] = {
11732 CreateMockRead(*conn_resp, 1),
11733 CreateMockRead(*wrapped_resp1, 3),
11734 CreateMockRead(*wrapped_body1, 4),
11735 CreateMockRead(*resp2, 6),
11736 CreateMockRead(*body2, 7),
11737 MockRead(ASYNC, ERR_IO_PENDING, 8)
11738 };
11739
[email protected]dd54bd82012-07-19 23:44:5711740 DeterministicSocketData data1(reads1, arraysize(reads1),
11741 writes1, arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0411742 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5711743 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0411744
[email protected]bb88e1d32013-05-03 23:11:0711745 session_deps_.proxy_service.reset(
[email protected]f6c63db52013-02-02 00:35:2211746 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
11747 CapturingNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0711748 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0411749 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
[email protected]23e482282013-06-14 16:08:0211750 ssl1.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711751 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0411752 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
[email protected]23e482282013-06-14 16:08:0211753 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711754 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11755 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0411756
11757 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0711758 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]8450d722012-07-02 19:14:0411759
11760 // Start the first transaction to set up the SpdySession
11761 HttpRequestInfo request1;
11762 request1.method = "GET";
11763 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0411764 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011765 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0411766 TestCompletionCallback callback1;
11767 EXPECT_EQ(ERR_IO_PENDING,
11768 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411769 base::MessageLoop::current()->RunUntilIdle();
[email protected]dd54bd82012-07-19 23:44:5711770 data1.RunFor(4);
[email protected]8450d722012-07-02 19:14:0411771
11772 EXPECT_EQ(OK, callback1.WaitForResult());
11773 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11774
[email protected]f6c63db52013-02-02 00:35:2211775 LoadTimingInfo load_timing_info1;
11776 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
11777 TestLoadTimingNotReusedWithPac(load_timing_info1,
11778 CONNECT_TIMING_HAS_SSL_TIMES);
11779
[email protected]8450d722012-07-02 19:14:0411780 // Now, start the HTTP request
11781 HttpRequestInfo request2;
11782 request2.method = "GET";
11783 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0411784 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011785 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0411786 TestCompletionCallback callback2;
11787 EXPECT_EQ(ERR_IO_PENDING,
11788 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411789 base::MessageLoop::current()->RunUntilIdle();
[email protected]dd54bd82012-07-19 23:44:5711790 data1.RunFor(3);
[email protected]8450d722012-07-02 19:14:0411791
11792 EXPECT_EQ(OK, callback2.WaitForResult());
11793 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2211794
11795 LoadTimingInfo load_timing_info2;
11796 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
11797 // The established SPDY sessions is considered reused by the HTTP request.
11798 TestLoadTimingReusedWithPac(load_timing_info2);
11799 // HTTP requests over a SPDY session should have a different connection
11800 // socket_log_id than requests over a tunnel.
11801 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0411802}
11803
[email protected]23e482282013-06-14 16:08:0211804TEST_P(HttpNetworkTransactionTest, UseSpdySessionForHttpWhenForced) {
[email protected]d7599122014-05-24 03:37:2311805 session_deps_.force_spdy_always = true;
lgarrona91df87f2014-12-05 00:51:3411806 const std::string https_url = "https://www.google.com:8080/";
11807 const std::string http_url = "http://www.google.com:8080/";
[email protected]8450d722012-07-02 19:14:0411808
11809 // SPDY GET for HTTPS URL
[email protected]cdf8f7e72013-05-23 10:56:4611810 scoped_ptr<SpdyFrame> req1(
11811 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0411812 // SPDY GET for the HTTP URL
[email protected]cdf8f7e72013-05-23 10:56:4611813 scoped_ptr<SpdyFrame> req2(
11814 spdy_util_.ConstructSpdyGet(http_url.c_str(), false, 3, MEDIUM));
[email protected]8450d722012-07-02 19:14:0411815
11816 MockWrite writes[] = {
11817 CreateMockWrite(*req1, 1),
11818 CreateMockWrite(*req2, 4),
11819 };
11820
[email protected]23e482282013-06-14 16:08:0211821 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11822 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
11823 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11824 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]8450d722012-07-02 19:14:0411825 MockRead reads[] = {
11826 CreateMockRead(*resp1, 2),
11827 CreateMockRead(*body1, 3),
11828 CreateMockRead(*resp2, 5),
11829 CreateMockRead(*body2, 6),
11830 MockRead(ASYNC, ERR_IO_PENDING, 7)
11831 };
11832
[email protected]dd54bd82012-07-19 23:44:5711833 OrderedSocketData data(reads, arraysize(reads),
11834 writes, arraysize(writes));
[email protected]8450d722012-07-02 19:14:0411835
[email protected]8450d722012-07-02 19:14:0411836 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211837 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711838 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11839 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8450d722012-07-02 19:14:0411840
[email protected]bb88e1d32013-05-03 23:11:0711841 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0411842
11843 // Start the first transaction to set up the SpdySession
11844 HttpRequestInfo request1;
11845 request1.method = "GET";
11846 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0411847 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011848 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0411849 TestCompletionCallback callback1;
11850 EXPECT_EQ(ERR_IO_PENDING,
11851 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411852 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411853
11854 EXPECT_EQ(OK, callback1.WaitForResult());
11855 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11856
11857 // Now, start the HTTP request
11858 HttpRequestInfo request2;
11859 request2.method = "GET";
11860 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0411861 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011862 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0411863 TestCompletionCallback callback2;
11864 EXPECT_EQ(ERR_IO_PENDING,
11865 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411866 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411867
11868 EXPECT_EQ(OK, callback2.WaitForResult());
11869 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11870}
11871
[email protected]2d88e7d2012-07-19 17:55:1711872// Test that in the case where we have a SPDY session to a SPDY proxy
11873// that we do not pool other origins that resolve to the same IP when
11874// the certificate does not match the new origin.
11875// http://crbug.com/134690
[email protected]23e482282013-06-14 16:08:0211876TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
[email protected]2d88e7d2012-07-19 17:55:1711877 const std::string url1 = "http://www.google.com/";
11878 const std::string url2 = "https://mail.google.com/";
11879 const std::string ip_addr = "1.2.3.4";
11880
11881 // SPDY GET for HTTP URL (through SPDY proxy)
[email protected]23e482282013-06-14 16:08:0211882 scoped_ptr<SpdyHeaderBlock> headers(
11883 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/"));
[email protected]745aa9c2014-06-27 02:21:2911884 scoped_ptr<SpdyFrame> req1(
11885 spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, false, true));
[email protected]2d88e7d2012-07-19 17:55:1711886
11887 MockWrite writes1[] = {
11888 CreateMockWrite(*req1, 0),
11889 };
11890
[email protected]23e482282013-06-14 16:08:0211891 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11892 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1711893 MockRead reads1[] = {
11894 CreateMockRead(*resp1, 1),
11895 CreateMockRead(*body1, 2),
11896 MockRead(ASYNC, OK, 3) // EOF
11897 };
11898
11899 scoped_ptr<DeterministicSocketData> data1(
11900 new DeterministicSocketData(reads1, arraysize(reads1),
11901 writes1, arraysize(writes1)));
11902 IPAddressNumber ip;
11903 ASSERT_TRUE(ParseIPLiteralToNumber(ip_addr, &ip));
11904 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11905 MockConnect connect_data1(ASYNC, OK, peer_addr);
11906 data1->set_connect_data(connect_data1);
11907
11908 // SPDY GET for HTTPS URL (direct)
[email protected]cdf8f7e72013-05-23 10:56:4611909 scoped_ptr<SpdyFrame> req2(
11910 spdy_util_.ConstructSpdyGet(url2.c_str(), false, 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1711911
11912 MockWrite writes2[] = {
11913 CreateMockWrite(*req2, 0),
11914 };
11915
[email protected]23e482282013-06-14 16:08:0211916 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11917 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1711918 MockRead reads2[] = {
11919 CreateMockRead(*resp2, 1),
11920 CreateMockRead(*body2, 2),
11921 MockRead(ASYNC, OK, 3) // EOF
11922 };
11923
11924 scoped_ptr<DeterministicSocketData> data2(
11925 new DeterministicSocketData(reads2, arraysize(reads2),
11926 writes2, arraysize(writes2)));
11927 MockConnect connect_data2(ASYNC, OK);
11928 data2->set_connect_data(connect_data2);
11929
11930 // Set up a proxy config that sends HTTP requests to a proxy, and
11931 // all others direct.
11932 ProxyConfig proxy_config;
11933 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
11934 CapturingProxyResolver* capturing_proxy_resolver =
11935 new CapturingProxyResolver();
[email protected]bb88e1d32013-05-03 23:11:0711936 session_deps_.proxy_service.reset(new ProxyService(
[email protected]2d88e7d2012-07-19 17:55:1711937 new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver,
11938 NULL));
11939
11940 // Load a valid cert. Note, that this does not need to
11941 // be valid for proxy because the MockSSLClientSocket does
11942 // not actually verify it. But SpdySession will use this
11943 // to see if it is valid for the new origin
[email protected]6cdfd7f2013-02-08 20:40:1511944 base::FilePath certs_dir = GetTestCertsDirectory();
[email protected]2d88e7d2012-07-19 17:55:1711945 scoped_refptr<X509Certificate> server_cert(
11946 ImportCertFromFile(certs_dir, "ok_cert.pem"));
dcheng48459ac22014-08-26 00:46:4111947 ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert.get());
[email protected]2d88e7d2012-07-19 17:55:1711948
11949 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
[email protected]23e482282013-06-14 16:08:0211950 ssl1.SetNextProto(GetParam());
[email protected]2d88e7d2012-07-19 17:55:1711951 ssl1.cert = server_cert;
[email protected]bb88e1d32013-05-03 23:11:0711952 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
11953 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11954 data1.get());
[email protected]2d88e7d2012-07-19 17:55:1711955
11956 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
[email protected]23e482282013-06-14 16:08:0211957 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711958 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11959 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11960 data2.get());
[email protected]2d88e7d2012-07-19 17:55:1711961
[email protected]bb88e1d32013-05-03 23:11:0711962 session_deps_.host_resolver.reset(new MockCachingHostResolver());
11963 session_deps_.host_resolver->rules()->AddRule("mail.google.com", ip_addr);
11964 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1711965
11966 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0711967 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]2d88e7d2012-07-19 17:55:1711968
11969 // Start the first transaction to set up the SpdySession
11970 HttpRequestInfo request1;
11971 request1.method = "GET";
11972 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1711973 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011974 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1711975 TestCompletionCallback callback1;
11976 ASSERT_EQ(ERR_IO_PENDING,
11977 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
11978 data1->RunFor(3);
11979
11980 ASSERT_TRUE(callback1.have_result());
11981 EXPECT_EQ(OK, callback1.WaitForResult());
11982 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11983
11984 // Now, start the HTTP request
11985 HttpRequestInfo request2;
11986 request2.method = "GET";
11987 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1711988 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011989 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1711990 TestCompletionCallback callback2;
11991 EXPECT_EQ(ERR_IO_PENDING,
11992 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411993 base::MessageLoop::current()->RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1711994 data2->RunFor(3);
11995
11996 ASSERT_TRUE(callback2.have_result());
11997 EXPECT_EQ(OK, callback2.WaitForResult());
11998 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11999}
12000
[email protected]85f97342013-04-17 06:12:2412001// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
12002// error) in SPDY session, removes the socket from pool and closes the SPDY
12003// session. Verify that new url's from the same HttpNetworkSession (and a new
12004// SpdySession) do work. http://crbug.com/224701
[email protected]23e482282013-06-14 16:08:0212005TEST_P(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
[email protected]85f97342013-04-17 06:12:2412006 const std::string https_url = "https://www.google.com/";
12007
12008 MockRead reads1[] = {
12009 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
12010 };
12011
12012 scoped_ptr<DeterministicSocketData> data1(
12013 new DeterministicSocketData(reads1, arraysize(reads1), NULL, 0));
12014 data1->SetStop(1);
12015
[email protected]cdf8f7e72013-05-23 10:56:4612016 scoped_ptr<SpdyFrame> req2(
12017 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2412018 MockWrite writes2[] = {
12019 CreateMockWrite(*req2, 0),
12020 };
12021
[email protected]23e482282013-06-14 16:08:0212022 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12023 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]85f97342013-04-17 06:12:2412024 MockRead reads2[] = {
12025 CreateMockRead(*resp2, 1),
12026 CreateMockRead(*body2, 2),
12027 MockRead(ASYNC, OK, 3) // EOF
12028 };
12029
12030 scoped_ptr<DeterministicSocketData> data2(
12031 new DeterministicSocketData(reads2, arraysize(reads2),
12032 writes2, arraysize(writes2)));
12033
[email protected]85f97342013-04-17 06:12:2412034 SSLSocketDataProvider ssl1(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212035 ssl1.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0712036 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
12037 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
12038 data1.get());
[email protected]85f97342013-04-17 06:12:2412039
12040 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212041 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0712042 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
12043 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
12044 data2.get());
[email protected]85f97342013-04-17 06:12:2412045
12046 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0712047 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]85f97342013-04-17 06:12:2412048
12049 // Start the first transaction to set up the SpdySession and verify that
12050 // connection was closed.
12051 HttpRequestInfo request1;
12052 request1.method = "GET";
12053 request1.url = GURL(https_url);
12054 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012055 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2412056 TestCompletionCallback callback1;
12057 EXPECT_EQ(ERR_IO_PENDING,
12058 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412059 base::MessageLoop::current()->RunUntilIdle();
[email protected]85f97342013-04-17 06:12:2412060 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback1.WaitForResult());
12061
12062 // Now, start the second request and make sure it succeeds.
12063 HttpRequestInfo request2;
12064 request2.method = "GET";
12065 request2.url = GURL(https_url);
12066 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012067 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2412068 TestCompletionCallback callback2;
12069 EXPECT_EQ(ERR_IO_PENDING,
12070 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412071 base::MessageLoop::current()->RunUntilIdle();
[email protected]85f97342013-04-17 06:12:2412072 data2->RunFor(3);
12073
12074 ASSERT_TRUE(callback2.have_result());
12075 EXPECT_EQ(OK, callback2.WaitForResult());
12076 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
12077}
12078
[email protected]23e482282013-06-14 16:08:0212079TEST_P(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]d7599122014-05-24 03:37:2312080 session_deps_.next_protos = SpdyNextProtos();
[email protected]483fa202013-05-14 01:07:0312081 ClientSocketPoolManager::set_max_sockets_per_group(
12082 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12083 ClientSocketPoolManager::set_max_sockets_per_pool(
12084 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12085
12086 // Use two different hosts with different IPs so they don't get pooled.
12087 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
12088 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
12089 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12090
12091 SSLSocketDataProvider ssl1(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212092 ssl1.SetNextProto(GetParam());
[email protected]483fa202013-05-14 01:07:0312093 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212094 ssl2.SetNextProto(GetParam());
[email protected]483fa202013-05-14 01:07:0312095 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
12096 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
12097
[email protected]cdf8f7e72013-05-23 10:56:4612098 scoped_ptr<SpdyFrame> host1_req(spdy_util_.ConstructSpdyGet(
[email protected]483fa202013-05-14 01:07:0312099 "https://www.a.com", false, 1, DEFAULT_PRIORITY));
12100 MockWrite spdy1_writes[] = {
12101 CreateMockWrite(*host1_req, 1),
12102 };
[email protected]23e482282013-06-14 16:08:0212103 scoped_ptr<SpdyFrame> host1_resp(
12104 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12105 scoped_ptr<SpdyFrame> host1_resp_body(
12106 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0312107 MockRead spdy1_reads[] = {
12108 CreateMockRead(*host1_resp, 2),
12109 CreateMockRead(*host1_resp_body, 3),
12110 MockRead(ASYNC, ERR_IO_PENDING, 4),
12111 };
12112
12113 scoped_ptr<OrderedSocketData> spdy1_data(
12114 new OrderedSocketData(
12115 spdy1_reads, arraysize(spdy1_reads),
12116 spdy1_writes, arraysize(spdy1_writes)));
12117 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
12118
[email protected]cdf8f7e72013-05-23 10:56:4612119 scoped_ptr<SpdyFrame> host2_req(spdy_util_.ConstructSpdyGet(
[email protected]483fa202013-05-14 01:07:0312120 "https://www.b.com", false, 1, DEFAULT_PRIORITY));
12121 MockWrite spdy2_writes[] = {
12122 CreateMockWrite(*host2_req, 1),
12123 };
[email protected]23e482282013-06-14 16:08:0212124 scoped_ptr<SpdyFrame> host2_resp(
12125 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12126 scoped_ptr<SpdyFrame> host2_resp_body(
12127 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0312128 MockRead spdy2_reads[] = {
12129 CreateMockRead(*host2_resp, 2),
12130 CreateMockRead(*host2_resp_body, 3),
12131 MockRead(ASYNC, ERR_IO_PENDING, 4),
12132 };
12133
12134 scoped_ptr<OrderedSocketData> spdy2_data(
12135 new OrderedSocketData(
12136 spdy2_reads, arraysize(spdy2_reads),
12137 spdy2_writes, arraysize(spdy2_writes)));
12138 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
12139
12140 MockWrite http_write[] = {
12141 MockWrite("GET / HTTP/1.1\r\n"
12142 "Host: www.a.com\r\n"
12143 "Connection: keep-alive\r\n\r\n"),
12144 };
12145
12146 MockRead http_read[] = {
12147 MockRead("HTTP/1.1 200 OK\r\n"),
12148 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12149 MockRead("Content-Length: 6\r\n\r\n"),
12150 MockRead("hello!"),
12151 };
12152 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
12153 http_write, arraysize(http_write));
12154 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12155
12156 HostPortPair host_port_pair_a("www.a.com", 443);
[email protected]e6d017652013-05-17 18:01:4012157 SpdySessionKey spdy_session_key_a(
[email protected]314b03992014-04-01 01:28:5312158 host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0312159 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2612160 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0312161
12162 TestCompletionCallback callback;
12163 HttpRequestInfo request1;
12164 request1.method = "GET";
12165 request1.url = GURL("https://www.a.com/");
12166 request1.load_flags = 0;
12167 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5012168 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0312169
12170 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
12171 EXPECT_EQ(ERR_IO_PENDING, rv);
12172 EXPECT_EQ(OK, callback.WaitForResult());
12173
12174 const HttpResponseInfo* response = trans->GetResponseInfo();
12175 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5012176 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0312177 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12178 EXPECT_TRUE(response->was_fetched_via_spdy);
12179 EXPECT_TRUE(response->was_npn_negotiated);
12180
12181 std::string response_data;
12182 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
12183 EXPECT_EQ("hello!", response_data);
12184 trans.reset();
12185 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2612186 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0312187
12188 HostPortPair host_port_pair_b("www.b.com", 443);
[email protected]e6d017652013-05-17 18:01:4012189 SpdySessionKey spdy_session_key_b(
[email protected]314b03992014-04-01 01:28:5312190 host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0312191 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2612192 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0312193 HttpRequestInfo request2;
12194 request2.method = "GET";
12195 request2.url = GURL("https://www.b.com/");
12196 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012197 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0312198
12199 rv = trans->Start(&request2, callback.callback(), BoundNetLog());
12200 EXPECT_EQ(ERR_IO_PENDING, rv);
12201 EXPECT_EQ(OK, callback.WaitForResult());
12202
12203 response = trans->GetResponseInfo();
12204 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5012205 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0312206 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12207 EXPECT_TRUE(response->was_fetched_via_spdy);
12208 EXPECT_TRUE(response->was_npn_negotiated);
12209 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
12210 EXPECT_EQ("hello!", response_data);
12211 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2612212 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0312213 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2612214 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0312215
12216 HostPortPair host_port_pair_a1("www.a.com", 80);
[email protected]e6d017652013-05-17 18:01:4012217 SpdySessionKey spdy_session_key_a1(
[email protected]314b03992014-04-01 01:28:5312218 host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0312219 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2612220 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0312221 HttpRequestInfo request3;
12222 request3.method = "GET";
12223 request3.url = GURL("http://www.a.com/");
12224 request3.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012225 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0312226
12227 rv = trans->Start(&request3, callback.callback(), BoundNetLog());
12228 EXPECT_EQ(ERR_IO_PENDING, rv);
12229 EXPECT_EQ(OK, callback.WaitForResult());
12230
12231 response = trans->GetResponseInfo();
12232 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5012233 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0312234 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12235 EXPECT_FALSE(response->was_fetched_via_spdy);
12236 EXPECT_FALSE(response->was_npn_negotiated);
12237 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
12238 EXPECT_EQ("hello!", response_data);
12239 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2612240 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0312241 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2612242 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0312243}
12244
[email protected]79e1fd62013-06-20 06:50:0412245TEST_P(HttpNetworkTransactionTest, HttpSyncConnectError) {
12246 HttpRequestInfo request;
12247 request.method = "GET";
12248 request.url = GURL("http://www.google.com/");
12249 request.load_flags = 0;
12250
[email protected]3fe8d2f82013-10-17 08:56:0712251 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412252 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112253 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412254
12255 MockConnect mock_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
12256 StaticSocketDataProvider data;
12257 data.set_connect_data(mock_connect);
12258 session_deps_.socket_factory->AddSocketDataProvider(&data);
12259
12260 TestCompletionCallback callback;
12261
12262 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12263 EXPECT_EQ(ERR_IO_PENDING, rv);
12264
12265 rv = callback.WaitForResult();
12266 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
12267
12268 EXPECT_EQ(NULL, trans->GetResponseInfo());
12269
12270 // We don't care whether this succeeds or fails, but it shouldn't crash.
12271 HttpRequestHeaders request_headers;
12272 trans->GetFullRequestHeaders(&request_headers);
12273}
12274
12275TEST_P(HttpNetworkTransactionTest, HttpAsyncConnectError) {
12276 HttpRequestInfo request;
12277 request.method = "GET";
12278 request.url = GURL("http://www.google.com/");
12279 request.load_flags = 0;
12280
[email protected]3fe8d2f82013-10-17 08:56:0712281 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412282 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112283 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412284
12285 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
12286 StaticSocketDataProvider data;
12287 data.set_connect_data(mock_connect);
12288 session_deps_.socket_factory->AddSocketDataProvider(&data);
12289
12290 TestCompletionCallback callback;
12291
12292 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12293 EXPECT_EQ(ERR_IO_PENDING, rv);
12294
12295 rv = callback.WaitForResult();
12296 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
12297
12298 EXPECT_EQ(NULL, trans->GetResponseInfo());
12299
12300 // We don't care whether this succeeds or fails, but it shouldn't crash.
12301 HttpRequestHeaders request_headers;
12302 trans->GetFullRequestHeaders(&request_headers);
12303}
12304
12305TEST_P(HttpNetworkTransactionTest, HttpSyncWriteError) {
12306 HttpRequestInfo request;
12307 request.method = "GET";
12308 request.url = GURL("http://www.google.com/");
12309 request.load_flags = 0;
12310
[email protected]3fe8d2f82013-10-17 08:56:0712311 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412312 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112313 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412314
12315 MockWrite data_writes[] = {
12316 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
12317 };
12318 MockRead data_reads[] = {
12319 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
12320 };
12321
12322 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12323 data_writes, arraysize(data_writes));
12324 session_deps_.socket_factory->AddSocketDataProvider(&data);
12325
12326 TestCompletionCallback callback;
12327
12328 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12329 EXPECT_EQ(ERR_IO_PENDING, rv);
12330
12331 rv = callback.WaitForResult();
12332 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12333
12334 EXPECT_EQ(NULL, trans->GetResponseInfo());
12335
12336 HttpRequestHeaders request_headers;
12337 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12338 EXPECT_TRUE(request_headers.HasHeader("Host"));
12339}
12340
12341TEST_P(HttpNetworkTransactionTest, HttpAsyncWriteError) {
12342 HttpRequestInfo request;
12343 request.method = "GET";
12344 request.url = GURL("http://www.google.com/");
12345 request.load_flags = 0;
12346
[email protected]3fe8d2f82013-10-17 08:56:0712347 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412348 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112349 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412350
12351 MockWrite data_writes[] = {
12352 MockWrite(ASYNC, ERR_CONNECTION_RESET),
12353 };
12354 MockRead data_reads[] = {
12355 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
12356 };
12357
12358 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12359 data_writes, arraysize(data_writes));
12360 session_deps_.socket_factory->AddSocketDataProvider(&data);
12361
12362 TestCompletionCallback callback;
12363
12364 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12365 EXPECT_EQ(ERR_IO_PENDING, rv);
12366
12367 rv = callback.WaitForResult();
12368 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12369
12370 EXPECT_EQ(NULL, trans->GetResponseInfo());
12371
12372 HttpRequestHeaders request_headers;
12373 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12374 EXPECT_TRUE(request_headers.HasHeader("Host"));
12375}
12376
12377TEST_P(HttpNetworkTransactionTest, HttpSyncReadError) {
12378 HttpRequestInfo request;
12379 request.method = "GET";
12380 request.url = GURL("http://www.google.com/");
12381 request.load_flags = 0;
12382
[email protected]3fe8d2f82013-10-17 08:56:0712383 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412384 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112385 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412386
12387 MockWrite data_writes[] = {
12388 MockWrite("GET / HTTP/1.1\r\n"
12389 "Host: www.google.com\r\n"
12390 "Connection: keep-alive\r\n\r\n"),
12391 };
12392 MockRead data_reads[] = {
12393 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
12394 };
12395
12396 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12397 data_writes, arraysize(data_writes));
12398 session_deps_.socket_factory->AddSocketDataProvider(&data);
12399
12400 TestCompletionCallback callback;
12401
12402 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12403 EXPECT_EQ(ERR_IO_PENDING, rv);
12404
12405 rv = callback.WaitForResult();
12406 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12407
12408 EXPECT_EQ(NULL, trans->GetResponseInfo());
12409
12410 HttpRequestHeaders request_headers;
12411 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12412 EXPECT_TRUE(request_headers.HasHeader("Host"));
12413}
12414
12415TEST_P(HttpNetworkTransactionTest, HttpAsyncReadError) {
12416 HttpRequestInfo request;
12417 request.method = "GET";
12418 request.url = GURL("http://www.google.com/");
12419 request.load_flags = 0;
12420
[email protected]3fe8d2f82013-10-17 08:56:0712421 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412422 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112423 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412424
12425 MockWrite data_writes[] = {
12426 MockWrite("GET / HTTP/1.1\r\n"
12427 "Host: www.google.com\r\n"
12428 "Connection: keep-alive\r\n\r\n"),
12429 };
12430 MockRead data_reads[] = {
12431 MockRead(ASYNC, ERR_CONNECTION_RESET),
12432 };
12433
12434 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12435 data_writes, arraysize(data_writes));
12436 session_deps_.socket_factory->AddSocketDataProvider(&data);
12437
12438 TestCompletionCallback callback;
12439
12440 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12441 EXPECT_EQ(ERR_IO_PENDING, rv);
12442
12443 rv = callback.WaitForResult();
12444 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12445
12446 EXPECT_EQ(NULL, trans->GetResponseInfo());
12447
12448 HttpRequestHeaders request_headers;
12449 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12450 EXPECT_TRUE(request_headers.HasHeader("Host"));
12451}
12452
12453TEST_P(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
12454 HttpRequestInfo request;
12455 request.method = "GET";
12456 request.url = GURL("http://www.google.com/");
12457 request.load_flags = 0;
12458 request.extra_headers.SetHeader("X-Foo", "bar");
12459
[email protected]3fe8d2f82013-10-17 08:56:0712460 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412461 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112462 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412463
12464 MockWrite data_writes[] = {
12465 MockWrite("GET / HTTP/1.1\r\n"
12466 "Host: www.google.com\r\n"
12467 "Connection: keep-alive\r\n"
12468 "X-Foo: bar\r\n\r\n"),
12469 };
12470 MockRead data_reads[] = {
12471 MockRead("HTTP/1.1 200 OK\r\n"
12472 "Content-Length: 5\r\n\r\n"
12473 "hello"),
12474 MockRead(ASYNC, ERR_UNEXPECTED),
12475 };
12476
12477 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12478 data_writes, arraysize(data_writes));
12479 session_deps_.socket_factory->AddSocketDataProvider(&data);
12480
12481 TestCompletionCallback callback;
12482
12483 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12484 EXPECT_EQ(ERR_IO_PENDING, rv);
12485
12486 rv = callback.WaitForResult();
12487 EXPECT_EQ(OK, rv);
12488
12489 HttpRequestHeaders request_headers;
12490 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12491 std::string foo;
12492 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
12493 EXPECT_EQ("bar", foo);
12494}
12495
[email protected]bf828982013-08-14 18:01:4712496namespace {
12497
yhiranoa7e05bb2014-11-06 05:40:3912498// Fake HttpStream that simply records calls to SetPriority().
12499class FakeStream : public HttpStream,
[email protected]e86839fd2013-08-14 18:29:0312500 public base::SupportsWeakPtr<FakeStream> {
12501 public:
12502 explicit FakeStream(RequestPriority priority) : priority_(priority) {}
dchengb03027d2014-10-21 12:00:2012503 ~FakeStream() override {}
[email protected]e86839fd2013-08-14 18:29:0312504
12505 RequestPriority priority() const { return priority_; }
12506
dchengb03027d2014-10-21 12:00:2012507 int InitializeStream(const HttpRequestInfo* request_info,
12508 RequestPriority priority,
12509 const BoundNetLog& net_log,
12510 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0312511 return ERR_IO_PENDING;
12512 }
12513
dchengb03027d2014-10-21 12:00:2012514 int SendRequest(const HttpRequestHeaders& request_headers,
12515 HttpResponseInfo* response,
12516 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0312517 ADD_FAILURE();
12518 return ERR_UNEXPECTED;
12519 }
12520
dchengb03027d2014-10-21 12:00:2012521 int ReadResponseHeaders(const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0312522 ADD_FAILURE();
12523 return ERR_UNEXPECTED;
12524 }
12525
dchengb03027d2014-10-21 12:00:2012526 int ReadResponseBody(IOBuffer* buf,
12527 int buf_len,
12528 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0312529 ADD_FAILURE();
12530 return ERR_UNEXPECTED;
12531 }
12532
dchengb03027d2014-10-21 12:00:2012533 void Close(bool not_reusable) override {}
[email protected]e86839fd2013-08-14 18:29:0312534
dchengb03027d2014-10-21 12:00:2012535 bool IsResponseBodyComplete() const override {
[email protected]e86839fd2013-08-14 18:29:0312536 ADD_FAILURE();
12537 return false;
12538 }
12539
dchengb03027d2014-10-21 12:00:2012540 bool CanFindEndOfResponse() const override { return false; }
[email protected]e86839fd2013-08-14 18:29:0312541
dchengb03027d2014-10-21 12:00:2012542 bool IsConnectionReused() const override {
[email protected]e86839fd2013-08-14 18:29:0312543 ADD_FAILURE();
12544 return false;
12545 }
12546
dchengb03027d2014-10-21 12:00:2012547 void SetConnectionReused() override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0312548
dchengb03027d2014-10-21 12:00:2012549 bool IsConnectionReusable() const override {
[email protected]e86839fd2013-08-14 18:29:0312550 ADD_FAILURE();
12551 return false;
12552 }
12553
dchengb03027d2014-10-21 12:00:2012554 int64 GetTotalReceivedBytes() const override {
[email protected]bc92bc972013-12-13 08:32:5912555 ADD_FAILURE();
12556 return 0;
12557 }
12558
dchengb03027d2014-10-21 12:00:2012559 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
[email protected]e86839fd2013-08-14 18:29:0312560 ADD_FAILURE();
12561 return false;
12562 }
12563
dchengb03027d2014-10-21 12:00:2012564 void GetSSLInfo(SSLInfo* ssl_info) override { ADD_FAILURE(); }
12565
12566 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
[email protected]e86839fd2013-08-14 18:29:0312567 ADD_FAILURE();
12568 }
12569
dchengb03027d2014-10-21 12:00:2012570 bool IsSpdyHttpStream() const override {
[email protected]e86839fd2013-08-14 18:29:0312571 ADD_FAILURE();
12572 return false;
12573 }
12574
dchengb03027d2014-10-21 12:00:2012575 void Drain(HttpNetworkSession* session) override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0312576
dchengb03027d2014-10-21 12:00:2012577 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]e86839fd2013-08-14 18:29:0312578
yhiranoa7e05bb2014-11-06 05:40:3912579 UploadProgress GetUploadProgress() const override { return UploadProgress(); }
12580
12581 HttpStream* RenewStreamForAuth() override { return NULL; }
12582
[email protected]e86839fd2013-08-14 18:29:0312583 private:
12584 RequestPriority priority_;
12585
12586 DISALLOW_COPY_AND_ASSIGN(FakeStream);
12587};
12588
12589// Fake HttpStreamRequest that simply records calls to SetPriority()
12590// and vends FakeStreams with its current priority.
[email protected]bf828982013-08-14 18:01:4712591class FakeStreamRequest : public HttpStreamRequest,
12592 public base::SupportsWeakPtr<FakeStreamRequest> {
12593 public:
[email protected]e86839fd2013-08-14 18:29:0312594 FakeStreamRequest(RequestPriority priority,
12595 HttpStreamRequest::Delegate* delegate)
12596 : priority_(priority),
[email protected]831e4a32013-11-14 02:14:4412597 delegate_(delegate),
12598 websocket_stream_create_helper_(NULL) {}
12599
12600 FakeStreamRequest(RequestPriority priority,
12601 HttpStreamRequest::Delegate* delegate,
12602 WebSocketHandshakeStreamBase::CreateHelper* create_helper)
12603 : priority_(priority),
12604 delegate_(delegate),
12605 websocket_stream_create_helper_(create_helper) {}
[email protected]e86839fd2013-08-14 18:29:0312606
dchengb03027d2014-10-21 12:00:2012607 ~FakeStreamRequest() override {}
[email protected]bf828982013-08-14 18:01:4712608
12609 RequestPriority priority() const { return priority_; }
12610
[email protected]831e4a32013-11-14 02:14:4412611 const WebSocketHandshakeStreamBase::CreateHelper*
12612 websocket_stream_create_helper() const {
12613 return websocket_stream_create_helper_;
12614 }
12615
[email protected]e86839fd2013-08-14 18:29:0312616 // Create a new FakeStream and pass it to the request's
12617 // delegate. Returns a weak pointer to the FakeStream.
12618 base::WeakPtr<FakeStream> FinishStreamRequest() {
12619 FakeStream* fake_stream = new FakeStream(priority_);
12620 // Do this before calling OnStreamReady() as OnStreamReady() may
12621 // immediately delete |fake_stream|.
12622 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
12623 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), fake_stream);
12624 return weak_stream;
12625 }
12626
dchengb03027d2014-10-21 12:00:2012627 int RestartTunnelWithProxyAuth(const AuthCredentials& credentials) override {
[email protected]bf828982013-08-14 18:01:4712628 ADD_FAILURE();
12629 return ERR_UNEXPECTED;
12630 }
12631
dchengb03027d2014-10-21 12:00:2012632 LoadState GetLoadState() const override {
[email protected]bf828982013-08-14 18:01:4712633 ADD_FAILURE();
12634 return LoadState();
12635 }
12636
dchengb03027d2014-10-21 12:00:2012637 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]bf828982013-08-14 18:01:4712638
dchengb03027d2014-10-21 12:00:2012639 bool was_npn_negotiated() const override { return false; }
[email protected]bf828982013-08-14 18:01:4712640
dchengb03027d2014-10-21 12:00:2012641 NextProto protocol_negotiated() const override { return kProtoUnknown; }
[email protected]bf828982013-08-14 18:01:4712642
dchengb03027d2014-10-21 12:00:2012643 bool using_spdy() const override { return false; }
[email protected]bf828982013-08-14 18:01:4712644
12645 private:
12646 RequestPriority priority_;
[email protected]e86839fd2013-08-14 18:29:0312647 HttpStreamRequest::Delegate* const delegate_;
[email protected]831e4a32013-11-14 02:14:4412648 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
[email protected]bf828982013-08-14 18:01:4712649
12650 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
12651};
12652
12653// Fake HttpStreamFactory that vends FakeStreamRequests.
12654class FakeStreamFactory : public HttpStreamFactory {
12655 public:
12656 FakeStreamFactory() {}
dchengb03027d2014-10-21 12:00:2012657 ~FakeStreamFactory() override {}
[email protected]bf828982013-08-14 18:01:4712658
12659 // Returns a WeakPtr<> to the last HttpStreamRequest returned by
12660 // RequestStream() (which may be NULL if it was destroyed already).
12661 base::WeakPtr<FakeStreamRequest> last_stream_request() {
12662 return last_stream_request_;
12663 }
12664
dchengb03027d2014-10-21 12:00:2012665 HttpStreamRequest* RequestStream(const HttpRequestInfo& info,
12666 RequestPriority priority,
12667 const SSLConfig& server_ssl_config,
12668 const SSLConfig& proxy_ssl_config,
12669 HttpStreamRequest::Delegate* delegate,
12670 const BoundNetLog& net_log) override {
[email protected]e86839fd2013-08-14 18:29:0312671 FakeStreamRequest* fake_request = new FakeStreamRequest(priority, delegate);
[email protected]bf828982013-08-14 18:01:4712672 last_stream_request_ = fake_request->AsWeakPtr();
12673 return fake_request;
12674 }
12675
dchengb03027d2014-10-21 12:00:2012676 HttpStreamRequest* RequestWebSocketHandshakeStream(
[email protected]bf828982013-08-14 18:01:4712677 const HttpRequestInfo& info,
12678 RequestPriority priority,
12679 const SSLConfig& server_ssl_config,
12680 const SSLConfig& proxy_ssl_config,
12681 HttpStreamRequest::Delegate* delegate,
[email protected]467086b2013-11-12 08:19:4612682 WebSocketHandshakeStreamBase::CreateHelper* create_helper,
mostynbba063d6032014-10-09 11:01:1312683 const BoundNetLog& net_log) override {
[email protected]831e4a32013-11-14 02:14:4412684 FakeStreamRequest* fake_request =
12685 new FakeStreamRequest(priority, delegate, create_helper);
12686 last_stream_request_ = fake_request->AsWeakPtr();
12687 return fake_request;
[email protected]bf828982013-08-14 18:01:4712688 }
12689
dchengb03027d2014-10-21 12:00:2012690 void PreconnectStreams(int num_streams,
12691 const HttpRequestInfo& info,
12692 RequestPriority priority,
12693 const SSLConfig& server_ssl_config,
12694 const SSLConfig& proxy_ssl_config) override {
[email protected]bf828982013-08-14 18:01:4712695 ADD_FAILURE();
12696 }
12697
dchengb03027d2014-10-21 12:00:2012698 const HostMappingRules* GetHostMappingRules() const override {
[email protected]bf828982013-08-14 18:01:4712699 ADD_FAILURE();
12700 return NULL;
12701 }
12702
12703 private:
12704 base::WeakPtr<FakeStreamRequest> last_stream_request_;
12705
12706 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
12707};
12708
Adam Rice425cf122015-01-19 06:18:2412709// TODO(ricea): Maybe unify this with the one in
12710// url_request_http_job_unittest.cc ?
12711class FakeWebSocketBasicHandshakeStream : public WebSocketHandshakeStreamBase {
12712 public:
12713 FakeWebSocketBasicHandshakeStream(scoped_ptr<ClientSocketHandle> connection,
12714 bool using_proxy)
12715 : state_(connection.release(), using_proxy) {}
12716
12717 // Fake implementation of HttpStreamBase methods.
12718 // This ends up being quite "real" because this object has to really send data
12719 // on the mock socket. It might be easier to use the real implementation, but
12720 // the fact that the WebSocket code is not compiled on iOS makes that
12721 // difficult.
12722 int InitializeStream(const HttpRequestInfo* request_info,
12723 RequestPriority priority,
12724 const BoundNetLog& net_log,
12725 const CompletionCallback& callback) override {
12726 state_.Initialize(request_info, priority, net_log, callback);
12727 return OK;
12728 }
12729
12730 int SendRequest(const HttpRequestHeaders& request_headers,
12731 HttpResponseInfo* response,
12732 const CompletionCallback& callback) override {
12733 return parser()->SendRequest(state_.GenerateRequestLine(), request_headers,
12734 response, callback);
12735 }
12736
12737 int ReadResponseHeaders(const CompletionCallback& callback) override {
12738 return parser()->ReadResponseHeaders(callback);
12739 }
12740
12741 int ReadResponseBody(IOBuffer* buf,
12742 int buf_len,
12743 const CompletionCallback& callback) override {
12744 NOTREACHED();
12745 return ERR_IO_PENDING;
12746 }
12747
12748 void Close(bool not_reusable) override {
12749 if (parser())
12750 parser()->Close(true);
12751 }
12752
12753 bool IsResponseBodyComplete() const override {
12754 NOTREACHED();
12755 return false;
12756 }
12757
12758 bool CanFindEndOfResponse() const override {
12759 return parser()->CanFindEndOfResponse();
12760 }
12761
12762 bool IsConnectionReused() const override {
12763 NOTREACHED();
12764 return false;
12765 }
12766 void SetConnectionReused() override { NOTREACHED(); }
12767
12768 bool IsConnectionReusable() const override {
12769 NOTREACHED();
12770 return false;
12771 }
12772
12773 int64 GetTotalReceivedBytes() const override {
12774 NOTREACHED();
12775 return 0;
12776 }
12777
12778 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
12779 NOTREACHED();
12780 return false;
12781 }
12782
Adam Ricecb76ac62015-02-20 05:33:2512783 void GetSSLInfo(SSLInfo* ssl_info) override {}
Adam Rice425cf122015-01-19 06:18:2412784
12785 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
12786 NOTREACHED();
12787 }
12788
12789 bool IsSpdyHttpStream() const override {
12790 NOTREACHED();
12791 return false;
12792 }
12793
12794 void Drain(HttpNetworkSession* session) override { NOTREACHED(); }
12795
12796 void SetPriority(RequestPriority priority) override { NOTREACHED(); }
12797
12798 UploadProgress GetUploadProgress() const override {
12799 NOTREACHED();
12800 return UploadProgress();
12801 }
12802
12803 HttpStream* RenewStreamForAuth() override {
12804 NOTREACHED();
12805 return nullptr;
12806 }
12807
12808 // Fake implementation of WebSocketHandshakeStreamBase method(s)
12809 scoped_ptr<WebSocketStream> Upgrade() override {
12810 NOTREACHED();
12811 return scoped_ptr<WebSocketStream>();
12812 }
12813
12814 private:
12815 HttpStreamParser* parser() const { return state_.parser(); }
12816 HttpBasicState state_;
12817
12818 DISALLOW_COPY_AND_ASSIGN(FakeWebSocketBasicHandshakeStream);
12819};
12820
[email protected]831e4a32013-11-14 02:14:4412821// TODO(yhirano): Split this class out into a net/websockets file, if it is
12822// worth doing.
12823class FakeWebSocketStreamCreateHelper :
12824 public WebSocketHandshakeStreamBase::CreateHelper {
12825 public:
dchengb03027d2014-10-21 12:00:2012826 WebSocketHandshakeStreamBase* CreateBasicStream(
[email protected]7e841a52013-11-22 09:04:2112827 scoped_ptr<ClientSocketHandle> connection,
mostynbba063d6032014-10-09 11:01:1312828 bool using_proxy) override {
Adam Rice425cf122015-01-19 06:18:2412829 return new FakeWebSocketBasicHandshakeStream(connection.Pass(),
12830 using_proxy);
[email protected]831e4a32013-11-14 02:14:4412831 }
12832
dchengb03027d2014-10-21 12:00:2012833 WebSocketHandshakeStreamBase* CreateSpdyStream(
[email protected]831e4a32013-11-14 02:14:4412834 const base::WeakPtr<SpdySession>& session,
mostynbba063d6032014-10-09 11:01:1312835 bool use_relative_url) override {
[email protected]831e4a32013-11-14 02:14:4412836 NOTREACHED();
12837 return NULL;
12838 };
12839
dchengb03027d2014-10-21 12:00:2012840 ~FakeWebSocketStreamCreateHelper() override {}
[email protected]831e4a32013-11-14 02:14:4412841
12842 virtual scoped_ptr<WebSocketStream> Upgrade() {
12843 NOTREACHED();
12844 return scoped_ptr<WebSocketStream>();
12845 }
12846};
12847
[email protected]bf828982013-08-14 18:01:4712848} // namespace
12849
12850// Make sure that HttpNetworkTransaction passes on its priority to its
12851// stream request on start.
12852TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
12853 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12854 HttpNetworkSessionPeer peer(session);
12855 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4412856 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4712857
dcheng48459ac22014-08-26 00:46:4112858 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4712859
12860 ASSERT_TRUE(fake_factory->last_stream_request() == NULL);
12861
12862 HttpRequestInfo request;
12863 TestCompletionCallback callback;
12864 EXPECT_EQ(ERR_IO_PENDING,
12865 trans.Start(&request, callback.callback(), BoundNetLog()));
12866
12867 base::WeakPtr<FakeStreamRequest> fake_request =
12868 fake_factory->last_stream_request();
12869 ASSERT_TRUE(fake_request != NULL);
12870 EXPECT_EQ(LOW, fake_request->priority());
12871}
12872
12873// Make sure that HttpNetworkTransaction passes on its priority
12874// updates to its stream request.
12875TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriority) {
12876 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12877 HttpNetworkSessionPeer peer(session);
12878 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4412879 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4712880
dcheng48459ac22014-08-26 00:46:4112881 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4712882
12883 HttpRequestInfo request;
12884 TestCompletionCallback callback;
12885 EXPECT_EQ(ERR_IO_PENDING,
12886 trans.Start(&request, callback.callback(), BoundNetLog()));
12887
12888 base::WeakPtr<FakeStreamRequest> fake_request =
12889 fake_factory->last_stream_request();
12890 ASSERT_TRUE(fake_request != NULL);
12891 EXPECT_EQ(LOW, fake_request->priority());
12892
12893 trans.SetPriority(LOWEST);
12894 ASSERT_TRUE(fake_request != NULL);
12895 EXPECT_EQ(LOWEST, fake_request->priority());
12896}
12897
[email protected]e86839fd2013-08-14 18:29:0312898// Make sure that HttpNetworkTransaction passes on its priority
12899// updates to its stream.
12900TEST_P(HttpNetworkTransactionTest, SetStreamPriority) {
12901 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12902 HttpNetworkSessionPeer peer(session);
12903 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4412904 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]e86839fd2013-08-14 18:29:0312905
dcheng48459ac22014-08-26 00:46:4112906 HttpNetworkTransaction trans(LOW, session.get());
[email protected]e86839fd2013-08-14 18:29:0312907
12908 HttpRequestInfo request;
12909 TestCompletionCallback callback;
12910 EXPECT_EQ(ERR_IO_PENDING,
12911 trans.Start(&request, callback.callback(), BoundNetLog()));
12912
12913 base::WeakPtr<FakeStreamRequest> fake_request =
12914 fake_factory->last_stream_request();
12915 ASSERT_TRUE(fake_request != NULL);
12916 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
12917 ASSERT_TRUE(fake_stream != NULL);
12918 EXPECT_EQ(LOW, fake_stream->priority());
12919
12920 trans.SetPriority(LOWEST);
12921 EXPECT_EQ(LOWEST, fake_stream->priority());
12922}
12923
[email protected]831e4a32013-11-14 02:14:4412924TEST_P(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
12925 // The same logic needs to be tested for both ws: and wss: schemes, but this
12926 // test is already parameterised on NextProto, so it uses a loop to verify
12927 // that the different schemes work.
12928 std::string test_cases[] = {"ws://www.google.com/", "wss://www.google.com/"};
12929 for (size_t i = 0; i < arraysize(test_cases); ++i) {
12930 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12931 HttpNetworkSessionPeer peer(session);
12932 FakeStreamFactory* fake_factory = new FakeStreamFactory();
12933 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
[email protected]0191b51c2013-11-18 10:55:2312934 peer.SetHttpStreamFactoryForWebSocket(
[email protected]831e4a32013-11-14 02:14:4412935 scoped_ptr<HttpStreamFactory>(fake_factory));
12936
dcheng48459ac22014-08-26 00:46:4112937 HttpNetworkTransaction trans(LOW, session.get());
[email protected]831e4a32013-11-14 02:14:4412938 trans.SetWebSocketHandshakeStreamCreateHelper(
12939 &websocket_stream_create_helper);
12940
12941 HttpRequestInfo request;
12942 TestCompletionCallback callback;
12943 request.method = "GET";
12944 request.url = GURL(test_cases[i]);
12945
12946 EXPECT_EQ(ERR_IO_PENDING,
12947 trans.Start(&request, callback.callback(), BoundNetLog()));
12948
12949 base::WeakPtr<FakeStreamRequest> fake_request =
12950 fake_factory->last_stream_request();
12951 ASSERT_TRUE(fake_request != NULL);
12952 EXPECT_EQ(&websocket_stream_create_helper,
12953 fake_request->websocket_stream_create_helper());
12954 }
12955}
12956
[email protected]043b68c82013-08-22 23:41:5212957// Tests that when a used socket is returned to the SSL socket pool, it's closed
12958// if the transport socket pool is stalled on the global socket limit.
12959TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
12960 ClientSocketPoolManager::set_max_sockets_per_group(
12961 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12962 ClientSocketPoolManager::set_max_sockets_per_pool(
12963 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12964
12965 // Set up SSL request.
12966
12967 HttpRequestInfo ssl_request;
12968 ssl_request.method = "GET";
12969 ssl_request.url = GURL("https://www.google.com/");
12970
12971 MockWrite ssl_writes[] = {
12972 MockWrite("GET / HTTP/1.1\r\n"
12973 "Host: www.google.com\r\n"
12974 "Connection: keep-alive\r\n\r\n"),
12975 };
12976 MockRead ssl_reads[] = {
12977 MockRead("HTTP/1.1 200 OK\r\n"),
12978 MockRead("Content-Length: 11\r\n\r\n"),
12979 MockRead("hello world"),
12980 MockRead(SYNCHRONOUS, OK),
12981 };
12982 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
12983 ssl_writes, arraysize(ssl_writes));
12984 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
12985
12986 SSLSocketDataProvider ssl(ASYNC, OK);
12987 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12988
12989 // Set up HTTP request.
12990
12991 HttpRequestInfo http_request;
12992 http_request.method = "GET";
12993 http_request.url = GURL("http://www.google.com/");
12994
12995 MockWrite http_writes[] = {
12996 MockWrite("GET / HTTP/1.1\r\n"
12997 "Host: www.google.com\r\n"
12998 "Connection: keep-alive\r\n\r\n"),
12999 };
13000 MockRead http_reads[] = {
13001 MockRead("HTTP/1.1 200 OK\r\n"),
13002 MockRead("Content-Length: 7\r\n\r\n"),
13003 MockRead("falafel"),
13004 MockRead(SYNCHRONOUS, OK),
13005 };
13006 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
13007 http_writes, arraysize(http_writes));
13008 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13009
13010 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13011
13012 // Start the SSL request.
13013 TestCompletionCallback ssl_callback;
13014 scoped_ptr<HttpTransaction> ssl_trans(
13015 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13016 ASSERT_EQ(ERR_IO_PENDING,
13017 ssl_trans->Start(&ssl_request, ssl_callback.callback(),
13018 BoundNetLog()));
13019
13020 // Start the HTTP request. Pool should stall.
13021 TestCompletionCallback http_callback;
13022 scoped_ptr<HttpTransaction> http_trans(
13023 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13024 ASSERT_EQ(ERR_IO_PENDING,
13025 http_trans->Start(&http_request, http_callback.callback(),
13026 BoundNetLog()));
dcheng48459ac22014-08-26 00:46:4113027 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5213028
13029 // Wait for response from SSL request.
13030 ASSERT_EQ(OK, ssl_callback.WaitForResult());
13031 std::string response_data;
13032 ASSERT_EQ(OK, ReadTransaction(ssl_trans.get(), &response_data));
13033 EXPECT_EQ("hello world", response_data);
13034
13035 // The SSL socket should automatically be closed, so the HTTP request can
13036 // start.
dcheng48459ac22014-08-26 00:46:4113037 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
13038 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5213039
13040 // The HTTP request can now complete.
13041 ASSERT_EQ(OK, http_callback.WaitForResult());
13042 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
13043 EXPECT_EQ("falafel", response_data);
13044
dcheng48459ac22014-08-26 00:46:4113045 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5213046}
13047
13048// Tests that when a SSL connection is established but there's no corresponding
13049// request that needs it, the new socket is closed if the transport socket pool
13050// is stalled on the global socket limit.
13051TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
13052 ClientSocketPoolManager::set_max_sockets_per_group(
13053 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13054 ClientSocketPoolManager::set_max_sockets_per_pool(
13055 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13056
13057 // Set up an ssl request.
13058
13059 HttpRequestInfo ssl_request;
13060 ssl_request.method = "GET";
13061 ssl_request.url = GURL("https://www.foopy.com/");
13062
13063 // No data will be sent on the SSL socket.
13064 StaticSocketDataProvider ssl_data;
13065 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
13066
13067 SSLSocketDataProvider ssl(ASYNC, OK);
13068 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13069
13070 // Set up HTTP request.
13071
13072 HttpRequestInfo http_request;
13073 http_request.method = "GET";
13074 http_request.url = GURL("http://www.google.com/");
13075
13076 MockWrite http_writes[] = {
13077 MockWrite("GET / HTTP/1.1\r\n"
13078 "Host: www.google.com\r\n"
13079 "Connection: keep-alive\r\n\r\n"),
13080 };
13081 MockRead http_reads[] = {
13082 MockRead("HTTP/1.1 200 OK\r\n"),
13083 MockRead("Content-Length: 7\r\n\r\n"),
13084 MockRead("falafel"),
13085 MockRead(SYNCHRONOUS, OK),
13086 };
13087 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
13088 http_writes, arraysize(http_writes));
13089 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13090
13091 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13092
13093 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
13094 // cancelled when a normal transaction is cancelled.
13095 net::HttpStreamFactory* http_stream_factory = session->http_stream_factory();
13096 net::SSLConfig ssl_config;
13097 session->ssl_config_service()->GetSSLConfig(&ssl_config);
13098 http_stream_factory->PreconnectStreams(1, ssl_request, DEFAULT_PRIORITY,
13099 ssl_config, ssl_config);
dcheng48459ac22014-08-26 00:46:4113100 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5213101
13102 // Start the HTTP request. Pool should stall.
13103 TestCompletionCallback http_callback;
13104 scoped_ptr<HttpTransaction> http_trans(
13105 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13106 ASSERT_EQ(ERR_IO_PENDING,
13107 http_trans->Start(&http_request, http_callback.callback(),
13108 BoundNetLog()));
dcheng48459ac22014-08-26 00:46:4113109 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5213110
13111 // The SSL connection will automatically be closed once the connection is
13112 // established, to let the HTTP request start.
13113 ASSERT_EQ(OK, http_callback.WaitForResult());
13114 std::string response_data;
13115 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
13116 EXPECT_EQ("falafel", response_data);
13117
dcheng48459ac22014-08-26 00:46:4113118 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5213119}
13120
[email protected]02d74a02014-04-23 18:10:5413121TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
13122 ScopedVector<UploadElementReader> element_readers;
13123 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713124 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413125
13126 HttpRequestInfo request;
13127 request.method = "POST";
13128 request.url = GURL("http://www.foo.com/");
13129 request.upload_data_stream = &upload_data_stream;
13130 request.load_flags = 0;
13131
13132 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13133 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113134 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413135 // Send headers successfully, but get an error while sending the body.
13136 MockWrite data_writes[] = {
13137 MockWrite("POST / HTTP/1.1\r\n"
13138 "Host: www.foo.com\r\n"
13139 "Connection: keep-alive\r\n"
13140 "Content-Length: 3\r\n\r\n"),
13141 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13142 };
13143
13144 MockRead data_reads[] = {
13145 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
13146 MockRead("hello world"),
13147 MockRead(SYNCHRONOUS, OK),
13148 };
13149 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13150 arraysize(data_writes));
13151 session_deps_.socket_factory->AddSocketDataProvider(&data);
13152
13153 TestCompletionCallback callback;
13154
13155 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13156 EXPECT_EQ(ERR_IO_PENDING, rv);
13157
13158 rv = callback.WaitForResult();
13159 EXPECT_EQ(OK, rv);
13160
13161 const HttpResponseInfo* response = trans->GetResponseInfo();
13162 ASSERT_TRUE(response != NULL);
13163
13164 EXPECT_TRUE(response->headers.get() != NULL);
13165 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
13166
13167 std::string response_data;
13168 rv = ReadTransaction(trans.get(), &response_data);
13169 EXPECT_EQ(OK, rv);
13170 EXPECT_EQ("hello world", response_data);
13171}
13172
13173// This test makes sure the retry logic doesn't trigger when reading an error
13174// response from a server that rejected a POST with a CONNECTION_RESET.
13175TEST_P(HttpNetworkTransactionTest,
13176 PostReadsErrorResponseAfterResetOnReusedSocket) {
13177 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13178 MockWrite data_writes[] = {
13179 MockWrite("GET / HTTP/1.1\r\n"
13180 "Host: www.foo.com\r\n"
13181 "Connection: keep-alive\r\n\r\n"),
13182 MockWrite("POST / HTTP/1.1\r\n"
13183 "Host: www.foo.com\r\n"
13184 "Connection: keep-alive\r\n"
13185 "Content-Length: 3\r\n\r\n"),
13186 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13187 };
13188
13189 MockRead data_reads[] = {
13190 MockRead("HTTP/1.1 200 Peachy\r\n"
13191 "Content-Length: 14\r\n\r\n"),
13192 MockRead("first response"),
13193 MockRead("HTTP/1.1 400 Not OK\r\n"
13194 "Content-Length: 15\r\n\r\n"),
13195 MockRead("second response"),
13196 MockRead(SYNCHRONOUS, OK),
13197 };
13198 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13199 arraysize(data_writes));
13200 session_deps_.socket_factory->AddSocketDataProvider(&data);
13201
13202 TestCompletionCallback callback;
13203 HttpRequestInfo request1;
13204 request1.method = "GET";
13205 request1.url = GURL("http://www.foo.com/");
13206 request1.load_flags = 0;
13207
13208 scoped_ptr<HttpTransaction> trans1(
dcheng48459ac22014-08-26 00:46:4113209 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413210 int rv = trans1->Start(&request1, callback.callback(), BoundNetLog());
13211 EXPECT_EQ(ERR_IO_PENDING, rv);
13212
13213 rv = callback.WaitForResult();
13214 EXPECT_EQ(OK, rv);
13215
13216 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
13217 ASSERT_TRUE(response1 != NULL);
13218
13219 EXPECT_TRUE(response1->headers.get() != NULL);
13220 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
13221
13222 std::string response_data1;
13223 rv = ReadTransaction(trans1.get(), &response_data1);
13224 EXPECT_EQ(OK, rv);
13225 EXPECT_EQ("first response", response_data1);
13226 // Delete the transaction to release the socket back into the socket pool.
13227 trans1.reset();
13228
13229 ScopedVector<UploadElementReader> element_readers;
13230 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713231 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413232
13233 HttpRequestInfo request2;
13234 request2.method = "POST";
13235 request2.url = GURL("http://www.foo.com/");
13236 request2.upload_data_stream = &upload_data_stream;
13237 request2.load_flags = 0;
13238
13239 scoped_ptr<HttpTransaction> trans2(
dcheng48459ac22014-08-26 00:46:4113240 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413241 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
13242 EXPECT_EQ(ERR_IO_PENDING, rv);
13243
13244 rv = callback.WaitForResult();
13245 EXPECT_EQ(OK, rv);
13246
13247 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
13248 ASSERT_TRUE(response2 != NULL);
13249
13250 EXPECT_TRUE(response2->headers.get() != NULL);
13251 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
13252
13253 std::string response_data2;
13254 rv = ReadTransaction(trans2.get(), &response_data2);
13255 EXPECT_EQ(OK, rv);
13256 EXPECT_EQ("second response", response_data2);
13257}
13258
13259TEST_P(HttpNetworkTransactionTest,
13260 PostReadsErrorResponseAfterResetPartialBodySent) {
13261 ScopedVector<UploadElementReader> element_readers;
13262 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713263 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413264
13265 HttpRequestInfo request;
13266 request.method = "POST";
13267 request.url = GURL("http://www.foo.com/");
13268 request.upload_data_stream = &upload_data_stream;
13269 request.load_flags = 0;
13270
13271 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13272 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113273 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413274 // Send headers successfully, but get an error while sending the body.
13275 MockWrite data_writes[] = {
13276 MockWrite("POST / HTTP/1.1\r\n"
13277 "Host: www.foo.com\r\n"
13278 "Connection: keep-alive\r\n"
13279 "Content-Length: 3\r\n\r\n"
13280 "fo"),
13281 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13282 };
13283
13284 MockRead data_reads[] = {
13285 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
13286 MockRead("hello world"),
13287 MockRead(SYNCHRONOUS, OK),
13288 };
13289 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13290 arraysize(data_writes));
13291 session_deps_.socket_factory->AddSocketDataProvider(&data);
13292
13293 TestCompletionCallback callback;
13294
13295 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13296 EXPECT_EQ(ERR_IO_PENDING, rv);
13297
13298 rv = callback.WaitForResult();
13299 EXPECT_EQ(OK, rv);
13300
13301 const HttpResponseInfo* response = trans->GetResponseInfo();
13302 ASSERT_TRUE(response != NULL);
13303
13304 EXPECT_TRUE(response->headers.get() != NULL);
13305 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
13306
13307 std::string response_data;
13308 rv = ReadTransaction(trans.get(), &response_data);
13309 EXPECT_EQ(OK, rv);
13310 EXPECT_EQ("hello world", response_data);
13311}
13312
13313// This tests the more common case than the previous test, where headers and
13314// body are not merged into a single request.
13315TEST_P(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
13316 ScopedVector<UploadElementReader> element_readers;
13317 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713318 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5413319
13320 HttpRequestInfo request;
13321 request.method = "POST";
13322 request.url = GURL("http://www.foo.com/");
13323 request.upload_data_stream = &upload_data_stream;
13324 request.load_flags = 0;
13325
13326 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13327 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113328 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413329 // Send headers successfully, but get an error while sending the body.
13330 MockWrite data_writes[] = {
13331 MockWrite("POST / HTTP/1.1\r\n"
13332 "Host: www.foo.com\r\n"
13333 "Connection: keep-alive\r\n"
13334 "Transfer-Encoding: chunked\r\n\r\n"),
13335 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13336 };
13337
13338 MockRead data_reads[] = {
13339 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
13340 MockRead("hello world"),
13341 MockRead(SYNCHRONOUS, OK),
13342 };
13343 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13344 arraysize(data_writes));
13345 session_deps_.socket_factory->AddSocketDataProvider(&data);
13346
13347 TestCompletionCallback callback;
13348
13349 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13350 EXPECT_EQ(ERR_IO_PENDING, rv);
13351 // Make sure the headers are sent before adding a chunk. This ensures that
13352 // they can't be merged with the body in a single send. Not currently
13353 // necessary since a chunked body is never merged with headers, but this makes
13354 // the test more future proof.
13355 base::RunLoop().RunUntilIdle();
13356
mmenkecbc2b712014-10-09 20:29:0713357 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5413358
13359 rv = callback.WaitForResult();
13360 EXPECT_EQ(OK, rv);
13361
13362 const HttpResponseInfo* response = trans->GetResponseInfo();
13363 ASSERT_TRUE(response != NULL);
13364
13365 EXPECT_TRUE(response->headers.get() != NULL);
13366 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
13367
13368 std::string response_data;
13369 rv = ReadTransaction(trans.get(), &response_data);
13370 EXPECT_EQ(OK, rv);
13371 EXPECT_EQ("hello world", response_data);
13372}
13373
13374TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
13375 ScopedVector<UploadElementReader> element_readers;
13376 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713377 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413378
13379 HttpRequestInfo request;
13380 request.method = "POST";
13381 request.url = GURL("http://www.foo.com/");
13382 request.upload_data_stream = &upload_data_stream;
13383 request.load_flags = 0;
13384
13385 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13386 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113387 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413388
13389 MockWrite data_writes[] = {
13390 MockWrite("POST / HTTP/1.1\r\n"
13391 "Host: www.foo.com\r\n"
13392 "Connection: keep-alive\r\n"
13393 "Content-Length: 3\r\n\r\n"),
13394 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13395 };
13396
13397 MockRead data_reads[] = {
13398 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
13399 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
13400 MockRead("hello world"),
13401 MockRead(SYNCHRONOUS, OK),
13402 };
13403 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13404 arraysize(data_writes));
13405 session_deps_.socket_factory->AddSocketDataProvider(&data);
13406
13407 TestCompletionCallback callback;
13408
13409 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13410 EXPECT_EQ(ERR_IO_PENDING, rv);
13411
13412 rv = callback.WaitForResult();
13413 EXPECT_EQ(OK, rv);
13414
13415 const HttpResponseInfo* response = trans->GetResponseInfo();
13416 ASSERT_TRUE(response != NULL);
13417
13418 EXPECT_TRUE(response->headers.get() != NULL);
13419 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
13420
13421 std::string response_data;
13422 rv = ReadTransaction(trans.get(), &response_data);
13423 EXPECT_EQ(OK, rv);
13424 EXPECT_EQ("hello world", response_data);
13425}
13426
13427TEST_P(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
13428 ScopedVector<UploadElementReader> element_readers;
13429 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713430 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413431
13432 HttpRequestInfo request;
13433 request.method = "POST";
13434 request.url = GURL("http://www.foo.com/");
13435 request.upload_data_stream = &upload_data_stream;
13436 request.load_flags = 0;
13437
13438 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13439 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113440 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413441 // Send headers successfully, but get an error while sending the body.
13442 MockWrite data_writes[] = {
13443 MockWrite("POST / HTTP/1.1\r\n"
13444 "Host: www.foo.com\r\n"
13445 "Connection: keep-alive\r\n"
13446 "Content-Length: 3\r\n\r\n"),
13447 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13448 };
13449
13450 MockRead data_reads[] = {
13451 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
13452 MockRead("hello world"),
13453 MockRead(SYNCHRONOUS, OK),
13454 };
13455 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13456 arraysize(data_writes));
13457 session_deps_.socket_factory->AddSocketDataProvider(&data);
13458
13459 TestCompletionCallback callback;
13460
13461 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13462 EXPECT_EQ(ERR_IO_PENDING, rv);
13463
13464 rv = callback.WaitForResult();
13465 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13466
13467 const HttpResponseInfo* response = trans->GetResponseInfo();
13468 EXPECT_TRUE(response == NULL);
13469}
13470
13471TEST_P(HttpNetworkTransactionTest,
13472 PostIgnoresNonErrorResponseAfterResetAnd100) {
13473 ScopedVector<UploadElementReader> element_readers;
13474 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713475 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413476
13477 HttpRequestInfo request;
13478 request.method = "POST";
13479 request.url = GURL("http://www.foo.com/");
13480 request.upload_data_stream = &upload_data_stream;
13481 request.load_flags = 0;
13482
13483 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13484 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113485 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413486 // Send headers successfully, but get an error while sending the body.
13487 MockWrite data_writes[] = {
13488 MockWrite("POST / HTTP/1.1\r\n"
13489 "Host: www.foo.com\r\n"
13490 "Connection: keep-alive\r\n"
13491 "Content-Length: 3\r\n\r\n"),
13492 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13493 };
13494
13495 MockRead data_reads[] = {
13496 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
13497 MockRead("HTTP/1.0 302 Redirect\r\n"),
13498 MockRead("Location: http://somewhere-else.com/\r\n"),
13499 MockRead("Content-Length: 0\r\n\r\n"),
13500 MockRead(SYNCHRONOUS, OK),
13501 };
13502 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13503 arraysize(data_writes));
13504 session_deps_.socket_factory->AddSocketDataProvider(&data);
13505
13506 TestCompletionCallback callback;
13507
13508 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13509 EXPECT_EQ(ERR_IO_PENDING, rv);
13510
13511 rv = callback.WaitForResult();
13512 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13513
13514 const HttpResponseInfo* response = trans->GetResponseInfo();
13515 EXPECT_TRUE(response == NULL);
13516}
13517
13518TEST_P(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
13519 ScopedVector<UploadElementReader> element_readers;
13520 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713521 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413522
13523 HttpRequestInfo request;
13524 request.method = "POST";
13525 request.url = GURL("http://www.foo.com/");
13526 request.upload_data_stream = &upload_data_stream;
13527 request.load_flags = 0;
13528
13529 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13530 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113531 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413532 // Send headers successfully, but get an error while sending the body.
13533 MockWrite data_writes[] = {
13534 MockWrite("POST / HTTP/1.1\r\n"
13535 "Host: www.foo.com\r\n"
13536 "Connection: keep-alive\r\n"
13537 "Content-Length: 3\r\n\r\n"),
13538 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13539 };
13540
13541 MockRead data_reads[] = {
13542 MockRead("HTTP 0.9 rocks!"),
13543 MockRead(SYNCHRONOUS, OK),
13544 };
13545 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13546 arraysize(data_writes));
13547 session_deps_.socket_factory->AddSocketDataProvider(&data);
13548
13549 TestCompletionCallback callback;
13550
13551 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13552 EXPECT_EQ(ERR_IO_PENDING, rv);
13553
13554 rv = callback.WaitForResult();
13555 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13556
13557 const HttpResponseInfo* response = trans->GetResponseInfo();
13558 EXPECT_TRUE(response == NULL);
13559}
13560
13561TEST_P(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
13562 ScopedVector<UploadElementReader> element_readers;
13563 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713564 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413565
13566 HttpRequestInfo request;
13567 request.method = "POST";
13568 request.url = GURL("http://www.foo.com/");
13569 request.upload_data_stream = &upload_data_stream;
13570 request.load_flags = 0;
13571
13572 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13573 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113574 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413575 // Send headers successfully, but get an error while sending the body.
13576 MockWrite data_writes[] = {
13577 MockWrite("POST / HTTP/1.1\r\n"
13578 "Host: www.foo.com\r\n"
13579 "Connection: keep-alive\r\n"
13580 "Content-Length: 3\r\n\r\n"),
13581 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13582 };
13583
13584 MockRead data_reads[] = {
13585 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
13586 MockRead(SYNCHRONOUS, OK),
13587 };
13588 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13589 arraysize(data_writes));
13590 session_deps_.socket_factory->AddSocketDataProvider(&data);
13591
13592 TestCompletionCallback callback;
13593
13594 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13595 EXPECT_EQ(ERR_IO_PENDING, rv);
13596
13597 rv = callback.WaitForResult();
13598 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13599
13600 const HttpResponseInfo* response = trans->GetResponseInfo();
13601 EXPECT_TRUE(response == NULL);
13602}
13603
Adam Rice425cf122015-01-19 06:18:2413604// Verify that proxy headers are not sent to the destination server when
13605// establishing a tunnel for a secure WebSocket connection.
13606TEST_P(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
13607 HttpRequestInfo request;
13608 request.method = "GET";
13609 request.url = GURL("wss://www.google.com/");
13610 AddWebSocketHeaders(&request.extra_headers);
13611
13612 // Configure against proxy server "myproxy:70".
13613 session_deps_.proxy_service.reset(
13614 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
13615
13616 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13617
13618 // Since a proxy is configured, try to establish a tunnel.
13619 MockWrite data_writes[] = {
13620 MockWrite(
13621 "CONNECT www.google.com:443 HTTP/1.1\r\n"
13622 "Host: www.google.com\r\n"
13623 "Proxy-Connection: keep-alive\r\n\r\n"),
13624
13625 // After calling trans->RestartWithAuth(), this is the request we should
13626 // be issuing -- the final header line contains the credentials.
13627 MockWrite(
13628 "CONNECT www.google.com:443 HTTP/1.1\r\n"
13629 "Host: www.google.com\r\n"
13630 "Proxy-Connection: keep-alive\r\n"
13631 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
13632
13633 MockWrite(
13634 "GET / HTTP/1.1\r\n"
13635 "Host: www.google.com\r\n"
13636 "Connection: Upgrade\r\n"
13637 "Upgrade: websocket\r\n"
13638 "Origin: http://www.google.com\r\n"
13639 "Sec-WebSocket-Version: 13\r\n"
13640 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
13641 };
13642
13643 // The proxy responds to the connect with a 407, using a persistent
13644 // connection.
13645 MockRead data_reads[] = {
13646 // No credentials.
13647 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
13648 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
13649 MockRead("Proxy-Connection: close\r\n\r\n"),
13650
13651 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
13652
13653 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
13654 MockRead("Upgrade: websocket\r\n"),
13655 MockRead("Connection: Upgrade\r\n"),
13656 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
13657 };
13658
13659 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13660 arraysize(data_writes));
13661 session_deps_.socket_factory->AddSocketDataProvider(&data);
13662 SSLSocketDataProvider ssl(ASYNC, OK);
13663 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13664
13665 scoped_ptr<HttpTransaction> trans(
13666 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13667 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
13668 trans->SetWebSocketHandshakeStreamCreateHelper(
13669 &websocket_stream_create_helper);
13670
13671 {
13672 TestCompletionCallback callback;
13673
13674 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13675 EXPECT_EQ(ERR_IO_PENDING, rv);
13676
13677 rv = callback.WaitForResult();
13678 EXPECT_EQ(OK, rv);
13679 }
13680
13681 const HttpResponseInfo* response = trans->GetResponseInfo();
13682 ASSERT_TRUE(response);
13683 ASSERT_TRUE(response->headers.get());
13684 EXPECT_EQ(407, response->headers->response_code());
13685
13686 {
13687 TestCompletionCallback callback;
13688
13689 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
13690 callback.callback());
13691 EXPECT_EQ(ERR_IO_PENDING, rv);
13692
13693 rv = callback.WaitForResult();
13694 EXPECT_EQ(OK, rv);
13695 }
13696
13697 response = trans->GetResponseInfo();
13698 ASSERT_TRUE(response);
13699 ASSERT_TRUE(response->headers.get());
13700
13701 EXPECT_EQ(101, response->headers->response_code());
13702
13703 trans.reset();
13704 session->CloseAllConnections();
13705}
13706
13707// Verify that proxy headers are not sent to the destination server when
13708// establishing a tunnel for an insecure WebSocket connection.
13709// This requires the authentication info to be injected into the auth cache
13710// due to crbug.com/395064
13711// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
13712TEST_P(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
13713 HttpRequestInfo request;
13714 request.method = "GET";
13715 request.url = GURL("ws://www.google.com/");
13716 AddWebSocketHeaders(&request.extra_headers);
13717
13718 // Configure against proxy server "myproxy:70".
13719 session_deps_.proxy_service.reset(
13720 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
13721
13722 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13723
13724 MockWrite data_writes[] = {
13725 // Try to establish a tunnel for the WebSocket connection, with
13726 // credentials. Because WebSockets have a separate set of socket pools,
13727 // they cannot and will not use the same TCP/IP connection as the
13728 // preflight HTTP request.
13729 MockWrite(
13730 "CONNECT www.google.com:80 HTTP/1.1\r\n"
13731 "Host: www.google.com\r\n"
13732 "Proxy-Connection: keep-alive\r\n"
13733 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
13734
13735 MockWrite(
13736 "GET / HTTP/1.1\r\n"
13737 "Host: www.google.com\r\n"
13738 "Connection: Upgrade\r\n"
13739 "Upgrade: websocket\r\n"
13740 "Origin: http://www.google.com\r\n"
13741 "Sec-WebSocket-Version: 13\r\n"
13742 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
13743 };
13744
13745 MockRead data_reads[] = {
13746 // HTTP CONNECT with credentials.
13747 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
13748
13749 // WebSocket connection established inside tunnel.
13750 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
13751 MockRead("Upgrade: websocket\r\n"),
13752 MockRead("Connection: Upgrade\r\n"),
13753 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
13754 };
13755
13756 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13757 arraysize(data_writes));
13758 session_deps_.socket_factory->AddSocketDataProvider(&data);
13759
13760 session->http_auth_cache()->Add(
13761 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
13762 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
13763
13764 scoped_ptr<HttpTransaction> trans(
13765 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13766 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
13767 trans->SetWebSocketHandshakeStreamCreateHelper(
13768 &websocket_stream_create_helper);
13769
13770 TestCompletionCallback callback;
13771
13772 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13773 EXPECT_EQ(ERR_IO_PENDING, rv);
13774
13775 rv = callback.WaitForResult();
13776 EXPECT_EQ(OK, rv);
13777
13778 const HttpResponseInfo* response = trans->GetResponseInfo();
13779 ASSERT_TRUE(response);
13780 ASSERT_TRUE(response->headers.get());
13781
13782 EXPECT_EQ(101, response->headers->response_code());
13783
13784 trans.reset();
13785 session->CloseAllConnections();
13786}
13787
[email protected]89ceba9a2009-03-21 03:46:0613788} // namespace net