blob: aa1697483294bacbd641d580fc734200609885bc [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
bnc57685ae62015-03-10 21:27:20423INSTANTIATE_TEST_CASE_P(NextProto,
424 HttpNetworkTransactionTest,
425 testing::Values(kProtoSPDY31,
426 kProtoSPDY4_14,
427 kProtoSPDY4));
[email protected]23e482282013-06-14 16:08:02428
[email protected]448d4ca52012-03-04 04:12:23429namespace {
430
[email protected]1826a402014-01-08 15:40:48431class BeforeNetworkStartHandler {
432 public:
433 explicit BeforeNetworkStartHandler(bool defer)
434 : defer_on_before_network_start_(defer),
435 observed_before_network_start_(false) {}
436
437 void OnBeforeNetworkStart(bool* defer) {
438 *defer = defer_on_before_network_start_;
439 observed_before_network_start_ = true;
440 }
441
442 bool observed_before_network_start() const {
443 return observed_before_network_start_;
444 }
445
446 private:
447 const bool defer_on_before_network_start_;
448 bool observed_before_network_start_;
449
450 DISALLOW_COPY_AND_ASSIGN(BeforeNetworkStartHandler);
451};
452
[email protected]597a1ab2014-06-26 08:12:27453class BeforeProxyHeadersSentHandler {
454 public:
455 BeforeProxyHeadersSentHandler()
456 : observed_before_proxy_headers_sent_(false) {}
457
[email protected]1252d42f2014-07-01 21:20:20458 void OnBeforeProxyHeadersSent(const ProxyInfo& proxy_info,
459 HttpRequestHeaders* request_headers) {
[email protected]597a1ab2014-06-26 08:12:27460 observed_before_proxy_headers_sent_ = true;
461 observed_proxy_server_uri_ = proxy_info.proxy_server().ToURI();
462 }
463
464 bool observed_before_proxy_headers_sent() const {
465 return observed_before_proxy_headers_sent_;
466 }
467
468 std::string observed_proxy_server_uri() const {
469 return observed_proxy_server_uri_;
470 }
471
472 private:
473 bool observed_before_proxy_headers_sent_;
474 std::string observed_proxy_server_uri_;
475
476 DISALLOW_COPY_AND_ASSIGN(BeforeProxyHeadersSentHandler);
477};
478
[email protected]15a5ccf82008-10-23 19:57:43479// Fill |str| with a long header list that consumes >= |size| bytes.
480void FillLargeHeadersString(std::string* str, int size) {
thestig9d3bb0c2015-01-24 00:49:51481 const char row[] =
[email protected]4ddaf2502008-10-23 18:26:19482 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
483 const int sizeof_row = strlen(row);
484 const int num_rows = static_cast<int>(
485 ceil(static_cast<float>(size) / sizeof_row));
486 const int sizeof_data = num_rows * sizeof_row;
487 DCHECK(sizeof_data >= size);
[email protected]15a5ccf82008-10-23 19:57:43488 str->reserve(sizeof_data);
[email protected]372d34a2008-11-05 21:30:51489
[email protected]4ddaf2502008-10-23 18:26:19490 for (int i = 0; i < num_rows; ++i)
[email protected]15a5ccf82008-10-23 19:57:43491 str->append(row, sizeof_row);
[email protected]4ddaf2502008-10-23 18:26:19492}
493
[email protected]385a4672009-03-11 22:21:29494// Alternative functions that eliminate randomness and dependency on the local
495// host name so that the generated NTLM messages are reproducible.
[email protected]fe2bc6a2009-03-23 16:52:20496void MockGenerateRandom1(uint8* output, size_t n) {
[email protected]385a4672009-03-11 22:21:29497 static const uint8 bytes[] = {
498 0x55, 0x29, 0x66, 0x26, 0x6b, 0x9c, 0x73, 0x54
499 };
500 static size_t current_byte = 0;
501 for (size_t i = 0; i < n; ++i) {
502 output[i] = bytes[current_byte++];
503 current_byte %= arraysize(bytes);
504 }
505}
506
[email protected]fe2bc6a2009-03-23 16:52:20507void MockGenerateRandom2(uint8* output, size_t n) {
[email protected]385a4672009-03-11 22:21:29508 static const uint8 bytes[] = {
509 0x96, 0x79, 0x85, 0xe7, 0x49, 0x93, 0x70, 0xa1,
510 0x4e, 0xe7, 0x87, 0x45, 0x31, 0x5b, 0xd3, 0x1f
511 };
512 static size_t current_byte = 0;
513 for (size_t i = 0; i < n; ++i) {
514 output[i] = bytes[current_byte++];
515 current_byte %= arraysize(bytes);
516 }
517}
518
[email protected]fe2bc6a2009-03-23 16:52:20519std::string MockGetHostName() {
520 return "WTC-WIN7";
[email protected]385a4672009-03-11 22:21:29521}
522
[email protected]e60e47a2010-07-14 03:37:18523template<typename ParentPool>
524class CaptureGroupNameSocketPool : public ParentPool {
[email protected]04e5be32009-06-26 20:00:31525 public:
[email protected]9e1bdd32011-02-03 21:48:34526 CaptureGroupNameSocketPool(HostResolver* host_resolver,
527 CertVerifier* cert_verifier);
[email protected]e60e47a2010-07-14 03:37:18528
[email protected]d80a4322009-08-14 07:07:49529 const std::string last_group_name_received() const {
530 return last_group_name_;
531 }
532
dmichaeld6e570d2014-12-18 22:30:57533 int RequestSocket(const std::string& group_name,
534 const void* socket_params,
535 RequestPriority priority,
536 ClientSocketHandle* handle,
537 const CompletionCallback& callback,
538 const BoundNetLog& net_log) override {
[email protected]04e5be32009-06-26 20:00:31539 last_group_name_ = group_name;
540 return ERR_IO_PENDING;
541 }
dmichaeld6e570d2014-12-18 22:30:57542 void CancelRequest(const std::string& group_name,
543 ClientSocketHandle* handle) override {}
544 void ReleaseSocket(const std::string& group_name,
545 scoped_ptr<StreamSocket> socket,
546 int id) override {}
547 void CloseIdleSockets() override {}
548 int IdleSocketCount() const override { return 0; }
549 int IdleSocketCountInGroup(const std::string& group_name) const override {
[email protected]04e5be32009-06-26 20:00:31550 return 0;
551 }
dmichaeld6e570d2014-12-18 22:30:57552 LoadState GetLoadState(const std::string& group_name,
553 const ClientSocketHandle* handle) const override {
[email protected]04e5be32009-06-26 20:00:31554 return LOAD_STATE_IDLE;
555 }
dmichaeld6e570d2014-12-18 22:30:57556 base::TimeDelta ConnectionTimeout() const override {
[email protected]a796bcec2010-03-22 17:17:26557 return base::TimeDelta();
558 }
[email protected]d80a4322009-08-14 07:07:49559
560 private:
[email protected]04e5be32009-06-26 20:00:31561 std::string last_group_name_;
562};
563
[email protected]ab739042011-04-07 15:22:28564typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
565CaptureGroupNameTransportSocketPool;
[email protected]e772db3f2010-07-12 18:11:13566typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
567CaptureGroupNameHttpProxySocketPool;
[email protected]2d731a32010-04-29 01:04:06568typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
[email protected]2227c692010-05-04 15:36:11569CaptureGroupNameSOCKSSocketPool;
[email protected]e60e47a2010-07-14 03:37:18570typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
571CaptureGroupNameSSLSocketPool;
572
573template<typename ParentPool>
574CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34575 HostResolver* host_resolver,
576 CertVerifier* /* cert_verifier */)
577 : ParentPool(0, 0, NULL, host_resolver, NULL, NULL) {}
[email protected]e60e47a2010-07-14 03:37:18578
hashimoto0d3e4fb2015-01-09 05:02:50579template <>
[email protected]2df19bb2010-08-25 20:13:46580CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21581 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34582 CertVerifier* /* cert_verifier */)
hashimotodae13b02015-01-15 04:28:21583 : HttpProxyClientSocketPool(0, 0, NULL, NULL, NULL, NULL) {
hashimoto0d3e4fb2015-01-09 05:02:50584}
[email protected]2df19bb2010-08-25 20:13:46585
[email protected]007b3f82013-04-09 08:46:45586template <>
[email protected]e60e47a2010-07-14 03:37:18587CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21588 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34589 CertVerifier* cert_verifier)
[email protected]007b3f82013-04-09 08:46:45590 : SSLClientSocketPool(0,
591 0,
592 NULL,
[email protected]007b3f82013-04-09 08:46:45593 cert_verifier,
594 NULL,
595 NULL,
[email protected]284303b62013-11-28 15:11:54596 NULL,
eranm6571b2b2014-12-03 15:53:23597 NULL,
[email protected]007b3f82013-04-09 08:46:45598 std::string(),
599 NULL,
600 NULL,
601 NULL,
602 NULL,
603 NULL,
[email protected]8e458552014-08-05 00:02:15604 false,
605 NULL) {
606}
[email protected]2227c692010-05-04 15:36:11607
[email protected]231d5a32008-09-13 00:45:27608//-----------------------------------------------------------------------------
609
[email protected]79cb5c12011-09-12 13:12:04610// Helper functions for validating that AuthChallengeInfo's are correctly
611// configured for common cases.
612bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
613 if (!auth_challenge)
614 return false;
615 EXPECT_FALSE(auth_challenge->is_proxy);
616 EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString());
617 EXPECT_EQ("MyRealm1", auth_challenge->realm);
618 EXPECT_EQ("basic", auth_challenge->scheme);
619 return true;
620}
621
622bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
623 if (!auth_challenge)
624 return false;
625 EXPECT_TRUE(auth_challenge->is_proxy);
626 EXPECT_EQ("myproxy:70", auth_challenge->challenger.ToString());
627 EXPECT_EQ("MyRealm1", auth_challenge->realm);
628 EXPECT_EQ("basic", auth_challenge->scheme);
629 return true;
630}
631
632bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
633 if (!auth_challenge)
634 return false;
635 EXPECT_FALSE(auth_challenge->is_proxy);
636 EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString());
637 EXPECT_EQ("digestive", auth_challenge->realm);
638 EXPECT_EQ("digest", auth_challenge->scheme);
639 return true;
640}
641
642bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
643 if (!auth_challenge)
644 return false;
645 EXPECT_FALSE(auth_challenge->is_proxy);
646 EXPECT_EQ("172.22.68.17:80", auth_challenge->challenger.ToString());
647 EXPECT_EQ(std::string(), auth_challenge->realm);
648 EXPECT_EQ("ntlm", auth_challenge->scheme);
649 return true;
650}
651
[email protected]448d4ca52012-03-04 04:12:23652} // namespace
653
[email protected]23e482282013-06-14 16:08:02654TEST_P(HttpNetworkTransactionTest, Basic) {
[email protected]3fe8d2f82013-10-17 08:56:07655 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:40656 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:41657 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]231d5a32008-09-13 00:45:27658}
659
[email protected]23e482282013-06-14 16:08:02660TEST_P(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27661 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35662 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
663 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06664 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27665 };
[email protected]31a2bfe2010-02-09 08:03:39666 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
667 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42668 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27669 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
670 EXPECT_EQ("hello world", out.response_data);
[email protected]b8015c42013-12-24 15:18:19671 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
672 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27673}
674
675// Response with no status line.
[email protected]23e482282013-06-14 16:08:02676TEST_P(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27677 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35678 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06679 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27680 };
[email protected]31a2bfe2010-02-09 08:03:39681 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
682 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42683 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27684 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
685 EXPECT_EQ("hello world", out.response_data);
[email protected]b8015c42013-12-24 15:18:19686 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
687 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27688}
689
690// Allow up to 4 bytes of junk to precede status line.
[email protected]23e482282013-06-14 16:08:02691TEST_P(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27692 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35693 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06694 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27695 };
[email protected]31a2bfe2010-02-09 08:03:39696 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
697 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42698 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27699 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
700 EXPECT_EQ("DATA", out.response_data);
[email protected]b8015c42013-12-24 15:18:19701 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
702 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27703}
704
705// Allow up to 4 bytes of junk to precede status line.
[email protected]23e482282013-06-14 16:08:02706TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27707 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35708 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06709 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27710 };
[email protected]31a2bfe2010-02-09 08:03:39711 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
712 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42713 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27714 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
715 EXPECT_EQ("DATA", out.response_data);
[email protected]b8015c42013-12-24 15:18:19716 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
717 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27718}
719
720// Beyond 4 bytes of slop and it should fail to find a status line.
[email protected]23e482282013-06-14 16:08:02721TEST_P(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27722 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35723 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06724 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27725 };
[email protected]31a2bfe2010-02-09 08:03:39726 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
727 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42728 EXPECT_EQ(OK, out.rv);
[email protected]3d2a59b2008-09-26 19:44:25729 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
730 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
[email protected]b8015c42013-12-24 15:18:19731 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
732 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27733}
734
735// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
[email protected]23e482282013-06-14 16:08:02736TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27737 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35738 MockRead("\n"),
739 MockRead("\n"),
740 MockRead("Q"),
741 MockRead("J"),
742 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06743 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27744 };
[email protected]31a2bfe2010-02-09 08:03:39745 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
746 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42747 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27748 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
749 EXPECT_EQ("DATA", out.response_data);
[email protected]b8015c42013-12-24 15:18:19750 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
751 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27752}
753
754// Close the connection before enough bytes to have a status line.
[email protected]23e482282013-06-14 16:08:02755TEST_P(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:27756 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35757 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:06758 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27759 };
[email protected]31a2bfe2010-02-09 08:03:39760 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
761 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42762 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27763 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
764 EXPECT_EQ("HTT", out.response_data);
[email protected]b8015c42013-12-24 15:18:19765 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
766 EXPECT_EQ(reads_size, out.totalReceivedBytes);
initial.commit586acc5fe2008-07-26 22:42:52767}
768
[email protected]f9d44aa2008-09-23 23:57:17769// Simulate a 204 response, lacking a Content-Length header, sent over a
770// persistent connection. The response should still terminate since a 204
771// cannot have a response body.
[email protected]23e482282013-06-14 16:08:02772TEST_P(HttpNetworkTransactionTest, StopsReading204) {
[email protected]b8015c42013-12-24 15:18:19773 char junk[] = "junk";
[email protected]f9d44aa2008-09-23 23:57:17774 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35775 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
[email protected]b8015c42013-12-24 15:18:19776 MockRead(junk), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:06777 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:17778 };
[email protected]31a2bfe2010-02-09 08:03:39779 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
780 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42781 EXPECT_EQ(OK, out.rv);
[email protected]f9d44aa2008-09-23 23:57:17782 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
783 EXPECT_EQ("", out.response_data);
[email protected]b8015c42013-12-24 15:18:19784 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
785 int64 response_size = reads_size - strlen(junk);
786 EXPECT_EQ(response_size, out.totalReceivedBytes);
[email protected]f9d44aa2008-09-23 23:57:17787}
788
[email protected]0877e3d2009-10-17 22:29:57789// A simple request using chunked encoding with some extra data after.
[email protected]23e482282013-06-14 16:08:02790TEST_P(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]b8015c42013-12-24 15:18:19791 std::string final_chunk = "0\r\n\r\n";
792 std::string extra_data = "HTTP/1.1 200 OK\r\n";
793 std::string last_read = final_chunk + extra_data;
[email protected]0877e3d2009-10-17 22:29:57794 MockRead data_reads[] = {
795 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
796 MockRead("5\r\nHello\r\n"),
797 MockRead("1\r\n"),
798 MockRead(" \r\n"),
799 MockRead("5\r\nworld\r\n"),
[email protected]b8015c42013-12-24 15:18:19800 MockRead(last_read.data()),
[email protected]8ddf8322012-02-23 18:08:06801 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:57802 };
[email protected]31a2bfe2010-02-09 08:03:39803 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
804 arraysize(data_reads));
[email protected]0877e3d2009-10-17 22:29:57805 EXPECT_EQ(OK, out.rv);
806 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
807 EXPECT_EQ("Hello world", out.response_data);
[email protected]b8015c42013-12-24 15:18:19808 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
809 int64 response_size = reads_size - extra_data.size();
810 EXPECT_EQ(response_size, out.totalReceivedBytes);
[email protected]0877e3d2009-10-17 22:29:57811}
812
[email protected]9fe44f52010-09-23 18:36:00813// Next tests deal with http://crbug.com/56344.
814
[email protected]23e482282013-06-14 16:08:02815TEST_P(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00816 MultipleContentLengthHeadersNoTransferEncoding) {
817 MockRead data_reads[] = {
818 MockRead("HTTP/1.1 200 OK\r\n"),
819 MockRead("Content-Length: 10\r\n"),
820 MockRead("Content-Length: 5\r\n\r\n"),
821 };
822 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
823 arraysize(data_reads));
824 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
825}
826
[email protected]23e482282013-06-14 16:08:02827TEST_P(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04828 DuplicateContentLengthHeadersNoTransferEncoding) {
829 MockRead data_reads[] = {
830 MockRead("HTTP/1.1 200 OK\r\n"),
831 MockRead("Content-Length: 5\r\n"),
832 MockRead("Content-Length: 5\r\n\r\n"),
833 MockRead("Hello"),
834 };
835 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
836 arraysize(data_reads));
837 EXPECT_EQ(OK, out.rv);
838 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
839 EXPECT_EQ("Hello", out.response_data);
840}
841
[email protected]23e482282013-06-14 16:08:02842TEST_P(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04843 ComplexContentLengthHeadersNoTransferEncoding) {
844 // More than 2 dupes.
845 {
846 MockRead data_reads[] = {
847 MockRead("HTTP/1.1 200 OK\r\n"),
848 MockRead("Content-Length: 5\r\n"),
849 MockRead("Content-Length: 5\r\n"),
850 MockRead("Content-Length: 5\r\n\r\n"),
851 MockRead("Hello"),
852 };
853 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
854 arraysize(data_reads));
855 EXPECT_EQ(OK, out.rv);
856 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
857 EXPECT_EQ("Hello", out.response_data);
858 }
859 // HTTP/1.0
860 {
861 MockRead data_reads[] = {
862 MockRead("HTTP/1.0 200 OK\r\n"),
863 MockRead("Content-Length: 5\r\n"),
864 MockRead("Content-Length: 5\r\n"),
865 MockRead("Content-Length: 5\r\n\r\n"),
866 MockRead("Hello"),
867 };
868 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
869 arraysize(data_reads));
870 EXPECT_EQ(OK, out.rv);
871 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
872 EXPECT_EQ("Hello", out.response_data);
873 }
874 // 2 dupes and one mismatched.
875 {
876 MockRead data_reads[] = {
877 MockRead("HTTP/1.1 200 OK\r\n"),
878 MockRead("Content-Length: 10\r\n"),
879 MockRead("Content-Length: 10\r\n"),
880 MockRead("Content-Length: 5\r\n\r\n"),
881 };
882 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
883 arraysize(data_reads));
884 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
885 }
886}
887
[email protected]23e482282013-06-14 16:08:02888TEST_P(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00889 MultipleContentLengthHeadersTransferEncoding) {
890 MockRead data_reads[] = {
891 MockRead("HTTP/1.1 200 OK\r\n"),
892 MockRead("Content-Length: 666\r\n"),
893 MockRead("Content-Length: 1337\r\n"),
894 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
895 MockRead("5\r\nHello\r\n"),
896 MockRead("1\r\n"),
897 MockRead(" \r\n"),
898 MockRead("5\r\nworld\r\n"),
899 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:06900 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:00901 };
902 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
903 arraysize(data_reads));
904 EXPECT_EQ(OK, out.rv);
905 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
906 EXPECT_EQ("Hello world", out.response_data);
907}
908
[email protected]1628fe92011-10-04 23:04:55909// Next tests deal with http://crbug.com/98895.
910
911// Checks that a single Content-Disposition header results in no error.
[email protected]23e482282013-06-14 16:08:02912TEST_P(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:55913 MockRead data_reads[] = {
914 MockRead("HTTP/1.1 200 OK\r\n"),
915 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
916 MockRead("Content-Length: 5\r\n\r\n"),
917 MockRead("Hello"),
918 };
919 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
920 arraysize(data_reads));
921 EXPECT_EQ(OK, out.rv);
922 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
923 EXPECT_EQ("Hello", out.response_data);
924}
925
[email protected]54a9c6e52012-03-21 20:10:59926// Checks that two identical Content-Disposition headers result in no error.
[email protected]23e482282013-06-14 16:08:02927TEST_P(HttpNetworkTransactionTest,
[email protected]54a9c6e52012-03-21 20:10:59928 TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:55929 MockRead data_reads[] = {
930 MockRead("HTTP/1.1 200 OK\r\n"),
931 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
932 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
933 MockRead("Content-Length: 5\r\n\r\n"),
934 MockRead("Hello"),
935 };
936 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
937 arraysize(data_reads));
[email protected]54a9c6e52012-03-21 20:10:59938 EXPECT_EQ(OK, out.rv);
939 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
940 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:55941}
942
943// Checks that two distinct Content-Disposition headers result in an error.
[email protected]23e482282013-06-14 16:08:02944TEST_P(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:55945 MockRead data_reads[] = {
946 MockRead("HTTP/1.1 200 OK\r\n"),
947 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
948 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
949 MockRead("Content-Length: 5\r\n\r\n"),
950 MockRead("Hello"),
951 };
952 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
953 arraysize(data_reads));
954 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION, out.rv);
955}
956
[email protected]54a9c6e52012-03-21 20:10:59957// Checks that two identical Location headers result in no error.
958// Also tests Location header behavior.
[email protected]23e482282013-06-14 16:08:02959TEST_P(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:55960 MockRead data_reads[] = {
961 MockRead("HTTP/1.1 302 Redirect\r\n"),
962 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:59963 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:55964 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:06965 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:55966 };
967
968 HttpRequestInfo request;
969 request.method = "GET";
970 request.url = GURL("http://redirect.com/");
971 request.load_flags = 0;
972
[email protected]3fe8d2f82013-10-17 08:56:07973 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1628fe92011-10-04 23:04:55974 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:41975 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]1628fe92011-10-04 23:04:55976
977 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:07978 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:55979
[email protected]49639fa2011-12-20 23:22:41980 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:55981
[email protected]49639fa2011-12-20 23:22:41982 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1628fe92011-10-04 23:04:55983 EXPECT_EQ(ERR_IO_PENDING, rv);
984
985 EXPECT_EQ(OK, callback.WaitForResult());
986
987 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]90499482013-06-01 00:39:50988 ASSERT_TRUE(response != NULL && response->headers.get() != NULL);
[email protected]1628fe92011-10-04 23:04:55989 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
990 std::string url;
991 EXPECT_TRUE(response->headers->IsRedirect(&url));
992 EXPECT_EQ("http://good.com/", url);
[email protected]d8fc4722014-06-13 13:17:15993 EXPECT_TRUE(response->proxy_server.IsEmpty());
[email protected]1628fe92011-10-04 23:04:55994}
995
[email protected]1628fe92011-10-04 23:04:55996// Checks that two distinct Location headers result in an error.
[email protected]23e482282013-06-14 16:08:02997TEST_P(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:55998 MockRead data_reads[] = {
999 MockRead("HTTP/1.1 302 Redirect\r\n"),
1000 MockRead("Location: http://good.com/\r\n"),
1001 MockRead("Location: http://evil.com/\r\n"),
1002 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061003 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551004 };
1005 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1006 arraysize(data_reads));
1007 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION, out.rv);
1008}
1009
[email protected]ef0faf2e72009-03-05 23:27:231010// Do a request using the HEAD method. Verify that we don't try to read the
1011// message body (since HEAD has none).
[email protected]23e482282013-06-14 16:08:021012TEST_P(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:421013 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:231014 request.method = "HEAD";
1015 request.url = GURL("http://www.google.com/");
1016 request.load_flags = 0;
1017
[email protected]3fe8d2f82013-10-17 08:56:071018 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271019 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411020 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]597a1ab2014-06-26 08:12:271021 BeforeProxyHeadersSentHandler proxy_headers_handler;
1022 trans->SetBeforeProxyHeadersSentCallback(
1023 base::Bind(&BeforeProxyHeadersSentHandler::OnBeforeProxyHeadersSent,
1024 base::Unretained(&proxy_headers_handler)));
[email protected]cb9bf6ca2011-01-28 13:15:271025
[email protected]ef0faf2e72009-03-05 23:27:231026 MockWrite data_writes1[] = {
1027 MockWrite("HEAD / HTTP/1.1\r\n"
1028 "Host: www.google.com\r\n"
1029 "Connection: keep-alive\r\n"
1030 "Content-Length: 0\r\n\r\n"),
1031 };
1032 MockRead data_reads1[] = {
1033 MockRead("HTTP/1.1 404 Not Found\r\n"),
1034 MockRead("Server: Blah\r\n"),
1035 MockRead("Content-Length: 1234\r\n\r\n"),
1036
1037 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:061038 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]ef0faf2e72009-03-05 23:27:231039 };
1040
[email protected]31a2bfe2010-02-09 08:03:391041 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1042 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:071043 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:231044
[email protected]49639fa2011-12-20 23:22:411045 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:231046
[email protected]49639fa2011-12-20 23:22:411047 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421048 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]ef0faf2e72009-03-05 23:27:231049
1050 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421051 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:231052
[email protected]1c773ea12009-04-28 19:58:421053 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501054 ASSERT_TRUE(response != NULL);
[email protected]ef0faf2e72009-03-05 23:27:231055
1056 // Check that the headers got parsed.
[email protected]90499482013-06-01 00:39:501057 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]ef0faf2e72009-03-05 23:27:231058 EXPECT_EQ(1234, response->headers->GetContentLength());
1059 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
[email protected]d8fc4722014-06-13 13:17:151060 EXPECT_TRUE(response->proxy_server.IsEmpty());
[email protected]597a1ab2014-06-26 08:12:271061 EXPECT_FALSE(proxy_headers_handler.observed_before_proxy_headers_sent());
[email protected]ef0faf2e72009-03-05 23:27:231062
1063 std::string server_header;
1064 void* iter = NULL;
1065 bool has_server_header = response->headers->EnumerateHeader(
1066 &iter, "Server", &server_header);
1067 EXPECT_TRUE(has_server_header);
1068 EXPECT_EQ("Blah", server_header);
1069
1070 // Reading should give EOF right away, since there is no message body
1071 // (despite non-zero content-length).
1072 std::string response_data;
1073 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421074 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:231075 EXPECT_EQ("", response_data);
1076}
1077
[email protected]23e482282013-06-14 16:08:021078TEST_P(HttpNetworkTransactionTest, ReuseConnection) {
[email protected]bb88e1d32013-05-03 23:11:071079 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:521080
1081 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351082 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1083 MockRead("hello"),
1084 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1085 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061086 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521087 };
[email protected]31a2bfe2010-02-09 08:03:391088 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071089 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521090
[email protected]0b0bf032010-09-21 18:08:501091 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521092 "hello", "world"
1093 };
1094
1095 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:421096 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521097 request.method = "GET";
1098 request.url = GURL("http://www.google.com/");
1099 request.load_flags = 0;
1100
[email protected]262eec82013-03-19 21:01:361101 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501102 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271103
[email protected]49639fa2011-12-20 23:22:411104 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521105
[email protected]49639fa2011-12-20 23:22:411106 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421107 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521108
1109 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421110 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521111
[email protected]1c773ea12009-04-28 19:58:421112 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501113 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521114
[email protected]90499482013-06-01 00:39:501115 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251116 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]d8fc4722014-06-13 13:17:151117 EXPECT_TRUE(response->proxy_server.IsEmpty());
initial.commit586acc5fe2008-07-26 22:42:521118
1119 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571120 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421121 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251122 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521123 }
1124}
1125
[email protected]23e482282013-06-14 16:08:021126TEST_P(HttpNetworkTransactionTest, Ignores100) {
[email protected]b2d26cfd2012-12-11 10:36:061127 ScopedVector<UploadElementReader> element_readers;
1128 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:071129 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:271130
[email protected]1c773ea12009-04-28 19:58:421131 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521132 request.method = "POST";
1133 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271134 request.upload_data_stream = &upload_data_stream;
initial.commit586acc5fe2008-07-26 22:42:521135 request.load_flags = 0;
1136
[email protected]3fe8d2f82013-10-17 08:56:071137 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271138 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411139 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271140
initial.commit586acc5fe2008-07-26 22:42:521141 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351142 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1143 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1144 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061145 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521146 };
[email protected]31a2bfe2010-02-09 08:03:391147 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071148 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521149
[email protected]49639fa2011-12-20 23:22:411150 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521151
[email protected]49639fa2011-12-20 23:22:411152 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421153 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521154
1155 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421156 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521157
[email protected]1c773ea12009-04-28 19:58:421158 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501159 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521160
[email protected]90499482013-06-01 00:39:501161 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251162 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521163
1164 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571165 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421166 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251167 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521168}
1169
[email protected]3a2d3662009-03-27 03:49:141170// This test is almost the same as Ignores100 above, but the response contains
1171// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571172// HTTP/1.1 and the two status headers are read in one read.
[email protected]23e482282013-06-14 16:08:021173TEST_P(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421174 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141175 request.method = "GET";
1176 request.url = GURL("http://www.foo.com/");
1177 request.load_flags = 0;
1178
[email protected]3fe8d2f82013-10-17 08:56:071179 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271180 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411181 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271182
[email protected]3a2d3662009-03-27 03:49:141183 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571184 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1185 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141186 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061187 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141188 };
[email protected]31a2bfe2010-02-09 08:03:391189 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071190 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141191
[email protected]49639fa2011-12-20 23:22:411192 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141193
[email protected]49639fa2011-12-20 23:22:411194 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421195 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3a2d3662009-03-27 03:49:141196
1197 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421198 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:141199
[email protected]1c773ea12009-04-28 19:58:421200 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501201 ASSERT_TRUE(response != NULL);
[email protected]3a2d3662009-03-27 03:49:141202
[email protected]90499482013-06-01 00:39:501203 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3a2d3662009-03-27 03:49:141204 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1205
1206 std::string response_data;
1207 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421208 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:141209 EXPECT_EQ("hello world", response_data);
1210}
1211
[email protected]23e482282013-06-14 16:08:021212TEST_P(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
[email protected]ee9410e72010-01-07 01:42:381213 HttpRequestInfo request;
1214 request.method = "POST";
1215 request.url = GURL("http://www.foo.com/");
1216 request.load_flags = 0;
1217
[email protected]3fe8d2f82013-10-17 08:56:071218 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271219 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411220 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271221
[email protected]ee9410e72010-01-07 01:42:381222 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061223 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1224 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381225 };
[email protected]31a2bfe2010-02-09 08:03:391226 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071227 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381228
[email protected]49639fa2011-12-20 23:22:411229 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381230
[email protected]49639fa2011-12-20 23:22:411231 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]ee9410e72010-01-07 01:42:381232 EXPECT_EQ(ERR_IO_PENDING, rv);
1233
1234 rv = callback.WaitForResult();
1235 EXPECT_EQ(OK, rv);
1236
1237 std::string response_data;
1238 rv = ReadTransaction(trans.get(), &response_data);
1239 EXPECT_EQ(OK, rv);
1240 EXPECT_EQ("", response_data);
1241}
1242
[email protected]23e482282013-06-14 16:08:021243TEST_P(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381244 HttpRequestInfo request;
1245 request.method = "POST";
1246 request.url = GURL("http://www.foo.com/");
1247 request.load_flags = 0;
1248
[email protected]3fe8d2f82013-10-17 08:56:071249 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271250 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411251 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271252
[email protected]ee9410e72010-01-07 01:42:381253 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061254 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381255 };
[email protected]31a2bfe2010-02-09 08:03:391256 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071257 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381258
[email protected]49639fa2011-12-20 23:22:411259 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381260
[email protected]49639fa2011-12-20 23:22:411261 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]ee9410e72010-01-07 01:42:381262 EXPECT_EQ(ERR_IO_PENDING, rv);
1263
1264 rv = callback.WaitForResult();
1265 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
1266}
1267
[email protected]23e482282013-06-14 16:08:021268void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511269 const MockWrite* write_failure,
1270 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421271 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521272 request.method = "GET";
1273 request.url = GURL("http://www.foo.com/");
1274 request.load_flags = 0;
1275
[email protected]58e32bb2013-01-21 18:23:251276 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071277 session_deps_.net_log = &net_log;
1278 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271279
[email protected]202965992011-12-07 23:04:511280 // Written data for successfully sending both requests.
1281 MockWrite data1_writes[] = {
1282 MockWrite("GET / HTTP/1.1\r\n"
1283 "Host: www.foo.com\r\n"
1284 "Connection: keep-alive\r\n\r\n"),
1285 MockWrite("GET / HTTP/1.1\r\n"
1286 "Host: www.foo.com\r\n"
1287 "Connection: keep-alive\r\n\r\n")
1288 };
1289
1290 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521291 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351292 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1293 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061294 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521295 };
[email protected]202965992011-12-07 23:04:511296
1297 if (write_failure) {
[email protected]a34f61ee2014-03-18 20:59:491298 ASSERT_FALSE(read_failure);
[email protected]202965992011-12-07 23:04:511299 data1_writes[1] = *write_failure;
1300 } else {
1301 ASSERT_TRUE(read_failure);
1302 data1_reads[2] = *read_failure;
1303 }
1304
1305 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
1306 data1_writes, arraysize(data1_writes));
[email protected]bb88e1d32013-05-03 23:11:071307 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521308
1309 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351310 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1311 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061312 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521313 };
[email protected]31a2bfe2010-02-09 08:03:391314 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071315 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521316
thestig9d3bb0c2015-01-24 00:49:511317 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521318 "hello", "world"
1319 };
1320
[email protected]58e32bb2013-01-21 18:23:251321 uint32 first_socket_log_id = NetLog::Source::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521322 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411323 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521324
[email protected]262eec82013-03-19 21:01:361325 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501326 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
initial.commit586acc5fe2008-07-26 22:42:521327
[email protected]49639fa2011-12-20 23:22:411328 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421329 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521330
1331 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421332 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521333
[email protected]58e32bb2013-01-21 18:23:251334 LoadTimingInfo load_timing_info;
1335 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1336 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1337 if (i == 0) {
1338 first_socket_log_id = load_timing_info.socket_log_id;
1339 } else {
1340 // The second request should be using a new socket.
1341 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1342 }
1343
[email protected]1c773ea12009-04-28 19:58:421344 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501345 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521346
[email protected]90499482013-06-01 00:39:501347 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251348 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521349
1350 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571351 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421352 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251353 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521354 }
1355}
[email protected]3d2a59b2008-09-26 19:44:251356
[email protected]a34f61ee2014-03-18 20:59:491357void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1358 const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:101359 const MockRead* read_failure,
1360 bool use_spdy) {
[email protected]a34f61ee2014-03-18 20:59:491361 HttpRequestInfo request;
1362 request.method = "GET";
[email protected]09356c652014-03-25 15:36:101363 request.url = GURL("https://www.foo.com/");
[email protected]a34f61ee2014-03-18 20:59:491364 request.load_flags = 0;
1365
1366 CapturingNetLog net_log;
1367 session_deps_.net_log = &net_log;
1368 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1369
[email protected]09356c652014-03-25 15:36:101370 SSLSocketDataProvider ssl1(ASYNC, OK);
1371 SSLSocketDataProvider ssl2(ASYNC, OK);
1372 if (use_spdy) {
1373 ssl1.SetNextProto(GetParam());
1374 ssl2.SetNextProto(GetParam());
1375 }
1376 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1377 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]a34f61ee2014-03-18 20:59:491378
[email protected]09356c652014-03-25 15:36:101379 // SPDY versions of the request and response.
1380 scoped_ptr<SpdyFrame> spdy_request(spdy_util_.ConstructSpdyGet(
1381 request.url.spec().c_str(), false, 1, DEFAULT_PRIORITY));
1382 scoped_ptr<SpdyFrame> spdy_response(
1383 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
1384 scoped_ptr<SpdyFrame> spdy_data(
1385 spdy_util_.ConstructSpdyBodyFrame(1, "hello", 5, true));
[email protected]a34f61ee2014-03-18 20:59:491386
[email protected]09356c652014-03-25 15:36:101387 // HTTP/1.1 versions of the request and response.
1388 const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1389 "Host: www.foo.com\r\n"
1390 "Connection: keep-alive\r\n\r\n";
1391 const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1392 const char kHttpData[] = "hello";
1393
1394 std::vector<MockRead> data1_reads;
1395 std::vector<MockWrite> data1_writes;
[email protected]a34f61ee2014-03-18 20:59:491396 if (write_failure) {
1397 ASSERT_FALSE(read_failure);
[email protected]09356c652014-03-25 15:36:101398 data1_writes.push_back(*write_failure);
1399 data1_reads.push_back(MockRead(ASYNC, OK));
[email protected]a34f61ee2014-03-18 20:59:491400 } else {
1401 ASSERT_TRUE(read_failure);
[email protected]09356c652014-03-25 15:36:101402 if (use_spdy) {
1403 data1_writes.push_back(CreateMockWrite(*spdy_request));
1404 } else {
1405 data1_writes.push_back(MockWrite(kHttpRequest));
1406 }
1407 data1_reads.push_back(*read_failure);
[email protected]a34f61ee2014-03-18 20:59:491408 }
1409
[email protected]09356c652014-03-25 15:36:101410 StaticSocketDataProvider data1(&data1_reads[0], data1_reads.size(),
1411 &data1_writes[0], data1_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491412 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1413
[email protected]09356c652014-03-25 15:36:101414 std::vector<MockRead> data2_reads;
1415 std::vector<MockWrite> data2_writes;
1416
1417 if (use_spdy) {
1418 data2_writes.push_back(CreateMockWrite(*spdy_request, 0, ASYNC));
1419
1420 data2_reads.push_back(CreateMockRead(*spdy_response, 1, ASYNC));
1421 data2_reads.push_back(CreateMockRead(*spdy_data, 2, ASYNC));
1422 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1423 } else {
1424 data2_writes.push_back(
1425 MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1426
1427 data2_reads.push_back(
1428 MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1429 data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1430 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1431 }
1432 OrderedSocketData data2(&data2_reads[0], data2_reads.size(),
1433 &data2_writes[0], data2_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491434 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1435
1436 // Preconnect a socket.
1437 net::SSLConfig ssl_config;
1438 session->ssl_config_service()->GetSSLConfig(&ssl_config);
[email protected]d7599122014-05-24 03:37:231439 session->GetNextProtos(&ssl_config.next_protos);
[email protected]a34f61ee2014-03-18 20:59:491440 session->http_stream_factory()->PreconnectStreams(
1441 1, request, DEFAULT_PRIORITY, ssl_config, ssl_config);
1442 // Wait for the preconnect to complete.
1443 // TODO(davidben): Some way to wait for an idle socket count might be handy.
1444 base::RunLoop().RunUntilIdle();
[email protected]09356c652014-03-25 15:36:101445 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]a34f61ee2014-03-18 20:59:491446
1447 // Make the request.
1448 TestCompletionCallback callback;
1449
1450 scoped_ptr<HttpTransaction> trans(
1451 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1452
1453 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1454 EXPECT_EQ(ERR_IO_PENDING, rv);
1455
1456 rv = callback.WaitForResult();
1457 EXPECT_EQ(OK, rv);
1458
1459 LoadTimingInfo load_timing_info;
1460 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
[email protected]09356c652014-03-25 15:36:101461 TestLoadTimingNotReused(
1462 load_timing_info,
1463 CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]a34f61ee2014-03-18 20:59:491464
1465 const HttpResponseInfo* response = trans->GetResponseInfo();
1466 ASSERT_TRUE(response != NULL);
1467
1468 EXPECT_TRUE(response->headers.get() != NULL);
1469 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1470
1471 std::string response_data;
1472 rv = ReadTransaction(trans.get(), &response_data);
1473 EXPECT_EQ(OK, rv);
[email protected]09356c652014-03-25 15:36:101474 EXPECT_EQ(kHttpData, response_data);
[email protected]a34f61ee2014-03-18 20:59:491475}
1476
[email protected]23e482282013-06-14 16:08:021477TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:231478 KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061479 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]202965992011-12-07 23:04:511480 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1481}
1482
[email protected]23e482282013-06-14 16:08:021483TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061484 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]202965992011-12-07 23:04:511485 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251486}
1487
[email protected]23e482282013-06-14 16:08:021488TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061489 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]202965992011-12-07 23:04:511490 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251491}
1492
[email protected]d58ceea82014-06-04 10:55:541493// Make sure that on a 408 response (Request Timeout), the request is retried,
1494// if the socket was a reused keep alive socket.
1495TEST_P(HttpNetworkTransactionTest, KeepAlive408) {
1496 MockRead read_failure(SYNCHRONOUS,
1497 "HTTP/1.1 408 Request Timeout\r\n"
1498 "Connection: Keep-Alive\r\n"
1499 "Content-Length: 6\r\n\r\n"
1500 "Pickle");
1501 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1502}
1503
[email protected]a34f61ee2014-03-18 20:59:491504TEST_P(HttpNetworkTransactionTest,
1505 PreconnectErrorNotConnectedOnWrite) {
1506 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]09356c652014-03-25 15:36:101507 PreconnectErrorResendRequestTest(&write_failure, NULL, false);
[email protected]a34f61ee2014-03-18 20:59:491508}
1509
1510TEST_P(HttpNetworkTransactionTest, PreconnectErrorReset) {
1511 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]09356c652014-03-25 15:36:101512 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
[email protected]a34f61ee2014-03-18 20:59:491513}
1514
1515TEST_P(HttpNetworkTransactionTest, PreconnectErrorEOF) {
1516 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]09356c652014-03-25 15:36:101517 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1518}
1519
1520TEST_P(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
1521 MockRead read_failure(ASYNC, OK); // EOF
1522 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1523}
1524
[email protected]d58ceea82014-06-04 10:55:541525// Make sure that on a 408 response (Request Timeout), the request is retried,
1526// if the socket was a preconnected (UNUSED_IDLE) socket.
1527TEST_P(HttpNetworkTransactionTest, RetryOnIdle408) {
1528 MockRead read_failure(SYNCHRONOUS,
1529 "HTTP/1.1 408 Request Timeout\r\n"
1530 "Connection: Keep-Alive\r\n"
1531 "Content-Length: 6\r\n\r\n"
1532 "Pickle");
1533 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1534 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1535}
1536
[email protected]09356c652014-03-25 15:36:101537TEST_P(HttpNetworkTransactionTest,
1538 SpdyPreconnectErrorNotConnectedOnWrite) {
1539 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1540 PreconnectErrorResendRequestTest(&write_failure, NULL, true);
1541}
1542
1543TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
1544 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1545 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1546}
1547
1548TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
1549 MockRead read_failure(SYNCHRONOUS, OK); // EOF
1550 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1551}
1552
1553TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
1554 MockRead read_failure(ASYNC, OK); // EOF
1555 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
[email protected]a34f61ee2014-03-18 20:59:491556}
1557
[email protected]23e482282013-06-14 16:08:021558TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:421559 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:251560 request.method = "GET";
1561 request.url = GURL("http://www.google.com/");
1562 request.load_flags = 0;
1563
[email protected]3fe8d2f82013-10-17 08:56:071564 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271565 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411566 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271567
[email protected]3d2a59b2008-09-26 19:44:251568 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061569 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:351570 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1571 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061572 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251573 };
[email protected]31a2bfe2010-02-09 08:03:391574 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071575 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:251576
[email protected]49639fa2011-12-20 23:22:411577 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:251578
[email protected]49639fa2011-12-20 23:22:411579 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421580 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3d2a59b2008-09-26 19:44:251581
1582 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421583 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]3d2a59b2008-09-26 19:44:251584
[email protected]1c773ea12009-04-28 19:58:421585 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]3d2a59b2008-09-26 19:44:251586 EXPECT_TRUE(response == NULL);
[email protected]3d2a59b2008-09-26 19:44:251587}
1588
1589// What do various browsers do when the server closes a non-keepalive
1590// connection without sending any response header or body?
1591//
1592// IE7: error page
1593// Safari 3.1.2 (Windows): error page
1594// Firefox 3.0.1: blank page
1595// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:421596// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1597// Us: error page (EMPTY_RESPONSE)
[email protected]23e482282013-06-14 16:08:021598TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:251599 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061600 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:351601 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1602 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061603 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251604 };
[email protected]31a2bfe2010-02-09 08:03:391605 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1606 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:421607 EXPECT_EQ(ERR_EMPTY_RESPONSE, out.rv);
[email protected]3d2a59b2008-09-26 19:44:251608}
[email protected]038e9a32008-10-08 22:40:161609
[email protected]1826a402014-01-08 15:40:481610// Test that network access can be deferred and resumed.
1611TEST_P(HttpNetworkTransactionTest, ThrottleBeforeNetworkStart) {
1612 HttpRequestInfo request;
1613 request.method = "GET";
1614 request.url = GURL("http://www.google.com/");
1615 request.load_flags = 0;
1616
1617 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1618 scoped_ptr<HttpTransaction> trans(
1619 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1620
1621 // Defer on OnBeforeNetworkStart.
1622 BeforeNetworkStartHandler net_start_handler(true); // defer
1623 trans->SetBeforeNetworkStartCallback(
1624 base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
1625 base::Unretained(&net_start_handler)));
1626
1627 MockRead data_reads[] = {
1628 MockRead("HTTP/1.0 200 OK\r\n"),
1629 MockRead("Content-Length: 5\r\n\r\n"),
1630 MockRead("hello"),
1631 MockRead(SYNCHRONOUS, 0),
1632 };
1633 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1634 session_deps_.socket_factory->AddSocketDataProvider(&data);
1635
1636 TestCompletionCallback callback;
1637
1638 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1639 EXPECT_EQ(ERR_IO_PENDING, rv);
1640 base::MessageLoop::current()->RunUntilIdle();
1641
1642 // Should have deferred for network start.
1643 EXPECT_TRUE(net_start_handler.observed_before_network_start());
1644 EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
1645 EXPECT_TRUE(trans->GetResponseInfo() == NULL);
1646
1647 trans->ResumeNetworkStart();
1648 rv = callback.WaitForResult();
1649 EXPECT_EQ(OK, rv);
1650 EXPECT_TRUE(trans->GetResponseInfo() != NULL);
1651
1652 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
1653 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
1654 if (rv == ERR_IO_PENDING)
1655 rv = callback.WaitForResult();
1656 EXPECT_EQ(5, rv);
1657 trans.reset();
1658}
1659
1660// Test that network use can be deferred and canceled.
1661TEST_P(HttpNetworkTransactionTest, ThrottleAndCancelBeforeNetworkStart) {
1662 HttpRequestInfo request;
1663 request.method = "GET";
1664 request.url = GURL("http://www.google.com/");
1665 request.load_flags = 0;
1666
1667 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1668 scoped_ptr<HttpTransaction> trans(
1669 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1670
1671 // Defer on OnBeforeNetworkStart.
1672 BeforeNetworkStartHandler net_start_handler(true); // defer
1673 trans->SetBeforeNetworkStartCallback(
1674 base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
1675 base::Unretained(&net_start_handler)));
1676
1677 TestCompletionCallback callback;
1678
1679 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1680 EXPECT_EQ(ERR_IO_PENDING, rv);
1681 base::MessageLoop::current()->RunUntilIdle();
1682
1683 // Should have deferred for network start.
1684 EXPECT_TRUE(net_start_handler.observed_before_network_start());
1685 EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
1686 EXPECT_TRUE(trans->GetResponseInfo() == NULL);
1687}
1688
[email protected]7a5378b2012-11-04 03:25:171689// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
1690// tests. There was a bug causing HttpNetworkTransaction to hang in the
1691// destructor in such situations.
1692// See http://crbug.com/154712 and http://crbug.com/156609.
[email protected]23e482282013-06-14 16:08:021693TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:171694 HttpRequestInfo request;
1695 request.method = "GET";
1696 request.url = GURL("http://www.google.com/");
1697 request.load_flags = 0;
1698
[email protected]bb88e1d32013-05-03 23:11:071699 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:361700 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501701 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171702
1703 MockRead data_reads[] = {
1704 MockRead("HTTP/1.0 200 OK\r\n"),
1705 MockRead("Connection: keep-alive\r\n"),
1706 MockRead("Content-Length: 100\r\n\r\n"),
1707 MockRead("hello"),
1708 MockRead(SYNCHRONOUS, 0),
1709 };
1710 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071711 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171712
1713 TestCompletionCallback callback;
1714
1715 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1716 EXPECT_EQ(ERR_IO_PENDING, rv);
1717
1718 rv = callback.WaitForResult();
1719 EXPECT_EQ(OK, rv);
1720
1721 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501722 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171723 if (rv == ERR_IO_PENDING)
1724 rv = callback.WaitForResult();
1725 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:501726 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171727 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1728
1729 trans.reset();
[email protected]2da659e2013-05-23 20:51:341730 base::MessageLoop::current()->RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171731 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1732}
1733
[email protected]23e482282013-06-14 16:08:021734TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:171735 HttpRequestInfo request;
1736 request.method = "GET";
1737 request.url = GURL("http://www.google.com/");
1738 request.load_flags = 0;
1739
[email protected]bb88e1d32013-05-03 23:11:071740 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:361741 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501742 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171743
1744 MockRead data_reads[] = {
1745 MockRead("HTTP/1.0 200 OK\r\n"),
1746 MockRead("Connection: keep-alive\r\n"),
1747 MockRead("Content-Length: 100\r\n\r\n"),
1748 MockRead(SYNCHRONOUS, 0),
1749 };
1750 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071751 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171752
1753 TestCompletionCallback callback;
1754
1755 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1756 EXPECT_EQ(ERR_IO_PENDING, rv);
1757
1758 rv = callback.WaitForResult();
1759 EXPECT_EQ(OK, rv);
1760
1761 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501762 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171763 if (rv == ERR_IO_PENDING)
1764 rv = callback.WaitForResult();
1765 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1766
1767 trans.reset();
[email protected]2da659e2013-05-23 20:51:341768 base::MessageLoop::current()->RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171769 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1770}
1771
[email protected]0b0bf032010-09-21 18:08:501772// Test that we correctly reuse a keep-alive connection after not explicitly
1773// reading the body.
[email protected]23e482282013-06-14 16:08:021774TEST_P(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:131775 HttpRequestInfo request;
1776 request.method = "GET";
1777 request.url = GURL("http://www.foo.com/");
1778 request.load_flags = 0;
1779
[email protected]58e32bb2013-01-21 18:23:251780 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071781 session_deps_.net_log = &net_log;
1782 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271783
[email protected]0b0bf032010-09-21 18:08:501784 // Note that because all these reads happen in the same
1785 // StaticSocketDataProvider, it shows that the same socket is being reused for
1786 // all transactions.
[email protected]fc31d6a42010-06-24 18:05:131787 MockRead data1_reads[] = {
[email protected]0b0bf032010-09-21 18:08:501788 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
1789 MockRead("HTTP/1.1 205 Reset Content\r\n\r\n"),
[email protected]fc31d6a42010-06-24 18:05:131790 MockRead("HTTP/1.1 304 Not Modified\r\n\r\n"),
[email protected]0b0bf032010-09-21 18:08:501791 MockRead("HTTP/1.1 302 Found\r\n"
1792 "Content-Length: 0\r\n\r\n"),
1793 MockRead("HTTP/1.1 302 Found\r\n"
1794 "Content-Length: 5\r\n\r\n"
1795 "hello"),
1796 MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1797 "Content-Length: 0\r\n\r\n"),
1798 MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1799 "Content-Length: 5\r\n\r\n"
1800 "hello"),
[email protected]fc31d6a42010-06-24 18:05:131801 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1802 MockRead("hello"),
1803 };
1804 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071805 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]fc31d6a42010-06-24 18:05:131806
1807 MockRead data2_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061808 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]fc31d6a42010-06-24 18:05:131809 };
1810 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071811 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]fc31d6a42010-06-24 18:05:131812
[email protected]0b0bf032010-09-21 18:08:501813 const int kNumUnreadBodies = arraysize(data1_reads) - 2;
1814 std::string response_lines[kNumUnreadBodies];
1815
[email protected]58e32bb2013-01-21 18:23:251816 uint32 first_socket_log_id = NetLog::Source::kInvalidId;
[email protected]0b0bf032010-09-21 18:08:501817 for (size_t i = 0; i < arraysize(data1_reads) - 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411818 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:131819
[email protected]262eec82013-03-19 21:01:361820 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501821 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]fc31d6a42010-06-24 18:05:131822
[email protected]49639fa2011-12-20 23:22:411823 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]fc31d6a42010-06-24 18:05:131824 EXPECT_EQ(ERR_IO_PENDING, rv);
1825
1826 rv = callback.WaitForResult();
1827 EXPECT_EQ(OK, rv);
1828
[email protected]58e32bb2013-01-21 18:23:251829 LoadTimingInfo load_timing_info;
1830 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1831 if (i == 0) {
1832 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1833 first_socket_log_id = load_timing_info.socket_log_id;
1834 } else {
1835 TestLoadTimingReused(load_timing_info);
1836 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
1837 }
1838
[email protected]fc31d6a42010-06-24 18:05:131839 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]0b0bf032010-09-21 18:08:501840 ASSERT_TRUE(response != NULL);
[email protected]fc31d6a42010-06-24 18:05:131841
[email protected]90499482013-06-01 00:39:501842 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]0b0bf032010-09-21 18:08:501843 response_lines[i] = response->headers->GetStatusLine();
1844
1845 // We intentionally don't read the response bodies.
[email protected]fc31d6a42010-06-24 18:05:131846 }
[email protected]0b0bf032010-09-21 18:08:501847
1848 const char* const kStatusLines[] = {
1849 "HTTP/1.1 204 No Content",
1850 "HTTP/1.1 205 Reset Content",
1851 "HTTP/1.1 304 Not Modified",
1852 "HTTP/1.1 302 Found",
1853 "HTTP/1.1 302 Found",
1854 "HTTP/1.1 301 Moved Permanently",
1855 "HTTP/1.1 301 Moved Permanently",
1856 };
1857
mostynb91e0da982015-01-20 19:17:271858 static_assert(kNumUnreadBodies == arraysize(kStatusLines),
1859 "forgot to update kStatusLines");
[email protected]0b0bf032010-09-21 18:08:501860
1861 for (int i = 0; i < kNumUnreadBodies; ++i)
1862 EXPECT_EQ(kStatusLines[i], response_lines[i]);
1863
[email protected]49639fa2011-12-20 23:22:411864 TestCompletionCallback callback;
[email protected]262eec82013-03-19 21:01:361865 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501866 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:411867 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0b0bf032010-09-21 18:08:501868 EXPECT_EQ(ERR_IO_PENDING, rv);
1869 rv = callback.WaitForResult();
1870 EXPECT_EQ(OK, rv);
1871 const HttpResponseInfo* response = trans->GetResponseInfo();
1872 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:501873 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]0b0bf032010-09-21 18:08:501874 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1875 std::string response_data;
1876 rv = ReadTransaction(trans.get(), &response_data);
1877 EXPECT_EQ(OK, rv);
1878 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:131879}
1880
[email protected]038e9a32008-10-08 22:40:161881// Test the request-challenge-retry sequence for basic auth.
1882// (basic auth is the easiest to mock, because it has no randomness).
[email protected]23e482282013-06-14 16:08:021883TEST_P(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:421884 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:161885 request.method = "GET";
1886 request.url = GURL("http://www.google.com/");
1887 request.load_flags = 0;
1888
[email protected]58e32bb2013-01-21 18:23:251889 CapturingNetLog log;
[email protected]bb88e1d32013-05-03 23:11:071890 session_deps_.net_log = &log;
[email protected]3fe8d2f82013-10-17 08:56:071891 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271892 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411893 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271894
[email protected]f9ee6b52008-11-08 06:46:231895 MockWrite data_writes1[] = {
1896 MockWrite("GET / HTTP/1.1\r\n"
1897 "Host: www.google.com\r\n"
1898 "Connection: keep-alive\r\n\r\n"),
1899 };
1900
[email protected]038e9a32008-10-08 22:40:161901 MockRead data_reads1[] = {
1902 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
1903 // Give a couple authenticate options (only the middle one is actually
1904 // supported).
[email protected]22927ad2009-09-21 19:56:191905 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:161906 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1907 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
1908 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1909 // Large content-length -- won't matter, as connection will be reset.
1910 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061911 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:161912 };
1913
1914 // After calling trans->RestartWithAuth(), this is the request we should
1915 // be issuing -- the final header line contains the credentials.
1916 MockWrite data_writes2[] = {
1917 MockWrite("GET / HTTP/1.1\r\n"
1918 "Host: www.google.com\r\n"
1919 "Connection: keep-alive\r\n"
1920 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1921 };
1922
1923 // Lastly, the server responds with the actual content.
1924 MockRead data_reads2[] = {
1925 MockRead("HTTP/1.0 200 OK\r\n"),
1926 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1927 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061928 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:161929 };
1930
[email protected]31a2bfe2010-02-09 08:03:391931 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1932 data_writes1, arraysize(data_writes1));
1933 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1934 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:071935 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1936 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:161937
[email protected]49639fa2011-12-20 23:22:411938 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:161939
[email protected]49639fa2011-12-20 23:22:411940 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421941 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:161942
1943 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421944 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:161945
[email protected]58e32bb2013-01-21 18:23:251946 LoadTimingInfo load_timing_info1;
1947 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
1948 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
1949
[email protected]b8015c42013-12-24 15:18:191950 int64 reads_size1 = ReadsSize(data_reads1, arraysize(data_reads1));
1951 EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
1952
[email protected]1c773ea12009-04-28 19:58:421953 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501954 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:041955 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:161956
[email protected]49639fa2011-12-20 23:22:411957 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:161958
[email protected]49639fa2011-12-20 23:22:411959 rv = trans->RestartWithAuth(
1960 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:421961 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:161962
1963 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421964 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:161965
[email protected]58e32bb2013-01-21 18:23:251966 LoadTimingInfo load_timing_info2;
1967 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
1968 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
1969 // The load timing after restart should have a new socket ID, and times after
1970 // those of the first load timing.
1971 EXPECT_LE(load_timing_info1.receive_headers_end,
1972 load_timing_info2.connect_timing.connect_start);
1973 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
1974
[email protected]b8015c42013-12-24 15:18:191975 int64 reads_size2 = ReadsSize(data_reads2, arraysize(data_reads2));
1976 EXPECT_EQ(reads_size1 + reads_size2, trans->GetTotalReceivedBytes());
1977
[email protected]038e9a32008-10-08 22:40:161978 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501979 ASSERT_TRUE(response != NULL);
[email protected]038e9a32008-10-08 22:40:161980 EXPECT_TRUE(response->auth_challenge.get() == NULL);
1981 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:161982}
1983
[email protected]23e482282013-06-14 16:08:021984TEST_P(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:461985 HttpRequestInfo request;
1986 request.method = "GET";
1987 request.url = GURL("http://www.google.com/");
1988 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
1989
[email protected]3fe8d2f82013-10-17 08:56:071990 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271991 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411992 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271993
[email protected]861fcd52009-08-26 02:33:461994 MockWrite data_writes[] = {
1995 MockWrite("GET / HTTP/1.1\r\n"
1996 "Host: www.google.com\r\n"
1997 "Connection: keep-alive\r\n\r\n"),
1998 };
1999
2000 MockRead data_reads[] = {
2001 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2002 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2003 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2004 // Large content-length -- won't matter, as connection will be reset.
2005 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062006 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:462007 };
2008
[email protected]31a2bfe2010-02-09 08:03:392009 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2010 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072011 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:412012 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:462013
[email protected]49639fa2011-12-20 23:22:412014 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]861fcd52009-08-26 02:33:462015 EXPECT_EQ(ERR_IO_PENDING, rv);
2016
2017 rv = callback.WaitForResult();
2018 EXPECT_EQ(0, rv);
2019
[email protected]b8015c42013-12-24 15:18:192020 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
2021 EXPECT_EQ(reads_size, trans->GetTotalReceivedBytes());
2022
[email protected]861fcd52009-08-26 02:33:462023 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502024 ASSERT_TRUE(response != NULL);
[email protected]861fcd52009-08-26 02:33:462025 EXPECT_TRUE(response->auth_challenge.get() == NULL);
2026}
2027
[email protected]2d2697f92009-02-18 21:00:322028// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2029// connection.
[email protected]23e482282013-06-14 16:08:022030TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
[email protected]1c773ea12009-04-28 19:58:422031 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322032 request.method = "GET";
2033 request.url = GURL("http://www.google.com/");
2034 request.load_flags = 0;
2035
[email protected]58e32bb2013-01-21 18:23:252036 CapturingNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072037 session_deps_.net_log = &log;
2038 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272039
[email protected]2d2697f92009-02-18 21:00:322040 MockWrite data_writes1[] = {
2041 MockWrite("GET / HTTP/1.1\r\n"
2042 "Host: www.google.com\r\n"
2043 "Connection: keep-alive\r\n\r\n"),
2044
2045 // After calling trans->RestartWithAuth(), this is the request we should
2046 // be issuing -- the final header line contains the credentials.
2047 MockWrite("GET / HTTP/1.1\r\n"
2048 "Host: www.google.com\r\n"
2049 "Connection: keep-alive\r\n"
2050 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2051 };
2052
2053 MockRead data_reads1[] = {
2054 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2055 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2056 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2057 MockRead("Content-Length: 14\r\n\r\n"),
2058 MockRead("Unauthorized\r\n"),
2059
2060 // Lastly, the server responds with the actual content.
2061 MockRead("HTTP/1.1 200 OK\r\n"),
2062 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502063 MockRead("Content-Length: 5\r\n\r\n"),
2064 MockRead("Hello"),
[email protected]2d2697f92009-02-18 21:00:322065 };
2066
[email protected]2d0a4f92011-05-05 16:38:462067 // If there is a regression where we disconnect a Keep-Alive
2068 // connection during an auth roundtrip, we'll end up reading this.
2069 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062070 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462071 };
2072
[email protected]31a2bfe2010-02-09 08:03:392073 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2074 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462075 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2076 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072077 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2078 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322079
[email protected]49639fa2011-12-20 23:22:412080 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322081
[email protected]262eec82013-03-19 21:01:362082 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502083 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412084 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422085 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322086
2087 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422088 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322089
[email protected]58e32bb2013-01-21 18:23:252090 LoadTimingInfo load_timing_info1;
2091 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
2092 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2093
[email protected]1c773ea12009-04-28 19:58:422094 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502095 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042096 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322097
[email protected]49639fa2011-12-20 23:22:412098 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322099
[email protected]49639fa2011-12-20 23:22:412100 rv = trans->RestartWithAuth(
2101 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422102 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322103
2104 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422105 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322106
[email protected]58e32bb2013-01-21 18:23:252107 LoadTimingInfo load_timing_info2;
2108 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
2109 TestLoadTimingReused(load_timing_info2);
2110 // The load timing after restart should have the same socket ID, and times
2111 // those of the first load timing.
2112 EXPECT_LE(load_timing_info1.receive_headers_end,
2113 load_timing_info2.send_start);
2114 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2115
[email protected]2d2697f92009-02-18 21:00:322116 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502117 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322118 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502119 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]b8015c42013-12-24 15:18:192120
2121 std::string response_data;
2122 rv = ReadTransaction(trans.get(), &response_data);
2123 EXPECT_EQ(OK, rv);
2124 int64 reads_size1 = ReadsSize(data_reads1, arraysize(data_reads1));
2125 EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
[email protected]2d2697f92009-02-18 21:00:322126}
2127
2128// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2129// connection and with no response body to drain.
[email protected]23e482282013-06-14 16:08:022130TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:422131 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322132 request.method = "GET";
2133 request.url = GURL("http://www.google.com/");
2134 request.load_flags = 0;
2135
[email protected]bb88e1d32013-05-03 23:11:072136 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272137
[email protected]2d2697f92009-02-18 21:00:322138 MockWrite data_writes1[] = {
2139 MockWrite("GET / HTTP/1.1\r\n"
2140 "Host: www.google.com\r\n"
2141 "Connection: keep-alive\r\n\r\n"),
2142
2143 // After calling trans->RestartWithAuth(), this is the request we should
2144 // be issuing -- the final header line contains the credentials.
2145 MockWrite("GET / HTTP/1.1\r\n"
2146 "Host: www.google.com\r\n"
2147 "Connection: keep-alive\r\n"
2148 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2149 };
2150
[email protected]2d2697f92009-02-18 21:00:322151 MockRead data_reads1[] = {
2152 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2153 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:312154 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:322155
2156 // Lastly, the server responds with the actual content.
2157 MockRead("HTTP/1.1 200 OK\r\n"),
2158 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502159 MockRead("Content-Length: 5\r\n\r\n"),
2160 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322161 };
2162
[email protected]2d0a4f92011-05-05 16:38:462163 // An incorrect reconnect would cause this to be read.
2164 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062165 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462166 };
2167
[email protected]31a2bfe2010-02-09 08:03:392168 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2169 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462170 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2171 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072172 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2173 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322174
[email protected]49639fa2011-12-20 23:22:412175 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322176
[email protected]262eec82013-03-19 21:01:362177 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502178 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412179 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422180 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322181
2182 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422183 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322184
[email protected]1c773ea12009-04-28 19:58:422185 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502186 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042187 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322188
[email protected]49639fa2011-12-20 23:22:412189 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322190
[email protected]49639fa2011-12-20 23:22:412191 rv = trans->RestartWithAuth(
2192 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422193 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322194
2195 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422196 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322197
2198 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502199 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322200 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502201 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322202}
2203
2204// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2205// connection and with a large response body to drain.
[email protected]23e482282013-06-14 16:08:022206TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:422207 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322208 request.method = "GET";
2209 request.url = GURL("http://www.google.com/");
2210 request.load_flags = 0;
2211
[email protected]bb88e1d32013-05-03 23:11:072212 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272213
[email protected]2d2697f92009-02-18 21:00:322214 MockWrite data_writes1[] = {
2215 MockWrite("GET / HTTP/1.1\r\n"
2216 "Host: www.google.com\r\n"
2217 "Connection: keep-alive\r\n\r\n"),
2218
2219 // After calling trans->RestartWithAuth(), this is the request we should
2220 // be issuing -- the final header line contains the credentials.
2221 MockWrite("GET / HTTP/1.1\r\n"
2222 "Host: www.google.com\r\n"
2223 "Connection: keep-alive\r\n"
2224 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2225 };
2226
2227 // Respond with 5 kb of response body.
2228 std::string large_body_string("Unauthorized");
2229 large_body_string.append(5 * 1024, ' ');
2230 large_body_string.append("\r\n");
2231
2232 MockRead data_reads1[] = {
2233 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2234 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2235 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2236 // 5134 = 12 + 5 * 1024 + 2
2237 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062238 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:322239
2240 // Lastly, the server responds with the actual content.
2241 MockRead("HTTP/1.1 200 OK\r\n"),
2242 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502243 MockRead("Content-Length: 5\r\n\r\n"),
2244 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322245 };
2246
[email protected]2d0a4f92011-05-05 16:38:462247 // An incorrect reconnect would cause this to be read.
2248 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062249 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462250 };
2251
[email protected]31a2bfe2010-02-09 08:03:392252 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2253 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462254 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2255 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072256 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2257 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322258
[email protected]49639fa2011-12-20 23:22:412259 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322260
[email protected]262eec82013-03-19 21:01:362261 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502262 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412263 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422264 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322265
2266 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422267 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322268
[email protected]1c773ea12009-04-28 19:58:422269 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502270 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042271 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322272
[email protected]49639fa2011-12-20 23:22:412273 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322274
[email protected]49639fa2011-12-20 23:22:412275 rv = trans->RestartWithAuth(
2276 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422277 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322278
2279 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422280 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322281
2282 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502283 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322284 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502285 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322286}
2287
2288// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:312289// connection, but the server gets impatient and closes the connection.
[email protected]23e482282013-06-14 16:08:022290TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:312291 HttpRequestInfo request;
2292 request.method = "GET";
2293 request.url = GURL("http://www.google.com/");
2294 request.load_flags = 0;
2295
[email protected]bb88e1d32013-05-03 23:11:072296 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272297
[email protected]11203f012009-11-12 23:02:312298 MockWrite data_writes1[] = {
2299 MockWrite("GET / HTTP/1.1\r\n"
2300 "Host: www.google.com\r\n"
2301 "Connection: keep-alive\r\n\r\n"),
2302 // This simulates the seemingly successful write to a closed connection
2303 // if the bug is not fixed.
2304 MockWrite("GET / HTTP/1.1\r\n"
2305 "Host: www.google.com\r\n"
2306 "Connection: keep-alive\r\n"
2307 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2308 };
2309
2310 MockRead data_reads1[] = {
2311 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2312 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2313 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2314 MockRead("Content-Length: 14\r\n\r\n"),
2315 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:062316 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:312317 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:062318 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:312319 };
2320
2321 // After calling trans->RestartWithAuth(), this is the request we should
2322 // be issuing -- the final header line contains the credentials.
2323 MockWrite data_writes2[] = {
2324 MockWrite("GET / HTTP/1.1\r\n"
2325 "Host: www.google.com\r\n"
2326 "Connection: keep-alive\r\n"
2327 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2328 };
2329
2330 // Lastly, the server responds with the actual content.
2331 MockRead data_reads2[] = {
2332 MockRead("HTTP/1.1 200 OK\r\n"),
2333 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502334 MockRead("Content-Length: 5\r\n\r\n"),
2335 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:312336 };
2337
[email protected]31a2bfe2010-02-09 08:03:392338 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2339 data_writes1, arraysize(data_writes1));
2340 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2341 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072342 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2343 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:312344
[email protected]49639fa2011-12-20 23:22:412345 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:312346
[email protected]262eec82013-03-19 21:01:362347 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502348 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412349 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]11203f012009-11-12 23:02:312350 EXPECT_EQ(ERR_IO_PENDING, rv);
2351
2352 rv = callback1.WaitForResult();
2353 EXPECT_EQ(OK, rv);
2354
2355 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502356 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042357 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:312358
[email protected]49639fa2011-12-20 23:22:412359 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:312360
[email protected]49639fa2011-12-20 23:22:412361 rv = trans->RestartWithAuth(
2362 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]11203f012009-11-12 23:02:312363 EXPECT_EQ(ERR_IO_PENDING, rv);
2364
2365 rv = callback2.WaitForResult();
2366 EXPECT_EQ(OK, rv);
2367
2368 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502369 ASSERT_TRUE(response != NULL);
[email protected]11203f012009-11-12 23:02:312370 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502371 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:312372}
2373
[email protected]394816e92010-08-03 07:38:592374// Test the request-challenge-retry sequence for basic auth, over a connection
2375// that requires a restart when setting up an SSL tunnel.
ttuttle34f63b52015-03-05 04:33:012376TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
2377 HttpRequestInfo request;
2378 request.method = "GET";
2379 request.url = GURL("https://www.google.com/");
2380 // when the no authentication data flag is set.
2381 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
2382
2383 // Configure against proxy server "myproxy:70".
2384 session_deps_.proxy_service.reset(
2385 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
2386 CapturingBoundNetLog log;
2387 session_deps_.net_log = log.bound().net_log();
2388 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2389
2390 // Since we have proxy, should try to establish tunnel.
2391 MockWrite data_writes1[] = {
2392 MockWrite(
2393 "CONNECT www.google.com:443 HTTP/1.1\r\n"
2394 "Host: www.google.com\r\n"
2395 "Proxy-Connection: keep-alive\r\n\r\n"),
2396
2397 // After calling trans->RestartWithAuth(), this is the request we should
2398 // be issuing -- the final header line contains the credentials.
2399 MockWrite(
2400 "CONNECT www.google.com:443 HTTP/1.1\r\n"
2401 "Host: www.google.com\r\n"
2402 "Proxy-Connection: keep-alive\r\n"
2403 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2404
2405 MockWrite(
2406 "GET / HTTP/1.1\r\n"
2407 "Host: www.google.com\r\n"
2408 "Connection: keep-alive\r\n\r\n"),
2409 };
2410
2411 // The proxy responds to the connect with a 407, using a persistent
2412 // connection.
2413 MockRead data_reads1[] = {
2414 // No credentials.
2415 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
2416 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
2417
2418 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
2419
2420 MockRead("HTTP/1.1 200 OK\r\n"),
2421 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2422 MockRead("Content-Length: 5\r\n\r\n"),
2423 MockRead(SYNCHRONOUS, "hello"),
2424 };
2425
2426 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2427 data_writes1, arraysize(data_writes1));
2428 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2429 SSLSocketDataProvider ssl(ASYNC, OK);
2430 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
2431
2432 TestCompletionCallback callback1;
2433
2434 scoped_ptr<HttpTransaction> trans(
2435 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2436
2437 int rv = trans->Start(&request, callback1.callback(), log.bound());
2438 EXPECT_EQ(ERR_IO_PENDING, rv);
2439
2440 rv = callback1.WaitForResult();
2441 EXPECT_EQ(OK, rv);
2442 net::CapturingNetLog::CapturedEntryList entries;
2443 log.GetEntries(&entries);
2444 size_t pos = ExpectLogContainsSomewhere(
2445 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
2446 NetLog::PHASE_NONE);
2447 ExpectLogContainsSomewhere(
2448 entries, pos, NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2449 NetLog::PHASE_NONE);
2450
2451 const HttpResponseInfo* response = trans->GetResponseInfo();
2452 ASSERT_TRUE(response != NULL);
2453 EXPECT_FALSE(response->headers->IsKeepAlive());
2454 ASSERT_FALSE(response->headers.get() == NULL);
2455 EXPECT_EQ(407, response->headers->response_code());
2456 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
2457 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2458
2459 LoadTimingInfo load_timing_info;
2460 // CONNECT requests and responses are handled at the connect job level, so
2461 // the transaction does not yet have a connection.
2462 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
2463
2464 TestCompletionCallback callback2;
2465
2466 rv =
2467 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
2468 EXPECT_EQ(ERR_IO_PENDING, rv);
2469
2470 rv = callback2.WaitForResult();
2471 EXPECT_EQ(OK, rv);
2472
2473 response = trans->GetResponseInfo();
2474 ASSERT_TRUE(response != NULL);
2475
2476 EXPECT_TRUE(response->headers->IsKeepAlive());
2477 EXPECT_EQ(200, response->headers->response_code());
2478 EXPECT_EQ(5, response->headers->GetContentLength());
2479 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2480
2481 // The password prompt info should not be set.
2482 EXPECT_TRUE(response->auth_challenge.get() == NULL);
2483
2484 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2485 TestLoadTimingNotReusedWithPac(load_timing_info,
2486 CONNECT_TIMING_HAS_SSL_TIMES);
2487
2488 trans.reset();
2489 session->CloseAllConnections();
2490}
2491
2492// Test the request-challenge-retry sequence for basic auth, over a connection
2493// that requires a restart when setting up an SSL tunnel.
2494TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) {
[email protected]394816e92010-08-03 07:38:592495 HttpRequestInfo request;
2496 request.method = "GET";
2497 request.url = GURL("https://www.google.com/");
2498 // when the no authentication data flag is set.
2499 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
2500
[email protected]cb9bf6ca2011-01-28 13:15:272501 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072502 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:202503 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
[email protected]333bdf62012-06-08 22:57:292504 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072505 session_deps_.net_log = log.bound().net_log();
2506 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272507
[email protected]394816e92010-08-03 07:38:592508 // Since we have proxy, should try to establish tunnel.
2509 MockWrite data_writes1[] = {
2510 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2511 "Host: www.google.com\r\n"
2512 "Proxy-Connection: keep-alive\r\n\r\n"),
2513
2514 // After calling trans->RestartWithAuth(), this is the request we should
2515 // be issuing -- the final header line contains the credentials.
2516 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2517 "Host: www.google.com\r\n"
2518 "Proxy-Connection: keep-alive\r\n"
2519 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2520
2521 MockWrite("GET / HTTP/1.1\r\n"
2522 "Host: www.google.com\r\n"
2523 "Connection: keep-alive\r\n\r\n"),
2524 };
2525
2526 // The proxy responds to the connect with a 407, using a persistent
2527 // connection.
2528 MockRead data_reads1[] = {
2529 // No credentials.
2530 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2531 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2532 MockRead("Proxy-Connection: close\r\n\r\n"),
2533
2534 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2535
2536 MockRead("HTTP/1.1 200 OK\r\n"),
2537 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502538 MockRead("Content-Length: 5\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062539 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:592540 };
2541
2542 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2543 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072544 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:062545 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072546 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:592547
[email protected]49639fa2011-12-20 23:22:412548 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:592549
[email protected]262eec82013-03-19 21:01:362550 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502551 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:502552
[email protected]49639fa2011-12-20 23:22:412553 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]394816e92010-08-03 07:38:592554 EXPECT_EQ(ERR_IO_PENDING, rv);
2555
2556 rv = callback1.WaitForResult();
2557 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:572558 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:402559 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:592560 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402561 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]394816e92010-08-03 07:38:592562 NetLog::PHASE_NONE);
2563 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402564 entries, pos,
[email protected]394816e92010-08-03 07:38:592565 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2566 NetLog::PHASE_NONE);
2567
2568 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502569 ASSERT_TRUE(response != NULL);
ttuttle34f63b52015-03-05 04:33:012570 EXPECT_FALSE(response->headers->IsKeepAlive());
[email protected]90499482013-06-01 00:39:502571 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]394816e92010-08-03 07:38:592572 EXPECT_EQ(407, response->headers->response_code());
2573 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042574 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:592575
[email protected]029c83b62013-01-24 05:28:202576 LoadTimingInfo load_timing_info;
2577 // CONNECT requests and responses are handled at the connect job level, so
2578 // the transaction does not yet have a connection.
2579 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
2580
[email protected]49639fa2011-12-20 23:22:412581 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:592582
[email protected]49639fa2011-12-20 23:22:412583 rv = trans->RestartWithAuth(
2584 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]394816e92010-08-03 07:38:592585 EXPECT_EQ(ERR_IO_PENDING, rv);
2586
2587 rv = callback2.WaitForResult();
2588 EXPECT_EQ(OK, rv);
2589
2590 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502591 ASSERT_TRUE(response != NULL);
[email protected]394816e92010-08-03 07:38:592592
2593 EXPECT_TRUE(response->headers->IsKeepAlive());
2594 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:502595 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:592596 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2597
2598 // The password prompt info should not be set.
2599 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502600
[email protected]029c83b62013-01-24 05:28:202601 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2602 TestLoadTimingNotReusedWithPac(load_timing_info,
2603 CONNECT_TIMING_HAS_SSL_TIMES);
2604
[email protected]0b0bf032010-09-21 18:08:502605 trans.reset();
[email protected]102e27c2011-02-23 01:01:312606 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:592607}
2608
[email protected]11203f012009-11-12 23:02:312609// Test the request-challenge-retry sequence for basic auth, over a keep-alive
ttuttle34f63b52015-03-05 04:33:012610// proxy connection with HTTP/1.0 responses, when setting up an SSL tunnel.
2611TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
2612 HttpRequestInfo request;
2613 request.method = "GET";
2614 request.url = GURL("https://www.google.com/");
2615 // Ensure that proxy authentication is attempted even
2616 // when the no authentication data flag is set.
2617 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
2618
2619 // Configure against proxy server "myproxy:70".
2620 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
2621 CapturingBoundNetLog log;
2622 session_deps_.net_log = log.bound().net_log();
2623 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2624
2625 scoped_ptr<HttpTransaction> trans(
2626 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2627
2628 // Since we have proxy, should try to establish tunnel.
2629 MockWrite data_writes1[] = {
2630 MockWrite(
2631 "CONNECT www.google.com:443 HTTP/1.1\r\n"
2632 "Host: www.google.com\r\n"
2633 "Proxy-Connection: keep-alive\r\n\r\n"),
2634
2635 // After calling trans->RestartWithAuth(), this is the request we should
2636 // be issuing -- the final header line contains the credentials.
2637 MockWrite(
2638 "CONNECT www.google.com:443 HTTP/1.1\r\n"
2639 "Host: www.google.com\r\n"
2640 "Proxy-Connection: keep-alive\r\n"
2641 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
2642 };
2643
2644 // The proxy responds to the connect with a 407, using a persistent
2645 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
2646 MockRead data_reads1[] = {
2647 // No credentials.
2648 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
2649 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2650 MockRead("Proxy-Connection: keep-alive\r\n"),
2651 MockRead("Content-Length: 10\r\n\r\n"),
2652 MockRead("0123456789"),
2653
2654 // Wrong credentials (wrong password).
2655 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
2656 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2657 MockRead("Proxy-Connection: keep-alive\r\n"),
2658 MockRead("Content-Length: 10\r\n\r\n"),
2659 // No response body because the test stops reading here.
2660 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
2661 };
2662
2663 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2664 data_writes1, arraysize(data_writes1));
2665 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2666
2667 TestCompletionCallback callback1;
2668
2669 int rv = trans->Start(&request, callback1.callback(), log.bound());
2670 EXPECT_EQ(ERR_IO_PENDING, rv);
2671
2672 rv = callback1.WaitForResult();
2673 EXPECT_EQ(OK, rv);
2674 net::CapturingNetLog::CapturedEntryList entries;
2675 log.GetEntries(&entries);
2676 size_t pos = ExpectLogContainsSomewhere(
2677 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
2678 NetLog::PHASE_NONE);
2679 ExpectLogContainsSomewhere(
2680 entries, pos, NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2681 NetLog::PHASE_NONE);
2682
2683 const HttpResponseInfo* response = trans->GetResponseInfo();
2684 ASSERT_TRUE(response);
2685 ASSERT_TRUE(response->headers);
2686 EXPECT_TRUE(response->headers->IsKeepAlive());
2687 EXPECT_EQ(407, response->headers->response_code());
2688 EXPECT_EQ(10, response->headers->GetContentLength());
2689 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
2690 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2691
2692 TestCompletionCallback callback2;
2693
2694 // Wrong password (should be "bar").
2695 rv =
2696 trans->RestartWithAuth(AuthCredentials(kFoo, kBaz), callback2.callback());
2697 EXPECT_EQ(ERR_IO_PENDING, rv);
2698
2699 rv = callback2.WaitForResult();
2700 EXPECT_EQ(OK, rv);
2701
2702 response = trans->GetResponseInfo();
2703 ASSERT_TRUE(response);
2704 ASSERT_TRUE(response->headers);
2705 EXPECT_TRUE(response->headers->IsKeepAlive());
2706 EXPECT_EQ(407, response->headers->response_code());
2707 EXPECT_EQ(10, response->headers->GetContentLength());
2708 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
2709 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2710
2711 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
2712 // out of scope.
2713 session->CloseAllConnections();
2714}
2715
2716// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2717// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel.
2718TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
[email protected]cb9bf6ca2011-01-28 13:15:272719 HttpRequestInfo request;
2720 request.method = "GET";
2721 request.url = GURL("https://www.google.com/");
2722 // Ensure that proxy authentication is attempted even
2723 // when the no authentication data flag is set.
2724 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
2725
[email protected]2d2697f92009-02-18 21:00:322726 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072727 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]333bdf62012-06-08 22:57:292728 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072729 session_deps_.net_log = log.bound().net_log();
2730 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:322731
[email protected]262eec82013-03-19 21:01:362732 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502733 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d2697f92009-02-18 21:00:322734
[email protected]2d2697f92009-02-18 21:00:322735 // Since we have proxy, should try to establish tunnel.
2736 MockWrite data_writes1[] = {
2737 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:452738 "Host: www.google.com\r\n"
2739 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322740
2741 // After calling trans->RestartWithAuth(), this is the request we should
2742 // be issuing -- the final header line contains the credentials.
2743 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2744 "Host: www.google.com\r\n"
[email protected]e44de5d2009-06-05 20:12:452745 "Proxy-Connection: keep-alive\r\n"
[email protected]2d2697f92009-02-18 21:00:322746 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
2747 };
2748
2749 // The proxy responds to the connect with a 407, using a persistent
2750 // connection.
2751 MockRead data_reads1[] = {
2752 // No credentials.
2753 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2754 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2755 MockRead("Content-Length: 10\r\n\r\n"),
2756 MockRead("0123456789"),
2757
2758 // Wrong credentials (wrong password).
2759 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2760 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2761 MockRead("Content-Length: 10\r\n\r\n"),
2762 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:062763 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]2d2697f92009-02-18 21:00:322764 };
2765
[email protected]31a2bfe2010-02-09 08:03:392766 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2767 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072768 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d2697f92009-02-18 21:00:322769
[email protected]49639fa2011-12-20 23:22:412770 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322771
[email protected]49639fa2011-12-20 23:22:412772 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]1c773ea12009-04-28 19:58:422773 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322774
2775 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422776 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:572777 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:402778 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:392779 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402780 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]dbb83db2010-05-11 18:13:392781 NetLog::PHASE_NONE);
2782 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402783 entries, pos,
[email protected]dbb83db2010-05-11 18:13:392784 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2785 NetLog::PHASE_NONE);
[email protected]2d2697f92009-02-18 21:00:322786
[email protected]1c773ea12009-04-28 19:58:422787 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:242788 ASSERT_TRUE(response);
2789 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:322790 EXPECT_TRUE(response->headers->IsKeepAlive());
2791 EXPECT_EQ(407, response->headers->response_code());
ttuttle34f63b52015-03-05 04:33:012792 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422793 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042794 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322795
[email protected]49639fa2011-12-20 23:22:412796 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322797
2798 // Wrong password (should be "bar").
[email protected]49639fa2011-12-20 23:22:412799 rv = trans->RestartWithAuth(
2800 AuthCredentials(kFoo, kBaz), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422801 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322802
2803 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422804 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322805
2806 response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:242807 ASSERT_TRUE(response);
2808 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:322809 EXPECT_TRUE(response->headers->IsKeepAlive());
2810 EXPECT_EQ(407, response->headers->response_code());
ttuttle34f63b52015-03-05 04:33:012811 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422812 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042813 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]e772db3f2010-07-12 18:11:132814
[email protected]e60e47a2010-07-14 03:37:182815 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
2816 // out of scope.
[email protected]102e27c2011-02-23 01:01:312817 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:322818}
2819
[email protected]a8e9b162009-03-12 00:06:442820// Test that we don't read the response body when we fail to establish a tunnel,
2821// even if the user cancels the proxy's auth attempt.
[email protected]23e482282013-06-14 16:08:022822TEST_P(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:272823 HttpRequestInfo request;
2824 request.method = "GET";
2825 request.url = GURL("https://www.google.com/");
2826 request.load_flags = 0;
2827
[email protected]a8e9b162009-03-12 00:06:442828 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072829 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]a8e9b162009-03-12 00:06:442830
[email protected]bb88e1d32013-05-03 23:11:072831 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:442832
[email protected]262eec82013-03-19 21:01:362833 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502834 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]a8e9b162009-03-12 00:06:442835
[email protected]a8e9b162009-03-12 00:06:442836 // Since we have proxy, should try to establish tunnel.
2837 MockWrite data_writes[] = {
2838 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:452839 "Host: www.google.com\r\n"
2840 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:442841 };
2842
2843 // The proxy responds to the connect with a 407.
2844 MockRead data_reads[] = {
ttuttle7933c112015-01-06 00:55:242845 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2846 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2847 MockRead("Content-Length: 10\r\n\r\n"),
2848 MockRead("0123456789"), // Should not be reached.
2849 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]a8e9b162009-03-12 00:06:442850 };
2851
[email protected]31a2bfe2010-02-09 08:03:392852 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2853 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072854 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:442855
[email protected]49639fa2011-12-20 23:22:412856 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:442857
[email protected]49639fa2011-12-20 23:22:412858 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422859 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a8e9b162009-03-12 00:06:442860
2861 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422862 EXPECT_EQ(OK, rv);
[email protected]a8e9b162009-03-12 00:06:442863
[email protected]1c773ea12009-04-28 19:58:422864 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:242865 ASSERT_TRUE(response);
2866 ASSERT_TRUE(response->headers);
[email protected]a8e9b162009-03-12 00:06:442867 EXPECT_TRUE(response->headers->IsKeepAlive());
2868 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:422869 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:442870
2871 std::string response_data;
2872 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:422873 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]e60e47a2010-07-14 03:37:182874
2875 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:312876 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:442877}
2878
ttuttle7933c112015-01-06 00:55:242879// Test that we don't pass extraneous headers from the proxy's response to the
2880// caller when the proxy responds to CONNECT with 407.
2881TEST_P(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
2882 HttpRequestInfo request;
2883 request.method = "GET";
2884 request.url = GURL("https://www.google.com/");
2885 request.load_flags = 0;
2886
2887 // Configure against proxy server "myproxy:70".
2888 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
2889
2890 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2891
2892 scoped_ptr<HttpTransaction> trans(
2893 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2894
2895 // Since we have proxy, should try to establish tunnel.
2896 MockWrite data_writes[] = {
2897 MockWrite(
2898 "CONNECT www.google.com:443 HTTP/1.1\r\n"
2899 "Host: www.google.com\r\n"
2900 "Proxy-Connection: keep-alive\r\n\r\n"),
2901 };
2902
2903 // The proxy responds to the connect with a 407.
2904 MockRead data_reads[] = {
2905 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2906 MockRead("X-Foo: bar\r\n"),
2907 MockRead("Set-Cookie: foo=bar\r\n"),
2908 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2909 MockRead("Content-Length: 10\r\n\r\n"),
2910 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
2911 };
2912
2913 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
2914 arraysize(data_writes));
2915 session_deps_.socket_factory->AddSocketDataProvider(&data);
2916
2917 TestCompletionCallback callback;
2918
2919 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
2920 EXPECT_EQ(ERR_IO_PENDING, rv);
2921
2922 rv = callback.WaitForResult();
2923 EXPECT_EQ(OK, rv);
2924
2925 const HttpResponseInfo* response = trans->GetResponseInfo();
2926 ASSERT_TRUE(response);
2927 ASSERT_TRUE(response->headers);
2928 EXPECT_TRUE(response->headers->IsKeepAlive());
2929 EXPECT_EQ(407, response->headers->response_code());
2930 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2931 EXPECT_FALSE(response->headers->HasHeader("X-Foo"));
2932 EXPECT_FALSE(response->headers->HasHeader("Set-Cookie"));
2933
2934 std::string response_data;
2935 rv = ReadTransaction(trans.get(), &response_data);
2936 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
2937
2938 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
2939 session->CloseAllConnections();
2940}
2941
[email protected]8fdbcd22010-05-05 02:54:522942// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
2943// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
[email protected]23e482282013-06-14 16:08:022944TEST_P(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:522945 HttpRequestInfo request;
2946 request.method = "GET";
2947 request.url = GURL("http://www.google.com/");
2948 request.load_flags = 0;
2949
[email protected]cb9bf6ca2011-01-28 13:15:272950 // We are using a DIRECT connection (i.e. no proxy) for this session.
[email protected]3fe8d2f82013-10-17 08:56:072951 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272952 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:412953 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:272954
[email protected]8fdbcd22010-05-05 02:54:522955 MockWrite data_writes1[] = {
2956 MockWrite("GET / HTTP/1.1\r\n"
2957 "Host: www.google.com\r\n"
2958 "Connection: keep-alive\r\n\r\n"),
2959 };
2960
2961 MockRead data_reads1[] = {
2962 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
2963 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2964 // Large content-length -- won't matter, as connection will be reset.
2965 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062966 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:522967 };
2968
2969 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2970 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072971 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:522972
[email protected]49639fa2011-12-20 23:22:412973 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:522974
[email protected]49639fa2011-12-20 23:22:412975 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]8fdbcd22010-05-05 02:54:522976 EXPECT_EQ(ERR_IO_PENDING, rv);
2977
2978 rv = callback.WaitForResult();
2979 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
2980}
2981
[email protected]7a67a8152010-11-05 18:31:102982// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
2983// through a non-authenticating proxy. The request should fail with
2984// ERR_UNEXPECTED_PROXY_AUTH.
2985// Note that it is impossible to detect if an HTTP server returns a 407 through
2986// a non-authenticating proxy - there is nothing to indicate whether the
2987// response came from the proxy or the server, so it is treated as if the proxy
2988// issued the challenge.
[email protected]23e482282013-06-14 16:08:022989TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:232990 HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:272991 HttpRequestInfo request;
2992 request.method = "GET";
2993 request.url = GURL("https://www.google.com/");
2994
[email protected]bb88e1d32013-05-03 23:11:072995 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]333bdf62012-06-08 22:57:292996 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072997 session_deps_.net_log = log.bound().net_log();
2998 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:102999
[email protected]7a67a8152010-11-05 18:31:103000 // Since we have proxy, should try to establish tunnel.
3001 MockWrite data_writes1[] = {
3002 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
3003 "Host: www.google.com\r\n"
3004 "Proxy-Connection: keep-alive\r\n\r\n"),
3005
3006 MockWrite("GET / HTTP/1.1\r\n"
3007 "Host: www.google.com\r\n"
3008 "Connection: keep-alive\r\n\r\n"),
3009 };
3010
3011 MockRead data_reads1[] = {
3012 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3013
3014 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
3015 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3016 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:063017 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:103018 };
3019
3020 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3021 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073022 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063023 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073024 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:103025
[email protected]49639fa2011-12-20 23:22:413026 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:103027
[email protected]262eec82013-03-19 21:01:363028 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503029 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a67a8152010-11-05 18:31:103030
[email protected]49639fa2011-12-20 23:22:413031 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7a67a8152010-11-05 18:31:103032 EXPECT_EQ(ERR_IO_PENDING, rv);
3033
3034 rv = callback1.WaitForResult();
3035 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
[email protected]f3da152d2012-06-02 01:00:573036 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:403037 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:103038 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403039 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]7a67a8152010-11-05 18:31:103040 NetLog::PHASE_NONE);
3041 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403042 entries, pos,
[email protected]7a67a8152010-11-05 18:31:103043 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3044 NetLog::PHASE_NONE);
3045}
[email protected]2df19bb2010-08-25 20:13:463046
[email protected]029c83b62013-01-24 05:28:203047// Test the load timing for HTTPS requests with an HTTP proxy.
[email protected]23e482282013-06-14 16:08:023048TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:203049 HttpRequestInfo request1;
3050 request1.method = "GET";
3051 request1.url = GURL("https://www.google.com/1");
3052
3053 HttpRequestInfo request2;
3054 request2.method = "GET";
3055 request2.url = GURL("https://www.google.com/2");
3056
3057 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073058 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:203059 ProxyService::CreateFixed("PROXY myproxy:70"));
3060 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073061 session_deps_.net_log = log.bound().net_log();
3062 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:203063
3064 // Since we have proxy, should try to establish tunnel.
3065 MockWrite data_writes1[] = {
3066 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
3067 "Host: www.google.com\r\n"
3068 "Proxy-Connection: keep-alive\r\n\r\n"),
3069
3070 MockWrite("GET /1 HTTP/1.1\r\n"
3071 "Host: www.google.com\r\n"
3072 "Connection: keep-alive\r\n\r\n"),
3073
3074 MockWrite("GET /2 HTTP/1.1\r\n"
3075 "Host: www.google.com\r\n"
3076 "Connection: keep-alive\r\n\r\n"),
3077 };
3078
3079 // The proxy responds to the connect with a 407, using a persistent
3080 // connection.
3081 MockRead data_reads1[] = {
3082 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3083
3084 MockRead("HTTP/1.1 200 OK\r\n"),
3085 MockRead("Content-Length: 1\r\n\r\n"),
3086 MockRead(SYNCHRONOUS, "1"),
3087
3088 MockRead("HTTP/1.1 200 OK\r\n"),
3089 MockRead("Content-Length: 2\r\n\r\n"),
3090 MockRead(SYNCHRONOUS, "22"),
3091 };
3092
3093 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3094 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073095 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:203096 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073097 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:203098
3099 TestCompletionCallback callback1;
[email protected]262eec82013-03-19 21:01:363100 scoped_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:503101 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:203102
3103 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
3104 EXPECT_EQ(ERR_IO_PENDING, rv);
3105
3106 rv = callback1.WaitForResult();
3107 EXPECT_EQ(OK, rv);
3108
3109 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
3110 ASSERT_TRUE(response1 != NULL);
[email protected]90499482013-06-01 00:39:503111 ASSERT_TRUE(response1->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:203112 EXPECT_EQ(1, response1->headers->GetContentLength());
3113
3114 LoadTimingInfo load_timing_info1;
3115 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
3116 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
3117
3118 trans1.reset();
3119
3120 TestCompletionCallback callback2;
[email protected]262eec82013-03-19 21:01:363121 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503122 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:203123
3124 rv = trans2->Start(&request2, callback2.callback(), log.bound());
3125 EXPECT_EQ(ERR_IO_PENDING, rv);
3126
3127 rv = callback2.WaitForResult();
3128 EXPECT_EQ(OK, rv);
3129
3130 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
3131 ASSERT_TRUE(response2 != NULL);
[email protected]90499482013-06-01 00:39:503132 ASSERT_TRUE(response2->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:203133 EXPECT_EQ(2, response2->headers->GetContentLength());
3134
3135 LoadTimingInfo load_timing_info2;
3136 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3137 TestLoadTimingReused(load_timing_info2);
3138
3139 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
3140
3141 trans2.reset();
3142 session->CloseAllConnections();
3143}
3144
3145// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
[email protected]23e482282013-06-14 16:08:023146TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:203147 HttpRequestInfo request1;
3148 request1.method = "GET";
3149 request1.url = GURL("https://www.google.com/1");
3150
3151 HttpRequestInfo request2;
3152 request2.method = "GET";
3153 request2.url = GURL("https://www.google.com/2");
3154
3155 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073156 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:203157 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
3158 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073159 session_deps_.net_log = log.bound().net_log();
3160 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:203161
3162 // Since we have proxy, should try to establish tunnel.
3163 MockWrite data_writes1[] = {
3164 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
3165 "Host: www.google.com\r\n"
3166 "Proxy-Connection: keep-alive\r\n\r\n"),
3167
3168 MockWrite("GET /1 HTTP/1.1\r\n"
3169 "Host: www.google.com\r\n"
3170 "Connection: keep-alive\r\n\r\n"),
3171
3172 MockWrite("GET /2 HTTP/1.1\r\n"
3173 "Host: www.google.com\r\n"
3174 "Connection: keep-alive\r\n\r\n"),
3175 };
3176
3177 // The proxy responds to the connect with a 407, using a persistent
3178 // connection.
3179 MockRead data_reads1[] = {
3180 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3181
3182 MockRead("HTTP/1.1 200 OK\r\n"),
3183 MockRead("Content-Length: 1\r\n\r\n"),
3184 MockRead(SYNCHRONOUS, "1"),
3185
3186 MockRead("HTTP/1.1 200 OK\r\n"),
3187 MockRead("Content-Length: 2\r\n\r\n"),
3188 MockRead(SYNCHRONOUS, "22"),
3189 };
3190
3191 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3192 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073193 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:203194 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073195 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:203196
3197 TestCompletionCallback callback1;
[email protected]262eec82013-03-19 21:01:363198 scoped_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:503199 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:203200
3201 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
3202 EXPECT_EQ(ERR_IO_PENDING, rv);
3203
3204 rv = callback1.WaitForResult();
3205 EXPECT_EQ(OK, rv);
3206
3207 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
3208 ASSERT_TRUE(response1 != NULL);
[email protected]90499482013-06-01 00:39:503209 ASSERT_TRUE(response1->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:203210 EXPECT_EQ(1, response1->headers->GetContentLength());
3211
3212 LoadTimingInfo load_timing_info1;
3213 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
3214 TestLoadTimingNotReusedWithPac(load_timing_info1,
3215 CONNECT_TIMING_HAS_SSL_TIMES);
3216
3217 trans1.reset();
3218
3219 TestCompletionCallback callback2;
[email protected]262eec82013-03-19 21:01:363220 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503221 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:203222
3223 rv = trans2->Start(&request2, callback2.callback(), log.bound());
3224 EXPECT_EQ(ERR_IO_PENDING, rv);
3225
3226 rv = callback2.WaitForResult();
3227 EXPECT_EQ(OK, rv);
3228
3229 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
3230 ASSERT_TRUE(response2 != NULL);
[email protected]90499482013-06-01 00:39:503231 ASSERT_TRUE(response2->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:203232 EXPECT_EQ(2, response2->headers->GetContentLength());
3233
3234 LoadTimingInfo load_timing_info2;
3235 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3236 TestLoadTimingReusedWithPac(load_timing_info2);
3237
3238 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
3239
3240 trans2.reset();
3241 session->CloseAllConnections();
3242}
3243
[email protected]2df19bb2010-08-25 20:13:463244// Test a simple get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023245TEST_P(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:273246 HttpRequestInfo request;
3247 request.method = "GET";
3248 request.url = GURL("http://www.google.com/");
3249
[email protected]2df19bb2010-08-25 20:13:463250 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073251 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113252 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:293253 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073254 session_deps_.net_log = log.bound().net_log();
3255 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:463256
[email protected]2df19bb2010-08-25 20:13:463257 // Since we have proxy, should use full url
3258 MockWrite data_writes1[] = {
3259 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
3260 "Host: www.google.com\r\n"
3261 "Proxy-Connection: keep-alive\r\n\r\n"),
3262 };
3263
3264 MockRead data_reads1[] = {
3265 MockRead("HTTP/1.1 200 OK\r\n"),
3266 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3267 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063268 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:463269 };
3270
3271 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3272 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073273 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063274 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073275 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:463276
[email protected]49639fa2011-12-20 23:22:413277 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:463278
[email protected]262eec82013-03-19 21:01:363279 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503280 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503281
[email protected]49639fa2011-12-20 23:22:413282 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:463283 EXPECT_EQ(ERR_IO_PENDING, rv);
3284
3285 rv = callback1.WaitForResult();
3286 EXPECT_EQ(OK, rv);
3287
[email protected]58e32bb2013-01-21 18:23:253288 LoadTimingInfo load_timing_info;
3289 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3290 TestLoadTimingNotReused(load_timing_info,
3291 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3292
[email protected]2df19bb2010-08-25 20:13:463293 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503294 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:463295
3296 EXPECT_TRUE(response->headers->IsKeepAlive());
3297 EXPECT_EQ(200, response->headers->response_code());
3298 EXPECT_EQ(100, response->headers->GetContentLength());
3299 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3300
3301 // The password prompt info should not be set.
3302 EXPECT_TRUE(response->auth_challenge.get() == NULL);
3303}
3304
[email protected]7642b5ae2010-09-01 20:55:173305// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023306TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:273307 HttpRequestInfo request;
3308 request.method = "GET";
3309 request.url = GURL("http://www.google.com/");
3310 request.load_flags = 0;
3311
[email protected]7642b5ae2010-09-01 20:55:173312 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073313 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113314 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:293315 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073316 session_deps_.net_log = log.bound().net_log();
3317 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:173318
[email protected]7642b5ae2010-09-01 20:55:173319 // fetch http://www.google.com/ via SPDY
[email protected]cdf8f7e72013-05-23 10:56:463320 scoped_ptr<SpdyFrame> req(
3321 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]7642b5ae2010-09-01 20:55:173322 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
3323
[email protected]23e482282013-06-14 16:08:023324 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3325 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:173326 MockRead spdy_reads[] = {
3327 CreateMockRead(*resp),
3328 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:063329 MockRead(ASYNC, 0, 0),
[email protected]7642b5ae2010-09-01 20:55:173330 };
3331
[email protected]dd54bd82012-07-19 23:44:573332 DelayedSocketData spdy_data(
3333 1, // wait for one write to finish before reading.
3334 spdy_reads, arraysize(spdy_reads),
3335 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073336 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:173337
[email protected]8ddf8322012-02-23 18:08:063338 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023339 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073340 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:173341
[email protected]49639fa2011-12-20 23:22:413342 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:173343
[email protected]262eec82013-03-19 21:01:363344 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503345 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503346
[email protected]49639fa2011-12-20 23:22:413347 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7642b5ae2010-09-01 20:55:173348 EXPECT_EQ(ERR_IO_PENDING, rv);
3349
3350 rv = callback1.WaitForResult();
3351 EXPECT_EQ(OK, rv);
3352
[email protected]58e32bb2013-01-21 18:23:253353 LoadTimingInfo load_timing_info;
3354 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3355 TestLoadTimingNotReused(load_timing_info,
3356 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3357
[email protected]7642b5ae2010-09-01 20:55:173358 const HttpResponseInfo* response = trans->GetResponseInfo();
3359 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503360 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]7642b5ae2010-09-01 20:55:173361 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3362
3363 std::string response_data;
3364 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:233365 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:173366}
3367
[email protected]1c173852014-06-19 12:51:503368// Verifies that a session which races and wins against the owning transaction
3369// (completing prior to host resolution), doesn't fail the transaction.
3370// Regression test for crbug.com/334413.
3371TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
3372 HttpRequestInfo request;
3373 request.method = "GET";
3374 request.url = GURL("http://www.google.com/");
3375 request.load_flags = 0;
3376
3377 // Configure SPDY proxy server "proxy:70".
3378 session_deps_.proxy_service.reset(
3379 ProxyService::CreateFixed("https://proxy:70"));
3380 CapturingBoundNetLog log;
3381 session_deps_.net_log = log.bound().net_log();
3382 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3383
3384 // Fetch http://www.google.com/ through the SPDY proxy.
3385 scoped_ptr<SpdyFrame> req(
3386 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
3387 MockWrite spdy_writes[] = {CreateMockWrite(*req)};
3388
3389 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3390 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
3391 MockRead spdy_reads[] = {
3392 CreateMockRead(*resp), CreateMockRead(*data), MockRead(ASYNC, 0, 0),
3393 };
3394
3395 DelayedSocketData spdy_data(
3396 1, // wait for one write to finish before reading.
3397 spdy_reads,
3398 arraysize(spdy_reads),
3399 spdy_writes,
3400 arraysize(spdy_writes));
3401 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
3402
3403 SSLSocketDataProvider ssl(ASYNC, OK);
3404 ssl.SetNextProto(GetParam());
3405 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3406
3407 TestCompletionCallback callback1;
3408
3409 scoped_ptr<HttpTransaction> trans(
3410 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3411
3412 // Stall the hostname resolution begun by the transaction.
3413 session_deps_.host_resolver->set_synchronous_mode(false);
3414 session_deps_.host_resolver->set_ondemand_mode(true);
3415
3416 int rv = trans->Start(&request, callback1.callback(), log.bound());
3417 EXPECT_EQ(ERR_IO_PENDING, rv);
3418
3419 // Race a session to the proxy, which completes first.
3420 session_deps_.host_resolver->set_ondemand_mode(false);
3421 SpdySessionKey key(
3422 HostPortPair("proxy", 70), ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
3423 base::WeakPtr<SpdySession> spdy_session =
3424 CreateSecureSpdySession(session, key, log.bound());
3425
3426 // Unstall the resolution begun by the transaction.
3427 session_deps_.host_resolver->set_ondemand_mode(true);
3428 session_deps_.host_resolver->ResolveAllPending();
3429
3430 EXPECT_FALSE(callback1.have_result());
3431 rv = callback1.WaitForResult();
3432 EXPECT_EQ(OK, rv);
3433
3434 const HttpResponseInfo* response = trans->GetResponseInfo();
3435 ASSERT_TRUE(response != NULL);
3436 ASSERT_TRUE(response->headers.get() != NULL);
3437 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3438
3439 std::string response_data;
3440 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
3441 EXPECT_EQ(kUploadData, response_data);
3442}
3443
[email protected]dc7bd1c52010-11-12 00:01:133444// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023445TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:273446 HttpRequestInfo request;
3447 request.method = "GET";
3448 request.url = GURL("http://www.google.com/");
3449 request.load_flags = 0;
3450
[email protected]79cb5c12011-09-12 13:12:043451 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073452 session_deps_.proxy_service.reset(
[email protected]79cb5c12011-09-12 13:12:043453 ProxyService::CreateFixed("https://myproxy:70"));
[email protected]333bdf62012-06-08 22:57:293454 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073455 session_deps_.net_log = log.bound().net_log();
3456 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:133457
[email protected]dc7bd1c52010-11-12 00:01:133458 // The first request will be a bare GET, the second request will be a
3459 // GET with a Proxy-Authorization header.
[email protected]ff98d7f02012-03-22 21:44:193460 scoped_ptr<SpdyFrame> req_get(
[email protected]cdf8f7e72013-05-23 10:56:463461 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]dc7bd1c52010-11-12 00:01:133462 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:463463 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:133464 };
[email protected]ff98d7f02012-03-22 21:44:193465 scoped_ptr<SpdyFrame> req_get_authorization(
[email protected]cdf8f7e72013-05-23 10:56:463466 spdy_util_.ConstructSpdyGet(kExtraAuthorizationHeaders,
3467 arraysize(kExtraAuthorizationHeaders) / 2,
3468 false,
3469 3,
3470 LOWEST,
3471 false));
[email protected]dc7bd1c52010-11-12 00:01:133472 MockWrite spdy_writes[] = {
3473 CreateMockWrite(*req_get, 1),
3474 CreateMockWrite(*req_get_authorization, 4),
3475 };
3476
3477 // The first response is a 407 proxy authentication challenge, and the second
3478 // response will be a 200 response since the second request includes a valid
3479 // Authorization header.
3480 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:463481 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:133482 };
[email protected]ff98d7f02012-03-22 21:44:193483 scoped_ptr<SpdyFrame> resp_authentication(
[email protected]23e482282013-06-14 16:08:023484 spdy_util_.ConstructSpdySynReplyError(
[email protected]dc7bd1c52010-11-12 00:01:133485 "407 Proxy Authentication Required",
3486 kExtraAuthenticationHeaders, arraysize(kExtraAuthenticationHeaders)/2,
3487 1));
[email protected]ff98d7f02012-03-22 21:44:193488 scoped_ptr<SpdyFrame> body_authentication(
[email protected]23e482282013-06-14 16:08:023489 spdy_util_.ConstructSpdyBodyFrame(1, true));
3490 scoped_ptr<SpdyFrame> resp_data(
3491 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
3492 scoped_ptr<SpdyFrame> body_data(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:133493 MockRead spdy_reads[] = {
3494 CreateMockRead(*resp_authentication, 2),
3495 CreateMockRead(*body_authentication, 3),
3496 CreateMockRead(*resp_data, 5),
3497 CreateMockRead(*body_data, 6),
[email protected]8ddf8322012-02-23 18:08:063498 MockRead(ASYNC, 0, 7),
[email protected]dc7bd1c52010-11-12 00:01:133499 };
3500
[email protected]dd54bd82012-07-19 23:44:573501 OrderedSocketData data(
3502 spdy_reads, arraysize(spdy_reads),
3503 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073504 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:133505
[email protected]8ddf8322012-02-23 18:08:063506 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023507 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073508 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:133509
[email protected]49639fa2011-12-20 23:22:413510 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:133511
[email protected]262eec82013-03-19 21:01:363512 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503513 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]dc7bd1c52010-11-12 00:01:133514
[email protected]49639fa2011-12-20 23:22:413515 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]dc7bd1c52010-11-12 00:01:133516 EXPECT_EQ(ERR_IO_PENDING, rv);
3517
3518 rv = callback1.WaitForResult();
3519 EXPECT_EQ(OK, rv);
3520
3521 const HttpResponseInfo* const response = trans->GetResponseInfo();
3522
3523 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503524 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]dc7bd1c52010-11-12 00:01:133525 EXPECT_EQ(407, response->headers->response_code());
3526 EXPECT_TRUE(response->was_fetched_via_spdy);
[email protected]79cb5c12011-09-12 13:12:043527 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:133528
[email protected]49639fa2011-12-20 23:22:413529 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:133530
[email protected]49639fa2011-12-20 23:22:413531 rv = trans->RestartWithAuth(
3532 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]dc7bd1c52010-11-12 00:01:133533 EXPECT_EQ(ERR_IO_PENDING, rv);
3534
3535 rv = callback2.WaitForResult();
3536 EXPECT_EQ(OK, rv);
3537
3538 const HttpResponseInfo* const response_restart = trans->GetResponseInfo();
3539
3540 ASSERT_TRUE(response_restart != NULL);
[email protected]90499482013-06-01 00:39:503541 ASSERT_TRUE(response_restart->headers.get() != NULL);
[email protected]dc7bd1c52010-11-12 00:01:133542 EXPECT_EQ(200, response_restart->headers->response_code());
3543 // The password prompt info should not be set.
3544 EXPECT_TRUE(response_restart->auth_challenge.get() == NULL);
3545}
3546
[email protected]d9da5fe2010-10-13 22:37:163547// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
[email protected]23e482282013-06-14 16:08:023548TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:273549 HttpRequestInfo request;
3550 request.method = "GET";
3551 request.url = GURL("https://www.google.com/");
3552 request.load_flags = 0;
3553
[email protected]d9da5fe2010-10-13 22:37:163554 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073555 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113556 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:293557 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073558 session_deps_.net_log = log.bound().net_log();
3559 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:163560
[email protected]262eec82013-03-19 21:01:363561 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503562 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:163563
[email protected]d9da5fe2010-10-13 22:37:163564 // CONNECT to www.google.com:443 via SPDY
lgarrona91df87f2014-12-05 00:51:343565 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(
3566 NULL, 0, 1, LOWEST, HostPortPair("www.google.com", 443)));
[email protected]d9da5fe2010-10-13 22:37:163567 // fetch https://www.google.com/ via HTTP
3568
3569 const char get[] = "GET / HTTP/1.1\r\n"
3570 "Host: www.google.com\r\n"
3571 "Connection: keep-alive\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:193572 scoped_ptr<SpdyFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:023573 spdy_util_.ConstructSpdyBodyFrame(1, get, strlen(get), false));
3574 scoped_ptr<SpdyFrame> conn_resp(
3575 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:163576 const char resp[] = "HTTP/1.1 200 OK\r\n"
3577 "Content-Length: 10\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:193578 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:023579 spdy_util_.ConstructSpdyBodyFrame(1, resp, strlen(resp), false));
[email protected]ff98d7f02012-03-22 21:44:193580 scoped_ptr<SpdyFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:023581 spdy_util_.ConstructSpdyBodyFrame(1, "1234567890", 10, false));
[email protected]ff98d7f02012-03-22 21:44:193582 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203583 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
[email protected]8d2f7012012-02-16 00:08:043584
3585 MockWrite spdy_writes[] = {
3586 CreateMockWrite(*connect, 1),
3587 CreateMockWrite(*wrapped_get, 3),
[email protected]cdf8f7e72013-05-23 10:56:463588 CreateMockWrite(*window_update, 5),
[email protected]8d2f7012012-02-16 00:08:043589 };
3590
[email protected]d9da5fe2010-10-13 22:37:163591 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:063592 CreateMockRead(*conn_resp, 2, ASYNC),
3593 CreateMockRead(*wrapped_get_resp, 4, ASYNC),
3594 CreateMockRead(*wrapped_body, 6, ASYNC),
3595 CreateMockRead(*wrapped_body, 7, ASYNC),
3596 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:163597 };
3598
[email protected]dd54bd82012-07-19 23:44:573599 OrderedSocketData spdy_data(
3600 spdy_reads, arraysize(spdy_reads),
3601 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073602 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163603
[email protected]8ddf8322012-02-23 18:08:063604 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023605 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073606 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063607 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]d9da5fe2010-10-13 22:37:163608 ssl2.was_npn_negotiated = false;
[email protected]8e3c78cb2012-03-31 03:58:463609 ssl2.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:073610 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163611
[email protected]49639fa2011-12-20 23:22:413612 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163613
[email protected]49639fa2011-12-20 23:22:413614 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163615 EXPECT_EQ(ERR_IO_PENDING, rv);
3616
3617 rv = callback1.WaitForResult();
3618 EXPECT_EQ(OK, rv);
3619
[email protected]58e32bb2013-01-21 18:23:253620 LoadTimingInfo load_timing_info;
3621 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3622 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3623
[email protected]d9da5fe2010-10-13 22:37:163624 const HttpResponseInfo* response = trans->GetResponseInfo();
3625 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503626 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d9da5fe2010-10-13 22:37:163627 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3628
3629 std::string response_data;
3630 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
3631 EXPECT_EQ("1234567890", response_data);
3632}
3633
3634// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
[email protected]23e482282013-06-14 16:08:023635TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
[email protected]cb9bf6ca2011-01-28 13:15:273636 HttpRequestInfo request;
3637 request.method = "GET";
3638 request.url = GURL("https://www.google.com/");
3639 request.load_flags = 0;
3640
[email protected]d9da5fe2010-10-13 22:37:163641 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073642 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113643 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:293644 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073645 session_deps_.net_log = log.bound().net_log();
3646 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:163647
[email protected]262eec82013-03-19 21:01:363648 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503649 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:163650
[email protected]d9da5fe2010-10-13 22:37:163651 // CONNECT to www.google.com:443 via SPDY
lgarrona91df87f2014-12-05 00:51:343652 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(
3653 NULL, 0, 1, LOWEST, HostPortPair("www.google.com", 443)));
[email protected]d9da5fe2010-10-13 22:37:163654 // fetch https://www.google.com/ via SPDY
thestig9d3bb0c2015-01-24 00:49:513655 const char kMyUrl[] = "https://www.google.com/";
[email protected]cdf8f7e72013-05-23 10:56:463656 scoped_ptr<SpdyFrame> get(
3657 spdy_util_.ConstructSpdyGet(kMyUrl, false, 1, LOWEST));
[email protected]23e482282013-06-14 16:08:023658 scoped_ptr<SpdyFrame> wrapped_get(
3659 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
3660 scoped_ptr<SpdyFrame> conn_resp(
3661 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3662 scoped_ptr<SpdyFrame> get_resp(
3663 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]ff98d7f02012-03-22 21:44:193664 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:023665 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
3666 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
3667 scoped_ptr<SpdyFrame> wrapped_body(
3668 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
[email protected]ff98d7f02012-03-22 21:44:193669 scoped_ptr<SpdyFrame> window_update_get_resp(
[email protected]c10b20852013-05-15 21:29:203670 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
[email protected]ff98d7f02012-03-22 21:44:193671 scoped_ptr<SpdyFrame> window_update_body(
[email protected]c10b20852013-05-15 21:29:203672 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body->size()));
[email protected]8d2f7012012-02-16 00:08:043673
3674 MockWrite spdy_writes[] = {
3675 CreateMockWrite(*connect, 1),
3676 CreateMockWrite(*wrapped_get, 3),
3677 CreateMockWrite(*window_update_get_resp, 5),
3678 CreateMockWrite(*window_update_body, 7),
3679 };
3680
[email protected]d9da5fe2010-10-13 22:37:163681 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:063682 CreateMockRead(*conn_resp, 2, ASYNC),
3683 CreateMockRead(*wrapped_get_resp, 4, ASYNC),
3684 CreateMockRead(*wrapped_body, 6, ASYNC),
3685 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:163686 };
3687
[email protected]dd54bd82012-07-19 23:44:573688 OrderedSocketData spdy_data(
3689 spdy_reads, arraysize(spdy_reads),
3690 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073691 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163692
[email protected]8ddf8322012-02-23 18:08:063693 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023694 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073695 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063696 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023697 ssl2.SetNextProto(GetParam());
3698 ssl2.protocol_negotiated = GetParam();
[email protected]bb88e1d32013-05-03 23:11:073699 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163700
[email protected]49639fa2011-12-20 23:22:413701 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163702
[email protected]49639fa2011-12-20 23:22:413703 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163704 EXPECT_EQ(ERR_IO_PENDING, rv);
3705
3706 rv = callback1.WaitForResult();
3707 EXPECT_EQ(OK, rv);
3708
[email protected]58e32bb2013-01-21 18:23:253709 LoadTimingInfo load_timing_info;
3710 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3711 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3712
[email protected]d9da5fe2010-10-13 22:37:163713 const HttpResponseInfo* response = trans->GetResponseInfo();
3714 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503715 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d9da5fe2010-10-13 22:37:163716 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3717
3718 std::string response_data;
3719 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:233720 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:163721}
3722
3723// Test a SPDY CONNECT failure through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023724TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:273725 HttpRequestInfo request;
3726 request.method = "GET";
3727 request.url = GURL("https://www.google.com/");
3728 request.load_flags = 0;
3729
[email protected]d9da5fe2010-10-13 22:37:163730 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073731 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113732 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:293733 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073734 session_deps_.net_log = log.bound().net_log();
3735 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:163736
[email protected]262eec82013-03-19 21:01:363737 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503738 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:163739
[email protected]d9da5fe2010-10-13 22:37:163740 // CONNECT to www.google.com:443 via SPDY
lgarrona91df87f2014-12-05 00:51:343741 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(
3742 NULL, 0, 1, LOWEST, HostPortPair("www.google.com", 443)));
[email protected]c10b20852013-05-15 21:29:203743 scoped_ptr<SpdyFrame> get(
3744 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:163745
3746 MockWrite spdy_writes[] = {
3747 CreateMockWrite(*connect, 1),
3748 CreateMockWrite(*get, 3),
3749 };
3750
[email protected]23e482282013-06-14 16:08:023751 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdySynReplyError(1));
3752 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:163753 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:063754 CreateMockRead(*resp, 2, ASYNC),
3755 MockRead(ASYNC, 0, 4),
[email protected]d9da5fe2010-10-13 22:37:163756 };
3757
[email protected]dd54bd82012-07-19 23:44:573758 OrderedSocketData spdy_data(
3759 spdy_reads, arraysize(spdy_reads),
3760 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073761 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163762
[email protected]8ddf8322012-02-23 18:08:063763 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023764 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073765 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063766 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023767 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073768 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163769
[email protected]49639fa2011-12-20 23:22:413770 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163771
[email protected]49639fa2011-12-20 23:22:413772 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163773 EXPECT_EQ(ERR_IO_PENDING, rv);
3774
3775 rv = callback1.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:173776 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]d9da5fe2010-10-13 22:37:163777
[email protected]4eddbc732012-08-09 05:40:173778 // TODO(ttuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:163779}
3780
[email protected]f6c63db52013-02-02 00:35:223781// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
3782// HTTPS Proxy to different servers.
[email protected]23e482282013-06-14 16:08:023783TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:223784 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
3785 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073786 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:223787 "https://proxy:70"));
3788 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073789 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:223790 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:073791 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:223792
3793 HttpRequestInfo request1;
3794 request1.method = "GET";
3795 request1.url = GURL("https://www.google.com/");
3796 request1.load_flags = 0;
3797
3798 HttpRequestInfo request2;
3799 request2.method = "GET";
3800 request2.url = GURL("https://news.google.com/");
3801 request2.load_flags = 0;
3802
3803 // CONNECT to www.google.com:443 via SPDY.
lgarrona91df87f2014-12-05 00:51:343804 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(
3805 NULL, 0, 1, LOWEST, HostPortPair("www.google.com", 443)));
[email protected]23e482282013-06-14 16:08:023806 scoped_ptr<SpdyFrame> conn_resp1(
3807 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:223808
3809 // Fetch https://www.google.com/ via HTTP.
3810 const char get1[] = "GET / HTTP/1.1\r\n"
3811 "Host: www.google.com\r\n"
3812 "Connection: keep-alive\r\n\r\n";
3813 scoped_ptr<SpdyFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:023814 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:223815 const char resp1[] = "HTTP/1.1 200 OK\r\n"
3816 "Content-Length: 1\r\n\r\n";
3817 scoped_ptr<SpdyFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:023818 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
3819 scoped_ptr<SpdyFrame> wrapped_body1(
3820 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
[email protected]f6c63db52013-02-02 00:35:223821 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203822 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:223823
3824 // CONNECT to news.google.com:443 via SPDY.
[email protected]745aa9c2014-06-27 02:21:293825 SpdyHeaderBlock connect2_block;
3826 connect2_block[spdy_util_.GetMethodKey()] = "CONNECT";
3827 connect2_block[spdy_util_.GetPathKey()] = "news.google.com:443";
3828 connect2_block[spdy_util_.GetHostKey()] = "news.google.com";
3829 spdy_util_.MaybeAddVersionHeader(&connect2_block);
[email protected]f6c63db52013-02-02 00:35:223830 scoped_ptr<SpdyFrame> connect2(
[email protected]745aa9c2014-06-27 02:21:293831 spdy_util_.ConstructSpdySyn(3, connect2_block, LOWEST, false, false));
[email protected]601e03f12014-04-06 16:26:393832
[email protected]23e482282013-06-14 16:08:023833 scoped_ptr<SpdyFrame> conn_resp2(
3834 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:223835
3836 // Fetch https://news.google.com/ via HTTP.
3837 const char get2[] = "GET / HTTP/1.1\r\n"
3838 "Host: news.google.com\r\n"
3839 "Connection: keep-alive\r\n\r\n";
3840 scoped_ptr<SpdyFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:023841 spdy_util_.ConstructSpdyBodyFrame(3, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:223842 const char resp2[] = "HTTP/1.1 200 OK\r\n"
3843 "Content-Length: 2\r\n\r\n";
3844 scoped_ptr<SpdyFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:023845 spdy_util_.ConstructSpdyBodyFrame(3, resp2, strlen(resp2), false));
[email protected]f6c63db52013-02-02 00:35:223846 scoped_ptr<SpdyFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:023847 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:223848
3849 MockWrite spdy_writes[] = {
3850 CreateMockWrite(*connect1, 0),
3851 CreateMockWrite(*wrapped_get1, 2),
3852 CreateMockWrite(*connect2, 5),
3853 CreateMockWrite(*wrapped_get2, 7),
3854 };
3855
3856 MockRead spdy_reads[] = {
3857 CreateMockRead(*conn_resp1, 1, ASYNC),
3858 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
3859 CreateMockRead(*wrapped_body1, 4, ASYNC),
3860 CreateMockRead(*conn_resp2, 6, ASYNC),
3861 CreateMockRead(*wrapped_get_resp2, 8, ASYNC),
3862 CreateMockRead(*wrapped_body2, 9, ASYNC),
3863 MockRead(ASYNC, 0, 10),
3864 };
3865
3866 DeterministicSocketData spdy_data(
3867 spdy_reads, arraysize(spdy_reads),
3868 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073869 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:223870
3871 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023872 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073873 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:223874 SSLSocketDataProvider ssl2(ASYNC, OK);
3875 ssl2.was_npn_negotiated = false;
3876 ssl2.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:073877 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:223878 SSLSocketDataProvider ssl3(ASYNC, OK);
3879 ssl3.was_npn_negotiated = false;
3880 ssl3.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:073881 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:223882
3883 TestCompletionCallback callback;
3884
[email protected]262eec82013-03-19 21:01:363885 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503886 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223887 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
3888 EXPECT_EQ(ERR_IO_PENDING, rv);
3889 // The first connect and request, each of their responses, and the body.
3890 spdy_data.RunFor(5);
3891
3892 rv = callback.WaitForResult();
3893 EXPECT_EQ(OK, rv);
3894
3895 LoadTimingInfo load_timing_info;
3896 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3897 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3898
3899 const HttpResponseInfo* response = trans->GetResponseInfo();
3900 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503901 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:223902 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3903
3904 std::string response_data;
3905 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
[email protected]90499482013-06-01 00:39:503906 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223907
[email protected]262eec82013-03-19 21:01:363908 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503909 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223910 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
3911 EXPECT_EQ(ERR_IO_PENDING, rv);
3912
3913 // The second connect and request, each of their responses, and the body.
3914 spdy_data.RunFor(5);
3915 rv = callback.WaitForResult();
3916 EXPECT_EQ(OK, rv);
3917
3918 LoadTimingInfo load_timing_info2;
3919 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3920 // Even though the SPDY connection is reused, a new tunnelled connection has
3921 // to be created, so the socket's load timing looks like a fresh connection.
3922 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
3923
3924 // The requests should have different IDs, since they each are using their own
3925 // separate stream.
3926 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
3927
[email protected]90499482013-06-01 00:39:503928 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223929}
3930
3931// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
3932// HTTPS Proxy to the same server.
[email protected]23e482282013-06-14 16:08:023933TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:223934 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
3935 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073936 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:223937 "https://proxy:70"));
3938 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073939 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:223940 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:073941 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:223942
3943 HttpRequestInfo request1;
3944 request1.method = "GET";
3945 request1.url = GURL("https://www.google.com/");
3946 request1.load_flags = 0;
3947
3948 HttpRequestInfo request2;
3949 request2.method = "GET";
3950 request2.url = GURL("https://www.google.com/2");
3951 request2.load_flags = 0;
3952
3953 // CONNECT to www.google.com:443 via SPDY.
lgarrona91df87f2014-12-05 00:51:343954 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(
3955 NULL, 0, 1, LOWEST, HostPortPair("www.google.com", 443)));
[email protected]23e482282013-06-14 16:08:023956 scoped_ptr<SpdyFrame> conn_resp1(
3957 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:223958
3959 // Fetch https://www.google.com/ via HTTP.
3960 const char get1[] = "GET / HTTP/1.1\r\n"
3961 "Host: www.google.com\r\n"
3962 "Connection: keep-alive\r\n\r\n";
3963 scoped_ptr<SpdyFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:023964 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:223965 const char resp1[] = "HTTP/1.1 200 OK\r\n"
3966 "Content-Length: 1\r\n\r\n";
3967 scoped_ptr<SpdyFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:023968 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
3969 scoped_ptr<SpdyFrame> wrapped_body1(
3970 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
[email protected]f6c63db52013-02-02 00:35:223971 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203972 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:223973
3974 // Fetch https://www.google.com/2 via HTTP.
3975 const char get2[] = "GET /2 HTTP/1.1\r\n"
3976 "Host: www.google.com\r\n"
3977 "Connection: keep-alive\r\n\r\n";
3978 scoped_ptr<SpdyFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:023979 spdy_util_.ConstructSpdyBodyFrame(1, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:223980 const char resp2[] = "HTTP/1.1 200 OK\r\n"
3981 "Content-Length: 2\r\n\r\n";
3982 scoped_ptr<SpdyFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:023983 spdy_util_.ConstructSpdyBodyFrame(1, resp2, strlen(resp2), false));
[email protected]f6c63db52013-02-02 00:35:223984 scoped_ptr<SpdyFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:023985 spdy_util_.ConstructSpdyBodyFrame(1, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:223986
3987 MockWrite spdy_writes[] = {
3988 CreateMockWrite(*connect1, 0),
3989 CreateMockWrite(*wrapped_get1, 2),
3990 CreateMockWrite(*wrapped_get2, 5),
3991 };
3992
3993 MockRead spdy_reads[] = {
3994 CreateMockRead(*conn_resp1, 1, ASYNC),
3995 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
3996 CreateMockRead(*wrapped_body1, 4, ASYNC),
3997 CreateMockRead(*wrapped_get_resp2, 6, ASYNC),
3998 CreateMockRead(*wrapped_body2, 7, ASYNC),
3999 MockRead(ASYNC, 0, 8),
4000 };
4001
4002 DeterministicSocketData spdy_data(
4003 spdy_reads, arraysize(spdy_reads),
4004 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074005 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:224006
4007 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:024008 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:074009 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:224010 SSLSocketDataProvider ssl2(ASYNC, OK);
4011 ssl2.was_npn_negotiated = false;
4012 ssl2.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:074013 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:224014
4015 TestCompletionCallback callback;
4016
[email protected]262eec82013-03-19 21:01:364017 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504018 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224019 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
4020 EXPECT_EQ(ERR_IO_PENDING, rv);
4021 // The first connect and request, each of their responses, and the body.
4022 spdy_data.RunFor(5);
4023
4024 rv = callback.WaitForResult();
4025 EXPECT_EQ(OK, rv);
4026
4027 LoadTimingInfo load_timing_info;
4028 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4029 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
4030
4031 const HttpResponseInfo* response = trans->GetResponseInfo();
4032 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504033 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:224034 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4035
4036 std::string response_data;
4037 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
[email protected]90499482013-06-01 00:39:504038 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:224039 trans.reset();
4040
[email protected]262eec82013-03-19 21:01:364041 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:504042 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224043 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
4044 EXPECT_EQ(ERR_IO_PENDING, rv);
4045
4046 // The second request, response, and body. There should not be a second
4047 // connect.
4048 spdy_data.RunFor(3);
4049 rv = callback.WaitForResult();
4050 EXPECT_EQ(OK, rv);
4051
4052 LoadTimingInfo load_timing_info2;
4053 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4054 TestLoadTimingReused(load_timing_info2);
4055
4056 // The requests should have the same ID.
4057 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
4058
[email protected]90499482013-06-01 00:39:504059 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:224060}
4061
4062// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
4063// Proxy to different servers.
[email protected]23e482282013-06-14 16:08:024064TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:224065 HttpsProxySpdyLoadTimingTwoHttpRequests) {
4066 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:074067 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:224068 "https://proxy:70"));
4069 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074070 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:224071 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:074072 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:224073
4074 HttpRequestInfo request1;
4075 request1.method = "GET";
4076 request1.url = GURL("http://www.google.com/");
4077 request1.load_flags = 0;
4078
4079 HttpRequestInfo request2;
4080 request2.method = "GET";
4081 request2.url = GURL("http://news.google.com/");
4082 request2.load_flags = 0;
4083
4084 // http://www.google.com/
[email protected]23e482282013-06-14 16:08:024085 scoped_ptr<SpdyHeaderBlock> headers(
4086 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/"));
[email protected]745aa9c2014-06-27 02:21:294087 scoped_ptr<SpdyFrame> get1(
4088 spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, false, true));
[email protected]23e482282013-06-14 16:08:024089 scoped_ptr<SpdyFrame> get_resp1(
4090 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
4091 scoped_ptr<SpdyFrame> body1(
4092 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, true));
[email protected]f6c63db52013-02-02 00:35:224093
4094 // http://news.google.com/
[email protected]23e482282013-06-14 16:08:024095 scoped_ptr<SpdyHeaderBlock> headers2(
4096 spdy_util_.ConstructGetHeaderBlockForProxy("http://news.google.com/"));
[email protected]745aa9c2014-06-27 02:21:294097 scoped_ptr<SpdyFrame> get2(
4098 spdy_util_.ConstructSpdySyn(3, *headers2, LOWEST, false, true));
[email protected]23e482282013-06-14 16:08:024099 scoped_ptr<SpdyFrame> get_resp2(
4100 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
4101 scoped_ptr<SpdyFrame> body2(
4102 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, true));
[email protected]f6c63db52013-02-02 00:35:224103
4104 MockWrite spdy_writes[] = {
4105 CreateMockWrite(*get1, 0),
4106 CreateMockWrite(*get2, 3),
4107 };
4108
4109 MockRead spdy_reads[] = {
4110 CreateMockRead(*get_resp1, 1, ASYNC),
4111 CreateMockRead(*body1, 2, ASYNC),
4112 CreateMockRead(*get_resp2, 4, ASYNC),
4113 CreateMockRead(*body2, 5, ASYNC),
4114 MockRead(ASYNC, 0, 6),
4115 };
4116
4117 DeterministicSocketData spdy_data(
4118 spdy_reads, arraysize(spdy_reads),
4119 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074120 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:224121
4122 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:024123 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:074124 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:224125
4126 TestCompletionCallback callback;
4127
[email protected]262eec82013-03-19 21:01:364128 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504129 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224130 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
4131 EXPECT_EQ(ERR_IO_PENDING, rv);
4132 spdy_data.RunFor(2);
4133
4134 rv = callback.WaitForResult();
4135 EXPECT_EQ(OK, rv);
4136
4137 LoadTimingInfo load_timing_info;
4138 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4139 TestLoadTimingNotReused(load_timing_info,
4140 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4141
4142 const HttpResponseInfo* response = trans->GetResponseInfo();
4143 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504144 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:224145 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4146
4147 std::string response_data;
4148 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
[email protected]90499482013-06-01 00:39:504149 EXPECT_EQ(ERR_IO_PENDING, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:224150 spdy_data.RunFor(1);
4151 EXPECT_EQ(1, callback.WaitForResult());
4152 // Delete the first request, so the second one can reuse the socket.
4153 trans.reset();
4154
[email protected]262eec82013-03-19 21:01:364155 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:504156 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224157 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
4158 EXPECT_EQ(ERR_IO_PENDING, rv);
4159
4160 spdy_data.RunFor(2);
4161 rv = callback.WaitForResult();
4162 EXPECT_EQ(OK, rv);
4163
4164 LoadTimingInfo load_timing_info2;
4165 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4166 TestLoadTimingReused(load_timing_info2);
4167
4168 // The requests should have the same ID.
4169 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
4170
[email protected]90499482013-06-01 00:39:504171 EXPECT_EQ(ERR_IO_PENDING, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:224172 spdy_data.RunFor(1);
4173 EXPECT_EQ(2, callback.WaitForResult());
4174}
4175
[email protected]2df19bb2010-08-25 20:13:464176// Test the challenge-response-retry sequence through an HTTPS Proxy
[email protected]23e482282013-06-14 16:08:024177TEST_P(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:464178 HttpRequestInfo request;
4179 request.method = "GET";
4180 request.url = GURL("http://www.google.com/");
4181 // when the no authentication data flag is set.
4182 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
4183
[email protected]79cb5c12011-09-12 13:12:044184 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:074185 session_deps_.proxy_service.reset(
[email protected]79cb5c12011-09-12 13:12:044186 ProxyService::CreateFixed("https://myproxy:70"));
[email protected]333bdf62012-06-08 22:57:294187 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074188 session_deps_.net_log = log.bound().net_log();
4189 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274190
[email protected]2df19bb2010-08-25 20:13:464191 // Since we have proxy, should use full url
4192 MockWrite data_writes1[] = {
4193 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
4194 "Host: www.google.com\r\n"
4195 "Proxy-Connection: keep-alive\r\n\r\n"),
4196
4197 // After calling trans->RestartWithAuth(), this is the request we should
4198 // be issuing -- the final header line contains the credentials.
4199 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
4200 "Host: www.google.com\r\n"
4201 "Proxy-Connection: keep-alive\r\n"
4202 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
4203 };
4204
4205 // The proxy responds to the GET with a 407, using a persistent
4206 // connection.
4207 MockRead data_reads1[] = {
4208 // No credentials.
4209 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4210 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4211 MockRead("Proxy-Connection: keep-alive\r\n"),
4212 MockRead("Content-Length: 0\r\n\r\n"),
4213
4214 MockRead("HTTP/1.1 200 OK\r\n"),
4215 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4216 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064217 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:464218 };
4219
4220 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4221 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074222 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:064223 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074224 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:464225
[email protected]49639fa2011-12-20 23:22:414226 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:464227
[email protected]262eec82013-03-19 21:01:364228 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504229 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504230
[email protected]49639fa2011-12-20 23:22:414231 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:464232 EXPECT_EQ(ERR_IO_PENDING, rv);
4233
4234 rv = callback1.WaitForResult();
4235 EXPECT_EQ(OK, rv);
4236
[email protected]58e32bb2013-01-21 18:23:254237 LoadTimingInfo load_timing_info;
4238 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4239 TestLoadTimingNotReused(load_timing_info,
4240 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4241
[email protected]2df19bb2010-08-25 20:13:464242 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504243 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504244 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]2df19bb2010-08-25 20:13:464245 EXPECT_EQ(407, response->headers->response_code());
4246 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:044247 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:464248
[email protected]49639fa2011-12-20 23:22:414249 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:464250
[email protected]49639fa2011-12-20 23:22:414251 rv = trans->RestartWithAuth(
4252 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]2df19bb2010-08-25 20:13:464253 EXPECT_EQ(ERR_IO_PENDING, rv);
4254
4255 rv = callback2.WaitForResult();
4256 EXPECT_EQ(OK, rv);
4257
[email protected]58e32bb2013-01-21 18:23:254258 load_timing_info = LoadTimingInfo();
4259 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4260 // Retrying with HTTP AUTH is considered to be reusing a socket.
4261 TestLoadTimingReused(load_timing_info);
4262
[email protected]2df19bb2010-08-25 20:13:464263 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504264 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:464265
4266 EXPECT_TRUE(response->headers->IsKeepAlive());
4267 EXPECT_EQ(200, response->headers->response_code());
4268 EXPECT_EQ(100, response->headers->GetContentLength());
4269 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4270
4271 // The password prompt info should not be set.
4272 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4273}
4274
[email protected]23e482282013-06-14 16:08:024275void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:084276 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:424277 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:084278 request.method = "GET";
4279 request.url = GURL("https://www.google.com/");
4280 request.load_flags = 0;
4281
[email protected]cb9bf6ca2011-01-28 13:15:274282 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:074283 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]bb88e1d32013-05-03 23:11:074284 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274285
[email protected]c744cf22009-02-27 07:28:084286 // Since we have proxy, should try to establish tunnel.
4287 MockWrite data_writes[] = {
4288 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:454289 "Host: www.google.com\r\n"
4290 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:084291 };
4292
4293 MockRead data_reads[] = {
4294 status,
4295 MockRead("Content-Length: 10\r\n\r\n"),
4296 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:064297 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]c744cf22009-02-27 07:28:084298 };
4299
[email protected]31a2bfe2010-02-09 08:03:394300 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
4301 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:074302 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:084303
[email protected]49639fa2011-12-20 23:22:414304 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:084305
[email protected]262eec82013-03-19 21:01:364306 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504307 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504308
[email protected]49639fa2011-12-20 23:22:414309 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424310 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]c744cf22009-02-27 07:28:084311
4312 rv = callback.WaitForResult();
4313 EXPECT_EQ(expected_status, rv);
4314}
4315
[email protected]23e482282013-06-14 16:08:024316void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:234317 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:084318 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:424319 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:084320}
4321
[email protected]23e482282013-06-14 16:08:024322TEST_P(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:084323 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
4324}
4325
[email protected]23e482282013-06-14 16:08:024326TEST_P(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:084327 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
4328}
4329
[email protected]23e482282013-06-14 16:08:024330TEST_P(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:084331 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
4332}
4333
[email protected]23e482282013-06-14 16:08:024334TEST_P(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:084335 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
4336}
4337
[email protected]23e482282013-06-14 16:08:024338TEST_P(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:084339 ConnectStatusHelper(
4340 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
4341}
4342
[email protected]23e482282013-06-14 16:08:024343TEST_P(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:084344 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
4345}
4346
[email protected]23e482282013-06-14 16:08:024347TEST_P(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:084348 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
4349}
4350
[email protected]23e482282013-06-14 16:08:024351TEST_P(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:084352 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
4353}
4354
[email protected]23e482282013-06-14 16:08:024355TEST_P(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:084356 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
4357}
4358
[email protected]23e482282013-06-14 16:08:024359TEST_P(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:084360 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
4361}
4362
[email protected]23e482282013-06-14 16:08:024363TEST_P(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:084364 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
4365}
4366
[email protected]23e482282013-06-14 16:08:024367TEST_P(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:084368 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
4369}
4370
[email protected]23e482282013-06-14 16:08:024371TEST_P(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:084372 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
4373}
4374
[email protected]23e482282013-06-14 16:08:024375TEST_P(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:084376 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
4377}
4378
[email protected]23e482282013-06-14 16:08:024379TEST_P(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:084380 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
4381}
4382
[email protected]23e482282013-06-14 16:08:024383TEST_P(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:084384 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
4385}
4386
[email protected]0a17aab32014-04-24 03:32:374387TEST_P(HttpNetworkTransactionTest, ConnectStatus308) {
4388 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
4389}
4390
[email protected]23e482282013-06-14 16:08:024391TEST_P(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:084392 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
4393}
4394
[email protected]23e482282013-06-14 16:08:024395TEST_P(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:084396 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
4397}
4398
[email protected]23e482282013-06-14 16:08:024399TEST_P(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:084400 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
4401}
4402
[email protected]23e482282013-06-14 16:08:024403TEST_P(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:084404 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
4405}
4406
[email protected]23e482282013-06-14 16:08:024407TEST_P(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:084408 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
4409}
4410
[email protected]23e482282013-06-14 16:08:024411TEST_P(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:084412 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
4413}
4414
[email protected]23e482282013-06-14 16:08:024415TEST_P(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:084416 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
4417}
4418
[email protected]23e482282013-06-14 16:08:024419TEST_P(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:084420 ConnectStatusHelperWithExpectedStatus(
4421 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:544422 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:084423}
4424
[email protected]23e482282013-06-14 16:08:024425TEST_P(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:084426 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
4427}
4428
[email protected]23e482282013-06-14 16:08:024429TEST_P(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:084430 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
4431}
4432
[email protected]23e482282013-06-14 16:08:024433TEST_P(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:084434 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
4435}
4436
[email protected]23e482282013-06-14 16:08:024437TEST_P(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:084438 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
4439}
4440
[email protected]23e482282013-06-14 16:08:024441TEST_P(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:084442 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
4443}
4444
[email protected]23e482282013-06-14 16:08:024445TEST_P(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:084446 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
4447}
4448
[email protected]23e482282013-06-14 16:08:024449TEST_P(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:084450 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
4451}
4452
[email protected]23e482282013-06-14 16:08:024453TEST_P(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:084454 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
4455}
4456
[email protected]23e482282013-06-14 16:08:024457TEST_P(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:084458 ConnectStatusHelper(
4459 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
4460}
4461
[email protected]23e482282013-06-14 16:08:024462TEST_P(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:084463 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
4464}
4465
[email protected]23e482282013-06-14 16:08:024466TEST_P(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:084467 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
4468}
4469
[email protected]23e482282013-06-14 16:08:024470TEST_P(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:084471 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
4472}
4473
[email protected]23e482282013-06-14 16:08:024474TEST_P(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:084475 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
4476}
4477
[email protected]23e482282013-06-14 16:08:024478TEST_P(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:084479 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
4480}
4481
[email protected]23e482282013-06-14 16:08:024482TEST_P(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:084483 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
4484}
4485
[email protected]23e482282013-06-14 16:08:024486TEST_P(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:084487 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
4488}
4489
[email protected]038e9a32008-10-08 22:40:164490// Test the flow when both the proxy server AND origin server require
4491// authentication. Again, this uses basic auth for both since that is
4492// the simplest to mock.
[email protected]23e482282013-06-14 16:08:024493TEST_P(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:274494 HttpRequestInfo request;
4495 request.method = "GET";
4496 request.url = GURL("http://www.google.com/");
4497 request.load_flags = 0;
4498
[email protected]038e9a32008-10-08 22:40:164499 // Configure against proxy server "myproxy:70".
[email protected]3fe8d2f82013-10-17 08:56:074500 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
4501 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4502
4503 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:414504 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]038e9a32008-10-08 22:40:164505
[email protected]f9ee6b52008-11-08 06:46:234506 MockWrite data_writes1[] = {
4507 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
4508 "Host: www.google.com\r\n"
4509 "Proxy-Connection: keep-alive\r\n\r\n"),
4510 };
4511
[email protected]038e9a32008-10-08 22:40:164512 MockRead data_reads1[] = {
4513 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
4514 // Give a couple authenticate options (only the middle one is actually
4515 // supported).
[email protected]22927ad2009-09-21 19:56:194516 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:164517 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4518 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
4519 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4520 // Large content-length -- won't matter, as connection will be reset.
4521 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064522 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:164523 };
4524
4525 // After calling trans->RestartWithAuth() the first time, this is the
4526 // request we should be issuing -- the final header line contains the
4527 // proxy's credentials.
4528 MockWrite data_writes2[] = {
4529 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
4530 "Host: www.google.com\r\n"
4531 "Proxy-Connection: keep-alive\r\n"
4532 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
4533 };
4534
4535 // Now the proxy server lets the request pass through to origin server.
4536 // The origin server responds with a 401.
4537 MockRead data_reads2[] = {
4538 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4539 // Note: We are using the same realm-name as the proxy server. This is
4540 // completely valid, as realms are unique across hosts.
4541 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4542 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4543 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064544 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:164545 };
4546
4547 // After calling trans->RestartWithAuth() the second time, we should send
4548 // the credentials for both the proxy and origin server.
4549 MockWrite data_writes3[] = {
4550 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
4551 "Host: www.google.com\r\n"
4552 "Proxy-Connection: keep-alive\r\n"
4553 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
4554 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
4555 };
4556
4557 // Lastly we get the desired content.
4558 MockRead data_reads3[] = {
4559 MockRead("HTTP/1.0 200 OK\r\n"),
4560 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4561 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064562 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:164563 };
4564
[email protected]31a2bfe2010-02-09 08:03:394565 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4566 data_writes1, arraysize(data_writes1));
4567 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4568 data_writes2, arraysize(data_writes2));
4569 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4570 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:074571 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4572 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4573 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:164574
[email protected]49639fa2011-12-20 23:22:414575 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:164576
[email protected]49639fa2011-12-20 23:22:414577 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424578 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:164579
4580 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424581 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:164582
[email protected]1c773ea12009-04-28 19:58:424583 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504584 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044585 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:164586
[email protected]49639fa2011-12-20 23:22:414587 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:164588
[email protected]49639fa2011-12-20 23:22:414589 rv = trans->RestartWithAuth(
4590 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:424591 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:164592
4593 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424594 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:164595
4596 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504597 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044598 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:164599
[email protected]49639fa2011-12-20 23:22:414600 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:164601
[email protected]49639fa2011-12-20 23:22:414602 rv = trans->RestartWithAuth(
4603 AuthCredentials(kFoo2, kBar2), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424604 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:164605
4606 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424607 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:164608
4609 response = trans->GetResponseInfo();
4610 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4611 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:164612}
[email protected]4ddaf2502008-10-23 18:26:194613
[email protected]ea9dc9a2009-09-05 00:43:324614// For the NTLM implementation using SSPI, we skip the NTLM tests since we
4615// can't hook into its internals to cause it to generate predictable NTLM
4616// authorization headers.
4617#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:294618// The NTLM authentication unit tests were generated by capturing the HTTP
4619// requests and responses using Fiddler 2 and inspecting the generated random
4620// bytes in the debugger.
4621
4622// Enter the correct password and authenticate successfully.
[email protected]23e482282013-06-14 16:08:024623TEST_P(HttpNetworkTransactionTest, NTLMAuth1) {
[email protected]1c773ea12009-04-28 19:58:424624 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:244625 request.method = "GET";
4626 request.url = GURL("http://172.22.68.17/kids/login.aspx");
[email protected]2217aa22013-10-11 03:03:544627
4628 // Ensure load is not disrupted by flags which suppress behaviour specific
4629 // to other auth schemes.
4630 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:244631
[email protected]cb9bf6ca2011-01-28 13:15:274632 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
4633 MockGetHostName);
[email protected]bb88e1d32013-05-03 23:11:074634 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274635
[email protected]3f918782009-02-28 01:29:244636 MockWrite data_writes1[] = {
4637 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4638 "Host: 172.22.68.17\r\n"
4639 "Connection: keep-alive\r\n\r\n"),
4640 };
4641
4642 MockRead data_reads1[] = {
4643 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:044644 // Negotiate and NTLM are often requested together. However, we only want
4645 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
4646 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:244647 MockRead("WWW-Authenticate: NTLM\r\n"),
4648 MockRead("Connection: close\r\n"),
4649 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364650 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:244651 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064652 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]3f918782009-02-28 01:29:244653 };
4654
4655 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:224656 // After restarting with a null identity, this is the
[email protected]3f918782009-02-28 01:29:244657 // request we should be issuing -- the final header line contains a Type
4658 // 1 message.
4659 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4660 "Host: 172.22.68.17\r\n"
4661 "Connection: keep-alive\r\n"
4662 "Authorization: NTLM "
4663 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4664
4665 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4666 // (the credentials for the origin server). The second request continues
4667 // on the same connection.
4668 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4669 "Host: 172.22.68.17\r\n"
4670 "Connection: keep-alive\r\n"
[email protected]385a4672009-03-11 22:21:294671 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4672 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4673 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
4674 "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
4675 "ahlhx5I=\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:244676 };
4677
4678 MockRead data_reads2[] = {
4679 // The origin server responds with a Type 2 message.
4680 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4681 MockRead("WWW-Authenticate: NTLM "
[email protected]385a4672009-03-11 22:21:294682 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
[email protected]3f918782009-02-28 01:29:244683 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4684 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4685 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4686 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4687 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4688 "BtAAAAAAA=\r\n"),
4689 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364690 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:244691 MockRead("You are not authorized to view this page\r\n"),
4692
4693 // Lastly we get the desired content.
4694 MockRead("HTTP/1.1 200 OK\r\n"),
4695 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
4696 MockRead("Content-Length: 13\r\n\r\n"),
4697 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:064698 MockRead(SYNCHRONOUS, OK),
[email protected]3f918782009-02-28 01:29:244699 };
4700
[email protected]31a2bfe2010-02-09 08:03:394701 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4702 data_writes1, arraysize(data_writes1));
4703 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4704 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:074705 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4706 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:244707
[email protected]49639fa2011-12-20 23:22:414708 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:244709
[email protected]262eec82013-03-19 21:01:364710 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504711 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504712
[email protected]49639fa2011-12-20 23:22:414713 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424714 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:244715
4716 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424717 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:244718
[email protected]0757e7702009-03-27 04:00:224719 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4720
[email protected]1c773ea12009-04-28 19:58:424721 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:044722 ASSERT_FALSE(response == NULL);
4723 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:244724
[email protected]49639fa2011-12-20 23:22:414725 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:254726
[email protected]f3cf9802011-10-28 18:44:584727 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:414728 callback2.callback());
[email protected]10af5fe72011-01-31 16:17:254729 EXPECT_EQ(ERR_IO_PENDING, rv);
4730
4731 rv = callback2.WaitForResult();
4732 EXPECT_EQ(OK, rv);
4733
4734 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4735
4736 response = trans->GetResponseInfo();
4737 ASSERT_TRUE(response != NULL);
[email protected]10af5fe72011-01-31 16:17:254738 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4739
[email protected]49639fa2011-12-20 23:22:414740 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:244741
[email protected]49639fa2011-12-20 23:22:414742 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424743 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:244744
[email protected]0757e7702009-03-27 04:00:224745 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424746 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:244747
4748 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504749 ASSERT_TRUE(response != NULL);
[email protected]3f918782009-02-28 01:29:244750 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4751 EXPECT_EQ(13, response->headers->GetContentLength());
4752}
4753
[email protected]385a4672009-03-11 22:21:294754// Enter a wrong password, and then the correct one.
[email protected]23e482282013-06-14 16:08:024755TEST_P(HttpNetworkTransactionTest, NTLMAuth2) {
[email protected]1c773ea12009-04-28 19:58:424756 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:294757 request.method = "GET";
4758 request.url = GURL("http://172.22.68.17/kids/login.aspx");
4759 request.load_flags = 0;
4760
[email protected]cb9bf6ca2011-01-28 13:15:274761 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
4762 MockGetHostName);
[email protected]bb88e1d32013-05-03 23:11:074763 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274764
[email protected]385a4672009-03-11 22:21:294765 MockWrite data_writes1[] = {
4766 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4767 "Host: 172.22.68.17\r\n"
4768 "Connection: keep-alive\r\n\r\n"),
4769 };
4770
4771 MockRead data_reads1[] = {
4772 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:044773 // Negotiate and NTLM are often requested together. However, we only want
4774 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
4775 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:294776 MockRead("WWW-Authenticate: NTLM\r\n"),
4777 MockRead("Connection: close\r\n"),
4778 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364779 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294780 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064781 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:294782 };
4783
4784 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:224785 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:294786 // request we should be issuing -- the final header line contains a Type
4787 // 1 message.
4788 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4789 "Host: 172.22.68.17\r\n"
4790 "Connection: keep-alive\r\n"
4791 "Authorization: NTLM "
4792 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4793
4794 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4795 // (the credentials for the origin server). The second request continues
4796 // on the same connection.
4797 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4798 "Host: 172.22.68.17\r\n"
4799 "Connection: keep-alive\r\n"
4800 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4801 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4802 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
4803 "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
4804 "4Ww7b7E=\r\n\r\n"),
4805 };
4806
4807 MockRead data_reads2[] = {
4808 // The origin server responds with a Type 2 message.
4809 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4810 MockRead("WWW-Authenticate: NTLM "
4811 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
4812 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4813 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4814 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4815 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4816 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4817 "BtAAAAAAA=\r\n"),
4818 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364819 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294820 MockRead("You are not authorized to view this page\r\n"),
4821
4822 // Wrong password.
4823 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]385a4672009-03-11 22:21:294824 MockRead("WWW-Authenticate: NTLM\r\n"),
4825 MockRead("Connection: close\r\n"),
4826 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364827 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294828 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064829 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:294830 };
4831
4832 MockWrite data_writes3[] = {
[email protected]0757e7702009-03-27 04:00:224833 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:294834 // request we should be issuing -- the final header line contains a Type
4835 // 1 message.
4836 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4837 "Host: 172.22.68.17\r\n"
4838 "Connection: keep-alive\r\n"
4839 "Authorization: NTLM "
4840 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4841
4842 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4843 // (the credentials for the origin server). The second request continues
4844 // on the same connection.
4845 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4846 "Host: 172.22.68.17\r\n"
4847 "Connection: keep-alive\r\n"
4848 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4849 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4850 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
4851 "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
4852 "+4MUm7c=\r\n\r\n"),
4853 };
4854
4855 MockRead data_reads3[] = {
4856 // The origin server responds with a Type 2 message.
4857 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4858 MockRead("WWW-Authenticate: NTLM "
4859 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
4860 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4861 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4862 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4863 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4864 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4865 "BtAAAAAAA=\r\n"),
4866 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364867 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294868 MockRead("You are not authorized to view this page\r\n"),
4869
4870 // Lastly we get the desired content.
4871 MockRead("HTTP/1.1 200 OK\r\n"),
4872 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
4873 MockRead("Content-Length: 13\r\n\r\n"),
4874 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:064875 MockRead(SYNCHRONOUS, OK),
[email protected]385a4672009-03-11 22:21:294876 };
4877
[email protected]31a2bfe2010-02-09 08:03:394878 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4879 data_writes1, arraysize(data_writes1));
4880 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4881 data_writes2, arraysize(data_writes2));
4882 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4883 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:074884 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4885 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4886 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:294887
[email protected]49639fa2011-12-20 23:22:414888 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:294889
[email protected]262eec82013-03-19 21:01:364890 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504891 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504892
[email protected]49639fa2011-12-20 23:22:414893 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424894 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:294895
4896 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424897 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:294898
[email protected]0757e7702009-03-27 04:00:224899 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:294900
[email protected]1c773ea12009-04-28 19:58:424901 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504902 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044903 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:294904
[email protected]49639fa2011-12-20 23:22:414905 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:294906
[email protected]0757e7702009-03-27 04:00:224907 // Enter the wrong password.
[email protected]f3cf9802011-10-28 18:44:584908 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword),
[email protected]49639fa2011-12-20 23:22:414909 callback2.callback());
[email protected]1c773ea12009-04-28 19:58:424910 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:294911
[email protected]10af5fe72011-01-31 16:17:254912 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424913 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:294914
[email protected]0757e7702009-03-27 04:00:224915 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:414916 TestCompletionCallback callback3;
4917 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424918 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]10af5fe72011-01-31 16:17:254919 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424920 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:224921 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4922
4923 response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:044924 ASSERT_FALSE(response == NULL);
4925 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:224926
[email protected]49639fa2011-12-20 23:22:414927 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:224928
4929 // Now enter the right password.
[email protected]f3cf9802011-10-28 18:44:584930 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:414931 callback4.callback());
[email protected]10af5fe72011-01-31 16:17:254932 EXPECT_EQ(ERR_IO_PENDING, rv);
4933
4934 rv = callback4.WaitForResult();
4935 EXPECT_EQ(OK, rv);
4936
4937 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4938
[email protected]49639fa2011-12-20 23:22:414939 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:254940
4941 // One more roundtrip
[email protected]49639fa2011-12-20 23:22:414942 rv = trans->RestartWithAuth(AuthCredentials(), callback5.callback());
[email protected]1c773ea12009-04-28 19:58:424943 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:224944
4945 rv = callback5.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424946 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:224947
[email protected]385a4672009-03-11 22:21:294948 response = trans->GetResponseInfo();
4949 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4950 EXPECT_EQ(13, response->headers->GetContentLength());
4951}
[email protected]ea9dc9a2009-09-05 00:43:324952#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:294953
[email protected]4ddaf2502008-10-23 18:26:194954// Test reading a server response which has only headers, and no body.
4955// After some maximum number of bytes is consumed, the transaction should
4956// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
[email protected]23e482282013-06-14 16:08:024957TEST_P(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:424958 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:194959 request.method = "GET";
4960 request.url = GURL("http://www.google.com/");
4961 request.load_flags = 0;
4962
[email protected]3fe8d2f82013-10-17 08:56:074963 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274964 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:414965 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:274966
[email protected]b75b7b2f2009-10-06 00:54:534967 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:434968 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:534969 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:194970
4971 MockRead data_reads[] = {
4972 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:064973 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:194974 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:064975 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:194976 };
[email protected]31a2bfe2010-02-09 08:03:394977 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:074978 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:194979
[email protected]49639fa2011-12-20 23:22:414980 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:194981
[email protected]49639fa2011-12-20 23:22:414982 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424983 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]4ddaf2502008-10-23 18:26:194984
4985 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424986 EXPECT_EQ(ERR_RESPONSE_HEADERS_TOO_BIG, rv);
[email protected]4ddaf2502008-10-23 18:26:194987
[email protected]1c773ea12009-04-28 19:58:424988 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]4ddaf2502008-10-23 18:26:194989 EXPECT_TRUE(response == NULL);
4990}
[email protected]f4e426b2008-11-05 00:24:494991
4992// Make sure that we don't try to reuse a TCPClientSocket when failing to
4993// establish tunnel.
4994// http://code.google.com/p/chromium/issues/detail?id=3772
[email protected]23e482282013-06-14 16:08:024995TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:234996 DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:274997 HttpRequestInfo request;
4998 request.method = "GET";
4999 request.url = GURL("https://www.google.com/");
5000 request.load_flags = 0;
5001
[email protected]f4e426b2008-11-05 00:24:495002 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:075003 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]db8f44c2008-12-13 04:52:015004
[email protected]bb88e1d32013-05-03 23:11:075005 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:495006
[email protected]262eec82013-03-19 21:01:365007 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505008 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f4e426b2008-11-05 00:24:495009
[email protected]f4e426b2008-11-05 00:24:495010 // Since we have proxy, should try to establish tunnel.
5011 MockWrite data_writes1[] = {
5012 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:455013 "Host: www.google.com\r\n"
5014 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:495015 };
5016
[email protected]77848d12008-11-14 00:00:225017 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:495018 // connection. Usually a proxy would return 501 (not implemented),
5019 // or 200 (tunnel established).
5020 MockRead data_reads1[] = {
5021 MockRead("HTTP/1.1 404 Not Found\r\n"),
5022 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065023 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]f4e426b2008-11-05 00:24:495024 };
5025
[email protected]31a2bfe2010-02-09 08:03:395026 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5027 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075028 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:495029
[email protected]49639fa2011-12-20 23:22:415030 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:495031
[email protected]49639fa2011-12-20 23:22:415032 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425033 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f4e426b2008-11-05 00:24:495034
5035 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425036 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]f4e426b2008-11-05 00:24:495037
[email protected]1c773ea12009-04-28 19:58:425038 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]c744cf22009-02-27 07:28:085039 EXPECT_TRUE(response == NULL);
[email protected]f4e426b2008-11-05 00:24:495040
[email protected]b4404c02009-04-10 16:38:525041 // Empty the current queue. This is necessary because idle sockets are
5042 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345043 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:525044
[email protected]f4e426b2008-11-05 00:24:495045 // We now check to make sure the TCPClientSocket was not added back to
5046 // the pool.
[email protected]90499482013-06-01 00:39:505047 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:495048 trans.reset();
[email protected]2da659e2013-05-23 20:51:345049 base::MessageLoop::current()->RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:495050 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:505051 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:495052}
[email protected]372d34a2008-11-05 21:30:515053
[email protected]1b157c02009-04-21 01:55:405054// Make sure that we recycle a socket after reading all of the response body.
[email protected]23e482282013-06-14 16:08:025055TEST_P(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:425056 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:405057 request.method = "GET";
5058 request.url = GURL("http://www.google.com/");
5059 request.load_flags = 0;
5060
[email protected]bb88e1d32013-05-03 23:11:075061 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275062
[email protected]262eec82013-03-19 21:01:365063 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505064 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275065
[email protected]1b157c02009-04-21 01:55:405066 MockRead data_reads[] = {
5067 // A part of the response body is received with the response headers.
5068 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
5069 // The rest of the response body is received in two parts.
5070 MockRead("lo"),
5071 MockRead(" world"),
5072 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:065073 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:405074 };
5075
[email protected]31a2bfe2010-02-09 08:03:395076 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:075077 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:405078
[email protected]49639fa2011-12-20 23:22:415079 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:405080
[email protected]49639fa2011-12-20 23:22:415081 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425082 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]1b157c02009-04-21 01:55:405083
5084 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425085 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:405086
[email protected]1c773ea12009-04-28 19:58:425087 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505088 ASSERT_TRUE(response != NULL);
[email protected]1b157c02009-04-21 01:55:405089
[email protected]90499482013-06-01 00:39:505090 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]1b157c02009-04-21 01:55:405091 std::string status_line = response->headers->GetStatusLine();
5092 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
5093
[email protected]90499482013-06-01 00:39:505094 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:405095
5096 std::string response_data;
5097 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:425098 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:405099 EXPECT_EQ("hello world", response_data);
5100
5101 // Empty the current queue. This is necessary because idle sockets are
5102 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345103 base::MessageLoop::current()->RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:405104
5105 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505106 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:405107}
5108
[email protected]76a505b2010-08-25 06:23:005109// Make sure that we recycle a SSL socket after reading all of the response
5110// body.
[email protected]23e482282013-06-14 16:08:025111TEST_P(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:005112 HttpRequestInfo request;
5113 request.method = "GET";
5114 request.url = GURL("https://www.google.com/");
5115 request.load_flags = 0;
5116
5117 MockWrite data_writes[] = {
5118 MockWrite("GET / HTTP/1.1\r\n"
5119 "Host: www.google.com\r\n"
5120 "Connection: keep-alive\r\n\r\n"),
5121 };
5122
5123 MockRead data_reads[] = {
5124 MockRead("HTTP/1.1 200 OK\r\n"),
5125 MockRead("Content-Length: 11\r\n\r\n"),
5126 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:065127 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:005128 };
5129
[email protected]8ddf8322012-02-23 18:08:065130 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075131 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:005132
5133 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5134 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:075135 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:005136
[email protected]49639fa2011-12-20 23:22:415137 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:005138
[email protected]bb88e1d32013-05-03 23:11:075139 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:365140 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505141 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:005142
[email protected]49639fa2011-12-20 23:22:415143 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:005144
5145 EXPECT_EQ(ERR_IO_PENDING, rv);
5146 EXPECT_EQ(OK, callback.WaitForResult());
5147
5148 const HttpResponseInfo* response = trans->GetResponseInfo();
5149 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:505150 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:005151 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5152
[email protected]90499482013-06-01 00:39:505153 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005154
5155 std::string response_data;
5156 rv = ReadTransaction(trans.get(), &response_data);
5157 EXPECT_EQ(OK, rv);
5158 EXPECT_EQ("hello world", response_data);
5159
5160 // Empty the current queue. This is necessary because idle sockets are
5161 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345162 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:005163
5164 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505165 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005166}
5167
5168// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
5169// from the pool and make sure that we recover okay.
[email protected]23e482282013-06-14 16:08:025170TEST_P(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:005171 HttpRequestInfo request;
5172 request.method = "GET";
5173 request.url = GURL("https://www.google.com/");
5174 request.load_flags = 0;
5175
5176 MockWrite data_writes[] = {
5177 MockWrite("GET / HTTP/1.1\r\n"
5178 "Host: www.google.com\r\n"
5179 "Connection: keep-alive\r\n\r\n"),
5180 MockWrite("GET / HTTP/1.1\r\n"
5181 "Host: www.google.com\r\n"
5182 "Connection: keep-alive\r\n\r\n"),
5183 };
5184
5185 MockRead data_reads[] = {
5186 MockRead("HTTP/1.1 200 OK\r\n"),
5187 MockRead("Content-Length: 11\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065188 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:005189 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:065190 MockRead(ASYNC, 0, 0) // EOF
[email protected]76a505b2010-08-25 06:23:005191 };
5192
[email protected]8ddf8322012-02-23 18:08:065193 SSLSocketDataProvider ssl(ASYNC, OK);
5194 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075195 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5196 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:005197
5198 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5199 data_writes, arraysize(data_writes));
5200 StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
5201 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:075202 session_deps_.socket_factory->AddSocketDataProvider(&data);
5203 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:005204
[email protected]49639fa2011-12-20 23:22:415205 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:005206
[email protected]bb88e1d32013-05-03 23:11:075207 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:365208 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505209 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:005210
[email protected]49639fa2011-12-20 23:22:415211 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:005212
5213 EXPECT_EQ(ERR_IO_PENDING, rv);
5214 EXPECT_EQ(OK, callback.WaitForResult());
5215
5216 const HttpResponseInfo* response = trans->GetResponseInfo();
5217 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:505218 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:005219 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5220
[email protected]90499482013-06-01 00:39:505221 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005222
5223 std::string response_data;
5224 rv = ReadTransaction(trans.get(), &response_data);
5225 EXPECT_EQ(OK, rv);
5226 EXPECT_EQ("hello world", response_data);
5227
5228 // Empty the current queue. This is necessary because idle sockets are
5229 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345230 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:005231
5232 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505233 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005234
5235 // Now start the second transaction, which should reuse the previous socket.
5236
[email protected]90499482013-06-01 00:39:505237 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:005238
[email protected]49639fa2011-12-20 23:22:415239 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:005240
5241 EXPECT_EQ(ERR_IO_PENDING, rv);
5242 EXPECT_EQ(OK, callback.WaitForResult());
5243
5244 response = trans->GetResponseInfo();
5245 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:505246 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:005247 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5248
[email protected]90499482013-06-01 00:39:505249 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005250
5251 rv = ReadTransaction(trans.get(), &response_data);
5252 EXPECT_EQ(OK, rv);
5253 EXPECT_EQ("hello world", response_data);
5254
5255 // Empty the current queue. This is necessary because idle sockets are
5256 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345257 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:005258
5259 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505260 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005261}
5262
[email protected]b4404c02009-04-10 16:38:525263// Make sure that we recycle a socket after a zero-length response.
5264// http://crbug.com/9880
[email protected]23e482282013-06-14 16:08:025265TEST_P(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:425266 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:525267 request.method = "GET";
5268 request.url = GURL("http://www.google.com/csi?v=3&s=web&action=&"
5269 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
5270 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
5271 "rt=prt.2642,ol.2649,xjs.2951");
5272 request.load_flags = 0;
5273
[email protected]bb88e1d32013-05-03 23:11:075274 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275275
[email protected]262eec82013-03-19 21:01:365276 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505277 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275278
[email protected]b4404c02009-04-10 16:38:525279 MockRead data_reads[] = {
5280 MockRead("HTTP/1.1 204 No Content\r\n"
5281 "Content-Length: 0\r\n"
5282 "Content-Type: text/html\r\n\r\n"),
5283 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:065284 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:525285 };
5286
[email protected]31a2bfe2010-02-09 08:03:395287 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:075288 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:525289
[email protected]49639fa2011-12-20 23:22:415290 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:525291
[email protected]49639fa2011-12-20 23:22:415292 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425293 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]b4404c02009-04-10 16:38:525294
5295 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425296 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:525297
[email protected]1c773ea12009-04-28 19:58:425298 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505299 ASSERT_TRUE(response != NULL);
[email protected]b4404c02009-04-10 16:38:525300
[email protected]90499482013-06-01 00:39:505301 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]b4404c02009-04-10 16:38:525302 std::string status_line = response->headers->GetStatusLine();
5303 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
5304
[email protected]90499482013-06-01 00:39:505305 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:525306
5307 std::string response_data;
5308 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:425309 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:525310 EXPECT_EQ("", response_data);
5311
5312 // Empty the current queue. This is necessary because idle sockets are
5313 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345314 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:525315
5316 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505317 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:525318}
5319
[email protected]23e482282013-06-14 16:08:025320TEST_P(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
[email protected]b2d26cfd2012-12-11 10:36:065321 ScopedVector<UploadElementReader> element_readers;
5322 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:075323 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:275324
[email protected]1c773ea12009-04-28 19:58:425325 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:515326 // Transaction 1: a GET request that succeeds. The socket is recycled
5327 // after use.
5328 request[0].method = "GET";
5329 request[0].url = GURL("http://www.google.com/");
5330 request[0].load_flags = 0;
5331 // Transaction 2: a POST request. Reuses the socket kept alive from
5332 // transaction 1. The first attempts fails when writing the POST data.
5333 // This causes the transaction to retry with a new socket. The second
5334 // attempt succeeds.
5335 request[1].method = "POST";
5336 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:275337 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:515338 request[1].load_flags = 0;
5339
[email protected]bb88e1d32013-05-03 23:11:075340 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:515341
5342 // The first socket is used for transaction 1 and the first attempt of
5343 // transaction 2.
5344
5345 // The response of transaction 1.
5346 MockRead data_reads1[] = {
5347 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
5348 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:065349 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:515350 };
5351 // The mock write results of transaction 1 and the first attempt of
5352 // transaction 2.
5353 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:065354 MockWrite(SYNCHRONOUS, 64), // GET
5355 MockWrite(SYNCHRONOUS, 93), // POST
5356 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:515357 };
[email protected]31a2bfe2010-02-09 08:03:395358 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5359 data_writes1, arraysize(data_writes1));
[email protected]372d34a2008-11-05 21:30:515360
5361 // The second socket is used for the second attempt of transaction 2.
5362
5363 // The response of transaction 2.
5364 MockRead data_reads2[] = {
5365 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
5366 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:065367 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:515368 };
5369 // The mock write results of the second attempt of transaction 2.
5370 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:065371 MockWrite(SYNCHRONOUS, 93), // POST
5372 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:515373 };
[email protected]31a2bfe2010-02-09 08:03:395374 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5375 data_writes2, arraysize(data_writes2));
[email protected]372d34a2008-11-05 21:30:515376
[email protected]bb88e1d32013-05-03 23:11:075377 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5378 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:515379
thestig9d3bb0c2015-01-24 00:49:515380 const char* const kExpectedResponseData[] = {
[email protected]372d34a2008-11-05 21:30:515381 "hello world", "welcome"
5382 };
5383
5384 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:425385 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505386 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]372d34a2008-11-05 21:30:515387
[email protected]49639fa2011-12-20 23:22:415388 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:515389
[email protected]49639fa2011-12-20 23:22:415390 int rv = trans->Start(&request[i], callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425391 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]372d34a2008-11-05 21:30:515392
5393 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425394 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:515395
[email protected]1c773ea12009-04-28 19:58:425396 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505397 ASSERT_TRUE(response != NULL);
[email protected]372d34a2008-11-05 21:30:515398
[email protected]90499482013-06-01 00:39:505399 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]372d34a2008-11-05 21:30:515400 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5401
5402 std::string response_data;
5403 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:425404 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:515405 EXPECT_EQ(kExpectedResponseData[i], response_data);
5406 }
5407}
[email protected]f9ee6b52008-11-08 06:46:235408
5409// Test the request-challenge-retry sequence for basic auth when there is
5410// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:165411// it fails the identity from the URL is used to answer the challenge.
[email protected]23e482282013-06-14 16:08:025412TEST_P(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:425413 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235414 request.method = "GET";
[email protected]a97cca42009-08-14 01:00:295415 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:415416 request.load_flags = LOAD_NORMAL;
[email protected]a97cca42009-08-14 01:00:295417
[email protected]3fe8d2f82013-10-17 08:56:075418 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275419 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415420 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275421
[email protected]a97cca42009-08-14 01:00:295422 // The password contains an escaped character -- for this test to pass it
5423 // will need to be unescaped by HttpNetworkTransaction.
5424 EXPECT_EQ("b%40r", request.url.password());
5425
[email protected]f9ee6b52008-11-08 06:46:235426 MockWrite data_writes1[] = {
5427 MockWrite("GET / HTTP/1.1\r\n"
5428 "Host: www.google.com\r\n"
5429 "Connection: keep-alive\r\n\r\n"),
5430 };
5431
5432 MockRead data_reads1[] = {
5433 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5434 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5435 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065436 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235437 };
5438
[email protected]2262e3a2012-05-22 16:08:165439 // After the challenge above, the transaction will be restarted using the
5440 // identity from the url (foo, b@r) to answer the challenge.
5441 MockWrite data_writes2[] = {
5442 MockWrite("GET / HTTP/1.1\r\n"
5443 "Host: www.google.com\r\n"
5444 "Connection: keep-alive\r\n"
5445 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
5446 };
5447
5448 MockRead data_reads2[] = {
5449 MockRead("HTTP/1.0 200 OK\r\n"),
5450 MockRead("Content-Length: 100\r\n\r\n"),
5451 MockRead(SYNCHRONOUS, OK),
5452 };
5453
[email protected]31a2bfe2010-02-09 08:03:395454 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5455 data_writes1, arraysize(data_writes1));
[email protected]2262e3a2012-05-22 16:08:165456 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5457 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075458 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5459 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235460
[email protected]49639fa2011-12-20 23:22:415461 TestCompletionCallback callback1;
[email protected]49639fa2011-12-20 23:22:415462 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425463 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235464 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425465 EXPECT_EQ(OK, rv);
[email protected]2262e3a2012-05-22 16:08:165466 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5467
5468 TestCompletionCallback callback2;
5469 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
5470 EXPECT_EQ(ERR_IO_PENDING, rv);
5471 rv = callback2.WaitForResult();
5472 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225473 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5474
[email protected]2262e3a2012-05-22 16:08:165475 const HttpResponseInfo* response = trans->GetResponseInfo();
5476 ASSERT_TRUE(response != NULL);
5477
5478 // There is no challenge info, since the identity in URL worked.
5479 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5480
5481 EXPECT_EQ(100, response->headers->GetContentLength());
5482
5483 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:345484 base::MessageLoop::current()->RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:165485}
5486
5487// Test the request-challenge-retry sequence for basic auth when there is an
5488// incorrect identity in the URL. The identity from the URL should be used only
5489// once.
[email protected]23e482282013-06-14 16:08:025490TEST_P(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:165491 HttpRequestInfo request;
5492 request.method = "GET";
5493 // Note: the URL has a username:password in it. The password "baz" is
5494 // wrong (should be "bar").
5495 request.url = GURL("http://foo:[email protected]/");
5496
5497 request.load_flags = LOAD_NORMAL;
5498
[email protected]3fe8d2f82013-10-17 08:56:075499 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2262e3a2012-05-22 16:08:165500 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415501 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2262e3a2012-05-22 16:08:165502
5503 MockWrite data_writes1[] = {
5504 MockWrite("GET / HTTP/1.1\r\n"
5505 "Host: www.google.com\r\n"
5506 "Connection: keep-alive\r\n\r\n"),
5507 };
5508
5509 MockRead data_reads1[] = {
5510 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5511 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5512 MockRead("Content-Length: 10\r\n\r\n"),
5513 MockRead(SYNCHRONOUS, ERR_FAILED),
5514 };
5515
5516 // After the challenge above, the transaction will be restarted using the
5517 // identity from the url (foo, baz) to answer the challenge.
5518 MockWrite data_writes2[] = {
5519 MockWrite("GET / HTTP/1.1\r\n"
5520 "Host: www.google.com\r\n"
5521 "Connection: keep-alive\r\n"
5522 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
5523 };
5524
5525 MockRead data_reads2[] = {
5526 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5527 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5528 MockRead("Content-Length: 10\r\n\r\n"),
5529 MockRead(SYNCHRONOUS, ERR_FAILED),
5530 };
5531
5532 // After the challenge above, the transaction will be restarted using the
5533 // identity supplied by the user (foo, bar) to answer the challenge.
5534 MockWrite data_writes3[] = {
5535 MockWrite("GET / HTTP/1.1\r\n"
5536 "Host: www.google.com\r\n"
5537 "Connection: keep-alive\r\n"
5538 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5539 };
5540
5541 MockRead data_reads3[] = {
5542 MockRead("HTTP/1.0 200 OK\r\n"),
5543 MockRead("Content-Length: 100\r\n\r\n"),
5544 MockRead(SYNCHRONOUS, OK),
5545 };
5546
5547 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5548 data_writes1, arraysize(data_writes1));
5549 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5550 data_writes2, arraysize(data_writes2));
5551 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5552 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075553 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5554 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5555 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:165556
5557 TestCompletionCallback callback1;
5558
5559 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5560 EXPECT_EQ(ERR_IO_PENDING, rv);
5561
5562 rv = callback1.WaitForResult();
5563 EXPECT_EQ(OK, rv);
5564
5565 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5566 TestCompletionCallback callback2;
5567 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
5568 EXPECT_EQ(ERR_IO_PENDING, rv);
5569 rv = callback2.WaitForResult();
5570 EXPECT_EQ(OK, rv);
5571 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5572
5573 const HttpResponseInfo* response = trans->GetResponseInfo();
5574 ASSERT_TRUE(response != NULL);
5575 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
5576
5577 TestCompletionCallback callback3;
5578 rv = trans->RestartWithAuth(
5579 AuthCredentials(kFoo, kBar), callback3.callback());
5580 EXPECT_EQ(ERR_IO_PENDING, rv);
5581 rv = callback3.WaitForResult();
5582 EXPECT_EQ(OK, rv);
5583 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5584
5585 response = trans->GetResponseInfo();
5586 ASSERT_TRUE(response != NULL);
5587
5588 // There is no challenge info, since the identity worked.
5589 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5590
5591 EXPECT_EQ(100, response->headers->GetContentLength());
5592
[email protected]ea9dc9a2009-09-05 00:43:325593 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:345594 base::MessageLoop::current()->RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:325595}
5596
[email protected]2217aa22013-10-11 03:03:545597
5598// Test the request-challenge-retry sequence for basic auth when there is a
5599// correct identity in the URL, but its use is being suppressed. The identity
5600// from the URL should never be used.
5601TEST_P(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
5602 HttpRequestInfo request;
5603 request.method = "GET";
5604 request.url = GURL("http://foo:[email protected]/");
5605 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
5606
[email protected]3fe8d2f82013-10-17 08:56:075607 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2217aa22013-10-11 03:03:545608 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415609 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2217aa22013-10-11 03:03:545610
5611 MockWrite data_writes1[] = {
5612 MockWrite("GET / HTTP/1.1\r\n"
5613 "Host: www.google.com\r\n"
5614 "Connection: keep-alive\r\n\r\n"),
5615 };
5616
5617 MockRead data_reads1[] = {
5618 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5619 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5620 MockRead("Content-Length: 10\r\n\r\n"),
5621 MockRead(SYNCHRONOUS, ERR_FAILED),
5622 };
5623
5624 // After the challenge above, the transaction will be restarted using the
5625 // identity supplied by the user, not the one in the URL, to answer the
5626 // challenge.
5627 MockWrite data_writes3[] = {
5628 MockWrite("GET / HTTP/1.1\r\n"
5629 "Host: www.google.com\r\n"
5630 "Connection: keep-alive\r\n"
5631 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5632 };
5633
5634 MockRead data_reads3[] = {
5635 MockRead("HTTP/1.0 200 OK\r\n"),
5636 MockRead("Content-Length: 100\r\n\r\n"),
5637 MockRead(SYNCHRONOUS, OK),
5638 };
5639
5640 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5641 data_writes1, arraysize(data_writes1));
5642 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5643 data_writes3, arraysize(data_writes3));
5644 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5645 session_deps_.socket_factory->AddSocketDataProvider(&data3);
5646
5647 TestCompletionCallback callback1;
5648 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5649 EXPECT_EQ(ERR_IO_PENDING, rv);
5650 rv = callback1.WaitForResult();
5651 EXPECT_EQ(OK, rv);
5652 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5653
5654 const HttpResponseInfo* response = trans->GetResponseInfo();
5655 ASSERT_TRUE(response != NULL);
5656 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
5657
5658 TestCompletionCallback callback3;
5659 rv = trans->RestartWithAuth(
5660 AuthCredentials(kFoo, kBar), callback3.callback());
5661 EXPECT_EQ(ERR_IO_PENDING, rv);
5662 rv = callback3.WaitForResult();
5663 EXPECT_EQ(OK, rv);
5664 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5665
5666 response = trans->GetResponseInfo();
5667 ASSERT_TRUE(response != NULL);
5668
5669 // There is no challenge info, since the identity worked.
5670 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5671 EXPECT_EQ(100, response->headers->GetContentLength());
5672
5673 // Empty the current queue.
5674 base::MessageLoop::current()->RunUntilIdle();
5675}
5676
[email protected]f9ee6b52008-11-08 06:46:235677// Test that previously tried username/passwords for a realm get re-used.
[email protected]23e482282013-06-14 16:08:025678TEST_P(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
[email protected]bb88e1d32013-05-03 23:11:075679 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:235680
5681 // Transaction 1: authenticate (foo, bar) on MyRealm1
5682 {
[email protected]1c773ea12009-04-28 19:58:425683 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235684 request.method = "GET";
5685 request.url = GURL("http://www.google.com/x/y/z");
5686 request.load_flags = 0;
5687
[email protected]262eec82013-03-19 21:01:365688 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505689 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275690
[email protected]f9ee6b52008-11-08 06:46:235691 MockWrite data_writes1[] = {
5692 MockWrite("GET /x/y/z HTTP/1.1\r\n"
5693 "Host: www.google.com\r\n"
5694 "Connection: keep-alive\r\n\r\n"),
5695 };
5696
5697 MockRead data_reads1[] = {
5698 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5699 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5700 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065701 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235702 };
5703
5704 // Resend with authorization (username=foo, password=bar)
5705 MockWrite data_writes2[] = {
5706 MockWrite("GET /x/y/z HTTP/1.1\r\n"
5707 "Host: www.google.com\r\n"
5708 "Connection: keep-alive\r\n"
5709 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5710 };
5711
5712 // Sever accepts the authorization.
5713 MockRead data_reads2[] = {
5714 MockRead("HTTP/1.0 200 OK\r\n"),
5715 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065716 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235717 };
5718
[email protected]31a2bfe2010-02-09 08:03:395719 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5720 data_writes1, arraysize(data_writes1));
5721 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5722 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075723 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5724 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235725
[email protected]49639fa2011-12-20 23:22:415726 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235727
[email protected]49639fa2011-12-20 23:22:415728 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425729 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235730
5731 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425732 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235733
[email protected]1c773ea12009-04-28 19:58:425734 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505735 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045736 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:235737
[email protected]49639fa2011-12-20 23:22:415738 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:235739
[email protected]49639fa2011-12-20 23:22:415740 rv = trans->RestartWithAuth(
5741 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425742 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235743
5744 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425745 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235746
5747 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505748 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235749 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5750 EXPECT_EQ(100, response->headers->GetContentLength());
5751 }
5752
5753 // ------------------------------------------------------------------------
5754
5755 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
5756 {
[email protected]1c773ea12009-04-28 19:58:425757 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235758 request.method = "GET";
5759 // Note that Transaction 1 was at /x/y/z, so this is in the same
5760 // protection space as MyRealm1.
5761 request.url = GURL("http://www.google.com/x/y/a/b");
5762 request.load_flags = 0;
5763
[email protected]262eec82013-03-19 21:01:365764 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505765 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275766
[email protected]f9ee6b52008-11-08 06:46:235767 MockWrite data_writes1[] = {
5768 MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
5769 "Host: www.google.com\r\n"
5770 "Connection: keep-alive\r\n"
5771 // Send preemptive authorization for MyRealm1
5772 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5773 };
5774
5775 // The server didn't like the preemptive authorization, and
5776 // challenges us for a different realm (MyRealm2).
5777 MockRead data_reads1[] = {
5778 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5779 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
5780 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065781 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235782 };
5783
5784 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
5785 MockWrite data_writes2[] = {
5786 MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
5787 "Host: www.google.com\r\n"
5788 "Connection: keep-alive\r\n"
5789 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
5790 };
5791
5792 // Sever accepts the authorization.
5793 MockRead data_reads2[] = {
5794 MockRead("HTTP/1.0 200 OK\r\n"),
5795 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065796 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235797 };
5798
[email protected]31a2bfe2010-02-09 08:03:395799 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5800 data_writes1, arraysize(data_writes1));
5801 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5802 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075803 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5804 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235805
[email protected]49639fa2011-12-20 23:22:415806 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235807
[email protected]49639fa2011-12-20 23:22:415808 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425809 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235810
5811 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425812 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235813
[email protected]1c773ea12009-04-28 19:58:425814 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505815 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045816 ASSERT_TRUE(response->auth_challenge.get());
5817 EXPECT_FALSE(response->auth_challenge->is_proxy);
5818 EXPECT_EQ("www.google.com:80",
5819 response->auth_challenge->challenger.ToString());
5820 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
5821 EXPECT_EQ("basic", response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:235822
[email protected]49639fa2011-12-20 23:22:415823 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:235824
[email protected]49639fa2011-12-20 23:22:415825 rv = trans->RestartWithAuth(
5826 AuthCredentials(kFoo2, kBar2), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425827 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235828
5829 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425830 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235831
5832 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505833 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235834 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5835 EXPECT_EQ(100, response->headers->GetContentLength());
5836 }
5837
5838 // ------------------------------------------------------------------------
5839
5840 // Transaction 3: Resend a request in MyRealm's protection space --
5841 // succeed with preemptive authorization.
5842 {
[email protected]1c773ea12009-04-28 19:58:425843 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235844 request.method = "GET";
5845 request.url = GURL("http://www.google.com/x/y/z2");
5846 request.load_flags = 0;
5847
[email protected]262eec82013-03-19 21:01:365848 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505849 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275850
[email protected]f9ee6b52008-11-08 06:46:235851 MockWrite data_writes1[] = {
5852 MockWrite("GET /x/y/z2 HTTP/1.1\r\n"
5853 "Host: www.google.com\r\n"
5854 "Connection: keep-alive\r\n"
5855 // The authorization for MyRealm1 gets sent preemptively
5856 // (since the url is in the same protection space)
5857 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5858 };
5859
5860 // Sever accepts the preemptive authorization
5861 MockRead data_reads1[] = {
5862 MockRead("HTTP/1.0 200 OK\r\n"),
5863 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065864 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235865 };
5866
[email protected]31a2bfe2010-02-09 08:03:395867 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5868 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075869 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:235870
[email protected]49639fa2011-12-20 23:22:415871 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235872
[email protected]49639fa2011-12-20 23:22:415873 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425874 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235875
5876 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425877 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235878
[email protected]1c773ea12009-04-28 19:58:425879 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505880 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235881
5882 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5883 EXPECT_EQ(100, response->headers->GetContentLength());
5884 }
5885
5886 // ------------------------------------------------------------------------
5887
5888 // Transaction 4: request another URL in MyRealm (however the
5889 // url is not known to belong to the protection space, so no pre-auth).
5890 {
[email protected]1c773ea12009-04-28 19:58:425891 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235892 request.method = "GET";
5893 request.url = GURL("http://www.google.com/x/1");
5894 request.load_flags = 0;
5895
[email protected]262eec82013-03-19 21:01:365896 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505897 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275898
[email protected]f9ee6b52008-11-08 06:46:235899 MockWrite data_writes1[] = {
5900 MockWrite("GET /x/1 HTTP/1.1\r\n"
5901 "Host: www.google.com\r\n"
5902 "Connection: keep-alive\r\n\r\n"),
5903 };
5904
5905 MockRead data_reads1[] = {
5906 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5907 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5908 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065909 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235910 };
5911
5912 // Resend with authorization from MyRealm's cache.
5913 MockWrite data_writes2[] = {
5914 MockWrite("GET /x/1 HTTP/1.1\r\n"
5915 "Host: www.google.com\r\n"
5916 "Connection: keep-alive\r\n"
5917 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5918 };
5919
5920 // Sever accepts the authorization.
5921 MockRead data_reads2[] = {
5922 MockRead("HTTP/1.0 200 OK\r\n"),
5923 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065924 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235925 };
5926
[email protected]31a2bfe2010-02-09 08:03:395927 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5928 data_writes1, arraysize(data_writes1));
5929 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5930 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075931 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5932 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235933
[email protected]49639fa2011-12-20 23:22:415934 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235935
[email protected]49639fa2011-12-20 23:22:415936 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425937 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235938
5939 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425940 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235941
[email protected]0757e7702009-03-27 04:00:225942 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:415943 TestCompletionCallback callback2;
5944 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425945 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:225946 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425947 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225948 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5949
[email protected]1c773ea12009-04-28 19:58:425950 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505951 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235952 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5953 EXPECT_EQ(100, response->headers->GetContentLength());
5954 }
5955
5956 // ------------------------------------------------------------------------
5957
5958 // Transaction 5: request a URL in MyRealm, but the server rejects the
5959 // cached identity. Should invalidate and re-prompt.
5960 {
[email protected]1c773ea12009-04-28 19:58:425961 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235962 request.method = "GET";
5963 request.url = GURL("http://www.google.com/p/q/t");
5964 request.load_flags = 0;
5965
[email protected]262eec82013-03-19 21:01:365966 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505967 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275968
[email protected]f9ee6b52008-11-08 06:46:235969 MockWrite data_writes1[] = {
5970 MockWrite("GET /p/q/t HTTP/1.1\r\n"
5971 "Host: www.google.com\r\n"
5972 "Connection: keep-alive\r\n\r\n"),
5973 };
5974
5975 MockRead data_reads1[] = {
5976 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5977 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5978 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065979 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235980 };
5981
5982 // Resend with authorization from cache for MyRealm.
5983 MockWrite data_writes2[] = {
5984 MockWrite("GET /p/q/t HTTP/1.1\r\n"
5985 "Host: www.google.com\r\n"
5986 "Connection: keep-alive\r\n"
5987 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5988 };
5989
5990 // Sever rejects the authorization.
5991 MockRead data_reads2[] = {
5992 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5993 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5994 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065995 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235996 };
5997
5998 // At this point we should prompt for new credentials for MyRealm.
5999 // Restart with username=foo3, password=foo4.
6000 MockWrite data_writes3[] = {
6001 MockWrite("GET /p/q/t HTTP/1.1\r\n"
6002 "Host: www.google.com\r\n"
6003 "Connection: keep-alive\r\n"
6004 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
6005 };
6006
6007 // Sever accepts the authorization.
6008 MockRead data_reads3[] = {
6009 MockRead("HTTP/1.0 200 OK\r\n"),
6010 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066011 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:236012 };
6013
[email protected]31a2bfe2010-02-09 08:03:396014 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6015 data_writes1, arraysize(data_writes1));
6016 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6017 data_writes2, arraysize(data_writes2));
6018 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6019 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076020 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6021 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6022 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:236023
[email protected]49639fa2011-12-20 23:22:416024 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:236025
[email protected]49639fa2011-12-20 23:22:416026 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426027 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236028
6029 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426030 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236031
[email protected]0757e7702009-03-27 04:00:226032 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:416033 TestCompletionCallback callback2;
6034 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:426035 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:226036 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426037 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:226038 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6039
[email protected]1c773ea12009-04-28 19:58:426040 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506041 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:046042 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:236043
[email protected]49639fa2011-12-20 23:22:416044 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:236045
[email protected]49639fa2011-12-20 23:22:416046 rv = trans->RestartWithAuth(
6047 AuthCredentials(kFoo3, kBar3), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:426048 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236049
[email protected]0757e7702009-03-27 04:00:226050 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426051 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236052
6053 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506054 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:236055 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6056 EXPECT_EQ(100, response->headers->GetContentLength());
6057 }
6058}
[email protected]89ceba9a2009-03-21 03:46:066059
[email protected]3c32c5f2010-05-18 15:18:126060// Tests that nonce count increments when multiple auth attempts
6061// are started with the same nonce.
[email protected]23e482282013-06-14 16:08:026062TEST_P(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:446063 HttpAuthHandlerDigest::Factory* digest_factory =
6064 new HttpAuthHandlerDigest::Factory();
6065 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
6066 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
6067 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:076068 session_deps_.http_auth_handler_factory.reset(digest_factory);
6069 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:126070
6071 // Transaction 1: authenticate (foo, bar) on MyRealm1
6072 {
[email protected]3c32c5f2010-05-18 15:18:126073 HttpRequestInfo request;
6074 request.method = "GET";
6075 request.url = GURL("http://www.google.com/x/y/z");
6076 request.load_flags = 0;
6077
[email protected]262eec82013-03-19 21:01:366078 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506079 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276080
[email protected]3c32c5f2010-05-18 15:18:126081 MockWrite data_writes1[] = {
6082 MockWrite("GET /x/y/z HTTP/1.1\r\n"
6083 "Host: www.google.com\r\n"
6084 "Connection: keep-alive\r\n\r\n"),
6085 };
6086
6087 MockRead data_reads1[] = {
6088 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6089 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
6090 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066091 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:126092 };
6093
6094 // Resend with authorization (username=foo, password=bar)
6095 MockWrite data_writes2[] = {
6096 MockWrite("GET /x/y/z HTTP/1.1\r\n"
6097 "Host: www.google.com\r\n"
6098 "Connection: keep-alive\r\n"
6099 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
6100 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
6101 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
6102 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
6103 };
6104
6105 // Sever accepts the authorization.
6106 MockRead data_reads2[] = {
6107 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:066108 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:126109 };
6110
6111 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6112 data_writes1, arraysize(data_writes1));
6113 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6114 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076115 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6116 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:126117
[email protected]49639fa2011-12-20 23:22:416118 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:126119
[email protected]49639fa2011-12-20 23:22:416120 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:126121 EXPECT_EQ(ERR_IO_PENDING, rv);
6122
6123 rv = callback1.WaitForResult();
6124 EXPECT_EQ(OK, rv);
6125
6126 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506127 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:046128 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:126129
[email protected]49639fa2011-12-20 23:22:416130 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:126131
[email protected]49639fa2011-12-20 23:22:416132 rv = trans->RestartWithAuth(
6133 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]3c32c5f2010-05-18 15:18:126134 EXPECT_EQ(ERR_IO_PENDING, rv);
6135
6136 rv = callback2.WaitForResult();
6137 EXPECT_EQ(OK, rv);
6138
6139 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506140 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:126141 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6142 }
6143
6144 // ------------------------------------------------------------------------
6145
6146 // Transaction 2: Request another resource in digestive's protection space.
6147 // This will preemptively add an Authorization header which should have an
6148 // "nc" value of 2 (as compared to 1 in the first use.
6149 {
[email protected]3c32c5f2010-05-18 15:18:126150 HttpRequestInfo request;
6151 request.method = "GET";
6152 // Note that Transaction 1 was at /x/y/z, so this is in the same
6153 // protection space as digest.
6154 request.url = GURL("http://www.google.com/x/y/a/b");
6155 request.load_flags = 0;
6156
[email protected]262eec82013-03-19 21:01:366157 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506158 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276159
[email protected]3c32c5f2010-05-18 15:18:126160 MockWrite data_writes1[] = {
6161 MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
6162 "Host: www.google.com\r\n"
6163 "Connection: keep-alive\r\n"
6164 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
6165 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
6166 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
6167 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
6168 };
6169
6170 // Sever accepts the authorization.
6171 MockRead data_reads1[] = {
6172 MockRead("HTTP/1.0 200 OK\r\n"),
6173 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066174 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:126175 };
6176
6177 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6178 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:076179 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:126180
[email protected]49639fa2011-12-20 23:22:416181 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:126182
[email protected]49639fa2011-12-20 23:22:416183 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:126184 EXPECT_EQ(ERR_IO_PENDING, rv);
6185
6186 rv = callback1.WaitForResult();
6187 EXPECT_EQ(OK, rv);
6188
6189 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506190 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:126191 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6192 }
6193}
6194
[email protected]89ceba9a2009-03-21 03:46:066195// Test the ResetStateForRestart() private method.
[email protected]23e482282013-06-14 16:08:026196TEST_P(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:066197 // Create a transaction (the dependencies aren't important).
[email protected]3fe8d2f82013-10-17 08:56:076198 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:406199 scoped_ptr<HttpNetworkTransaction> trans(
dcheng48459ac22014-08-26 00:46:416200 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]89ceba9a2009-03-21 03:46:066201
6202 // Setup some state (which we expect ResetStateForRestart() will clear).
[email protected]89ceba9a2009-03-21 03:46:066203 trans->read_buf_ = new IOBuffer(15);
6204 trans->read_buf_len_ = 15;
[email protected]b94f92d2010-10-27 16:45:206205 trans->request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:066206
6207 // Setup state in response_
[email protected]a7e41312009-12-16 23:18:146208 HttpResponseInfo* response = &trans->response_;
[email protected]0877e3d2009-10-17 22:29:576209 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:086210 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:576211 response->response_time = base::Time::Now();
6212 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:066213
6214 { // Setup state for response_.vary_data
6215 HttpRequestInfo request;
6216 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
6217 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:276218 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:436219 request.extra_headers.SetHeader("Foo", "1");
6220 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:506221 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:066222 }
6223
6224 // Cause the above state to be reset.
6225 trans->ResetStateForRestart();
6226
6227 // Verify that the state that needed to be reset, has been reset.
[email protected]9b6fee12009-09-29 18:13:076228 EXPECT_TRUE(trans->read_buf_.get() == NULL);
[email protected]89ceba9a2009-03-21 03:46:066229 EXPECT_EQ(0, trans->read_buf_len_);
[email protected]b94f92d2010-10-27 16:45:206230 EXPECT_TRUE(trans->request_headers_.IsEmpty());
[email protected]0877e3d2009-10-17 22:29:576231 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6232 EXPECT_TRUE(response->headers.get() == NULL);
[email protected]34f40942010-10-04 00:34:046233 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:086234 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:576235 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:066236}
6237
[email protected]bacff652009-03-31 17:50:336238// Test HTTPS connections to a site with a bad certificate
[email protected]23e482282013-06-14 16:08:026239TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:336240 HttpRequestInfo request;
6241 request.method = "GET";
6242 request.url = GURL("https://www.google.com/");
6243 request.load_flags = 0;
6244
[email protected]3fe8d2f82013-10-17 08:56:076245 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276246 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416247 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276248
[email protected]bacff652009-03-31 17:50:336249 MockWrite data_writes[] = {
6250 MockWrite("GET / HTTP/1.1\r\n"
6251 "Host: www.google.com\r\n"
6252 "Connection: keep-alive\r\n\r\n"),
6253 };
6254
6255 MockRead data_reads[] = {
6256 MockRead("HTTP/1.0 200 OK\r\n"),
6257 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6258 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066259 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:336260 };
6261
[email protected]5ecc992a42009-11-11 01:41:596262 StaticSocketDataProvider ssl_bad_certificate;
[email protected]31a2bfe2010-02-09 08:03:396263 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6264 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066265 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
6266 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:336267
[email protected]bb88e1d32013-05-03 23:11:076268 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
6269 session_deps_.socket_factory->AddSocketDataProvider(&data);
6270 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
6271 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:336272
[email protected]49639fa2011-12-20 23:22:416273 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:336274
[email protected]49639fa2011-12-20 23:22:416275 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:336276 EXPECT_EQ(ERR_IO_PENDING, rv);
6277
6278 rv = callback.WaitForResult();
6279 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
6280
[email protected]49639fa2011-12-20 23:22:416281 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:336282 EXPECT_EQ(ERR_IO_PENDING, rv);
6283
6284 rv = callback.WaitForResult();
6285 EXPECT_EQ(OK, rv);
6286
6287 const HttpResponseInfo* response = trans->GetResponseInfo();
6288
[email protected]fe2255a2011-09-20 19:37:506289 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:336290 EXPECT_EQ(100, response->headers->GetContentLength());
6291}
6292
6293// Test HTTPS connections to a site with a bad certificate, going through a
6294// proxy
[email protected]23e482282013-06-14 16:08:026295TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
[email protected]bb88e1d32013-05-03 23:11:076296 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]bacff652009-03-31 17:50:336297
6298 HttpRequestInfo request;
6299 request.method = "GET";
6300 request.url = GURL("https://www.google.com/");
6301 request.load_flags = 0;
6302
6303 MockWrite proxy_writes[] = {
6304 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:456305 "Host: www.google.com\r\n"
6306 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:336307 };
6308
6309 MockRead proxy_reads[] = {
6310 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066311 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:336312 };
6313
6314 MockWrite data_writes[] = {
6315 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:456316 "Host: www.google.com\r\n"
6317 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:336318 MockWrite("GET / HTTP/1.1\r\n"
6319 "Host: www.google.com\r\n"
6320 "Connection: keep-alive\r\n\r\n"),
6321 };
6322
6323 MockRead data_reads[] = {
6324 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
6325 MockRead("HTTP/1.0 200 OK\r\n"),
6326 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6327 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066328 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:336329 };
6330
[email protected]31a2bfe2010-02-09 08:03:396331 StaticSocketDataProvider ssl_bad_certificate(
6332 proxy_reads, arraysize(proxy_reads),
6333 proxy_writes, arraysize(proxy_writes));
6334 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6335 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066336 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
6337 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:336338
[email protected]bb88e1d32013-05-03 23:11:076339 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
6340 session_deps_.socket_factory->AddSocketDataProvider(&data);
6341 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
6342 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:336343
[email protected]49639fa2011-12-20 23:22:416344 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:336345
6346 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:076347 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:336348
[email protected]3fe8d2f82013-10-17 08:56:076349 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:406350 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416351 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bacff652009-03-31 17:50:336352
[email protected]49639fa2011-12-20 23:22:416353 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:336354 EXPECT_EQ(ERR_IO_PENDING, rv);
6355
6356 rv = callback.WaitForResult();
6357 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
6358
[email protected]49639fa2011-12-20 23:22:416359 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:336360 EXPECT_EQ(ERR_IO_PENDING, rv);
6361
6362 rv = callback.WaitForResult();
6363 EXPECT_EQ(OK, rv);
6364
6365 const HttpResponseInfo* response = trans->GetResponseInfo();
6366
[email protected]fe2255a2011-09-20 19:37:506367 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:336368 EXPECT_EQ(100, response->headers->GetContentLength());
6369 }
6370}
6371
[email protected]2df19bb2010-08-25 20:13:466372
6373// Test HTTPS connections to a site, going through an HTTPS proxy
[email protected]23e482282013-06-14 16:08:026374TEST_P(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076375 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206376 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
6377 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076378 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:466379
6380 HttpRequestInfo request;
6381 request.method = "GET";
6382 request.url = GURL("https://www.google.com/");
6383 request.load_flags = 0;
6384
6385 MockWrite data_writes[] = {
6386 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6387 "Host: www.google.com\r\n"
6388 "Proxy-Connection: keep-alive\r\n\r\n"),
6389 MockWrite("GET / HTTP/1.1\r\n"
6390 "Host: www.google.com\r\n"
6391 "Connection: keep-alive\r\n\r\n"),
6392 };
6393
6394 MockRead data_reads[] = {
6395 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
6396 MockRead("HTTP/1.1 200 OK\r\n"),
6397 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6398 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066399 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:466400 };
6401
6402 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6403 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066404 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
6405 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:466406
[email protected]bb88e1d32013-05-03 23:11:076407 session_deps_.socket_factory->AddSocketDataProvider(&data);
6408 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
6409 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:466410
[email protected]49639fa2011-12-20 23:22:416411 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:466412
[email protected]3fe8d2f82013-10-17 08:56:076413 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:466414 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416415 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2df19bb2010-08-25 20:13:466416
[email protected]49639fa2011-12-20 23:22:416417 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:466418 EXPECT_EQ(ERR_IO_PENDING, rv);
6419
6420 rv = callback.WaitForResult();
6421 EXPECT_EQ(OK, rv);
6422 const HttpResponseInfo* response = trans->GetResponseInfo();
6423
[email protected]fe2255a2011-09-20 19:37:506424 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:466425
6426 EXPECT_TRUE(response->headers->IsKeepAlive());
6427 EXPECT_EQ(200, response->headers->response_code());
6428 EXPECT_EQ(100, response->headers->GetContentLength());
6429 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:206430
6431 LoadTimingInfo load_timing_info;
6432 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6433 TestLoadTimingNotReusedWithPac(load_timing_info,
6434 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:466435}
6436
[email protected]511f6f52010-12-17 03:58:296437// Test an HTTPS Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:026438TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076439 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206440 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
6441 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076442 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:296443
6444 HttpRequestInfo request;
6445 request.method = "GET";
6446 request.url = GURL("https://www.google.com/");
6447 request.load_flags = 0;
6448
6449 MockWrite data_writes[] = {
6450 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6451 "Host: www.google.com\r\n"
6452 "Proxy-Connection: keep-alive\r\n\r\n"),
6453 };
6454
6455 MockRead data_reads[] = {
6456 MockRead("HTTP/1.1 302 Redirect\r\n"),
6457 MockRead("Location: http://login.example.com/\r\n"),
6458 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066459 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:296460 };
6461
6462 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6463 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066464 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:296465
[email protected]bb88e1d32013-05-03 23:11:076466 session_deps_.socket_factory->AddSocketDataProvider(&data);
6467 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296468
[email protected]49639fa2011-12-20 23:22:416469 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296470
[email protected]3fe8d2f82013-10-17 08:56:076471 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296472 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416473 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:296474
[email protected]49639fa2011-12-20 23:22:416475 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296476 EXPECT_EQ(ERR_IO_PENDING, rv);
6477
6478 rv = callback.WaitForResult();
6479 EXPECT_EQ(OK, rv);
6480 const HttpResponseInfo* response = trans->GetResponseInfo();
6481
[email protected]fe2255a2011-09-20 19:37:506482 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:296483
6484 EXPECT_EQ(302, response->headers->response_code());
6485 std::string url;
6486 EXPECT_TRUE(response->headers->IsRedirect(&url));
6487 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:206488
6489 // In the case of redirects from proxies, HttpNetworkTransaction returns
6490 // timing for the proxy connection instead of the connection to the host,
6491 // and no send / receive times.
6492 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
6493 LoadTimingInfo load_timing_info;
6494 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6495
6496 EXPECT_FALSE(load_timing_info.socket_reused);
6497 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
6498
6499 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
6500 EXPECT_LE(load_timing_info.proxy_resolve_start,
6501 load_timing_info.proxy_resolve_end);
6502 EXPECT_LE(load_timing_info.proxy_resolve_end,
6503 load_timing_info.connect_timing.connect_start);
6504 ExpectConnectTimingHasTimes(
6505 load_timing_info.connect_timing,
6506 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
6507
6508 EXPECT_TRUE(load_timing_info.send_start.is_null());
6509 EXPECT_TRUE(load_timing_info.send_end.is_null());
6510 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:296511}
6512
6513// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:026514TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
[email protected]bb88e1d32013-05-03 23:11:076515 session_deps_.proxy_service.reset(
[email protected]511f6f52010-12-17 03:58:296516 ProxyService::CreateFixed("https://proxy:70"));
6517
6518 HttpRequestInfo request;
6519 request.method = "GET";
6520 request.url = GURL("https://www.google.com/");
6521 request.load_flags = 0;
6522
lgarrona91df87f2014-12-05 00:51:346523 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(
6524 NULL, 0, 1, LOWEST, HostPortPair("www.google.com", 443)));
[email protected]c10b20852013-05-15 21:29:206525 scoped_ptr<SpdyFrame> goaway(
6526 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:296527 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:066528 CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
[email protected]57d2dfa2013-06-24 06:04:126529 CreateMockWrite(*goaway.get(), 3, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:296530 };
6531
6532 static const char* const kExtraHeaders[] = {
6533 "location",
6534 "http://login.example.com/",
6535 };
[email protected]ff98d7f02012-03-22 21:44:196536 scoped_ptr<SpdyFrame> resp(
[email protected]23e482282013-06-14 16:08:026537 spdy_util_.ConstructSpdySynReplyError("302 Redirect", kExtraHeaders,
[email protected]511f6f52010-12-17 03:58:296538 arraysize(kExtraHeaders)/2, 1));
6539 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:066540 CreateMockRead(*resp.get(), 1, SYNCHRONOUS),
6541 MockRead(ASYNC, 0, 2), // EOF
[email protected]511f6f52010-12-17 03:58:296542 };
6543
[email protected]dd54bd82012-07-19 23:44:576544 DelayedSocketData data(
6545 1, // wait for one write to finish before reading.
6546 data_reads, arraysize(data_reads),
6547 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066548 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]23e482282013-06-14 16:08:026549 proxy_ssl.SetNextProto(GetParam());
[email protected]511f6f52010-12-17 03:58:296550
[email protected]bb88e1d32013-05-03 23:11:076551 session_deps_.socket_factory->AddSocketDataProvider(&data);
6552 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296553
[email protected]49639fa2011-12-20 23:22:416554 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296555
[email protected]3fe8d2f82013-10-17 08:56:076556 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296557 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416558 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:296559
[email protected]49639fa2011-12-20 23:22:416560 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296561 EXPECT_EQ(ERR_IO_PENDING, rv);
6562
6563 rv = callback.WaitForResult();
6564 EXPECT_EQ(OK, rv);
6565 const HttpResponseInfo* response = trans->GetResponseInfo();
6566
[email protected]fe2255a2011-09-20 19:37:506567 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:296568
6569 EXPECT_EQ(302, response->headers->response_code());
6570 std::string url;
6571 EXPECT_TRUE(response->headers->IsRedirect(&url));
6572 EXPECT_EQ("http://login.example.com/", url);
6573}
6574
[email protected]4eddbc732012-08-09 05:40:176575// Test that an HTTPS proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:026576TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:176577 ErrorResponseToHttpsConnectViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076578 session_deps_.proxy_service.reset(
[email protected]511f6f52010-12-17 03:58:296579 ProxyService::CreateFixed("https://proxy:70"));
6580
6581 HttpRequestInfo request;
6582 request.method = "GET";
6583 request.url = GURL("https://www.google.com/");
6584 request.load_flags = 0;
6585
6586 MockWrite data_writes[] = {
6587 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6588 "Host: www.google.com\r\n"
6589 "Proxy-Connection: keep-alive\r\n\r\n"),
6590 };
6591
6592 MockRead data_reads[] = {
6593 MockRead("HTTP/1.1 404 Not Found\r\n"),
6594 MockRead("Content-Length: 23\r\n\r\n"),
6595 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:066596 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:296597 };
6598
6599 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6600 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066601 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:296602
[email protected]bb88e1d32013-05-03 23:11:076603 session_deps_.socket_factory->AddSocketDataProvider(&data);
6604 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296605
[email protected]49639fa2011-12-20 23:22:416606 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296607
[email protected]3fe8d2f82013-10-17 08:56:076608 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296609 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416610 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:296611
[email protected]49639fa2011-12-20 23:22:416612 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296613 EXPECT_EQ(ERR_IO_PENDING, rv);
6614
6615 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:176616 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:296617
[email protected]4eddbc732012-08-09 05:40:176618 // TODO(ttuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:296619}
6620
[email protected]4eddbc732012-08-09 05:40:176621// Test that a SPDY proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:026622TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:176623 ErrorResponseToHttpsConnectViaSpdyProxy) {
[email protected]bb88e1d32013-05-03 23:11:076624 session_deps_.proxy_service.reset(
6625 ProxyService::CreateFixed("https://proxy:70"));
[email protected]511f6f52010-12-17 03:58:296626
6627 HttpRequestInfo request;
6628 request.method = "GET";
6629 request.url = GURL("https://www.google.com/");
6630 request.load_flags = 0;
6631
lgarrona91df87f2014-12-05 00:51:346632 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(
6633 NULL, 0, 1, LOWEST, HostPortPair("www.google.com", 443)));
[email protected]c10b20852013-05-15 21:29:206634 scoped_ptr<SpdyFrame> rst(
6635 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:296636 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:066637 CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
[email protected]4eddbc732012-08-09 05:40:176638 CreateMockWrite(*rst.get(), 3, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:296639 };
6640
6641 static const char* const kExtraHeaders[] = {
6642 "location",
6643 "http://login.example.com/",
6644 };
[email protected]ff98d7f02012-03-22 21:44:196645 scoped_ptr<SpdyFrame> resp(
[email protected]23e482282013-06-14 16:08:026646 spdy_util_.ConstructSpdySynReplyError("404 Not Found", kExtraHeaders,
[email protected]511f6f52010-12-17 03:58:296647 arraysize(kExtraHeaders)/2, 1));
[email protected]ff98d7f02012-03-22 21:44:196648 scoped_ptr<SpdyFrame> body(
[email protected]23e482282013-06-14 16:08:026649 spdy_util_.ConstructSpdyBodyFrame(
6650 1, "The host does not exist", 23, true));
[email protected]511f6f52010-12-17 03:58:296651 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:066652 CreateMockRead(*resp.get(), 1, SYNCHRONOUS),
6653 CreateMockRead(*body.get(), 2, SYNCHRONOUS),
[email protected]4eddbc732012-08-09 05:40:176654 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:296655 };
6656
[email protected]dd54bd82012-07-19 23:44:576657 DelayedSocketData data(
6658 1, // wait for one write to finish before reading.
6659 data_reads, arraysize(data_reads),
6660 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066661 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]23e482282013-06-14 16:08:026662 proxy_ssl.SetNextProto(GetParam());
[email protected]511f6f52010-12-17 03:58:296663
[email protected]bb88e1d32013-05-03 23:11:076664 session_deps_.socket_factory->AddSocketDataProvider(&data);
6665 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296666
[email protected]49639fa2011-12-20 23:22:416667 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296668
[email protected]3fe8d2f82013-10-17 08:56:076669 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296670 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416671 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:296672
[email protected]49639fa2011-12-20 23:22:416673 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296674 EXPECT_EQ(ERR_IO_PENDING, rv);
6675
6676 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:176677 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:296678
[email protected]4eddbc732012-08-09 05:40:176679 // TODO(ttuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:296680}
6681
[email protected]0c5fb722012-02-28 11:50:356682// Test the request-challenge-retry sequence for basic auth, through
6683// a SPDY proxy over a single SPDY session.
[email protected]23e482282013-06-14 16:08:026684TEST_P(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:356685 HttpRequestInfo request;
6686 request.method = "GET";
6687 request.url = GURL("https://www.google.com/");
6688 // when the no authentication data flag is set.
6689 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
6690
6691 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076692 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206693 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
[email protected]333bdf62012-06-08 22:57:296694 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076695 session_deps_.net_log = log.bound().net_log();
6696 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:356697
6698 // Since we have proxy, should try to establish tunnel.
lgarrona91df87f2014-12-05 00:51:346699 scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyConnect(
6700 NULL, 0, 1, LOWEST, HostPortPair("www.google.com", 443)));
[email protected]c10b20852013-05-15 21:29:206701 scoped_ptr<SpdyFrame> rst(
6702 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]0c5fb722012-02-28 11:50:356703
6704 // After calling trans->RestartWithAuth(), this is the request we should
6705 // be issuing -- the final header line contains the credentials.
6706 const char* const kAuthCredentials[] = {
6707 "proxy-authorization", "Basic Zm9vOmJhcg==",
6708 };
[email protected]fba2dbde2013-05-24 16:09:016709 scoped_ptr<SpdyFrame> connect2(spdy_util_.ConstructSpdyConnect(
lgarrona91df87f2014-12-05 00:51:346710 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST,
6711 HostPortPair("www.google.com", 443)));
[email protected]0c5fb722012-02-28 11:50:356712 // fetch https://www.google.com/ via HTTP
6713 const char get[] = "GET / HTTP/1.1\r\n"
6714 "Host: www.google.com\r\n"
6715 "Connection: keep-alive\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:196716 scoped_ptr<SpdyFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:026717 spdy_util_.ConstructSpdyBodyFrame(3, get, strlen(get), false));
[email protected]0c5fb722012-02-28 11:50:356718
6719 MockWrite spdy_writes[] = {
[email protected]3d7c43f2012-07-10 21:26:206720 CreateMockWrite(*req, 1, ASYNC),
[email protected]c92f4b4542012-07-26 23:53:216721 CreateMockWrite(*rst, 4, ASYNC),
6722 CreateMockWrite(*connect2, 5),
[email protected]3d7c43f2012-07-10 21:26:206723 CreateMockWrite(*wrapped_get, 8),
[email protected]0c5fb722012-02-28 11:50:356724 };
6725
6726 // The proxy responds to the connect with a 407, using a persistent
6727 // connection.
thestig9d3bb0c2015-01-24 00:49:516728 const char kAuthStatus[] = "407";
[email protected]0c5fb722012-02-28 11:50:356729 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:356730 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
6731 };
[email protected]745aa9c2014-06-27 02:21:296732 scoped_ptr<SpdyFrame> conn_auth_resp(spdy_util_.ConstructSpdySynReplyError(
6733 kAuthStatus, kAuthChallenge, arraysize(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:356734
[email protected]23e482282013-06-14 16:08:026735 scoped_ptr<SpdyFrame> conn_resp(
6736 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:356737 const char resp[] = "HTTP/1.1 200 OK\r\n"
6738 "Content-Length: 5\r\n\r\n";
6739
[email protected]ff98d7f02012-03-22 21:44:196740 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:026741 spdy_util_.ConstructSpdyBodyFrame(3, resp, strlen(resp), false));
[email protected]ff98d7f02012-03-22 21:44:196742 scoped_ptr<SpdyFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:026743 spdy_util_.ConstructSpdyBodyFrame(3, "hello", 5, false));
[email protected]0c5fb722012-02-28 11:50:356744 MockRead spdy_reads[] = {
[email protected]3d7c43f2012-07-10 21:26:206745 CreateMockRead(*conn_auth_resp, 2, ASYNC),
6746 CreateMockRead(*conn_resp, 6, ASYNC),
6747 CreateMockRead(*wrapped_get_resp, 9, ASYNC),
6748 CreateMockRead(*wrapped_body, 10, ASYNC),
6749 MockRead(ASYNC, OK, 11), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:356750 };
6751
[email protected]dd54bd82012-07-19 23:44:576752 OrderedSocketData spdy_data(
6753 spdy_reads, arraysize(spdy_reads),
6754 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:076755 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:356756 // Negotiate SPDY to the proxy
6757 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:026758 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:076759 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:356760 // Vanilla SSL to the server
6761 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076762 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:356763
6764 TestCompletionCallback callback1;
6765
[email protected]262eec82013-03-19 21:01:366766 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506767 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0c5fb722012-02-28 11:50:356768
6769 int rv = trans->Start(&request, callback1.callback(), log.bound());
6770 EXPECT_EQ(ERR_IO_PENDING, rv);
6771
6772 rv = callback1.WaitForResult();
6773 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:576774 net::CapturingNetLog::CapturedEntryList entries;
[email protected]0c5fb722012-02-28 11:50:356775 log.GetEntries(&entries);
6776 size_t pos = ExpectLogContainsSomewhere(
6777 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
6778 NetLog::PHASE_NONE);
6779 ExpectLogContainsSomewhere(
6780 entries, pos,
6781 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
6782 NetLog::PHASE_NONE);
6783
6784 const HttpResponseInfo* response = trans->GetResponseInfo();
6785 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:506786 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]0c5fb722012-02-28 11:50:356787 EXPECT_EQ(407, response->headers->response_code());
6788 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6789 EXPECT_TRUE(response->auth_challenge.get() != NULL);
6790 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
6791
6792 TestCompletionCallback callback2;
6793
6794 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
6795 callback2.callback());
6796 EXPECT_EQ(ERR_IO_PENDING, rv);
6797
6798 rv = callback2.WaitForResult();
6799 EXPECT_EQ(OK, rv);
6800
6801 response = trans->GetResponseInfo();
6802 ASSERT_TRUE(response != NULL);
6803
6804 EXPECT_TRUE(response->headers->IsKeepAlive());
6805 EXPECT_EQ(200, response->headers->response_code());
6806 EXPECT_EQ(5, response->headers->GetContentLength());
6807 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6808
6809 // The password prompt info should not be set.
6810 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6811
[email protected]029c83b62013-01-24 05:28:206812 LoadTimingInfo load_timing_info;
6813 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6814 TestLoadTimingNotReusedWithPac(load_timing_info,
6815 CONNECT_TIMING_HAS_SSL_TIMES);
6816
[email protected]0c5fb722012-02-28 11:50:356817 trans.reset();
6818 session->CloseAllConnections();
6819}
6820
[email protected]7c6f7ba2012-04-03 04:09:296821// Test that an explicitly trusted SPDY proxy can push a resource from an
6822// origin that is different from that of its associated resource.
[email protected]23e482282013-06-14 16:08:026823TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPush) {
[email protected]7c6f7ba2012-04-03 04:09:296824 HttpRequestInfo request;
6825 HttpRequestInfo push_request;
6826
[email protected]7c6f7ba2012-04-03 04:09:296827 request.method = "GET";
6828 request.url = GURL("http://www.google.com/");
6829 push_request.method = "GET";
6830 push_request.url = GURL("http://www.another-origin.com/foo.dat");
6831
[email protected]7c6f7ba2012-04-03 04:09:296832 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076833 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206834 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
[email protected]333bdf62012-06-08 22:57:296835 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076836 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:506837
6838 // Enable cross-origin push.
[email protected]bb88e1d32013-05-03 23:11:076839 session_deps_.trusted_spdy_proxy = "myproxy:70";
[email protected]61b4efc2012-04-27 18:12:506840
[email protected]bb88e1d32013-05-03 23:11:076841 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:296842
[email protected]cdf8f7e72013-05-23 10:56:466843 scoped_ptr<SpdyFrame> stream1_syn(
6844 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]7c6f7ba2012-04-03 04:09:296845
6846 MockWrite spdy_writes[] = {
[email protected]cdf8f7e72013-05-23 10:56:466847 CreateMockWrite(*stream1_syn, 1, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:296848 };
6849
6850 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026851 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:296852
6853 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026854 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:296855
6856 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026857 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
[email protected]7c6f7ba2012-04-03 04:09:296858 0,
6859 2,
6860 1,
6861 "http://www.another-origin.com/foo.dat"));
[email protected]8a0fc822013-06-27 20:52:436862 const char kPushedData[] = "pushed";
6863 scoped_ptr<SpdyFrame> stream2_body(
6864 spdy_util_.ConstructSpdyBodyFrame(
6865 2, kPushedData, strlen(kPushedData), true));
[email protected]7c6f7ba2012-04-03 04:09:296866
6867 MockRead spdy_reads[] = {
6868 CreateMockRead(*stream1_reply, 2, ASYNC),
6869 CreateMockRead(*stream2_syn, 3, ASYNC),
6870 CreateMockRead(*stream1_body, 4, ASYNC),
[email protected]8a0fc822013-06-27 20:52:436871 CreateMockRead(*stream2_body, 5, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:296872 MockRead(ASYNC, ERR_IO_PENDING, 6), // Force a pause
6873 };
6874
[email protected]dd54bd82012-07-19 23:44:576875 OrderedSocketData spdy_data(
6876 spdy_reads, arraysize(spdy_reads),
6877 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:076878 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:296879 // Negotiate SPDY to the proxy
6880 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:026881 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:076882 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:296883
[email protected]262eec82013-03-19 21:01:366884 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506885 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7c6f7ba2012-04-03 04:09:296886 TestCompletionCallback callback;
6887 int rv = trans->Start(&request, callback.callback(), log.bound());
6888 EXPECT_EQ(ERR_IO_PENDING, rv);
6889
6890 rv = callback.WaitForResult();
6891 EXPECT_EQ(OK, rv);
6892 const HttpResponseInfo* response = trans->GetResponseInfo();
6893
[email protected]262eec82013-03-19 21:01:366894 scoped_ptr<HttpTransaction> push_trans(
[email protected]90499482013-06-01 00:39:506895 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
6896 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
[email protected]7c6f7ba2012-04-03 04:09:296897 EXPECT_EQ(ERR_IO_PENDING, rv);
6898
6899 rv = callback.WaitForResult();
6900 EXPECT_EQ(OK, rv);
6901 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
6902
6903 ASSERT_TRUE(response != NULL);
6904 EXPECT_TRUE(response->headers->IsKeepAlive());
6905
6906 EXPECT_EQ(200, response->headers->response_code());
6907 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6908
6909 std::string response_data;
6910 rv = ReadTransaction(trans.get(), &response_data);
6911 EXPECT_EQ(OK, rv);
6912 EXPECT_EQ("hello!", response_data);
6913
[email protected]029c83b62013-01-24 05:28:206914 LoadTimingInfo load_timing_info;
6915 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6916 TestLoadTimingNotReusedWithPac(load_timing_info,
6917 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6918
[email protected]7c6f7ba2012-04-03 04:09:296919 // Verify the pushed stream.
[email protected]90499482013-06-01 00:39:506920 EXPECT_TRUE(push_response->headers.get() != NULL);
[email protected]7c6f7ba2012-04-03 04:09:296921 EXPECT_EQ(200, push_response->headers->response_code());
6922
6923 rv = ReadTransaction(push_trans.get(), &response_data);
6924 EXPECT_EQ(OK, rv);
6925 EXPECT_EQ("pushed", response_data);
6926
[email protected]029c83b62013-01-24 05:28:206927 LoadTimingInfo push_load_timing_info;
6928 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
6929 TestLoadTimingReusedWithPac(push_load_timing_info);
6930 // The transactions should share a socket ID, despite being for different
6931 // origins.
6932 EXPECT_EQ(load_timing_info.socket_log_id,
6933 push_load_timing_info.socket_log_id);
6934
[email protected]7c6f7ba2012-04-03 04:09:296935 trans.reset();
6936 push_trans.reset();
6937 session->CloseAllConnections();
6938}
6939
[email protected]8c843192012-04-05 07:15:006940// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
[email protected]23e482282013-06-14 16:08:026941TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
[email protected]8c843192012-04-05 07:15:006942 HttpRequestInfo request;
6943
6944 request.method = "GET";
6945 request.url = GURL("http://www.google.com/");
6946
[email protected]8c843192012-04-05 07:15:006947 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076948 session_deps_.proxy_service.reset(
[email protected]8c843192012-04-05 07:15:006949 ProxyService::CreateFixed("https://myproxy:70"));
[email protected]333bdf62012-06-08 22:57:296950 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076951 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:506952
6953 // Enable cross-origin push.
[email protected]bb88e1d32013-05-03 23:11:076954 session_deps_.trusted_spdy_proxy = "myproxy:70";
[email protected]61b4efc2012-04-27 18:12:506955
[email protected]bb88e1d32013-05-03 23:11:076956 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:006957
[email protected]cdf8f7e72013-05-23 10:56:466958 scoped_ptr<SpdyFrame> stream1_syn(
6959 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]8c843192012-04-05 07:15:006960
6961 scoped_ptr<SpdyFrame> push_rst(
[email protected]c10b20852013-05-15 21:29:206962 spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:006963
6964 MockWrite spdy_writes[] = {
6965 CreateMockWrite(*stream1_syn, 1, ASYNC),
6966 CreateMockWrite(*push_rst, 4),
6967 };
6968
6969 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026970 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:006971
6972 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026973 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8c843192012-04-05 07:15:006974
6975 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026976 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
[email protected]8c843192012-04-05 07:15:006977 0,
6978 2,
6979 1,
6980 "https://www.another-origin.com/foo.dat"));
6981
6982 MockRead spdy_reads[] = {
6983 CreateMockRead(*stream1_reply, 2, ASYNC),
6984 CreateMockRead(*stream2_syn, 3, ASYNC),
6985 CreateMockRead(*stream1_body, 5, ASYNC),
6986 MockRead(ASYNC, ERR_IO_PENDING, 6), // Force a pause
6987 };
6988
[email protected]dd54bd82012-07-19 23:44:576989 OrderedSocketData spdy_data(
6990 spdy_reads, arraysize(spdy_reads),
6991 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:076992 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:006993 // Negotiate SPDY to the proxy
6994 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:026995 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:076996 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:006997
[email protected]262eec82013-03-19 21:01:366998 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506999 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c843192012-04-05 07:15:007000 TestCompletionCallback callback;
7001 int rv = trans->Start(&request, callback.callback(), log.bound());
7002 EXPECT_EQ(ERR_IO_PENDING, rv);
7003
7004 rv = callback.WaitForResult();
7005 EXPECT_EQ(OK, rv);
7006 const HttpResponseInfo* response = trans->GetResponseInfo();
7007
7008 ASSERT_TRUE(response != NULL);
7009 EXPECT_TRUE(response->headers->IsKeepAlive());
7010
7011 EXPECT_EQ(200, response->headers->response_code());
7012 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
7013
7014 std::string response_data;
7015 rv = ReadTransaction(trans.get(), &response_data);
7016 EXPECT_EQ(OK, rv);
7017 EXPECT_EQ("hello!", response_data);
7018
7019 trans.reset();
7020 session->CloseAllConnections();
7021}
7022
[email protected]2df19bb2010-08-25 20:13:467023// Test HTTPS connections to a site with a bad certificate, going through an
7024// HTTPS proxy
[email protected]23e482282013-06-14 16:08:027025TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:077026 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:117027 "https://proxy:70"));
[email protected]2df19bb2010-08-25 20:13:467028
7029 HttpRequestInfo request;
7030 request.method = "GET";
7031 request.url = GURL("https://www.google.com/");
7032 request.load_flags = 0;
7033
7034 // Attempt to fetch the URL from a server with a bad cert
7035 MockWrite bad_cert_writes[] = {
7036 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
7037 "Host: www.google.com\r\n"
7038 "Proxy-Connection: keep-alive\r\n\r\n"),
7039 };
7040
7041 MockRead bad_cert_reads[] = {
7042 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067043 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:467044 };
7045
7046 // Attempt to fetch the URL with a good cert
7047 MockWrite good_data_writes[] = {
7048 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
7049 "Host: www.google.com\r\n"
7050 "Proxy-Connection: keep-alive\r\n\r\n"),
7051 MockWrite("GET / HTTP/1.1\r\n"
7052 "Host: www.google.com\r\n"
7053 "Connection: keep-alive\r\n\r\n"),
7054 };
7055
7056 MockRead good_cert_reads[] = {
7057 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
7058 MockRead("HTTP/1.0 200 OK\r\n"),
7059 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7060 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067061 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:467062 };
7063
7064 StaticSocketDataProvider ssl_bad_certificate(
7065 bad_cert_reads, arraysize(bad_cert_reads),
7066 bad_cert_writes, arraysize(bad_cert_writes));
7067 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
7068 good_data_writes, arraysize(good_data_writes));
[email protected]8ddf8322012-02-23 18:08:067069 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
7070 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:467071
7072 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:077073 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7074 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
7075 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:467076
7077 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:077078 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7079 session_deps_.socket_factory->AddSocketDataProvider(&data);
7080 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:467081
[email protected]49639fa2011-12-20 23:22:417082 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:467083
[email protected]3fe8d2f82013-10-17 08:56:077084 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:467085 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417086 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2df19bb2010-08-25 20:13:467087
[email protected]49639fa2011-12-20 23:22:417088 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:467089 EXPECT_EQ(ERR_IO_PENDING, rv);
7090
7091 rv = callback.WaitForResult();
7092 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
7093
[email protected]49639fa2011-12-20 23:22:417094 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]2df19bb2010-08-25 20:13:467095 EXPECT_EQ(ERR_IO_PENDING, rv);
7096
7097 rv = callback.WaitForResult();
7098 EXPECT_EQ(OK, rv);
7099
7100 const HttpResponseInfo* response = trans->GetResponseInfo();
7101
[email protected]fe2255a2011-09-20 19:37:507102 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:467103 EXPECT_EQ(100, response->headers->GetContentLength());
7104}
7105
[email protected]23e482282013-06-14 16:08:027106TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:427107 HttpRequestInfo request;
7108 request.method = "GET";
7109 request.url = GURL("http://www.google.com/");
[email protected]8c76ae22010-04-20 22:15:437110 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
7111 "Chromium Ultra Awesome X Edition");
[email protected]1c773ea12009-04-28 19:58:427112
[email protected]3fe8d2f82013-10-17 08:56:077113 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277114 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417115 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277116
[email protected]1c773ea12009-04-28 19:58:427117 MockWrite data_writes[] = {
7118 MockWrite("GET / HTTP/1.1\r\n"
7119 "Host: www.google.com\r\n"
7120 "Connection: keep-alive\r\n"
7121 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
7122 };
7123
7124 // Lastly, the server responds with the actual content.
7125 MockRead data_reads[] = {
7126 MockRead("HTTP/1.0 200 OK\r\n"),
7127 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7128 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067129 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427130 };
7131
[email protected]31a2bfe2010-02-09 08:03:397132 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7133 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077134 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427135
[email protected]49639fa2011-12-20 23:22:417136 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427137
[email protected]49639fa2011-12-20 23:22:417138 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427139 EXPECT_EQ(ERR_IO_PENDING, rv);
7140
7141 rv = callback.WaitForResult();
7142 EXPECT_EQ(OK, rv);
7143}
7144
[email protected]23e482282013-06-14 16:08:027145TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:297146 HttpRequestInfo request;
7147 request.method = "GET";
7148 request.url = GURL("https://www.google.com/");
7149 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
7150 "Chromium Ultra Awesome X Edition");
7151
[email protected]bb88e1d32013-05-03 23:11:077152 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]3fe8d2f82013-10-17 08:56:077153 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277154 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417155 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277156
[email protected]da81f132010-08-18 23:39:297157 MockWrite data_writes[] = {
7158 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
7159 "Host: www.google.com\r\n"
7160 "Proxy-Connection: keep-alive\r\n"
7161 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
7162 };
7163 MockRead data_reads[] = {
7164 // Return an error, so the transaction stops here (this test isn't
7165 // interested in the rest).
7166 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
7167 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7168 MockRead("Proxy-Connection: close\r\n\r\n"),
7169 };
7170
7171 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7172 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077173 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:297174
[email protected]49639fa2011-12-20 23:22:417175 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:297176
[email protected]49639fa2011-12-20 23:22:417177 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]da81f132010-08-18 23:39:297178 EXPECT_EQ(ERR_IO_PENDING, rv);
7179
7180 rv = callback.WaitForResult();
7181 EXPECT_EQ(OK, rv);
7182}
7183
[email protected]23e482282013-06-14 16:08:027184TEST_P(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:427185 HttpRequestInfo request;
7186 request.method = "GET";
7187 request.url = GURL("http://www.google.com/");
7188 request.load_flags = 0;
[email protected]c10450102011-06-27 09:06:167189 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
7190 "http://the.previous.site.com/");
[email protected]1c773ea12009-04-28 19:58:427191
[email protected]3fe8d2f82013-10-17 08:56:077192 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277193 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417194 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277195
[email protected]1c773ea12009-04-28 19:58:427196 MockWrite data_writes[] = {
7197 MockWrite("GET / HTTP/1.1\r\n"
7198 "Host: www.google.com\r\n"
7199 "Connection: keep-alive\r\n"
7200 "Referer: http://the.previous.site.com/\r\n\r\n"),
7201 };
7202
7203 // Lastly, the server responds with the actual content.
7204 MockRead data_reads[] = {
7205 MockRead("HTTP/1.0 200 OK\r\n"),
7206 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7207 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067208 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427209 };
7210
[email protected]31a2bfe2010-02-09 08:03:397211 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7212 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077213 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427214
[email protected]49639fa2011-12-20 23:22:417215 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427216
[email protected]49639fa2011-12-20 23:22:417217 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427218 EXPECT_EQ(ERR_IO_PENDING, rv);
7219
7220 rv = callback.WaitForResult();
7221 EXPECT_EQ(OK, rv);
7222}
7223
[email protected]23e482282013-06-14 16:08:027224TEST_P(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:427225 HttpRequestInfo request;
7226 request.method = "POST";
7227 request.url = GURL("http://www.google.com/");
7228
[email protected]3fe8d2f82013-10-17 08:56:077229 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277230 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417231 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277232
[email protected]1c773ea12009-04-28 19:58:427233 MockWrite data_writes[] = {
7234 MockWrite("POST / HTTP/1.1\r\n"
7235 "Host: www.google.com\r\n"
7236 "Connection: keep-alive\r\n"
7237 "Content-Length: 0\r\n\r\n"),
7238 };
7239
7240 // Lastly, the server responds with the actual content.
7241 MockRead data_reads[] = {
7242 MockRead("HTTP/1.0 200 OK\r\n"),
7243 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7244 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067245 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427246 };
7247
[email protected]31a2bfe2010-02-09 08:03:397248 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7249 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077250 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427251
[email protected]49639fa2011-12-20 23:22:417252 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427253
[email protected]49639fa2011-12-20 23:22:417254 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427255 EXPECT_EQ(ERR_IO_PENDING, rv);
7256
7257 rv = callback.WaitForResult();
7258 EXPECT_EQ(OK, rv);
7259}
7260
[email protected]23e482282013-06-14 16:08:027261TEST_P(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:427262 HttpRequestInfo request;
7263 request.method = "PUT";
7264 request.url = GURL("http://www.google.com/");
7265
[email protected]3fe8d2f82013-10-17 08:56:077266 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277267 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417268 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277269
[email protected]1c773ea12009-04-28 19:58:427270 MockWrite data_writes[] = {
7271 MockWrite("PUT / HTTP/1.1\r\n"
7272 "Host: www.google.com\r\n"
7273 "Connection: keep-alive\r\n"
7274 "Content-Length: 0\r\n\r\n"),
7275 };
7276
7277 // Lastly, the server responds with the actual content.
7278 MockRead data_reads[] = {
7279 MockRead("HTTP/1.0 200 OK\r\n"),
7280 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7281 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067282 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427283 };
7284
[email protected]31a2bfe2010-02-09 08:03:397285 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7286 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077287 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427288
[email protected]49639fa2011-12-20 23:22:417289 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427290
[email protected]49639fa2011-12-20 23:22:417291 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427292 EXPECT_EQ(ERR_IO_PENDING, rv);
7293
7294 rv = callback.WaitForResult();
7295 EXPECT_EQ(OK, rv);
7296}
7297
[email protected]23e482282013-06-14 16:08:027298TEST_P(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:427299 HttpRequestInfo request;
7300 request.method = "HEAD";
7301 request.url = GURL("http://www.google.com/");
7302
[email protected]3fe8d2f82013-10-17 08:56:077303 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277304 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417305 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277306
[email protected]1c773ea12009-04-28 19:58:427307 MockWrite data_writes[] = {
7308 MockWrite("HEAD / HTTP/1.1\r\n"
7309 "Host: www.google.com\r\n"
7310 "Connection: keep-alive\r\n"
7311 "Content-Length: 0\r\n\r\n"),
7312 };
7313
7314 // Lastly, the server responds with the actual content.
7315 MockRead data_reads[] = {
7316 MockRead("HTTP/1.0 200 OK\r\n"),
7317 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7318 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067319 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427320 };
7321
[email protected]31a2bfe2010-02-09 08:03:397322 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7323 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077324 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427325
[email protected]49639fa2011-12-20 23:22:417326 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427327
[email protected]49639fa2011-12-20 23:22:417328 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427329 EXPECT_EQ(ERR_IO_PENDING, rv);
7330
7331 rv = callback.WaitForResult();
7332 EXPECT_EQ(OK, rv);
7333}
7334
[email protected]23e482282013-06-14 16:08:027335TEST_P(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:427336 HttpRequestInfo request;
7337 request.method = "GET";
7338 request.url = GURL("http://www.google.com/");
7339 request.load_flags = LOAD_BYPASS_CACHE;
7340
[email protected]3fe8d2f82013-10-17 08:56:077341 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277342 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417343 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277344
[email protected]1c773ea12009-04-28 19:58:427345 MockWrite data_writes[] = {
7346 MockWrite("GET / HTTP/1.1\r\n"
7347 "Host: www.google.com\r\n"
7348 "Connection: keep-alive\r\n"
7349 "Pragma: no-cache\r\n"
7350 "Cache-Control: no-cache\r\n\r\n"),
7351 };
7352
7353 // Lastly, the server responds with the actual content.
7354 MockRead data_reads[] = {
7355 MockRead("HTTP/1.0 200 OK\r\n"),
7356 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7357 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067358 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427359 };
7360
[email protected]31a2bfe2010-02-09 08:03:397361 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7362 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077363 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427364
[email protected]49639fa2011-12-20 23:22:417365 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427366
[email protected]49639fa2011-12-20 23:22:417367 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427368 EXPECT_EQ(ERR_IO_PENDING, rv);
7369
7370 rv = callback.WaitForResult();
7371 EXPECT_EQ(OK, rv);
7372}
7373
[email protected]23e482282013-06-14 16:08:027374TEST_P(HttpNetworkTransactionTest,
[email protected]1c773ea12009-04-28 19:58:427375 BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:427376 HttpRequestInfo request;
7377 request.method = "GET";
7378 request.url = GURL("http://www.google.com/");
7379 request.load_flags = LOAD_VALIDATE_CACHE;
7380
[email protected]3fe8d2f82013-10-17 08:56:077381 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277382 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417383 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277384
[email protected]1c773ea12009-04-28 19:58:427385 MockWrite data_writes[] = {
7386 MockWrite("GET / HTTP/1.1\r\n"
7387 "Host: www.google.com\r\n"
7388 "Connection: keep-alive\r\n"
7389 "Cache-Control: max-age=0\r\n\r\n"),
7390 };
7391
7392 // Lastly, the server responds with the actual content.
7393 MockRead data_reads[] = {
7394 MockRead("HTTP/1.0 200 OK\r\n"),
7395 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7396 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067397 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427398 };
7399
[email protected]31a2bfe2010-02-09 08:03:397400 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7401 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077402 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427403
[email protected]49639fa2011-12-20 23:22:417404 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427405
[email protected]49639fa2011-12-20 23:22:417406 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427407 EXPECT_EQ(ERR_IO_PENDING, rv);
7408
7409 rv = callback.WaitForResult();
7410 EXPECT_EQ(OK, rv);
7411}
7412
[email protected]23e482282013-06-14 16:08:027413TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:427414 HttpRequestInfo request;
7415 request.method = "GET";
7416 request.url = GURL("http://www.google.com/");
[email protected]8c76ae22010-04-20 22:15:437417 request.extra_headers.SetHeader("FooHeader", "Bar");
[email protected]1c773ea12009-04-28 19:58:427418
[email protected]3fe8d2f82013-10-17 08:56:077419 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277420 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417421 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277422
[email protected]1c773ea12009-04-28 19:58:427423 MockWrite data_writes[] = {
7424 MockWrite("GET / HTTP/1.1\r\n"
7425 "Host: www.google.com\r\n"
7426 "Connection: keep-alive\r\n"
7427 "FooHeader: Bar\r\n\r\n"),
7428 };
7429
7430 // Lastly, the server responds with the actual content.
7431 MockRead data_reads[] = {
7432 MockRead("HTTP/1.0 200 OK\r\n"),
7433 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7434 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067435 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427436 };
7437
[email protected]31a2bfe2010-02-09 08:03:397438 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7439 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077440 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427441
[email protected]49639fa2011-12-20 23:22:417442 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427443
[email protected]49639fa2011-12-20 23:22:417444 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427445 EXPECT_EQ(ERR_IO_PENDING, rv);
7446
7447 rv = callback.WaitForResult();
7448 EXPECT_EQ(OK, rv);
7449}
7450
[email protected]23e482282013-06-14 16:08:027451TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:477452 HttpRequestInfo request;
7453 request.method = "GET";
7454 request.url = GURL("http://www.google.com/");
[email protected]8c76ae22010-04-20 22:15:437455 request.extra_headers.SetHeader("referer", "www.foo.com");
7456 request.extra_headers.SetHeader("hEllo", "Kitty");
7457 request.extra_headers.SetHeader("FoO", "bar");
[email protected]270c6412010-03-29 22:02:477458
[email protected]3fe8d2f82013-10-17 08:56:077459 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277460 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417461 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277462
[email protected]270c6412010-03-29 22:02:477463 MockWrite data_writes[] = {
7464 MockWrite("GET / HTTP/1.1\r\n"
7465 "Host: www.google.com\r\n"
7466 "Connection: keep-alive\r\n"
[email protected]c10450102011-06-27 09:06:167467 "referer: www.foo.com\r\n"
[email protected]270c6412010-03-29 22:02:477468 "hEllo: Kitty\r\n"
7469 "FoO: bar\r\n\r\n"),
7470 };
7471
7472 // Lastly, the server responds with the actual content.
7473 MockRead data_reads[] = {
7474 MockRead("HTTP/1.0 200 OK\r\n"),
7475 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7476 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067477 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:477478 };
7479
7480 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7481 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077482 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:477483
[email protected]49639fa2011-12-20 23:22:417484 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:477485
[email protected]49639fa2011-12-20 23:22:417486 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]270c6412010-03-29 22:02:477487 EXPECT_EQ(ERR_IO_PENDING, rv);
7488
7489 rv = callback.WaitForResult();
7490 EXPECT_EQ(OK, rv);
7491}
7492
[email protected]23e482282013-06-14 16:08:027493TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277494 HttpRequestInfo request;
7495 request.method = "GET";
7496 request.url = GURL("http://www.google.com/");
7497 request.load_flags = 0;
7498
[email protected]bb88e1d32013-05-03 23:11:077499 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207500 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
7501 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077502 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:027503
[email protected]3fe8d2f82013-10-17 08:56:077504 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3cd17242009-06-23 02:59:027505 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417506 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3cd17242009-06-23 02:59:027507
[email protected]3cd17242009-06-23 02:59:027508 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
7509 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7510
7511 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:067512 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
[email protected]3cd17242009-06-23 02:59:027513 MockWrite("GET / HTTP/1.1\r\n"
7514 "Host: www.google.com\r\n"
7515 "Connection: keep-alive\r\n\r\n")
7516 };
7517
7518 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:067519 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:027520 MockRead("HTTP/1.0 200 OK\r\n"),
7521 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7522 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067523 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:027524 };
7525
[email protected]31a2bfe2010-02-09 08:03:397526 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7527 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077528 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:027529
[email protected]49639fa2011-12-20 23:22:417530 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:027531
[email protected]49639fa2011-12-20 23:22:417532 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:027533 EXPECT_EQ(ERR_IO_PENDING, rv);
7534
7535 rv = callback.WaitForResult();
7536 EXPECT_EQ(OK, rv);
7537
7538 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507539 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:027540
[email protected]029c83b62013-01-24 05:28:207541 LoadTimingInfo load_timing_info;
7542 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7543 TestLoadTimingNotReusedWithPac(load_timing_info,
7544 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7545
[email protected]3cd17242009-06-23 02:59:027546 std::string response_text;
7547 rv = ReadTransaction(trans.get(), &response_text);
7548 EXPECT_EQ(OK, rv);
7549 EXPECT_EQ("Payload", response_text);
7550}
7551
[email protected]23e482282013-06-14 16:08:027552TEST_P(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277553 HttpRequestInfo request;
7554 request.method = "GET";
7555 request.url = GURL("https://www.google.com/");
7556 request.load_flags = 0;
7557
[email protected]bb88e1d32013-05-03 23:11:077558 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207559 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
7560 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077561 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:027562
[email protected]3fe8d2f82013-10-17 08:56:077563 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3cd17242009-06-23 02:59:027564 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417565 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3cd17242009-06-23 02:59:027566
[email protected]3cd17242009-06-23 02:59:027567 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
7568 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7569
7570 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:067571 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
[email protected]e0c27be2009-07-15 13:09:357572 arraysize(write_buffer)),
[email protected]3cd17242009-06-23 02:59:027573 MockWrite("GET / HTTP/1.1\r\n"
7574 "Host: www.google.com\r\n"
7575 "Connection: keep-alive\r\n\r\n")
7576 };
7577
7578 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:017579 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
7580 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:357581 MockRead("HTTP/1.0 200 OK\r\n"),
7582 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7583 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067584 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:357585 };
7586
[email protected]31a2bfe2010-02-09 08:03:397587 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7588 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077589 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:357590
[email protected]8ddf8322012-02-23 18:08:067591 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077592 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:357593
[email protected]49639fa2011-12-20 23:22:417594 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:357595
[email protected]49639fa2011-12-20 23:22:417596 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:357597 EXPECT_EQ(ERR_IO_PENDING, rv);
7598
7599 rv = callback.WaitForResult();
7600 EXPECT_EQ(OK, rv);
7601
[email protected]029c83b62013-01-24 05:28:207602 LoadTimingInfo load_timing_info;
7603 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7604 TestLoadTimingNotReusedWithPac(load_timing_info,
7605 CONNECT_TIMING_HAS_SSL_TIMES);
7606
[email protected]e0c27be2009-07-15 13:09:357607 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507608 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:357609
7610 std::string response_text;
7611 rv = ReadTransaction(trans.get(), &response_text);
7612 EXPECT_EQ(OK, rv);
7613 EXPECT_EQ("Payload", response_text);
7614}
7615
[email protected]23e482282013-06-14 16:08:027616TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:207617 HttpRequestInfo request;
7618 request.method = "GET";
7619 request.url = GURL("http://www.google.com/");
7620 request.load_flags = 0;
7621
[email protected]bb88e1d32013-05-03 23:11:077622 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207623 ProxyService::CreateFixed("socks4://myproxy:1080"));
7624 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077625 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:207626
[email protected]3fe8d2f82013-10-17 08:56:077627 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:207628 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417629 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:207630
7631 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
7632 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7633
7634 MockWrite data_writes[] = {
7635 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
7636 MockWrite("GET / HTTP/1.1\r\n"
7637 "Host: www.google.com\r\n"
7638 "Connection: keep-alive\r\n\r\n")
7639 };
7640
7641 MockRead data_reads[] = {
7642 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
7643 MockRead("HTTP/1.0 200 OK\r\n"),
7644 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7645 MockRead("Payload"),
7646 MockRead(SYNCHRONOUS, OK)
7647 };
7648
7649 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7650 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077651 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:207652
7653 TestCompletionCallback callback;
7654
7655 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7656 EXPECT_EQ(ERR_IO_PENDING, rv);
7657
7658 rv = callback.WaitForResult();
7659 EXPECT_EQ(OK, rv);
7660
7661 const HttpResponseInfo* response = trans->GetResponseInfo();
7662 ASSERT_TRUE(response != NULL);
7663
7664 LoadTimingInfo load_timing_info;
7665 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7666 TestLoadTimingNotReused(load_timing_info,
7667 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7668
7669 std::string response_text;
7670 rv = ReadTransaction(trans.get(), &response_text);
7671 EXPECT_EQ(OK, rv);
7672 EXPECT_EQ("Payload", response_text);
7673}
7674
[email protected]23e482282013-06-14 16:08:027675TEST_P(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277676 HttpRequestInfo request;
7677 request.method = "GET";
7678 request.url = GURL("http://www.google.com/");
7679 request.load_flags = 0;
7680
[email protected]bb88e1d32013-05-03 23:11:077681 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207682 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
7683 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077684 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:357685
[email protected]3fe8d2f82013-10-17 08:56:077686 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e0c27be2009-07-15 13:09:357687 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417688 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]e0c27be2009-07-15 13:09:357689
[email protected]e0c27be2009-07-15 13:09:357690 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
7691 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:377692 const char kSOCKS5OkRequest[] = {
7693 0x05, // Version
7694 0x01, // Command (CONNECT)
7695 0x00, // Reserved.
7696 0x03, // Address type (DOMAINNAME).
7697 0x0E, // Length of domain (14)
7698 // Domain string:
7699 'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
7700 0x00, 0x50, // 16-bit port (80)
7701 };
[email protected]e0c27be2009-07-15 13:09:357702 const char kSOCKS5OkResponse[] =
7703 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
7704
7705 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:067706 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
7707 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
[email protected]e0c27be2009-07-15 13:09:357708 MockWrite("GET / HTTP/1.1\r\n"
7709 "Host: www.google.com\r\n"
7710 "Connection: keep-alive\r\n\r\n")
7711 };
7712
7713 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:017714 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
7715 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:357716 MockRead("HTTP/1.0 200 OK\r\n"),
7717 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7718 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067719 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:357720 };
7721
[email protected]31a2bfe2010-02-09 08:03:397722 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7723 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077724 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:357725
[email protected]49639fa2011-12-20 23:22:417726 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:357727
[email protected]49639fa2011-12-20 23:22:417728 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:357729 EXPECT_EQ(ERR_IO_PENDING, rv);
7730
7731 rv = callback.WaitForResult();
7732 EXPECT_EQ(OK, rv);
7733
7734 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507735 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:357736
[email protected]029c83b62013-01-24 05:28:207737 LoadTimingInfo load_timing_info;
7738 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7739 TestLoadTimingNotReusedWithPac(load_timing_info,
7740 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7741
[email protected]e0c27be2009-07-15 13:09:357742 std::string response_text;
7743 rv = ReadTransaction(trans.get(), &response_text);
7744 EXPECT_EQ(OK, rv);
7745 EXPECT_EQ("Payload", response_text);
7746}
7747
[email protected]23e482282013-06-14 16:08:027748TEST_P(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277749 HttpRequestInfo request;
7750 request.method = "GET";
7751 request.url = GURL("https://www.google.com/");
7752 request.load_flags = 0;
7753
[email protected]bb88e1d32013-05-03 23:11:077754 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207755 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
7756 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077757 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:357758
[email protected]3fe8d2f82013-10-17 08:56:077759 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e0c27be2009-07-15 13:09:357760 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417761 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]e0c27be2009-07-15 13:09:357762
[email protected]e0c27be2009-07-15 13:09:357763 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
7764 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:377765 const unsigned char kSOCKS5OkRequest[] = {
7766 0x05, // Version
7767 0x01, // Command (CONNECT)
7768 0x00, // Reserved.
7769 0x03, // Address type (DOMAINNAME).
7770 0x0E, // Length of domain (14)
7771 // Domain string:
7772 'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
7773 0x01, 0xBB, // 16-bit port (443)
7774 };
7775
[email protected]e0c27be2009-07-15 13:09:357776 const char kSOCKS5OkResponse[] =
7777 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
7778
7779 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:067780 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
7781 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
[email protected]e0c27be2009-07-15 13:09:357782 arraysize(kSOCKS5OkRequest)),
7783 MockWrite("GET / HTTP/1.1\r\n"
7784 "Host: www.google.com\r\n"
7785 "Connection: keep-alive\r\n\r\n")
7786 };
7787
7788 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:017789 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
7790 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:027791 MockRead("HTTP/1.0 200 OK\r\n"),
7792 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7793 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067794 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:027795 };
7796
[email protected]31a2bfe2010-02-09 08:03:397797 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7798 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077799 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:027800
[email protected]8ddf8322012-02-23 18:08:067801 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077802 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:027803
[email protected]49639fa2011-12-20 23:22:417804 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:027805
[email protected]49639fa2011-12-20 23:22:417806 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:027807 EXPECT_EQ(ERR_IO_PENDING, rv);
7808
7809 rv = callback.WaitForResult();
7810 EXPECT_EQ(OK, rv);
7811
7812 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507813 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:027814
[email protected]029c83b62013-01-24 05:28:207815 LoadTimingInfo load_timing_info;
7816 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7817 TestLoadTimingNotReusedWithPac(load_timing_info,
7818 CONNECT_TIMING_HAS_SSL_TIMES);
7819
[email protected]3cd17242009-06-23 02:59:027820 std::string response_text;
7821 rv = ReadTransaction(trans.get(), &response_text);
7822 EXPECT_EQ(OK, rv);
7823 EXPECT_EQ("Payload", response_text);
7824}
7825
[email protected]448d4ca52012-03-04 04:12:237826namespace {
7827
[email protected]04e5be32009-06-26 20:00:317828// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:067829
7830struct GroupNameTest {
7831 std::string proxy_server;
7832 std::string url;
7833 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:187834 bool ssl;
[email protected]2d731a32010-04-29 01:04:067835};
7836
7837scoped_refptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]8a0fc822013-06-27 20:52:437838 NextProto next_proto,
[email protected]bb88e1d32013-05-03 23:11:077839 SpdySessionDependencies* session_deps_) {
7840 scoped_refptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:067841
[email protected]30d4c022013-07-18 22:58:167842 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:537843 session->http_server_properties();
7844 http_server_properties->SetAlternateProtocol(
[email protected]2d731a32010-04-29 01:04:067845 HostPortPair("host.with.alternate", 80), 443,
bnc1102b552015-01-30 20:11:017846 AlternateProtocolFromNextProto(next_proto), 1.0);
[email protected]2d731a32010-04-29 01:04:067847
7848 return session;
7849}
7850
7851int GroupNameTransactionHelper(
7852 const std::string& url,
7853 const scoped_refptr<HttpNetworkSession>& session) {
[email protected]2d731a32010-04-29 01:04:067854 HttpRequestInfo request;
7855 request.method = "GET";
7856 request.url = GURL(url);
7857 request.load_flags = 0;
7858
[email protected]262eec82013-03-19 21:01:367859 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507860 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277861
[email protected]49639fa2011-12-20 23:22:417862 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:067863
7864 // We do not complete this request, the dtor will clean the transaction up.
[email protected]49639fa2011-12-20 23:22:417865 return trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d731a32010-04-29 01:04:067866}
7867
[email protected]448d4ca52012-03-04 04:12:237868} // namespace
7869
[email protected]23e482282013-06-14 16:08:027870TEST_P(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:067871 const GroupNameTest tests[] = {
[email protected]04e5be32009-06-26 20:00:317872 {
[email protected]2d731a32010-04-29 01:04:067873 "", // unused
[email protected]04e5be32009-06-26 20:00:317874 "http://www.google.com/direct",
[email protected]2ff8b312010-04-26 22:20:547875 "www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:187876 false,
[email protected]2ff8b312010-04-26 22:20:547877 },
7878 {
[email protected]2d731a32010-04-29 01:04:067879 "", // unused
[email protected]2ff8b312010-04-26 22:20:547880 "http://[2001:1418:13:1::25]/direct",
7881 "[2001:1418:13:1::25]:80",
[email protected]e60e47a2010-07-14 03:37:187882 false,
[email protected]04e5be32009-06-26 20:00:317883 },
[email protected]04e5be32009-06-26 20:00:317884
7885 // SSL Tests
7886 {
[email protected]2d731a32010-04-29 01:04:067887 "", // unused
[email protected]04e5be32009-06-26 20:00:317888 "https://www.google.com/direct_ssl",
[email protected]0e88ad602010-05-04 23:47:027889 "ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:187890 true,
[email protected]04e5be32009-06-26 20:00:317891 },
7892 {
[email protected]2d731a32010-04-29 01:04:067893 "", // unused
7894 "https://[2001:1418:13:1::25]/direct",
[email protected]0e88ad602010-05-04 23:47:027895 "ssl/[2001:1418:13:1::25]:443",
[email protected]e60e47a2010-07-14 03:37:187896 true,
[email protected]04e5be32009-06-26 20:00:317897 },
7898 {
[email protected]2d731a32010-04-29 01:04:067899 "", // unused
[email protected]2ff8b312010-04-26 22:20:547900 "http://host.with.alternate/direct",
[email protected]0e88ad602010-05-04 23:47:027901 "ssl/host.with.alternate:443",
[email protected]e60e47a2010-07-14 03:37:187902 true,
[email protected]2ff8b312010-04-26 22:20:547903 },
[email protected]2d731a32010-04-29 01:04:067904 };
[email protected]2ff8b312010-04-26 22:20:547905
[email protected]d7599122014-05-24 03:37:237906 session_deps_.use_alternate_protocols = true;
[email protected]2d731a32010-04-29 01:04:067907
viettrungluue4a8b882014-10-16 06:17:387908 for (size_t i = 0; i < arraysize(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:077909 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:027910 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:067911 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:437912 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:067913
7914 HttpNetworkSessionPeer peer(session);
[email protected]ab739042011-04-07 15:22:287915 CaptureGroupNameTransportSocketPool* transport_conn_pool =
7916 new CaptureGroupNameTransportSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:137917 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347918 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]831e4a32013-11-14 02:14:447919 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
7920 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:027921 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
7922 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
dchenge3d1ddc2014-10-15 19:30:517923 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]2d731a32010-04-29 01:04:067924
7925 EXPECT_EQ(ERR_IO_PENDING,
7926 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:187927 if (tests[i].ssl)
7928 EXPECT_EQ(tests[i].expected_group_name,
7929 ssl_conn_pool->last_group_name_received());
7930 else
7931 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:287932 transport_conn_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:067933 }
7934
[email protected]2d731a32010-04-29 01:04:067935}
7936
[email protected]23e482282013-06-14 16:08:027937TEST_P(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:067938 const GroupNameTest tests[] = {
7939 {
7940 "http_proxy",
7941 "http://www.google.com/http_proxy_normal",
7942 "www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:187943 false,
[email protected]2d731a32010-04-29 01:04:067944 },
7945
7946 // SSL Tests
7947 {
7948 "http_proxy",
7949 "https://www.google.com/http_connect_ssl",
[email protected]0e88ad602010-05-04 23:47:027950 "ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:187951 true,
[email protected]2d731a32010-04-29 01:04:067952 },
[email protected]af3490e2010-10-16 21:02:297953
[email protected]9faeded92010-04-29 20:03:057954 {
7955 "http_proxy",
7956 "http://host.with.alternate/direct",
[email protected]0e88ad602010-05-04 23:47:027957 "ssl/host.with.alternate:443",
[email protected]e60e47a2010-07-14 03:37:187958 true,
[email protected]9faeded92010-04-29 20:03:057959 },
[email protected]45499252013-01-23 17:12:567960
7961 {
7962 "http_proxy",
7963 "ftp://ftp.google.com/http_proxy_normal",
7964 "ftp/ftp.google.com:21",
7965 false,
7966 },
[email protected]2d731a32010-04-29 01:04:067967 };
7968
[email protected]d7599122014-05-24 03:37:237969 session_deps_.use_alternate_protocols = true;
[email protected]2d731a32010-04-29 01:04:067970
viettrungluue4a8b882014-10-16 06:17:387971 for (size_t i = 0; i < arraysize(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:077972 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:027973 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:067974 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:437975 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:067976
7977 HttpNetworkSessionPeer peer(session);
7978
[email protected]e60e47a2010-07-14 03:37:187979 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:137980 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:347981 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:137982 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347983 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:027984
[email protected]831e4a32013-11-14 02:14:447985 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
7986 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:027987 mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool);
7988 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
dchenge3d1ddc2014-10-15 19:30:517989 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]2d731a32010-04-29 01:04:067990
7991 EXPECT_EQ(ERR_IO_PENDING,
7992 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:187993 if (tests[i].ssl)
7994 EXPECT_EQ(tests[i].expected_group_name,
7995 ssl_conn_pool->last_group_name_received());
7996 else
7997 EXPECT_EQ(tests[i].expected_group_name,
7998 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:067999 }
[email protected]2d731a32010-04-29 01:04:068000}
8001
[email protected]23e482282013-06-14 16:08:028002TEST_P(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:068003 const GroupNameTest tests[] = {
8004 {
8005 "socks4://socks_proxy:1080",
8006 "http://www.google.com/socks4_direct",
8007 "socks4/www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:188008 false,
[email protected]2d731a32010-04-29 01:04:068009 },
8010 {
8011 "socks5://socks_proxy:1080",
8012 "http://www.google.com/socks5_direct",
8013 "socks5/www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:188014 false,
[email protected]2d731a32010-04-29 01:04:068015 },
8016
8017 // SSL Tests
8018 {
8019 "socks4://socks_proxy:1080",
8020 "https://www.google.com/socks4_ssl",
[email protected]0e88ad602010-05-04 23:47:028021 "socks4/ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:188022 true,
[email protected]2d731a32010-04-29 01:04:068023 },
8024 {
8025 "socks5://socks_proxy:1080",
8026 "https://www.google.com/socks5_ssl",
[email protected]0e88ad602010-05-04 23:47:028027 "socks5/ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:188028 true,
[email protected]2d731a32010-04-29 01:04:068029 },
[email protected]af3490e2010-10-16 21:02:298030
[email protected]9faeded92010-04-29 20:03:058031 {
8032 "socks4://socks_proxy:1080",
8033 "http://host.with.alternate/direct",
[email protected]0e88ad602010-05-04 23:47:028034 "socks4/ssl/host.with.alternate:443",
[email protected]e60e47a2010-07-14 03:37:188035 true,
[email protected]9faeded92010-04-29 20:03:058036 },
[email protected]04e5be32009-06-26 20:00:318037 };
8038
[email protected]d7599122014-05-24 03:37:238039 session_deps_.use_alternate_protocols = true;
[email protected]2ff8b312010-04-26 22:20:548040
viettrungluue4a8b882014-10-16 06:17:388041 for (size_t i = 0; i < arraysize(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:078042 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:028043 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:068044 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:438045 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]8b114dd72011-03-25 05:33:028046
[email protected]2d731a32010-04-29 01:04:068047 HttpNetworkSessionPeer peer(session);
[email protected]04e5be32009-06-26 20:00:318048
[email protected]e60e47a2010-07-14 03:37:188049 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:138050 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:348051 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:138052 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:348053 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:028054
[email protected]831e4a32013-11-14 02:14:448055 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
8056 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:028057 mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_conn_pool);
8058 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
dchenge3d1ddc2014-10-15 19:30:518059 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]04e5be32009-06-26 20:00:318060
[email protected]262eec82013-03-19 21:01:368061 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508062 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]04e5be32009-06-26 20:00:318063
[email protected]2d731a32010-04-29 01:04:068064 EXPECT_EQ(ERR_IO_PENDING,
8065 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:188066 if (tests[i].ssl)
8067 EXPECT_EQ(tests[i].expected_group_name,
8068 ssl_conn_pool->last_group_name_received());
8069 else
8070 EXPECT_EQ(tests[i].expected_group_name,
8071 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:318072 }
8073}
8074
[email protected]23e482282013-06-14 16:08:028075TEST_P(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:278076 HttpRequestInfo request;
8077 request.method = "GET";
8078 request.url = GURL("http://www.google.com/");
8079
[email protected]bb88e1d32013-05-03 23:11:078080 session_deps_.proxy_service.reset(
[email protected]81cdfcd2010-10-16 00:49:008081 ProxyService::CreateFixed("myproxy:70;foobar:80"));
[email protected]b59ff372009-07-15 22:04:328082
[email protected]69719062010-01-05 20:09:218083 // This simulates failure resolving all hostnames; that means we will fail
8084 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:078085 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:328086
[email protected]3fe8d2f82013-10-17 08:56:078087 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]9172a982009-06-06 00:30:258088 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418089 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]9172a982009-06-06 00:30:258090
[email protected]49639fa2011-12-20 23:22:418091 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:258092
[email protected]49639fa2011-12-20 23:22:418093 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9172a982009-06-06 00:30:258094 EXPECT_EQ(ERR_IO_PENDING, rv);
8095
[email protected]9172a982009-06-06 00:30:258096 rv = callback.WaitForResult();
[email protected]f7fccee2010-09-16 20:53:018097 EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
[email protected]9172a982009-06-06 00:30:258098}
8099
[email protected]685af592010-05-11 19:31:248100// Base test to make sure that when the load flags for a request specify to
8101// bypass the cache, the DNS cache is not used.
[email protected]23e482282013-06-14 16:08:028102void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
[email protected]bb88e1d32013-05-03 23:11:078103 int load_flags) {
[email protected]cb9bf6ca2011-01-28 13:15:278104 // Issue a request, asking to bypass the cache(s).
8105 HttpRequestInfo request;
8106 request.method = "GET";
8107 request.load_flags = load_flags;
8108 request.url = GURL("http://www.google.com/");
8109
[email protected]a2c2fb92009-07-18 07:31:048110 // Select a host resolver that does caching.
[email protected]bb88e1d32013-05-03 23:11:078111 session_deps_.host_resolver.reset(new MockCachingHostResolver);
[email protected]b59ff372009-07-15 22:04:328112
[email protected]3fe8d2f82013-10-17 08:56:078113 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8114 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418115 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3b9cca42009-06-16 01:08:288116
[email protected]6e78dfb2011-07-28 21:34:478117 // Warm up the host cache so it has an entry for "www.google.com".
[email protected]3b9cca42009-06-16 01:08:288118 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:298119 TestCompletionCallback callback;
[email protected]bb88e1d32013-05-03 23:11:078120 int rv = session_deps_.host_resolver->Resolve(
[email protected]5109c1952013-08-20 18:44:108121 HostResolver::RequestInfo(HostPortPair("www.google.com", 80)),
8122 DEFAULT_PRIORITY,
[email protected]b9823c02013-08-16 21:24:418123 &addrlist,
8124 callback.callback(),
8125 NULL,
8126 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:478127 EXPECT_EQ(ERR_IO_PENDING, rv);
8128 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:288129 EXPECT_EQ(OK, rv);
8130
8131 // Verify that it was added to host cache, by doing a subsequent async lookup
8132 // and confirming it completes synchronously.
[email protected]bb88e1d32013-05-03 23:11:078133 rv = session_deps_.host_resolver->Resolve(
[email protected]5109c1952013-08-20 18:44:108134 HostResolver::RequestInfo(HostPortPair("www.google.com", 80)),
8135 DEFAULT_PRIORITY,
[email protected]b9823c02013-08-16 21:24:418136 &addrlist,
8137 callback.callback(),
8138 NULL,
8139 BoundNetLog());
[email protected]b59ff372009-07-15 22:04:328140 ASSERT_EQ(OK, rv);
[email protected]3b9cca42009-06-16 01:08:288141
8142 // Inject a failure the next time that "www.google.com" is resolved. This way
8143 // we can tell if the next lookup hit the cache, or the "network".
8144 // (cache --> success, "network" --> failure).
[email protected]bb88e1d32013-05-03 23:11:078145 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.google.com");
[email protected]3b9cca42009-06-16 01:08:288146
8147 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
8148 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:068149 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
[email protected]31a2bfe2010-02-09 08:03:398150 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078151 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:288152
[email protected]3b9cca42009-06-16 01:08:288153 // Run the request.
[email protected]49639fa2011-12-20 23:22:418154 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3b9cca42009-06-16 01:08:288155 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:418156 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:288157
8158 // If we bypassed the cache, we would have gotten a failure while resolving
8159 // "www.google.com".
8160 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
8161}
8162
[email protected]685af592010-05-11 19:31:248163// There are multiple load flags that should trigger the host cache bypass.
8164// Test each in isolation:
[email protected]23e482282013-06-14 16:08:028165TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
[email protected]685af592010-05-11 19:31:248166 BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
8167}
8168
[email protected]23e482282013-06-14 16:08:028169TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
[email protected]685af592010-05-11 19:31:248170 BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
8171}
8172
[email protected]23e482282013-06-14 16:08:028173TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
[email protected]685af592010-05-11 19:31:248174 BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
8175}
8176
[email protected]0877e3d2009-10-17 22:29:578177// Make sure we can handle an error when writing the request.
[email protected]23e482282013-06-14 16:08:028178TEST_P(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:578179 HttpRequestInfo request;
8180 request.method = "GET";
8181 request.url = GURL("http://www.foo.com/");
8182 request.load_flags = 0;
8183
8184 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:068185 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:578186 };
[email protected]31a2bfe2010-02-09 08:03:398187 StaticSocketDataProvider data(NULL, 0,
8188 write_failure, arraysize(write_failure));
[email protected]bb88e1d32013-05-03 23:11:078189 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3fe8d2f82013-10-17 08:56:078190 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578191
[email protected]49639fa2011-12-20 23:22:418192 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:578193
8194 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418195 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:578196
[email protected]49639fa2011-12-20 23:22:418197 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578198 EXPECT_EQ(ERR_IO_PENDING, rv);
8199
8200 rv = callback.WaitForResult();
8201 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
8202}
8203
8204// Check that a connection closed after the start of the headers finishes ok.
[email protected]23e482282013-06-14 16:08:028205TEST_P(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:578206 HttpRequestInfo request;
8207 request.method = "GET";
8208 request.url = GURL("http://www.foo.com/");
8209 request.load_flags = 0;
8210
8211 MockRead data_reads[] = {
8212 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:068213 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:578214 };
8215
[email protected]31a2bfe2010-02-09 08:03:398216 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078217 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3fe8d2f82013-10-17 08:56:078218 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578219
[email protected]49639fa2011-12-20 23:22:418220 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:578221
8222 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418223 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:578224
[email protected]49639fa2011-12-20 23:22:418225 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578226 EXPECT_EQ(ERR_IO_PENDING, rv);
8227
8228 rv = callback.WaitForResult();
8229 EXPECT_EQ(OK, rv);
8230
8231 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508232 ASSERT_TRUE(response != NULL);
[email protected]0877e3d2009-10-17 22:29:578233
[email protected]90499482013-06-01 00:39:508234 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]0877e3d2009-10-17 22:29:578235 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
8236
8237 std::string response_data;
8238 rv = ReadTransaction(trans.get(), &response_data);
8239 EXPECT_EQ(OK, rv);
8240 EXPECT_EQ("", response_data);
8241}
8242
8243// Make sure that a dropped connection while draining the body for auth
8244// restart does the right thing.
[email protected]23e482282013-06-14 16:08:028245TEST_P(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:578246 HttpRequestInfo request;
8247 request.method = "GET";
8248 request.url = GURL("http://www.google.com/");
8249 request.load_flags = 0;
8250
8251 MockWrite data_writes1[] = {
8252 MockWrite("GET / HTTP/1.1\r\n"
8253 "Host: www.google.com\r\n"
8254 "Connection: keep-alive\r\n\r\n"),
8255 };
8256
8257 MockRead data_reads1[] = {
8258 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
8259 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8260 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8261 MockRead("Content-Length: 14\r\n\r\n"),
8262 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:068263 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:578264 };
8265
[email protected]31a2bfe2010-02-09 08:03:398266 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8267 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:078268 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:578269
8270 // After calling trans->RestartWithAuth(), this is the request we should
8271 // be issuing -- the final header line contains the credentials.
8272 MockWrite data_writes2[] = {
8273 MockWrite("GET / HTTP/1.1\r\n"
8274 "Host: www.google.com\r\n"
8275 "Connection: keep-alive\r\n"
8276 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
8277 };
8278
8279 // Lastly, the server responds with the actual content.
8280 MockRead data_reads2[] = {
8281 MockRead("HTTP/1.1 200 OK\r\n"),
8282 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8283 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068284 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:578285 };
8286
[email protected]31a2bfe2010-02-09 08:03:398287 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8288 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:078289 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3fe8d2f82013-10-17 08:56:078290 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578291
[email protected]49639fa2011-12-20 23:22:418292 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:578293
[email protected]262eec82013-03-19 21:01:368294 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508295 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:508296
[email protected]49639fa2011-12-20 23:22:418297 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578298 EXPECT_EQ(ERR_IO_PENDING, rv);
8299
8300 rv = callback1.WaitForResult();
8301 EXPECT_EQ(OK, rv);
8302
8303 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508304 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048305 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:578306
[email protected]49639fa2011-12-20 23:22:418307 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:578308
[email protected]49639fa2011-12-20 23:22:418309 rv = trans->RestartWithAuth(
8310 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]0877e3d2009-10-17 22:29:578311 EXPECT_EQ(ERR_IO_PENDING, rv);
8312
8313 rv = callback2.WaitForResult();
8314 EXPECT_EQ(OK, rv);
8315
8316 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508317 ASSERT_TRUE(response != NULL);
[email protected]0877e3d2009-10-17 22:29:578318 EXPECT_TRUE(response->auth_challenge.get() == NULL);
8319 EXPECT_EQ(100, response->headers->GetContentLength());
8320}
8321
8322// Test HTTPS connections going through a proxy that sends extra data.
[email protected]23e482282013-06-14 16:08:028323TEST_P(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
[email protected]bb88e1d32013-05-03 23:11:078324 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]0877e3d2009-10-17 22:29:578325
8326 HttpRequestInfo request;
8327 request.method = "GET";
8328 request.url = GURL("https://www.google.com/");
8329 request.load_flags = 0;
8330
8331 MockRead proxy_reads[] = {
8332 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:068333 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:578334 };
8335
[email protected]31a2bfe2010-02-09 08:03:398336 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
[email protected]8ddf8322012-02-23 18:08:068337 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:578338
[email protected]bb88e1d32013-05-03 23:11:078339 session_deps_.socket_factory->AddSocketDataProvider(&data);
8340 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:578341
[email protected]49639fa2011-12-20 23:22:418342 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:578343
[email protected]bb88e1d32013-05-03 23:11:078344 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:578345
[email protected]3fe8d2f82013-10-17 08:56:078346 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578347 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418348 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:578349
[email protected]49639fa2011-12-20 23:22:418350 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578351 EXPECT_EQ(ERR_IO_PENDING, rv);
8352
8353 rv = callback.WaitForResult();
8354 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
8355}
8356
[email protected]23e482282013-06-14 16:08:028357TEST_P(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:468358 HttpRequestInfo request;
8359 request.method = "GET";
8360 request.url = GURL("http://www.google.com/");
8361 request.load_flags = 0;
8362
[email protected]3fe8d2f82013-10-17 08:56:078363 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:278364 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418365 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278366
[email protected]e22e1362009-11-23 21:31:128367 MockRead data_reads[] = {
8368 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068369 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:128370 };
[email protected]9492e4a2010-02-24 00:58:468371
8372 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078373 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:468374
[email protected]49639fa2011-12-20 23:22:418375 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:468376
[email protected]49639fa2011-12-20 23:22:418377 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9492e4a2010-02-24 00:58:468378 EXPECT_EQ(ERR_IO_PENDING, rv);
8379
8380 EXPECT_EQ(OK, callback.WaitForResult());
8381
8382 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508383 ASSERT_TRUE(response != NULL);
[email protected]9492e4a2010-02-24 00:58:468384
[email protected]90499482013-06-01 00:39:508385 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]9492e4a2010-02-24 00:58:468386 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
8387
8388 std::string response_data;
8389 rv = ReadTransaction(trans.get(), &response_data);
[email protected]5543cbb2012-04-20 16:35:238390 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
[email protected]e22e1362009-11-23 21:31:128391}
8392
[email protected]23e482282013-06-14 16:08:028393TEST_P(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:158394 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:528395 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
[email protected]95d88ffe2010-02-04 21:25:338396 const uint64 kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:218397 UploadFileElementReader::ScopedOverridingContentLengthForTests
8398 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:338399
[email protected]b2d26cfd2012-12-11 10:36:068400 ScopedVector<UploadElementReader> element_readers;
8401 element_readers.push_back(
[email protected]cadac622013-06-11 16:46:368402 new UploadFileElementReader(base::MessageLoopProxy::current().get(),
8403 temp_file_path,
8404 0,
8405 kuint64max,
8406 base::Time()));
mmenkecbc2b712014-10-09 20:29:078407 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:278408
8409 HttpRequestInfo request;
8410 request.method = "POST";
8411 request.url = GURL("http://www.google.com/upload");
8412 request.upload_data_stream = &upload_data_stream;
8413 request.load_flags = 0;
8414
[email protected]3fe8d2f82013-10-17 08:56:078415 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]329b68b2012-11-14 17:54:278416 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418417 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]95d88ffe2010-02-04 21:25:338418
8419 MockRead data_reads[] = {
8420 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
8421 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068422 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:338423 };
[email protected]31a2bfe2010-02-09 08:03:398424 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078425 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:338426
[email protected]49639fa2011-12-20 23:22:418427 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:338428
[email protected]49639fa2011-12-20 23:22:418429 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]95d88ffe2010-02-04 21:25:338430 EXPECT_EQ(ERR_IO_PENDING, rv);
8431
8432 rv = callback.WaitForResult();
8433 EXPECT_EQ(OK, rv);
8434
8435 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508436 ASSERT_TRUE(response != NULL);
[email protected]95d88ffe2010-02-04 21:25:338437
[email protected]90499482013-06-01 00:39:508438 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]95d88ffe2010-02-04 21:25:338439 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
8440
8441 std::string response_data;
8442 rv = ReadTransaction(trans.get(), &response_data);
8443 EXPECT_EQ(OK, rv);
8444 EXPECT_EQ("hello world", response_data);
8445
[email protected]dd3aa792013-07-16 19:10:238446 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:338447}
8448
[email protected]23e482282013-06-14 16:08:028449TEST_P(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:158450 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:528451 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:368452 std::string temp_file_content("Unreadable file.");
[email protected]e5c2a22e2014-03-06 20:42:308453 ASSERT_TRUE(base::WriteFile(temp_file, temp_file_content.c_str(),
[email protected]6624b4622010-03-29 19:58:368454 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:118455 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:368456
[email protected]b2d26cfd2012-12-11 10:36:068457 ScopedVector<UploadElementReader> element_readers;
8458 element_readers.push_back(
[email protected]cadac622013-06-11 16:46:368459 new UploadFileElementReader(base::MessageLoopProxy::current().get(),
8460 temp_file,
8461 0,
8462 kuint64max,
8463 base::Time()));
mmenkecbc2b712014-10-09 20:29:078464 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:278465
8466 HttpRequestInfo request;
8467 request.method = "POST";
8468 request.url = GURL("http://www.google.com/upload");
8469 request.upload_data_stream = &upload_data_stream;
8470 request.load_flags = 0;
8471
[email protected]999dd8c2013-11-12 06:45:548472 // If we try to upload an unreadable file, the transaction should fail.
[email protected]3fe8d2f82013-10-17 08:56:078473 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]329b68b2012-11-14 17:54:278474 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418475 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]6624b4622010-03-29 19:58:368476
[email protected]999dd8c2013-11-12 06:45:548477 StaticSocketDataProvider data(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078478 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:368479
[email protected]49639fa2011-12-20 23:22:418480 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:368481
[email protected]49639fa2011-12-20 23:22:418482 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]6624b4622010-03-29 19:58:368483 EXPECT_EQ(ERR_IO_PENDING, rv);
8484
8485 rv = callback.WaitForResult();
[email protected]999dd8c2013-11-12 06:45:548486 EXPECT_EQ(ERR_ACCESS_DENIED, rv);
[email protected]6624b4622010-03-29 19:58:368487
8488 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]999dd8c2013-11-12 06:45:548489 EXPECT_FALSE(response);
[email protected]6624b4622010-03-29 19:58:368490
[email protected]dd3aa792013-07-16 19:10:238491 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:368492}
8493
[email protected]02cad5d2013-10-02 08:14:038494TEST_P(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
8495 class FakeUploadElementReader : public UploadElementReader {
8496 public:
8497 FakeUploadElementReader() {}
dchengb03027d2014-10-21 12:00:208498 ~FakeUploadElementReader() override {}
[email protected]02cad5d2013-10-02 08:14:038499
8500 const CompletionCallback& callback() const { return callback_; }
8501
8502 // UploadElementReader overrides:
dchengb03027d2014-10-21 12:00:208503 int Init(const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:038504 callback_ = callback;
8505 return ERR_IO_PENDING;
8506 }
dchengb03027d2014-10-21 12:00:208507 uint64 GetContentLength() const override { return 0; }
8508 uint64 BytesRemaining() const override { return 0; }
8509 int Read(IOBuffer* buf,
8510 int buf_length,
8511 const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:038512 return ERR_FAILED;
8513 }
8514
8515 private:
8516 CompletionCallback callback_;
8517 };
8518
8519 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
8520 ScopedVector<UploadElementReader> element_readers;
8521 element_readers.push_back(fake_reader);
mmenkecbc2b712014-10-09 20:29:078522 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02cad5d2013-10-02 08:14:038523
8524 HttpRequestInfo request;
8525 request.method = "POST";
8526 request.url = GURL("http://www.google.com/upload");
8527 request.upload_data_stream = &upload_data_stream;
8528 request.load_flags = 0;
8529
[email protected]3fe8d2f82013-10-17 08:56:078530 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02cad5d2013-10-02 08:14:038531 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418532 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02cad5d2013-10-02 08:14:038533
8534 StaticSocketDataProvider data;
8535 session_deps_.socket_factory->AddSocketDataProvider(&data);
8536
8537 TestCompletionCallback callback;
8538 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8539 EXPECT_EQ(ERR_IO_PENDING, rv);
8540 base::MessageLoop::current()->RunUntilIdle();
8541
8542 // Transaction is pending on request body initialization.
8543 ASSERT_FALSE(fake_reader->callback().is_null());
8544
8545 // Return Init()'s result after the transaction gets destroyed.
8546 trans.reset();
8547 fake_reader->callback().Run(OK); // Should not crash.
8548}
8549
[email protected]aeefc9e82010-02-19 16:18:278550// Tests that changes to Auth realms are treated like auth rejections.
[email protected]23e482282013-06-14 16:08:028551TEST_P(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:278552
8553 HttpRequestInfo request;
8554 request.method = "GET";
8555 request.url = GURL("http://www.google.com/");
8556 request.load_flags = 0;
8557
8558 // First transaction will request a resource and receive a Basic challenge
8559 // with realm="first_realm".
8560 MockWrite data_writes1[] = {
8561 MockWrite("GET / HTTP/1.1\r\n"
8562 "Host: www.google.com\r\n"
8563 "Connection: keep-alive\r\n"
8564 "\r\n"),
8565 };
8566 MockRead data_reads1[] = {
8567 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8568 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
8569 "\r\n"),
8570 };
8571
8572 // After calling trans->RestartWithAuth(), provide an Authentication header
8573 // for first_realm. The server will reject and provide a challenge with
8574 // second_realm.
8575 MockWrite data_writes2[] = {
8576 MockWrite("GET / HTTP/1.1\r\n"
8577 "Host: www.google.com\r\n"
8578 "Connection: keep-alive\r\n"
8579 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
8580 "\r\n"),
8581 };
8582 MockRead data_reads2[] = {
8583 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8584 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
8585 "\r\n"),
8586 };
8587
8588 // This again fails, and goes back to first_realm. Make sure that the
8589 // entry is removed from cache.
8590 MockWrite data_writes3[] = {
8591 MockWrite("GET / HTTP/1.1\r\n"
8592 "Host: www.google.com\r\n"
8593 "Connection: keep-alive\r\n"
8594 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
8595 "\r\n"),
8596 };
8597 MockRead data_reads3[] = {
8598 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8599 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
8600 "\r\n"),
8601 };
8602
8603 // Try one last time (with the correct password) and get the resource.
8604 MockWrite data_writes4[] = {
8605 MockWrite("GET / HTTP/1.1\r\n"
8606 "Host: www.google.com\r\n"
8607 "Connection: keep-alive\r\n"
8608 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
8609 "\r\n"),
8610 };
8611 MockRead data_reads4[] = {
8612 MockRead("HTTP/1.1 200 OK\r\n"
8613 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:508614 "Content-Length: 5\r\n"
8615 "\r\n"
8616 "hello"),
[email protected]aeefc9e82010-02-19 16:18:278617 };
8618
8619 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8620 data_writes1, arraysize(data_writes1));
8621 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8622 data_writes2, arraysize(data_writes2));
8623 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
8624 data_writes3, arraysize(data_writes3));
8625 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
8626 data_writes4, arraysize(data_writes4));
[email protected]bb88e1d32013-05-03 23:11:078627 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8628 session_deps_.socket_factory->AddSocketDataProvider(&data2);
8629 session_deps_.socket_factory->AddSocketDataProvider(&data3);
8630 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:278631
[email protected]49639fa2011-12-20 23:22:418632 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:278633
[email protected]3fe8d2f82013-10-17 08:56:078634 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0b0bf032010-09-21 18:08:508635 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418636 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:508637
[email protected]aeefc9e82010-02-19 16:18:278638 // Issue the first request with Authorize headers. There should be a
8639 // password prompt for first_realm waiting to be filled in after the
8640 // transaction completes.
[email protected]49639fa2011-12-20 23:22:418641 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]aeefc9e82010-02-19 16:18:278642 EXPECT_EQ(ERR_IO_PENDING, rv);
8643 rv = callback1.WaitForResult();
8644 EXPECT_EQ(OK, rv);
8645 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508646 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048647 const AuthChallengeInfo* challenge = response->auth_challenge.get();
8648 ASSERT_FALSE(challenge == NULL);
8649 EXPECT_FALSE(challenge->is_proxy);
8650 EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
8651 EXPECT_EQ("first_realm", challenge->realm);
8652 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278653
8654 // Issue the second request with an incorrect password. There should be a
8655 // password prompt for second_realm waiting to be filled in after the
8656 // transaction completes.
[email protected]49639fa2011-12-20 23:22:418657 TestCompletionCallback callback2;
8658 rv = trans->RestartWithAuth(
8659 AuthCredentials(kFirst, kBaz), callback2.callback());
[email protected]aeefc9e82010-02-19 16:18:278660 EXPECT_EQ(ERR_IO_PENDING, rv);
8661 rv = callback2.WaitForResult();
8662 EXPECT_EQ(OK, rv);
8663 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508664 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048665 challenge = response->auth_challenge.get();
8666 ASSERT_FALSE(challenge == NULL);
8667 EXPECT_FALSE(challenge->is_proxy);
8668 EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
8669 EXPECT_EQ("second_realm", challenge->realm);
8670 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278671
8672 // Issue the third request with another incorrect password. There should be
8673 // a password prompt for first_realm waiting to be filled in. If the password
8674 // prompt is not present, it indicates that the HttpAuthCacheEntry for
8675 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:418676 TestCompletionCallback callback3;
8677 rv = trans->RestartWithAuth(
8678 AuthCredentials(kSecond, kFou), callback3.callback());
[email protected]aeefc9e82010-02-19 16:18:278679 EXPECT_EQ(ERR_IO_PENDING, rv);
8680 rv = callback3.WaitForResult();
8681 EXPECT_EQ(OK, rv);
8682 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508683 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048684 challenge = response->auth_challenge.get();
8685 ASSERT_FALSE(challenge == NULL);
8686 EXPECT_FALSE(challenge->is_proxy);
8687 EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
8688 EXPECT_EQ("first_realm", challenge->realm);
8689 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278690
8691 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:418692 TestCompletionCallback callback4;
8693 rv = trans->RestartWithAuth(
8694 AuthCredentials(kFirst, kBar), callback4.callback());
[email protected]aeefc9e82010-02-19 16:18:278695 EXPECT_EQ(ERR_IO_PENDING, rv);
8696 rv = callback4.WaitForResult();
8697 EXPECT_EQ(OK, rv);
8698 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508699 ASSERT_TRUE(response != NULL);
[email protected]aeefc9e82010-02-19 16:18:278700 EXPECT_TRUE(response->auth_challenge.get() == NULL);
8701}
8702
[email protected]23e482282013-06-14 16:08:028703TEST_P(HttpNetworkTransactionTest, HonorAlternateProtocolHeader) {
[email protected]d7599122014-05-24 03:37:238704 session_deps_.next_protos = SpdyNextProtos();
8705 session_deps_.use_alternate_protocols = true;
[email protected]a2cb8122010-03-10 17:22:428706
[email protected]8a0fc822013-06-27 20:52:438707 std::string alternate_protocol_http_header =
8708 GetAlternateProtocolHttpHeader();
8709
[email protected]564b4912010-03-09 16:30:428710 MockRead data_reads[] = {
8711 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438712 MockRead(alternate_protocol_http_header.c_str()),
[email protected]564b4912010-03-09 16:30:428713 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068714 MockRead(SYNCHRONOUS, OK),
[email protected]564b4912010-03-09 16:30:428715 };
8716
8717 HttpRequestInfo request;
8718 request.method = "GET";
8719 request.url = GURL("http://www.google.com/");
8720 request.load_flags = 0;
8721
8722 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
8723
[email protected]bb88e1d32013-05-03 23:11:078724 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]564b4912010-03-09 16:30:428725
[email protected]49639fa2011-12-20 23:22:418726 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:428727
[email protected]bb88e1d32013-05-03 23:11:078728 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:368729 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508730 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]564b4912010-03-09 16:30:428731
[email protected]49639fa2011-12-20 23:22:418732 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:428733 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]9e743cd2010-03-16 07:03:538734
[email protected]2fbaecf22010-07-22 22:20:358735 HostPortPair http_host_port_pair("www.google.com", 80);
[email protected]9801e3702014-03-07 09:33:558736 HttpServerProperties& http_server_properties =
[email protected]17291a022011-10-10 07:32:538737 *session->http_server_properties();
bnc3c2553312015-02-03 23:12:018738 AlternateProtocolInfo alternate =
8739 http_server_properties.GetAlternateProtocol(http_host_port_pair);
8740 EXPECT_EQ(alternate.protocol, UNINITIALIZED_ALTERNATE_PROTOCOL);
[email protected]564b4912010-03-09 16:30:428741
8742 EXPECT_EQ(OK, callback.WaitForResult());
8743
8744 const HttpResponseInfo* response = trans->GetResponseInfo();
8745 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508746 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:428747 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:538748 EXPECT_FALSE(response->was_fetched_via_spdy);
8749 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]564b4912010-03-09 16:30:428750
8751 std::string response_data;
8752 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8753 EXPECT_EQ("hello world", response_data);
8754
bnc3c2553312015-02-03 23:12:018755 alternate = http_server_properties.GetAlternateProtocol(http_host_port_pair);
8756 EXPECT_EQ(443, alternate.port);
8757 EXPECT_EQ(AlternateProtocolFromNextProto(GetParam()), alternate.protocol);
8758 EXPECT_EQ(1.0, alternate.probability);
[email protected]564b4912010-03-09 16:30:428759}
8760
[email protected]23e482282013-06-14 16:08:028761TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238762 MarkBrokenAlternateProtocolAndFallback) {
[email protected]d7599122014-05-24 03:37:238763 session_deps_.use_alternate_protocols = true;
[email protected]564b4912010-03-09 16:30:428764
8765 HttpRequestInfo request;
8766 request.method = "GET";
8767 request.url = GURL("http://www.google.com/");
8768 request.load_flags = 0;
8769
[email protected]d973e99a2012-02-17 21:02:368770 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:428771 StaticSocketDataProvider first_data;
8772 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078773 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]564b4912010-03-09 16:30:428774
8775 MockRead data_reads[] = {
8776 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8777 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068778 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:428779 };
8780 StaticSocketDataProvider second_data(
8781 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078782 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:428783
[email protected]bb88e1d32013-05-03 23:11:078784 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:428785
[email protected]30d4c022013-07-18 22:58:168786 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538787 session->http_server_properties();
bnc8445b3002015-03-13 01:57:098788 const HostPortPair host_port_pair = HostPortPair::FromURL(request.url);
[email protected]3912662a32011-10-04 00:51:118789 // Port must be < 1024, or the header will be ignored (since initial port was
8790 // port 80 (another restricted port).
[email protected]17291a022011-10-10 07:32:538791 http_server_properties->SetAlternateProtocol(
bnc8445b3002015-03-13 01:57:098792 host_port_pair, 666 /* port is ignored by MockConnect anyway */,
bnc1102b552015-01-30 20:11:018793 AlternateProtocolFromNextProto(GetParam()), 1.0);
[email protected]564b4912010-03-09 16:30:428794
[email protected]262eec82013-03-19 21:01:368795 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508796 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418797 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:428798
[email protected]49639fa2011-12-20 23:22:418799 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:428800 EXPECT_EQ(ERR_IO_PENDING, rv);
8801 EXPECT_EQ(OK, callback.WaitForResult());
8802
8803 const HttpResponseInfo* response = trans->GetResponseInfo();
8804 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508805 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:428806 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8807
8808 std::string response_data;
8809 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8810 EXPECT_EQ("hello world", response_data);
8811
[email protected]287d9412014-07-08 23:01:008812 const AlternateProtocolInfo alternate =
bnc8445b3002015-03-13 01:57:098813 http_server_properties->GetAlternateProtocol(host_port_pair);
bnc3c2553312015-02-03 23:12:018814 EXPECT_NE(UNINITIALIZED_ALTERNATE_PROTOCOL, alternate.protocol);
bnc8445b3002015-03-13 01:57:098815 const AlternativeService alternative_service(
8816 alternate.protocol, host_port_pair.host(), alternate.port);
8817 EXPECT_TRUE(
8818 http_server_properties->IsAlternativeServiceBroken(alternative_service));
[email protected]564b4912010-03-09 16:30:428819}
8820
[email protected]23e482282013-06-14 16:08:028821TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238822 AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:118823 // Ensure that we're not allowed to redirect traffic via an alternate
8824 // protocol to an unrestricted (port >= 1024) when the original traffic was
8825 // on a restricted port (port < 1024). Ensure that we can redirect in all
8826 // other cases.
[email protected]d7599122014-05-24 03:37:238827 session_deps_.use_alternate_protocols = true;
[email protected]3912662a32011-10-04 00:51:118828
8829 HttpRequestInfo restricted_port_request;
8830 restricted_port_request.method = "GET";
8831 restricted_port_request.url = GURL("http://www.google.com:1023/");
8832 restricted_port_request.load_flags = 0;
8833
[email protected]d973e99a2012-02-17 21:02:368834 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118835 StaticSocketDataProvider first_data;
8836 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078837 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118838
8839 MockRead data_reads[] = {
8840 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8841 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068842 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118843 };
8844 StaticSocketDataProvider second_data(
8845 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078846 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118847
[email protected]bb88e1d32013-05-03 23:11:078848 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118849
[email protected]30d4c022013-07-18 22:58:168850 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538851 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118852 const int kUnrestrictedAlternatePort = 1024;
[email protected]17291a022011-10-10 07:32:538853 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118854 HostPortPair::FromURL(restricted_port_request.url),
bnc1102b552015-01-30 20:11:018855 kUnrestrictedAlternatePort, AlternateProtocolFromNextProto(GetParam()),
8856 1.0);
[email protected]3912662a32011-10-04 00:51:118857
[email protected]262eec82013-03-19 21:01:368858 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508859 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418860 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118861
[email protected]49639fa2011-12-20 23:22:418862 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:368863 &restricted_port_request,
8864 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118865 EXPECT_EQ(ERR_IO_PENDING, rv);
8866 // Invalid change to unrestricted port should fail.
8867 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.WaitForResult());
[email protected]c54c6962013-02-01 04:53:198868}
[email protected]3912662a32011-10-04 00:51:118869
[email protected]23e482282013-06-14 16:08:028870TEST_P(HttpNetworkTransactionTest,
[email protected]c54c6962013-02-01 04:53:198871 AlternateProtocolPortRestrictedPermitted) {
8872 // Ensure that we're allowed to redirect traffic via an alternate
8873 // protocol to an unrestricted (port >= 1024) when the original traffic was
8874 // on a restricted port (port < 1024) if we set
8875 // enable_user_alternate_protocol_ports.
8876
[email protected]d7599122014-05-24 03:37:238877 session_deps_.use_alternate_protocols = true;
[email protected]bb88e1d32013-05-03 23:11:078878 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:198879
8880 HttpRequestInfo restricted_port_request;
8881 restricted_port_request.method = "GET";
8882 restricted_port_request.url = GURL("http://www.google.com:1023/");
8883 restricted_port_request.load_flags = 0;
8884
8885 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
8886 StaticSocketDataProvider first_data;
8887 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078888 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:198889
8890 MockRead data_reads[] = {
8891 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8892 MockRead("hello world"),
8893 MockRead(ASYNC, OK),
8894 };
8895 StaticSocketDataProvider second_data(
8896 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078897 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]c54c6962013-02-01 04:53:198898
[email protected]bb88e1d32013-05-03 23:11:078899 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:198900
[email protected]30d4c022013-07-18 22:58:168901 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]c54c6962013-02-01 04:53:198902 session->http_server_properties();
8903 const int kUnrestrictedAlternatePort = 1024;
8904 http_server_properties->SetAlternateProtocol(
8905 HostPortPair::FromURL(restricted_port_request.url),
bnc1102b552015-01-30 20:11:018906 kUnrestrictedAlternatePort, AlternateProtocolFromNextProto(GetParam()),
8907 1.0);
[email protected]c54c6962013-02-01 04:53:198908
[email protected]262eec82013-03-19 21:01:368909 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508910 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]c54c6962013-02-01 04:53:198911 TestCompletionCallback callback;
8912
8913 EXPECT_EQ(ERR_IO_PENDING, trans->Start(
[email protected]262eec82013-03-19 21:01:368914 &restricted_port_request,
8915 callback.callback(), BoundNetLog()));
[email protected]c54c6962013-02-01 04:53:198916 // Change to unrestricted port should succeed.
8917 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:118918}
8919
[email protected]23e482282013-06-14 16:08:028920TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238921 AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:118922 // Ensure that we're not allowed to redirect traffic via an alternate
8923 // protocol to an unrestricted (port >= 1024) when the original traffic was
8924 // on a restricted port (port < 1024). Ensure that we can redirect in all
8925 // other cases.
[email protected]d7599122014-05-24 03:37:238926 session_deps_.use_alternate_protocols = true;
[email protected]3912662a32011-10-04 00:51:118927
8928 HttpRequestInfo restricted_port_request;
8929 restricted_port_request.method = "GET";
8930 restricted_port_request.url = GURL("http://www.google.com:1023/");
8931 restricted_port_request.load_flags = 0;
8932
[email protected]d973e99a2012-02-17 21:02:368933 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118934 StaticSocketDataProvider first_data;
8935 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078936 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118937
8938 MockRead data_reads[] = {
8939 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8940 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068941 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118942 };
8943 StaticSocketDataProvider second_data(
8944 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078945 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118946
[email protected]bb88e1d32013-05-03 23:11:078947 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118948
[email protected]30d4c022013-07-18 22:58:168949 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538950 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118951 const int kRestrictedAlternatePort = 80;
[email protected]17291a022011-10-10 07:32:538952 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118953 HostPortPair::FromURL(restricted_port_request.url),
bnc1102b552015-01-30 20:11:018954 kRestrictedAlternatePort, AlternateProtocolFromNextProto(GetParam()),
8955 1.0);
[email protected]3912662a32011-10-04 00:51:118956
[email protected]262eec82013-03-19 21:01:368957 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508958 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418959 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118960
[email protected]49639fa2011-12-20 23:22:418961 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:368962 &restricted_port_request,
8963 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118964 EXPECT_EQ(ERR_IO_PENDING, rv);
8965 // Valid change to restricted port should pass.
8966 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:118967}
8968
[email protected]23e482282013-06-14 16:08:028969TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238970 AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:118971 // Ensure that we're not allowed to redirect traffic via an alternate
8972 // protocol to an unrestricted (port >= 1024) when the original traffic was
8973 // on a restricted port (port < 1024). Ensure that we can redirect in all
8974 // other cases.
[email protected]d7599122014-05-24 03:37:238975 session_deps_.use_alternate_protocols = true;
[email protected]3912662a32011-10-04 00:51:118976
8977 HttpRequestInfo unrestricted_port_request;
8978 unrestricted_port_request.method = "GET";
8979 unrestricted_port_request.url = GURL("http://www.google.com:1024/");
8980 unrestricted_port_request.load_flags = 0;
8981
[email protected]d973e99a2012-02-17 21:02:368982 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118983 StaticSocketDataProvider first_data;
8984 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078985 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118986
8987 MockRead data_reads[] = {
8988 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8989 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068990 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118991 };
8992 StaticSocketDataProvider second_data(
8993 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078994 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118995
[email protected]bb88e1d32013-05-03 23:11:078996 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118997
[email protected]30d4c022013-07-18 22:58:168998 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538999 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:119000 const int kRestrictedAlternatePort = 80;
[email protected]17291a022011-10-10 07:32:539001 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:119002 HostPortPair::FromURL(unrestricted_port_request.url),
bnc1102b552015-01-30 20:11:019003 kRestrictedAlternatePort, AlternateProtocolFromNextProto(GetParam()),
9004 1.0);
[email protected]3912662a32011-10-04 00:51:119005
[email protected]262eec82013-03-19 21:01:369006 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509007 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419008 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:119009
[email protected]49639fa2011-12-20 23:22:419010 int rv = trans->Start(
9011 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:119012 EXPECT_EQ(ERR_IO_PENDING, rv);
9013 // Valid change to restricted port should pass.
9014 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:119015}
9016
[email protected]23e482282013-06-14 16:08:029017TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239018 AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:119019 // Ensure that we're not allowed to redirect traffic via an alternate
9020 // protocol to an unrestricted (port >= 1024) when the original traffic was
9021 // on a restricted port (port < 1024). Ensure that we can redirect in all
9022 // other cases.
[email protected]d7599122014-05-24 03:37:239023 session_deps_.use_alternate_protocols = true;
[email protected]3912662a32011-10-04 00:51:119024
9025 HttpRequestInfo unrestricted_port_request;
9026 unrestricted_port_request.method = "GET";
9027 unrestricted_port_request.url = GURL("http://www.google.com:1024/");
9028 unrestricted_port_request.load_flags = 0;
9029
[email protected]d973e99a2012-02-17 21:02:369030 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:119031 StaticSocketDataProvider first_data;
9032 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079033 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:119034
9035 MockRead data_reads[] = {
9036 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9037 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069038 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:119039 };
9040 StaticSocketDataProvider second_data(
9041 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079042 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:119043
[email protected]bb88e1d32013-05-03 23:11:079044 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:119045
[email protected]30d4c022013-07-18 22:58:169046 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:539047 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:119048 const int kUnrestrictedAlternatePort = 1024;
[email protected]17291a022011-10-10 07:32:539049 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:119050 HostPortPair::FromURL(unrestricted_port_request.url),
bnc1102b552015-01-30 20:11:019051 kUnrestrictedAlternatePort, AlternateProtocolFromNextProto(GetParam()),
9052 1.0);
[email protected]3912662a32011-10-04 00:51:119053
[email protected]262eec82013-03-19 21:01:369054 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509055 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419056 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:119057
[email protected]49639fa2011-12-20 23:22:419058 int rv = trans->Start(
9059 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:119060 EXPECT_EQ(ERR_IO_PENDING, rv);
9061 // Valid change to an unrestricted port should pass.
9062 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:119063}
9064
[email protected]d7599122014-05-24 03:37:239065TEST_P(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:029066 // Ensure that we're not allowed to redirect traffic via an alternate
9067 // protocol to an unsafe port, and that we resume the second
9068 // HttpStreamFactoryImpl::Job once the alternate protocol request fails.
[email protected]d7599122014-05-24 03:37:239069 session_deps_.use_alternate_protocols = true;
[email protected]eb6234e2012-01-19 01:50:029070
9071 HttpRequestInfo request;
9072 request.method = "GET";
9073 request.url = GURL("http://www.google.com/");
9074 request.load_flags = 0;
9075
9076 // The alternate protocol request will error out before we attempt to connect,
9077 // so only the standard HTTP request will try to connect.
9078 MockRead data_reads[] = {
9079 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9080 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069081 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:029082 };
9083 StaticSocketDataProvider data(
9084 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079085 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:029086
[email protected]bb88e1d32013-05-03 23:11:079087 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:029088
[email protected]30d4c022013-07-18 22:58:169089 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]eb6234e2012-01-19 01:50:029090 session->http_server_properties();
9091 const int kUnsafePort = 7;
9092 http_server_properties->SetAlternateProtocol(
bnc1102b552015-01-30 20:11:019093 HostPortPair::FromURL(request.url), kUnsafePort,
9094 AlternateProtocolFromNextProto(GetParam()), 1.0);
[email protected]eb6234e2012-01-19 01:50:029095
[email protected]262eec82013-03-19 21:01:369096 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509097 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]eb6234e2012-01-19 01:50:029098 TestCompletionCallback callback;
9099
9100 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9101 EXPECT_EQ(ERR_IO_PENDING, rv);
9102 // The HTTP request should succeed.
9103 EXPECT_EQ(OK, callback.WaitForResult());
9104
9105 // Disable alternate protocol before the asserts.
[email protected]d7599122014-05-24 03:37:239106 // HttpStreamFactory::set_use_alternate_protocols(false);
[email protected]eb6234e2012-01-19 01:50:029107
9108 const HttpResponseInfo* response = trans->GetResponseInfo();
9109 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509110 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]eb6234e2012-01-19 01:50:029111 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9112
9113 std::string response_data;
9114 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9115 EXPECT_EQ("hello world", response_data);
9116}
9117
[email protected]23e482282013-06-14 16:08:029118TEST_P(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]d7599122014-05-24 03:37:239119 session_deps_.use_alternate_protocols = true;
9120 session_deps_.next_protos = SpdyNextProtos();
[email protected]2ff8b312010-04-26 22:20:549121
9122 HttpRequestInfo request;
9123 request.method = "GET";
9124 request.url = GURL("http://www.google.com/");
9125 request.load_flags = 0;
9126
[email protected]8a0fc822013-06-27 20:52:439127 std::string alternate_protocol_http_header =
9128 GetAlternateProtocolHttpHeader();
9129
[email protected]2ff8b312010-04-26 22:20:549130 MockRead data_reads[] = {
9131 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439132 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2ff8b312010-04-26 22:20:549133 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:179134 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
9135 MockRead(ASYNC, OK)
[email protected]2ff8b312010-04-26 22:20:549136 };
9137
9138 StaticSocketDataProvider first_transaction(
9139 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079140 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:549141
[email protected]8ddf8322012-02-23 18:08:069142 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029143 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:079144 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:549145
[email protected]cdf8f7e72013-05-23 10:56:469146 scoped_ptr<SpdyFrame> req(
9147 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]e7f75092010-07-01 22:39:139148 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
[email protected]2ff8b312010-04-26 22:20:549149
[email protected]23e482282013-06-14 16:08:029150 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9151 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:549152 MockRead spdy_reads[] = {
[email protected]e7f75092010-07-01 22:39:139153 CreateMockRead(*resp),
9154 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:069155 MockRead(ASYNC, 0, 0),
[email protected]2ff8b312010-04-26 22:20:549156 };
9157
[email protected]dd54bd82012-07-19 23:44:579158 DelayedSocketData spdy_data(
9159 1, // wait for one write to finish before reading.
9160 spdy_reads, arraysize(spdy_reads),
9161 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079162 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:549163
[email protected]d973e99a2012-02-17 21:02:369164 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559165 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
9166 NULL, 0, NULL, 0);
9167 hanging_non_alternate_protocol_socket.set_connect_data(
9168 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:079169 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:559170 &hanging_non_alternate_protocol_socket);
9171
[email protected]49639fa2011-12-20 23:22:419172 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:549173
[email protected]bb88e1d32013-05-03 23:11:079174 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369175 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509176 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:549177
[email protected]49639fa2011-12-20 23:22:419178 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:549179 EXPECT_EQ(ERR_IO_PENDING, rv);
9180 EXPECT_EQ(OK, callback.WaitForResult());
9181
9182 const HttpResponseInfo* response = trans->GetResponseInfo();
9183 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509184 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:549185 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9186
9187 std::string response_data;
9188 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9189 EXPECT_EQ("hello world", response_data);
9190
[email protected]90499482013-06-01 00:39:509191 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:549192
[email protected]49639fa2011-12-20 23:22:419193 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:549194 EXPECT_EQ(ERR_IO_PENDING, rv);
9195 EXPECT_EQ(OK, callback.WaitForResult());
9196
9197 response = trans->GetResponseInfo();
9198 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509199 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:549200 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539201 EXPECT_TRUE(response->was_fetched_via_spdy);
9202 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:549203
9204 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9205 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:549206}
9207
[email protected]23e482282013-06-14 16:08:029208TEST_P(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]d7599122014-05-24 03:37:239209 session_deps_.use_alternate_protocols = true;
9210 session_deps_.next_protos = SpdyNextProtos();
[email protected]2d6728692011-03-12 01:39:559211
9212 HttpRequestInfo request;
9213 request.method = "GET";
9214 request.url = GURL("http://www.google.com/");
9215 request.load_flags = 0;
9216
[email protected]8a0fc822013-06-27 20:52:439217 std::string alternate_protocol_http_header =
9218 GetAlternateProtocolHttpHeader();
9219
[email protected]2d6728692011-03-12 01:39:559220 MockRead data_reads[] = {
9221 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439222 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2d6728692011-03-12 01:39:559223 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:179224 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:069225 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:559226 };
9227
9228 StaticSocketDataProvider first_transaction(
9229 data_reads, arraysize(data_reads), NULL, 0);
9230 // Socket 1 is the HTTP transaction with the Alternate-Protocol header.
[email protected]bb88e1d32013-05-03 23:11:079231 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:559232
[email protected]d973e99a2012-02-17 21:02:369233 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559234 StaticSocketDataProvider hanging_socket(
9235 NULL, 0, NULL, 0);
9236 hanging_socket.set_connect_data(never_finishing_connect);
9237 // Socket 2 and 3 are the hanging Alternate-Protocol and
9238 // non-Alternate-Protocol jobs from the 2nd transaction.
[email protected]bb88e1d32013-05-03 23:11:079239 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
9240 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
[email protected]2d6728692011-03-12 01:39:559241
[email protected]8ddf8322012-02-23 18:08:069242 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029243 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:079244 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:559245
[email protected]cdf8f7e72013-05-23 10:56:469246 scoped_ptr<SpdyFrame> req1(
9247 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
9248 scoped_ptr<SpdyFrame> req2(
9249 spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
[email protected]2d6728692011-03-12 01:39:559250 MockWrite spdy_writes[] = {
9251 CreateMockWrite(*req1),
9252 CreateMockWrite(*req2),
9253 };
[email protected]23e482282013-06-14 16:08:029254 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9255 scoped_ptr<SpdyFrame> data1(spdy_util_.ConstructSpdyBodyFrame(1, true));
9256 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
9257 scoped_ptr<SpdyFrame> data2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]2d6728692011-03-12 01:39:559258 MockRead spdy_reads[] = {
9259 CreateMockRead(*resp1),
9260 CreateMockRead(*data1),
9261 CreateMockRead(*resp2),
9262 CreateMockRead(*data2),
[email protected]8ddf8322012-02-23 18:08:069263 MockRead(ASYNC, 0, 0),
[email protected]2d6728692011-03-12 01:39:559264 };
9265
[email protected]dd54bd82012-07-19 23:44:579266 DelayedSocketData spdy_data(
9267 2, // wait for writes to finish before reading.
9268 spdy_reads, arraysize(spdy_reads),
9269 spdy_writes, arraysize(spdy_writes));
[email protected]2d6728692011-03-12 01:39:559270 // Socket 4 is the successful Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:079271 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:559272
9273 // Socket 5 is the unsuccessful non-Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:079274 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
[email protected]2d6728692011-03-12 01:39:559275
[email protected]bb88e1d32013-05-03 23:11:079276 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:419277 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:509278 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:559279
[email protected]49639fa2011-12-20 23:22:419280 int rv = trans1.Start(&request, callback1.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559281 EXPECT_EQ(ERR_IO_PENDING, rv);
9282 EXPECT_EQ(OK, callback1.WaitForResult());
9283
9284 const HttpResponseInfo* response = trans1.GetResponseInfo();
9285 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509286 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559287 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9288
9289 std::string response_data;
9290 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
9291 EXPECT_EQ("hello world", response_data);
9292
[email protected]49639fa2011-12-20 23:22:419293 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:509294 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:419295 rv = trans2.Start(&request, callback2.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559296 EXPECT_EQ(ERR_IO_PENDING, rv);
9297
[email protected]49639fa2011-12-20 23:22:419298 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:509299 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:419300 rv = trans3.Start(&request, callback3.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559301 EXPECT_EQ(ERR_IO_PENDING, rv);
9302
9303 EXPECT_EQ(OK, callback2.WaitForResult());
9304 EXPECT_EQ(OK, callback3.WaitForResult());
9305
9306 response = trans2.GetResponseInfo();
9307 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509308 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559309 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9310 EXPECT_TRUE(response->was_fetched_via_spdy);
9311 EXPECT_TRUE(response->was_npn_negotiated);
9312 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
9313 EXPECT_EQ("hello!", response_data);
9314
9315 response = trans3.GetResponseInfo();
9316 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509317 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559318 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9319 EXPECT_TRUE(response->was_fetched_via_spdy);
9320 EXPECT_TRUE(response->was_npn_negotiated);
9321 ASSERT_EQ(OK, ReadTransaction(&trans3, &response_data));
9322 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:559323}
9324
[email protected]23e482282013-06-14 16:08:029325TEST_P(HttpNetworkTransactionTest, StallAlternateProtocolForNpnSpdy) {
[email protected]d7599122014-05-24 03:37:239326 session_deps_.use_alternate_protocols = true;
9327 session_deps_.next_protos = SpdyNextProtos();
[email protected]2d6728692011-03-12 01:39:559328
9329 HttpRequestInfo request;
9330 request.method = "GET";
9331 request.url = GURL("http://www.google.com/");
9332 request.load_flags = 0;
9333
[email protected]8a0fc822013-06-27 20:52:439334 std::string alternate_protocol_http_header =
9335 GetAlternateProtocolHttpHeader();
9336
[email protected]2d6728692011-03-12 01:39:559337 MockRead data_reads[] = {
9338 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439339 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2d6728692011-03-12 01:39:559340 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:179341 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:069342 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:559343 };
9344
9345 StaticSocketDataProvider first_transaction(
9346 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079347 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:559348
[email protected]8ddf8322012-02-23 18:08:069349 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029350 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:079351 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:559352
[email protected]d973e99a2012-02-17 21:02:369353 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559354 StaticSocketDataProvider hanging_alternate_protocol_socket(
9355 NULL, 0, NULL, 0);
9356 hanging_alternate_protocol_socket.set_connect_data(
9357 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:079358 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:559359 &hanging_alternate_protocol_socket);
9360
9361 // 2nd request is just a copy of the first one, over HTTP again.
[email protected]bb88e1d32013-05-03 23:11:079362 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:559363
[email protected]49639fa2011-12-20 23:22:419364 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:559365
[email protected]bb88e1d32013-05-03 23:11:079366 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369367 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509368 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:559369
[email protected]49639fa2011-12-20 23:22:419370 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559371 EXPECT_EQ(ERR_IO_PENDING, rv);
9372 EXPECT_EQ(OK, callback.WaitForResult());
9373
9374 const HttpResponseInfo* response = trans->GetResponseInfo();
9375 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509376 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559377 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9378
9379 std::string response_data;
9380 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9381 EXPECT_EQ("hello world", response_data);
9382
[email protected]90499482013-06-01 00:39:509383 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:559384
[email protected]49639fa2011-12-20 23:22:419385 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559386 EXPECT_EQ(ERR_IO_PENDING, rv);
9387 EXPECT_EQ(OK, callback.WaitForResult());
9388
9389 response = trans->GetResponseInfo();
9390 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509391 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559392 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9393 EXPECT_FALSE(response->was_fetched_via_spdy);
9394 EXPECT_FALSE(response->was_npn_negotiated);
9395
9396 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9397 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:559398}
9399
[email protected]631f1322010-04-30 17:59:119400class CapturingProxyResolver : public ProxyResolver {
9401 public:
9402 CapturingProxyResolver() : ProxyResolver(false /* expects_pac_bytes */) {}
dchengb03027d2014-10-21 12:00:209403 ~CapturingProxyResolver() override {}
[email protected]631f1322010-04-30 17:59:119404
dchengb03027d2014-10-21 12:00:209405 int GetProxyForURL(const GURL& url,
9406 ProxyInfo* results,
9407 const CompletionCallback& callback,
9408 RequestHandle* request,
9409 const BoundNetLog& net_log) override {
[email protected]fae7669f2010-08-02 21:49:409410 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
9411 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:429412 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:119413 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:429414 return OK;
[email protected]631f1322010-04-30 17:59:119415 }
9416
dchengb03027d2014-10-21 12:00:209417 void CancelRequest(RequestHandle request) override { NOTREACHED(); }
[email protected]631f1322010-04-30 17:59:119418
dchengb03027d2014-10-21 12:00:209419 LoadState GetLoadState(RequestHandle request) const override {
[email protected]f2c971f2011-11-08 00:33:179420 NOTREACHED();
9421 return LOAD_STATE_IDLE;
9422 }
9423
dchengb03027d2014-10-21 12:00:209424 void CancelSetPacScript() override { NOTREACHED(); }
[email protected]1e605472010-12-16 21:41:409425
dchengb03027d2014-10-21 12:00:209426 int SetPacScript(const scoped_refptr<ProxyResolverScriptData>&,
9427 const CompletionCallback& /*callback*/) override {
[email protected]d911f1b2010-05-05 22:39:429428 return OK;
[email protected]631f1322010-04-30 17:59:119429 }
9430
[email protected]24476402010-07-20 20:55:179431 const std::vector<GURL>& resolved() const { return resolved_; }
9432
9433 private:
[email protected]631f1322010-04-30 17:59:119434 std::vector<GURL> resolved_;
9435
9436 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
9437};
9438
[email protected]23e482282013-06-14 16:08:029439TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239440 UseAlternateProtocolForTunneledNpnSpdy) {
[email protected]d7599122014-05-24 03:37:239441 session_deps_.use_alternate_protocols = true;
9442 session_deps_.next_protos = SpdyNextProtos();
[email protected]631f1322010-04-30 17:59:119443
9444 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:429445 proxy_config.set_auto_detect(true);
9446 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:119447
[email protected]631f1322010-04-30 17:59:119448 CapturingProxyResolver* capturing_proxy_resolver =
9449 new CapturingProxyResolver();
[email protected]bb88e1d32013-05-03 23:11:079450 session_deps_.proxy_service.reset(new ProxyService(
[email protected]66761b952010-06-25 21:30:389451 new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver,
9452 NULL));
[email protected]029c83b62013-01-24 05:28:209453 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079454 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:119455
9456 HttpRequestInfo request;
9457 request.method = "GET";
9458 request.url = GURL("http://www.google.com/");
9459 request.load_flags = 0;
9460
[email protected]8a0fc822013-06-27 20:52:439461 std::string alternate_protocol_http_header =
9462 GetAlternateProtocolHttpHeader();
9463
[email protected]631f1322010-04-30 17:59:119464 MockRead data_reads[] = {
9465 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439466 MockRead(alternate_protocol_http_header.c_str()),
[email protected]631f1322010-04-30 17:59:119467 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:179468 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:069469 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:119470 };
9471
9472 StaticSocketDataProvider first_transaction(
9473 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079474 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]631f1322010-04-30 17:59:119475
[email protected]8ddf8322012-02-23 18:08:069476 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029477 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:079478 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]631f1322010-04-30 17:59:119479
[email protected]cdf8f7e72013-05-23 10:56:469480 scoped_ptr<SpdyFrame> req(
9481 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]631f1322010-04-30 17:59:119482 MockWrite spdy_writes[] = {
9483 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
9484 "Host: www.google.com\r\n"
[email protected]d911f1b2010-05-05 22:39:429485 "Proxy-Connection: keep-alive\r\n\r\n"), // 0
[email protected]cdf8f7e72013-05-23 10:56:469486 CreateMockWrite(*req), // 3
[email protected]631f1322010-04-30 17:59:119487 };
9488
[email protected]d911f1b2010-05-05 22:39:429489 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
9490
[email protected]23e482282013-06-14 16:08:029491 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9492 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]631f1322010-04-30 17:59:119493 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:069494 MockRead(ASYNC, kCONNECTResponse, arraysize(kCONNECTResponse) - 1, 1), // 1
[email protected]e7f75092010-07-01 22:39:139495 CreateMockRead(*resp.get(), 4), // 2, 4
9496 CreateMockRead(*data.get(), 4), // 5
[email protected]8ddf8322012-02-23 18:08:069497 MockRead(ASYNC, 0, 0, 4), // 6
[email protected]631f1322010-04-30 17:59:119498 };
9499
[email protected]dd54bd82012-07-19 23:44:579500 OrderedSocketData spdy_data(
9501 spdy_reads, arraysize(spdy_reads),
9502 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079503 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:119504
[email protected]d973e99a2012-02-17 21:02:369505 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559506 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
9507 NULL, 0, NULL, 0);
9508 hanging_non_alternate_protocol_socket.set_connect_data(
9509 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:079510 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:559511 &hanging_non_alternate_protocol_socket);
9512
[email protected]49639fa2011-12-20 23:22:419513 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:119514
[email protected]bb88e1d32013-05-03 23:11:079515 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369516 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509517 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:119518
[email protected]49639fa2011-12-20 23:22:419519 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:119520 EXPECT_EQ(ERR_IO_PENDING, rv);
9521 EXPECT_EQ(OK, callback.WaitForResult());
9522
9523 const HttpResponseInfo* response = trans->GetResponseInfo();
9524 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509525 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]631f1322010-04-30 17:59:119526 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539527 EXPECT_FALSE(response->was_fetched_via_spdy);
9528 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:119529
9530 std::string response_data;
9531 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9532 EXPECT_EQ("hello world", response_data);
9533
[email protected]90499482013-06-01 00:39:509534 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:119535
[email protected]49639fa2011-12-20 23:22:419536 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:119537 EXPECT_EQ(ERR_IO_PENDING, rv);
9538 EXPECT_EQ(OK, callback.WaitForResult());
9539
9540 response = trans->GetResponseInfo();
9541 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509542 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]631f1322010-04-30 17:59:119543 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539544 EXPECT_TRUE(response->was_fetched_via_spdy);
9545 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:119546
9547 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9548 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:559549 ASSERT_EQ(3u, capturing_proxy_resolver->resolved().size());
[email protected]d911f1b2010-05-05 22:39:429550 EXPECT_EQ("http://www.google.com/",
[email protected]631f1322010-04-30 17:59:119551 capturing_proxy_resolver->resolved()[0].spec());
[email protected]d911f1b2010-05-05 22:39:429552 EXPECT_EQ("https://www.google.com/",
9553 capturing_proxy_resolver->resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:119554
[email protected]029c83b62013-01-24 05:28:209555 LoadTimingInfo load_timing_info;
9556 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
9557 TestLoadTimingNotReusedWithPac(load_timing_info,
9558 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:119559}
[email protected]631f1322010-04-30 17:59:119560
[email protected]23e482282013-06-14 16:08:029561TEST_P(HttpNetworkTransactionTest,
[email protected]2ff8b312010-04-26 22:20:549562 UseAlternateProtocolForNpnSpdyWithExistingSpdySession) {
[email protected]d7599122014-05-24 03:37:239563 session_deps_.use_alternate_protocols = true;
9564 session_deps_.next_protos = SpdyNextProtos();
[email protected]2ff8b312010-04-26 22:20:549565
9566 HttpRequestInfo request;
9567 request.method = "GET";
9568 request.url = GURL("http://www.google.com/");
9569 request.load_flags = 0;
9570
[email protected]8a0fc822013-06-27 20:52:439571 std::string alternate_protocol_http_header =
9572 GetAlternateProtocolHttpHeader();
9573
[email protected]2ff8b312010-04-26 22:20:549574 MockRead data_reads[] = {
9575 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439576 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2ff8b312010-04-26 22:20:549577 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069578 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:549579 };
9580
9581 StaticSocketDataProvider first_transaction(
9582 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079583 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:549584
[email protected]8ddf8322012-02-23 18:08:069585 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029586 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:079587 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:549588
[email protected]cdf8f7e72013-05-23 10:56:469589 scoped_ptr<SpdyFrame> req(
9590 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]e7f75092010-07-01 22:39:139591 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
[email protected]2ff8b312010-04-26 22:20:549592
[email protected]23e482282013-06-14 16:08:029593 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9594 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:549595 MockRead spdy_reads[] = {
[email protected]e7f75092010-07-01 22:39:139596 CreateMockRead(*resp),
9597 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:069598 MockRead(ASYNC, 0, 0),
[email protected]2ff8b312010-04-26 22:20:549599 };
9600
[email protected]dd54bd82012-07-19 23:44:579601 DelayedSocketData spdy_data(
9602 1, // wait for one write to finish before reading.
9603 spdy_reads, arraysize(spdy_reads),
9604 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079605 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:549606
[email protected]83039bb2011-12-09 18:43:559607 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:549608
[email protected]bb88e1d32013-05-03 23:11:079609 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:549610
[email protected]262eec82013-03-19 21:01:369611 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509612 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:549613
[email protected]49639fa2011-12-20 23:22:419614 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:549615 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:419616 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:549617
9618 const HttpResponseInfo* response = trans->GetResponseInfo();
9619 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509620 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:549621 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9622
9623 std::string response_data;
9624 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9625 EXPECT_EQ("hello world", response_data);
9626
9627 // Set up an initial SpdySession in the pool to reuse.
[email protected]02b0c342010-09-25 21:09:389628 HostPortPair host_port_pair("www.google.com", 443);
[email protected]e6d017652013-05-17 18:01:409629 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:539630 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:279631 base::WeakPtr<SpdySession> spdy_session =
[email protected]41d64e82013-07-03 22:44:269632 CreateSecureSpdySession(session, key, BoundNetLog());
[email protected]02b0c342010-09-25 21:09:389633
[email protected]90499482013-06-01 00:39:509634 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:549635
[email protected]49639fa2011-12-20 23:22:419636 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:549637 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:419638 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:549639
9640 response = trans->GetResponseInfo();
9641 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509642 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:549643 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539644 EXPECT_TRUE(response->was_fetched_via_spdy);
9645 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:549646
9647 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9648 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:429649}
9650
[email protected]044de0642010-06-17 10:42:159651// GenerateAuthToken is a mighty big test.
9652// It tests all permutation of GenerateAuthToken behavior:
9653// - Synchronous and Asynchronous completion.
9654// - OK or error on completion.
9655// - Direct connection, non-authenticating proxy, and authenticating proxy.
9656// - HTTP or HTTPS backend (to include proxy tunneling).
9657// - Non-authenticating and authenticating backend.
9658//
[email protected]fe3b7dc2012-02-03 19:52:099659// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:159660// problems generating an auth token for an authenticating proxy, we don't
9661// need to test all permutations of the backend server).
9662//
9663// The test proceeds by going over each of the configuration cases, and
9664// potentially running up to three rounds in each of the tests. The TestConfig
9665// specifies both the configuration for the test as well as the expectations
9666// for the results.
[email protected]23e482282013-06-14 16:08:029667TEST_P(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:509668 static const char kServer[] = "http://www.example.com";
9669 static const char kSecureServer[] = "https://www.example.com";
9670 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:159671 const int kAuthErr = ERR_INVALID_AUTH_CREDENTIALS;
9672
9673 enum AuthTiming {
9674 AUTH_NONE,
9675 AUTH_SYNC,
9676 AUTH_ASYNC,
9677 };
9678
9679 const MockWrite kGet(
9680 "GET / HTTP/1.1\r\n"
9681 "Host: www.example.com\r\n"
9682 "Connection: keep-alive\r\n\r\n");
9683 const MockWrite kGetProxy(
9684 "GET http://www.example.com/ HTTP/1.1\r\n"
9685 "Host: www.example.com\r\n"
9686 "Proxy-Connection: keep-alive\r\n\r\n");
9687 const MockWrite kGetAuth(
9688 "GET / HTTP/1.1\r\n"
9689 "Host: www.example.com\r\n"
9690 "Connection: keep-alive\r\n"
9691 "Authorization: auth_token\r\n\r\n");
9692 const MockWrite kGetProxyAuth(
9693 "GET http://www.example.com/ HTTP/1.1\r\n"
9694 "Host: www.example.com\r\n"
9695 "Proxy-Connection: keep-alive\r\n"
9696 "Proxy-Authorization: auth_token\r\n\r\n");
9697 const MockWrite kGetAuthThroughProxy(
9698 "GET http://www.example.com/ HTTP/1.1\r\n"
9699 "Host: www.example.com\r\n"
9700 "Proxy-Connection: keep-alive\r\n"
9701 "Authorization: auth_token\r\n\r\n");
9702 const MockWrite kGetAuthWithProxyAuth(
9703 "GET http://www.example.com/ HTTP/1.1\r\n"
9704 "Host: www.example.com\r\n"
9705 "Proxy-Connection: keep-alive\r\n"
9706 "Proxy-Authorization: auth_token\r\n"
9707 "Authorization: auth_token\r\n\r\n");
9708 const MockWrite kConnect(
9709 "CONNECT www.example.com:443 HTTP/1.1\r\n"
9710 "Host: www.example.com\r\n"
9711 "Proxy-Connection: keep-alive\r\n\r\n");
9712 const MockWrite kConnectProxyAuth(
9713 "CONNECT www.example.com:443 HTTP/1.1\r\n"
9714 "Host: www.example.com\r\n"
9715 "Proxy-Connection: keep-alive\r\n"
9716 "Proxy-Authorization: auth_token\r\n\r\n");
9717
9718 const MockRead kSuccess(
9719 "HTTP/1.1 200 OK\r\n"
9720 "Content-Type: text/html; charset=iso-8859-1\r\n"
9721 "Content-Length: 3\r\n\r\n"
9722 "Yes");
9723 const MockRead kFailure(
9724 "Should not be called.");
9725 const MockRead kServerChallenge(
9726 "HTTP/1.1 401 Unauthorized\r\n"
9727 "WWW-Authenticate: Mock realm=server\r\n"
9728 "Content-Type: text/html; charset=iso-8859-1\r\n"
9729 "Content-Length: 14\r\n\r\n"
9730 "Unauthorized\r\n");
9731 const MockRead kProxyChallenge(
9732 "HTTP/1.1 407 Unauthorized\r\n"
9733 "Proxy-Authenticate: Mock realm=proxy\r\n"
9734 "Proxy-Connection: close\r\n"
9735 "Content-Type: text/html; charset=iso-8859-1\r\n"
9736 "Content-Length: 14\r\n\r\n"
9737 "Unauthorized\r\n");
9738 const MockRead kProxyConnected(
9739 "HTTP/1.1 200 Connection Established\r\n\r\n");
9740
9741 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
9742 // no constructors, but the C++ compiler on Windows warns about
9743 // unspecified data in compound literals. So, moved to using constructors,
9744 // and TestRound's created with the default constructor should not be used.
9745 struct TestRound {
9746 TestRound()
9747 : expected_rv(ERR_UNEXPECTED),
9748 extra_write(NULL),
9749 extra_read(NULL) {
9750 }
9751 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
9752 int expected_rv_arg)
9753 : write(write_arg),
9754 read(read_arg),
9755 expected_rv(expected_rv_arg),
9756 extra_write(NULL),
9757 extra_read(NULL) {
9758 }
9759 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
9760 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:019761 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:159762 : write(write_arg),
9763 read(read_arg),
9764 expected_rv(expected_rv_arg),
9765 extra_write(extra_write_arg),
9766 extra_read(extra_read_arg) {
9767 }
9768 MockWrite write;
9769 MockRead read;
9770 int expected_rv;
9771 const MockWrite* extra_write;
9772 const MockRead* extra_read;
9773 };
9774
9775 static const int kNoSSL = 500;
9776
9777 struct TestConfig {
thestig9d3bb0c2015-01-24 00:49:519778 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:159779 AuthTiming proxy_auth_timing;
9780 int proxy_auth_rv;
thestig9d3bb0c2015-01-24 00:49:519781 const char* const server_url;
[email protected]044de0642010-06-17 10:42:159782 AuthTiming server_auth_timing;
9783 int server_auth_rv;
9784 int num_auth_rounds;
9785 int first_ssl_round;
9786 TestRound rounds[3];
9787 } test_configs[] = {
9788 // Non-authenticating HTTP server with a direct connection.
9789 { NULL, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
9790 { TestRound(kGet, kSuccess, OK)}},
9791 // Authenticating HTTP server with a direct connection.
9792 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
9793 { TestRound(kGet, kServerChallenge, OK),
9794 TestRound(kGetAuth, kSuccess, OK)}},
9795 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
9796 { TestRound(kGet, kServerChallenge, OK),
9797 TestRound(kGetAuth, kFailure, kAuthErr)}},
9798 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
9799 { TestRound(kGet, kServerChallenge, OK),
9800 TestRound(kGetAuth, kSuccess, OK)}},
9801 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
9802 { TestRound(kGet, kServerChallenge, OK),
9803 TestRound(kGetAuth, kFailure, kAuthErr)}},
9804 // Non-authenticating HTTP server through a non-authenticating proxy.
9805 { kProxy, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
9806 { TestRound(kGetProxy, kSuccess, OK)}},
9807 // Authenticating HTTP server through a non-authenticating proxy.
9808 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
9809 { TestRound(kGetProxy, kServerChallenge, OK),
9810 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
9811 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
9812 { TestRound(kGetProxy, kServerChallenge, OK),
9813 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
9814 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
9815 { TestRound(kGetProxy, kServerChallenge, OK),
9816 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
9817 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
9818 { TestRound(kGetProxy, kServerChallenge, OK),
9819 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
9820 // Non-authenticating HTTP server through an authenticating proxy.
9821 { kProxy, AUTH_SYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
9822 { TestRound(kGetProxy, kProxyChallenge, OK),
9823 TestRound(kGetProxyAuth, kSuccess, OK)}},
9824 { kProxy, AUTH_SYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
9825 { TestRound(kGetProxy, kProxyChallenge, OK),
9826 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
9827 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
9828 { TestRound(kGetProxy, kProxyChallenge, OK),
9829 TestRound(kGetProxyAuth, kSuccess, OK)}},
9830 { kProxy, AUTH_ASYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
9831 { TestRound(kGetProxy, kProxyChallenge, OK),
9832 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
9833 // Authenticating HTTP server through an authenticating proxy.
9834 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
9835 { TestRound(kGetProxy, kProxyChallenge, OK),
9836 TestRound(kGetProxyAuth, kServerChallenge, OK),
9837 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9838 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
9839 { TestRound(kGetProxy, kProxyChallenge, OK),
9840 TestRound(kGetProxyAuth, kServerChallenge, OK),
9841 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9842 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
9843 { TestRound(kGetProxy, kProxyChallenge, OK),
9844 TestRound(kGetProxyAuth, kServerChallenge, OK),
9845 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9846 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
9847 { TestRound(kGetProxy, kProxyChallenge, OK),
9848 TestRound(kGetProxyAuth, kServerChallenge, OK),
9849 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9850 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
9851 { TestRound(kGetProxy, kProxyChallenge, OK),
9852 TestRound(kGetProxyAuth, kServerChallenge, OK),
9853 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9854 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
9855 { TestRound(kGetProxy, kProxyChallenge, OK),
9856 TestRound(kGetProxyAuth, kServerChallenge, OK),
9857 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9858 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
9859 { TestRound(kGetProxy, kProxyChallenge, OK),
9860 TestRound(kGetProxyAuth, kServerChallenge, OK),
9861 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9862 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
9863 { TestRound(kGetProxy, kProxyChallenge, OK),
9864 TestRound(kGetProxyAuth, kServerChallenge, OK),
9865 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9866 // Non-authenticating HTTPS server with a direct connection.
9867 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
9868 { TestRound(kGet, kSuccess, OK)}},
9869 // Authenticating HTTPS server with a direct connection.
9870 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
9871 { TestRound(kGet, kServerChallenge, OK),
9872 TestRound(kGetAuth, kSuccess, OK)}},
9873 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
9874 { TestRound(kGet, kServerChallenge, OK),
9875 TestRound(kGetAuth, kFailure, kAuthErr)}},
9876 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
9877 { TestRound(kGet, kServerChallenge, OK),
9878 TestRound(kGetAuth, kSuccess, OK)}},
9879 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
9880 { TestRound(kGet, kServerChallenge, OK),
9881 TestRound(kGetAuth, kFailure, kAuthErr)}},
9882 // Non-authenticating HTTPS server with a non-authenticating proxy.
9883 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
9884 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
9885 // Authenticating HTTPS server through a non-authenticating proxy.
9886 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
9887 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9888 TestRound(kGetAuth, kSuccess, OK)}},
9889 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
9890 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9891 TestRound(kGetAuth, kFailure, kAuthErr)}},
9892 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
9893 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9894 TestRound(kGetAuth, kSuccess, OK)}},
9895 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
9896 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9897 TestRound(kGetAuth, kFailure, kAuthErr)}},
9898 // Non-Authenticating HTTPS server through an authenticating proxy.
9899 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
9900 { TestRound(kConnect, kProxyChallenge, OK),
9901 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
9902 { kProxy, AUTH_SYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
9903 { TestRound(kConnect, kProxyChallenge, OK),
9904 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
9905 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
9906 { TestRound(kConnect, kProxyChallenge, OK),
9907 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
9908 { kProxy, AUTH_ASYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
9909 { TestRound(kConnect, kProxyChallenge, OK),
9910 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
9911 // Authenticating HTTPS server through an authenticating proxy.
9912 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
9913 { TestRound(kConnect, kProxyChallenge, OK),
9914 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9915 &kGet, &kServerChallenge),
9916 TestRound(kGetAuth, kSuccess, OK)}},
9917 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
9918 { TestRound(kConnect, kProxyChallenge, OK),
9919 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9920 &kGet, &kServerChallenge),
9921 TestRound(kGetAuth, kFailure, kAuthErr)}},
9922 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
9923 { TestRound(kConnect, kProxyChallenge, OK),
9924 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9925 &kGet, &kServerChallenge),
9926 TestRound(kGetAuth, kSuccess, OK)}},
9927 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
9928 { TestRound(kConnect, kProxyChallenge, OK),
9929 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9930 &kGet, &kServerChallenge),
9931 TestRound(kGetAuth, kFailure, kAuthErr)}},
9932 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
9933 { TestRound(kConnect, kProxyChallenge, OK),
9934 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9935 &kGet, &kServerChallenge),
9936 TestRound(kGetAuth, kSuccess, OK)}},
9937 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
9938 { TestRound(kConnect, kProxyChallenge, OK),
9939 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9940 &kGet, &kServerChallenge),
9941 TestRound(kGetAuth, kFailure, kAuthErr)}},
9942 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
9943 { TestRound(kConnect, kProxyChallenge, OK),
9944 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9945 &kGet, &kServerChallenge),
9946 TestRound(kGetAuth, kSuccess, OK)}},
9947 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
9948 { TestRound(kConnect, kProxyChallenge, OK),
9949 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9950 &kGet, &kServerChallenge),
9951 TestRound(kGetAuth, kFailure, kAuthErr)}},
9952 };
9953
viettrungluue4a8b882014-10-16 06:17:389954 for (size_t i = 0; i < arraysize(test_configs); ++i) {
[email protected]2d01c262011-08-11 23:07:089955 HttpAuthHandlerMock::Factory* auth_factory(
9956 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:079957 session_deps_.http_auth_handler_factory.reset(auth_factory);
[email protected]044de0642010-06-17 10:42:159958 const TestConfig& test_config = test_configs[i];
[email protected]65d34382010-07-01 18:12:269959
9960 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:159961 if (test_config.proxy_auth_timing != AUTH_NONE) {
[email protected]2d01c262011-08-11 23:07:089962 for (int n = 0; n < 2; n++) {
9963 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
9964 std::string auth_challenge = "Mock realm=proxy";
9965 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:249966 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
9967 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:089968 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
9969 origin, BoundNetLog());
9970 auth_handler->SetGenerateExpectation(
9971 test_config.proxy_auth_timing == AUTH_ASYNC,
9972 test_config.proxy_auth_rv);
9973 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
9974 }
[email protected]044de0642010-06-17 10:42:159975 }
9976 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:009977 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:159978 std::string auth_challenge = "Mock realm=server";
9979 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:249980 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
9981 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:159982 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
9983 origin, BoundNetLog());
9984 auth_handler->SetGenerateExpectation(
9985 test_config.server_auth_timing == AUTH_ASYNC,
9986 test_config.server_auth_rv);
[email protected]2d01c262011-08-11 23:07:089987 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:159988 }
9989 if (test_config.proxy_url) {
[email protected]bb88e1d32013-05-03 23:11:079990 session_deps_.proxy_service.reset(
[email protected]6104ea5d2011-04-27 21:37:129991 ProxyService::CreateFixed(test_config.proxy_url));
[email protected]044de0642010-06-17 10:42:159992 } else {
[email protected]bb88e1d32013-05-03 23:11:079993 session_deps_.proxy_service.reset(ProxyService::CreateDirect());
[email protected]044de0642010-06-17 10:42:159994 }
9995
9996 HttpRequestInfo request;
9997 request.method = "GET";
9998 request.url = GURL(test_config.server_url);
9999 request.load_flags = 0;
10000
[email protected]bb88e1d32013-05-03 23:11:0710001 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
dcheng48459ac22014-08-26 00:46:4110002 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]044de0642010-06-17 10:42:1510003
10004 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
10005 const TestRound& read_write_round = test_config.rounds[round];
10006
10007 // Set up expected reads and writes.
10008 MockRead reads[2];
10009 reads[0] = read_write_round.read;
10010 size_t length_reads = 1;
10011 if (read_write_round.extra_read) {
10012 reads[1] = *read_write_round.extra_read;
10013 length_reads = 2;
10014 }
10015
10016 MockWrite writes[2];
10017 writes[0] = read_write_round.write;
10018 size_t length_writes = 1;
10019 if (read_write_round.extra_write) {
10020 writes[1] = *read_write_round.extra_write;
10021 length_writes = 2;
10022 }
10023 StaticSocketDataProvider data_provider(
10024 reads, length_reads, writes, length_writes);
[email protected]bb88e1d32013-05-03 23:11:0710025 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]044de0642010-06-17 10:42:1510026
10027 // Add an SSL sequence if necessary.
[email protected]8ddf8322012-02-23 18:08:0610028 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
[email protected]044de0642010-06-17 10:42:1510029 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0710030 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1510031 &ssl_socket_data_provider);
10032
10033 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4110034 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1510035 int rv;
10036 if (round == 0) {
[email protected]49639fa2011-12-20 23:22:4110037 rv = trans.Start(&request, callback.callback(), BoundNetLog());
[email protected]044de0642010-06-17 10:42:1510038 } else {
[email protected]49639fa2011-12-20 23:22:4110039 rv = trans.RestartWithAuth(
10040 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1510041 }
10042 if (rv == ERR_IO_PENDING)
10043 rv = callback.WaitForResult();
10044
10045 // Compare results with expected data.
10046 EXPECT_EQ(read_write_round.expected_rv, rv);
[email protected]0b0bf032010-09-21 18:08:5010047 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]044de0642010-06-17 10:42:1510048 if (read_write_round.expected_rv == OK) {
[email protected]fe2255a2011-09-20 19:37:5010049 ASSERT_TRUE(response != NULL);
[email protected]044de0642010-06-17 10:42:1510050 } else {
10051 EXPECT_TRUE(response == NULL);
10052 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
10053 continue;
10054 }
10055 if (round + 1 < test_config.num_auth_rounds) {
10056 EXPECT_FALSE(response->auth_challenge.get() == NULL);
10057 } else {
10058 EXPECT_TRUE(response->auth_challenge.get() == NULL);
10059 }
10060 }
[email protected]e5ae96a2010-04-14 20:12:4510061 }
10062}
10063
[email protected]23e482282013-06-14 16:08:0210064TEST_P(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1410065 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1410066 HttpAuthHandlerMock::Factory* auth_factory(
10067 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0710068 session_deps_.http_auth_handler_factory.reset(auth_factory);
10069 session_deps_.proxy_service.reset(ProxyService::CreateDirect());
10070 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
10071 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:1410072
10073 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
10074 auth_handler->set_connection_based(true);
10075 std::string auth_challenge = "Mock realm=server";
10076 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2410077 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
10078 auth_challenge.end());
[email protected]c871bce92010-07-15 21:51:1410079 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
10080 origin, BoundNetLog());
[email protected]2d01c262011-08-11 23:07:0810081 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1410082
[email protected]c871bce92010-07-15 21:51:1410083 int rv = OK;
10084 const HttpResponseInfo* response = NULL;
10085 HttpRequestInfo request;
10086 request.method = "GET";
10087 request.url = origin;
10088 request.load_flags = 0;
[email protected]cb9bf6ca2011-01-28 13:15:2710089
[email protected]bb88e1d32013-05-03 23:11:0710090 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1010091
10092 // Use a TCP Socket Pool with only one connection per group. This is used
10093 // to validate that the TCP socket is not released to the pool between
10094 // each round of multi-round authentication.
10095 HttpNetworkSessionPeer session_peer(session);
[email protected]ab739042011-04-07 15:22:2810096 ClientSocketPoolHistograms transport_pool_histograms("SmallTCP");
10097 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:1010098 50, // Max sockets for pool
10099 1, // Max sockets per group
[email protected]ab739042011-04-07 15:22:2810100 &transport_pool_histograms,
[email protected]bb88e1d32013-05-03 23:11:0710101 session_deps_.host_resolver.get(),
10102 session_deps_.socket_factory.get(),
10103 session_deps_.net_log);
[email protected]831e4a32013-11-14 02:14:4410104 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
10105 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:0210106 mock_pool_manager->SetTransportSocketPool(transport_pool);
dchenge3d1ddc2014-10-15 19:30:5110107 session_peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]7ef4cbbb2011-02-06 11:19:1010108
[email protected]262eec82013-03-19 21:01:3610109 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010110 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110111 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1410112
10113 const MockWrite kGet(
10114 "GET / HTTP/1.1\r\n"
10115 "Host: www.example.com\r\n"
10116 "Connection: keep-alive\r\n\r\n");
10117 const MockWrite kGetAuth(
10118 "GET / HTTP/1.1\r\n"
10119 "Host: www.example.com\r\n"
10120 "Connection: keep-alive\r\n"
10121 "Authorization: auth_token\r\n\r\n");
10122
10123 const MockRead kServerChallenge(
10124 "HTTP/1.1 401 Unauthorized\r\n"
10125 "WWW-Authenticate: Mock realm=server\r\n"
10126 "Content-Type: text/html; charset=iso-8859-1\r\n"
10127 "Content-Length: 14\r\n\r\n"
10128 "Unauthorized\r\n");
10129 const MockRead kSuccess(
10130 "HTTP/1.1 200 OK\r\n"
10131 "Content-Type: text/html; charset=iso-8859-1\r\n"
10132 "Content-Length: 3\r\n\r\n"
10133 "Yes");
10134
10135 MockWrite writes[] = {
10136 // First round
10137 kGet,
10138 // Second round
10139 kGetAuth,
10140 // Third round
10141 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3010142 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1010143 kGetAuth,
10144 // Competing request
10145 kGet,
[email protected]c871bce92010-07-15 21:51:1410146 };
10147 MockRead reads[] = {
10148 // First round
10149 kServerChallenge,
10150 // Second round
10151 kServerChallenge,
10152 // Third round
[email protected]eca50e122010-09-11 14:03:3010153 kServerChallenge,
10154 // Fourth round
[email protected]c871bce92010-07-15 21:51:1410155 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1010156 // Competing response
10157 kSuccess,
[email protected]c871bce92010-07-15 21:51:1410158 };
10159 StaticSocketDataProvider data_provider(reads, arraysize(reads),
10160 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:0710161 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1410162
thestig9d3bb0c2015-01-24 00:49:5110163 const char kSocketGroup[] = "www.example.com:80";
[email protected]7ef4cbbb2011-02-06 11:19:1010164
10165 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1410166 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4110167 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]c871bce92010-07-15 21:51:1410168 if (rv == ERR_IO_PENDING)
10169 rv = callback.WaitForResult();
10170 EXPECT_EQ(OK, rv);
10171 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010172 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:1410173 EXPECT_FALSE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2810174 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1410175
[email protected]7ef4cbbb2011-02-06 11:19:1010176 // In between rounds, another request comes in for the same domain.
10177 // It should not be able to grab the TCP socket that trans has already
10178 // claimed.
10179 scoped_ptr<HttpTransaction> trans_compete(
[email protected]90499482013-06-01 00:39:5010180 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110181 TestCompletionCallback callback_compete;
10182 rv = trans_compete->Start(
10183 &request, callback_compete.callback(), BoundNetLog());
[email protected]7ef4cbbb2011-02-06 11:19:1010184 EXPECT_EQ(ERR_IO_PENDING, rv);
10185 // callback_compete.WaitForResult at this point would stall forever,
10186 // since the HttpNetworkTransaction does not release the request back to
10187 // the pool until after authentication completes.
10188
10189 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1410190 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4110191 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1410192 if (rv == ERR_IO_PENDING)
10193 rv = callback.WaitForResult();
10194 EXPECT_EQ(OK, rv);
10195 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010196 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:1410197 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2810198 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1410199
[email protected]7ef4cbbb2011-02-06 11:19:1010200 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1410201 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4110202 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1410203 if (rv == ERR_IO_PENDING)
10204 rv = callback.WaitForResult();
10205 EXPECT_EQ(OK, rv);
10206 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010207 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:1410208 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2810209 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]eca50e122010-09-11 14:03:3010210
[email protected]7ef4cbbb2011-02-06 11:19:1010211 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3010212 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4110213 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3010214 if (rv == ERR_IO_PENDING)
10215 rv = callback.WaitForResult();
10216 EXPECT_EQ(OK, rv);
10217 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010218 ASSERT_TRUE(response != NULL);
[email protected]eca50e122010-09-11 14:03:3010219 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2810220 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1010221
10222 // Read the body since the fourth round was successful. This will also
10223 // release the socket back to the pool.
10224 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
[email protected]90499482013-06-01 00:39:5010225 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1010226 if (rv == ERR_IO_PENDING)
10227 rv = callback.WaitForResult();
10228 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:5010229 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1010230 EXPECT_EQ(0, rv);
10231 // There are still 0 idle sockets, since the trans_compete transaction
10232 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:2810233 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1010234
10235 // The competing request can now finish. Wait for the headers and then
10236 // read the body.
10237 rv = callback_compete.WaitForResult();
10238 EXPECT_EQ(OK, rv);
[email protected]90499482013-06-01 00:39:5010239 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1010240 if (rv == ERR_IO_PENDING)
10241 rv = callback.WaitForResult();
10242 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:5010243 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1010244 EXPECT_EQ(0, rv);
10245
10246 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:2810247 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1410248}
10249
[email protected]65041fa2010-05-21 06:56:5310250// This tests the case that a request is issued via http instead of spdy after
10251// npn is negotiated.
[email protected]23e482282013-06-14 16:08:0210252TEST_P(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]d7599122014-05-24 03:37:2310253 session_deps_.use_alternate_protocols = true;
10254 NextProtoVector next_protos;
[email protected]0ce3af82013-07-22 16:17:1610255 next_protos.push_back(kProtoHTTP11);
[email protected]d7599122014-05-24 03:37:2310256 session_deps_.next_protos = next_protos;
10257
[email protected]65041fa2010-05-21 06:56:5310258 HttpRequestInfo request;
10259 request.method = "GET";
10260 request.url = GURL("https://www.google.com/");
10261 request.load_flags = 0;
10262
10263 MockWrite data_writes[] = {
10264 MockWrite("GET / HTTP/1.1\r\n"
10265 "Host: www.google.com\r\n"
10266 "Connection: keep-alive\r\n\r\n"),
10267 };
10268
[email protected]8a0fc822013-06-27 20:52:4310269 std::string alternate_protocol_http_header =
10270 GetAlternateProtocolHttpHeader();
10271
[email protected]65041fa2010-05-21 06:56:5310272 MockRead data_reads[] = {
10273 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:4310274 MockRead(alternate_protocol_http_header.c_str()),
[email protected]65041fa2010-05-21 06:56:5310275 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610276 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5310277 };
10278
[email protected]8ddf8322012-02-23 18:08:0610279 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]65041fa2010-05-21 06:56:5310280 ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
10281 ssl.next_proto = "http/1.1";
[email protected]8e3c78cb2012-03-31 03:58:4610282 ssl.protocol_negotiated = kProtoHTTP11;
[email protected]65041fa2010-05-21 06:56:5310283
[email protected]bb88e1d32013-05-03 23:11:0710284 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5310285
10286 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
10287 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0710288 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5310289
[email protected]49639fa2011-12-20 23:22:4110290 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5310291
[email protected]bb88e1d32013-05-03 23:11:0710292 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610293 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010294 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]65041fa2010-05-21 06:56:5310295
[email protected]49639fa2011-12-20 23:22:4110296 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]65041fa2010-05-21 06:56:5310297
10298 EXPECT_EQ(ERR_IO_PENDING, rv);
10299 EXPECT_EQ(OK, callback.WaitForResult());
10300
10301 const HttpResponseInfo* response = trans->GetResponseInfo();
10302 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010303 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]65041fa2010-05-21 06:56:5310304 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10305
10306 std::string response_data;
10307 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10308 EXPECT_EQ("hello world", response_data);
10309
10310 EXPECT_FALSE(response->was_fetched_via_spdy);
10311 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]65041fa2010-05-21 06:56:5310312}
[email protected]26ef6582010-06-24 02:30:4710313
[email protected]23e482282013-06-14 16:08:0210314TEST_P(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:4710315 // Simulate the SSL handshake completing with an NPN negotiation
10316 // followed by an immediate server closing of the socket.
10317 // Fix crash: http://crbug.com/46369
[email protected]d7599122014-05-24 03:37:2310318 session_deps_.use_alternate_protocols = true;
10319 session_deps_.next_protos = SpdyNextProtos();
[email protected]26ef6582010-06-24 02:30:4710320
10321 HttpRequestInfo request;
10322 request.method = "GET";
10323 request.url = GURL("https://www.google.com/");
10324 request.load_flags = 0;
10325
[email protected]8ddf8322012-02-23 18:08:0610326 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210327 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710328 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4710329
[email protected]cdf8f7e72013-05-23 10:56:4610330 scoped_ptr<SpdyFrame> req(
10331 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]e7f75092010-07-01 22:39:1310332 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
[email protected]26ef6582010-06-24 02:30:4710333
10334 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0610335 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4710336 };
10337
[email protected]dd54bd82012-07-19 23:44:5710338 DelayedSocketData spdy_data(
10339 0, // don't wait in this case, immediate hangup.
10340 spdy_reads, arraysize(spdy_reads),
10341 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710342 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4710343
[email protected]49639fa2011-12-20 23:22:4110344 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4710345
[email protected]bb88e1d32013-05-03 23:11:0710346 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610347 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010348 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]26ef6582010-06-24 02:30:4710349
[email protected]49639fa2011-12-20 23:22:4110350 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]26ef6582010-06-24 02:30:4710351 EXPECT_EQ(ERR_IO_PENDING, rv);
10352 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult());
[email protected]26ef6582010-06-24 02:30:4710353}
[email protected]65d34382010-07-01 18:12:2610354
[email protected]795cbf82013-07-22 09:37:2710355// A subclass of HttpAuthHandlerMock that records the request URL when
10356// it gets it. This is needed since the auth handler may get destroyed
10357// before we get a chance to query it.
10358class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
10359 public:
10360 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
10361
dchengb03027d2014-10-21 12:00:2010362 ~UrlRecordingHttpAuthHandlerMock() override {}
[email protected]795cbf82013-07-22 09:37:2710363
10364 protected:
dchengb03027d2014-10-21 12:00:2010365 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
10366 const HttpRequestInfo* request,
10367 const CompletionCallback& callback,
10368 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2710369 *url_ = request->url;
10370 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
10371 credentials, request, callback, auth_token);
10372 }
10373
10374 private:
10375 GURL* url_;
10376};
10377
[email protected]23e482282013-06-14 16:08:0210378TEST_P(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) {
[email protected]f45c1ee2010-08-03 00:54:3010379 // This test ensures that the URL passed into the proxy is upgraded
10380 // to https when doing an Alternate Protocol upgrade.
[email protected]d7599122014-05-24 03:37:2310381 session_deps_.use_alternate_protocols = true;
10382 session_deps_.next_protos = SpdyNextProtos();
[email protected]f45c1ee2010-08-03 00:54:3010383
[email protected]bb88e1d32013-05-03 23:11:0710384 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:2010385 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
10386 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710387 session_deps_.net_log = &net_log;
[email protected]795cbf82013-07-22 09:37:2710388 GURL request_url;
10389 {
10390 HttpAuthHandlerMock::Factory* auth_factory =
10391 new HttpAuthHandlerMock::Factory();
10392 UrlRecordingHttpAuthHandlerMock* auth_handler =
10393 new UrlRecordingHttpAuthHandlerMock(&request_url);
10394 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
10395 auth_factory->set_do_init_from_challenge(true);
10396 session_deps_.http_auth_handler_factory.reset(auth_factory);
10397 }
[email protected]f45c1ee2010-08-03 00:54:3010398
10399 HttpRequestInfo request;
10400 request.method = "GET";
10401 request.url = GURL("http://www.google.com");
10402 request.load_flags = 0;
10403
10404 // First round goes unauthenticated through the proxy.
10405 MockWrite data_writes_1[] = {
10406 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
10407 "Host: www.google.com\r\n"
10408 "Proxy-Connection: keep-alive\r\n"
10409 "\r\n"),
10410 };
10411 MockRead data_reads_1[] = {
[email protected]8ddf8322012-02-23 18:08:0610412 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
bnc33b8cef42014-11-19 17:30:3810413 MockRead("HTTP/1.1 200 OK\r\n"),
10414 MockRead("Alternate-Protocol: 443:"),
10415 MockRead(GetAlternateProtocolFromParam()),
10416 MockRead("\r\n"),
10417 MockRead("Proxy-Connection: close\r\n"),
10418 MockRead("\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3010419 };
10420 StaticSocketDataProvider data_1(data_reads_1, arraysize(data_reads_1),
10421 data_writes_1, arraysize(data_writes_1));
10422
10423 // Second round tries to tunnel to www.google.com due to the
10424 // Alternate-Protocol announcement in the first round. It fails due
10425 // to a proxy authentication challenge.
[email protected]394816e92010-08-03 07:38:5910426 // After the failure, a tunnel is established to www.google.com using
10427 // Proxy-Authorization headers. There is then a SPDY request round.
10428 //
[email protected]fe3b7dc2012-02-03 19:52:0910429 // NOTE: Despite the "Proxy-Connection: Close", these are done on the
10430 // same MockTCPClientSocket since the underlying HttpNetworkClientSocket
10431 // does a Disconnect and Connect on the same socket, rather than trying
10432 // to obtain a new one.
10433 //
[email protected]394816e92010-08-03 07:38:5910434 // NOTE: Originally, the proxy response to the second CONNECT request
10435 // simply returned another 407 so the unit test could skip the SSL connection
10436 // establishment and SPDY framing issues. Alas, the
10437 // retry-http-when-alternate-protocol fails logic kicks in, which was more
[email protected]f45c1ee2010-08-03 00:54:3010438 // complicated to set up expectations for than the SPDY session.
[email protected]394816e92010-08-03 07:38:5910439
[email protected]cdf8f7e72013-05-23 10:56:4610440 scoped_ptr<SpdyFrame> req(
10441 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]23e482282013-06-14 16:08:0210442 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10443 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]f45c1ee2010-08-03 00:54:3010444
[email protected]394816e92010-08-03 07:38:5910445 MockWrite data_writes_2[] = {
10446 // First connection attempt without Proxy-Authorization.
10447 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
10448 "Host: www.google.com\r\n"
10449 "Proxy-Connection: keep-alive\r\n"
10450 "\r\n"),
10451
10452 // Second connection attempt with Proxy-Authorization.
[email protected]f45c1ee2010-08-03 00:54:3010453 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
10454 "Host: www.google.com\r\n"
10455 "Proxy-Connection: keep-alive\r\n"
10456 "Proxy-Authorization: auth_token\r\n"
10457 "\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3010458
[email protected]394816e92010-08-03 07:38:5910459 // SPDY request
10460 CreateMockWrite(*req),
[email protected]f45c1ee2010-08-03 00:54:3010461 };
[email protected]394816e92010-08-03 07:38:5910462 const char kRejectConnectResponse[] = ("HTTP/1.1 407 Unauthorized\r\n"
10463 "Proxy-Authenticate: Mock\r\n"
10464 "Proxy-Connection: close\r\n"
10465 "\r\n");
10466 const char kAcceptConnectResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
10467 MockRead data_reads_2[] = {
10468 // First connection attempt fails
[email protected]8ddf8322012-02-23 18:08:0610469 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ, 1),
10470 MockRead(ASYNC, kRejectConnectResponse,
[email protected]394816e92010-08-03 07:38:5910471 arraysize(kRejectConnectResponse) - 1, 1),
10472
10473 // Second connection attempt passes
[email protected]8ddf8322012-02-23 18:08:0610474 MockRead(ASYNC, kAcceptConnectResponse,
[email protected]fe3b7dc2012-02-03 19:52:0910475 arraysize(kAcceptConnectResponse) -1, 4),
[email protected]394816e92010-08-03 07:38:5910476
10477 // SPDY response
[email protected]fe3b7dc2012-02-03 19:52:0910478 CreateMockRead(*resp.get(), 6),
10479 CreateMockRead(*data.get(), 6),
[email protected]8ddf8322012-02-23 18:08:0610480 MockRead(ASYNC, 0, 0, 6),
[email protected]394816e92010-08-03 07:38:5910481 };
[email protected]dd54bd82012-07-19 23:44:5710482 OrderedSocketData data_2(
10483 data_reads_2, arraysize(data_reads_2),
10484 data_writes_2, arraysize(data_writes_2));
[email protected]f45c1ee2010-08-03 00:54:3010485
[email protected]8ddf8322012-02-23 18:08:0610486 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210487 ssl.SetNextProto(GetParam());
[email protected]f45c1ee2010-08-03 00:54:3010488
[email protected]d973e99a2012-02-17 21:02:3610489 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5510490 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
10491 NULL, 0, NULL, 0);
10492 hanging_non_alternate_protocol_socket.set_connect_data(
10493 never_finishing_connect);
10494
[email protected]bb88e1d32013-05-03 23:11:0710495 session_deps_.socket_factory->AddSocketDataProvider(&data_1);
10496 session_deps_.socket_factory->AddSocketDataProvider(&data_2);
10497 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10498 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5510499 &hanging_non_alternate_protocol_socket);
[email protected]bb88e1d32013-05-03 23:11:0710500 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f45c1ee2010-08-03 00:54:3010501
10502 // First round should work and provide the Alternate-Protocol state.
[email protected]49639fa2011-12-20 23:22:4110503 TestCompletionCallback callback_1;
[email protected]262eec82013-03-19 21:01:3610504 scoped_ptr<HttpTransaction> trans_1(
[email protected]90499482013-06-01 00:39:5010505 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110506 int rv = trans_1->Start(&request, callback_1.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:3010507 EXPECT_EQ(ERR_IO_PENDING, rv);
10508 EXPECT_EQ(OK, callback_1.WaitForResult());
10509
10510 // Second round should attempt a tunnel connect and get an auth challenge.
[email protected]49639fa2011-12-20 23:22:4110511 TestCompletionCallback callback_2;
[email protected]262eec82013-03-19 21:01:3610512 scoped_ptr<HttpTransaction> trans_2(
[email protected]90499482013-06-01 00:39:5010513 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110514 rv = trans_2->Start(&request, callback_2.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:3010515 EXPECT_EQ(ERR_IO_PENDING, rv);
10516 EXPECT_EQ(OK, callback_2.WaitForResult());
10517 const HttpResponseInfo* response = trans_2->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010518 ASSERT_TRUE(response != NULL);
[email protected]f45c1ee2010-08-03 00:54:3010519 ASSERT_FALSE(response->auth_challenge.get() == NULL);
10520
10521 // Restart with auth. Tunnel should work and response received.
[email protected]49639fa2011-12-20 23:22:4110522 TestCompletionCallback callback_3;
10523 rv = trans_2->RestartWithAuth(
10524 AuthCredentials(kFoo, kBar), callback_3.callback());
[email protected]f45c1ee2010-08-03 00:54:3010525 EXPECT_EQ(ERR_IO_PENDING, rv);
10526 EXPECT_EQ(OK, callback_3.WaitForResult());
10527
10528 // After all that work, these two lines (or actually, just the scheme) are
10529 // what this test is all about. Make sure it happens correctly.
[email protected]f45c1ee2010-08-03 00:54:3010530 EXPECT_EQ("https", request_url.scheme());
10531 EXPECT_EQ("www.google.com", request_url.host());
10532
[email protected]029c83b62013-01-24 05:28:2010533 LoadTimingInfo load_timing_info;
10534 EXPECT_TRUE(trans_2->GetLoadTimingInfo(&load_timing_info));
10535 TestLoadTimingNotReusedWithPac(load_timing_info,
10536 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]8e6441ca2010-08-19 05:56:3810537}
10538
10539// Test that if we cancel the transaction as the connection is completing, that
10540// everything tears down correctly.
[email protected]23e482282013-06-14 16:08:0210541TEST_P(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3810542 // Setup everything about the connection to complete synchronously, so that
10543 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
10544 // for is the callback from the HttpStreamRequest.
10545 // Then cancel the transaction.
10546 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3610547 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3810548 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0610549 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
10550 MockRead(SYNCHRONOUS, "hello world"),
10551 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3810552 };
10553
[email protected]8e6441ca2010-08-19 05:56:3810554 HttpRequestInfo request;
10555 request.method = "GET";
10556 request.url = GURL("http://www.google.com/");
10557 request.load_flags = 0;
10558
[email protected]bb88e1d32013-05-03 23:11:0710559 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]3fe8d2f82013-10-17 08:56:0710560 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:2710561 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4110562 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:2710563
[email protected]8e6441ca2010-08-19 05:56:3810564 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10565 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710566 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3810567
[email protected]49639fa2011-12-20 23:22:4110568 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3810569
[email protected]333bdf62012-06-08 22:57:2910570 CapturingBoundNetLog log;
[email protected]49639fa2011-12-20 23:22:4110571 int rv = trans->Start(&request, callback.callback(), log.bound());
[email protected]8e6441ca2010-08-19 05:56:3810572 EXPECT_EQ(ERR_IO_PENDING, rv);
10573 trans.reset(); // Cancel the transaction here.
10574
[email protected]2da659e2013-05-23 20:51:3410575 base::MessageLoop::current()->RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3010576}
10577
[email protected]ecab6e052014-05-16 14:58:1210578// Test that if a transaction is cancelled after receiving the headers, the
10579// stream is drained properly and added back to the socket pool. The main
10580// purpose of this test is to make sure that an HttpStreamParser can be read
10581// from after the HttpNetworkTransaction and the objects it owns have been
10582// deleted.
10583// See http://crbug.com/368418
10584TEST_P(HttpNetworkTransactionTest, CancelAfterHeaders) {
10585 MockRead data_reads[] = {
10586 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
10587 MockRead(ASYNC, "Content-Length: 2\r\n"),
10588 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
10589 MockRead(ASYNC, "1"),
10590 // 2 async reads are necessary to trigger a ReadResponseBody call after the
10591 // HttpNetworkTransaction has been deleted.
10592 MockRead(ASYNC, "2"),
10593 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
10594 };
10595 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10596 session_deps_.socket_factory->AddSocketDataProvider(&data);
10597
10598 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10599
10600 {
10601 HttpRequestInfo request;
10602 request.method = "GET";
10603 request.url = GURL("http://www.google.com/");
10604 request.load_flags = 0;
10605
dcheng48459ac22014-08-26 00:46:4110606 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1210607 TestCompletionCallback callback;
10608
10609 int rv = trans.Start(&request, callback.callback(), BoundNetLog());
10610 EXPECT_EQ(ERR_IO_PENDING, rv);
10611 callback.WaitForResult();
10612
10613 const HttpResponseInfo* response = trans.GetResponseInfo();
10614 ASSERT_TRUE(response != NULL);
10615 EXPECT_TRUE(response->headers.get() != NULL);
10616 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10617
10618 // The transaction and HttpRequestInfo are deleted.
10619 }
10620
10621 // Let the HttpResponseBodyDrainer drain the socket.
10622 base::MessageLoop::current()->RunUntilIdle();
10623
10624 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4110625 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1210626}
10627
[email protected]76a505b2010-08-25 06:23:0010628// Test a basic GET request through a proxy.
[email protected]23e482282013-06-14 16:08:0210629TEST_P(HttpNetworkTransactionTest, ProxyGet) {
[email protected]bb88e1d32013-05-03 23:11:0710630 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:2010631 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
[email protected]333bdf62012-06-08 22:57:2910632 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710633 session_deps_.net_log = log.bound().net_log();
10634 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0010635
[email protected]76a505b2010-08-25 06:23:0010636 HttpRequestInfo request;
10637 request.method = "GET";
10638 request.url = GURL("http://www.google.com/");
10639
10640 MockWrite data_writes1[] = {
10641 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
10642 "Host: www.google.com\r\n"
10643 "Proxy-Connection: keep-alive\r\n\r\n"),
10644 };
10645
10646 MockRead data_reads1[] = {
10647 MockRead("HTTP/1.1 200 OK\r\n"),
10648 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10649 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610650 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0010651 };
10652
10653 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10654 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710655 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0010656
[email protected]49639fa2011-12-20 23:22:4110657 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0010658
[email protected]262eec82013-03-19 21:01:3610659 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010660 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]597a1ab2014-06-26 08:12:2710661 BeforeProxyHeadersSentHandler proxy_headers_handler;
10662 trans->SetBeforeProxyHeadersSentCallback(
10663 base::Bind(&BeforeProxyHeadersSentHandler::OnBeforeProxyHeadersSent,
10664 base::Unretained(&proxy_headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5010665
[email protected]49639fa2011-12-20 23:22:4110666 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0010667 EXPECT_EQ(ERR_IO_PENDING, rv);
10668
10669 rv = callback1.WaitForResult();
10670 EXPECT_EQ(OK, rv);
10671
10672 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010673 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:0010674
10675 EXPECT_TRUE(response->headers->IsKeepAlive());
10676 EXPECT_EQ(200, response->headers->response_code());
10677 EXPECT_EQ(100, response->headers->GetContentLength());
10678 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]d8fc4722014-06-13 13:17:1510679 EXPECT_TRUE(
10680 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
[email protected]597a1ab2014-06-26 08:12:2710681 EXPECT_TRUE(proxy_headers_handler.observed_before_proxy_headers_sent());
10682 EXPECT_EQ("myproxy:70", proxy_headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0010683 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2010684
10685 LoadTimingInfo load_timing_info;
10686 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10687 TestLoadTimingNotReusedWithPac(load_timing_info,
10688 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0010689}
10690
10691// Test a basic HTTPS GET request through a proxy.
[email protected]23e482282013-06-14 16:08:0210692TEST_P(HttpNetworkTransactionTest, ProxyTunnelGet) {
[email protected]bb88e1d32013-05-03 23:11:0710693 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:2010694 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
[email protected]333bdf62012-06-08 22:57:2910695 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710696 session_deps_.net_log = log.bound().net_log();
10697 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0010698
[email protected]76a505b2010-08-25 06:23:0010699 HttpRequestInfo request;
10700 request.method = "GET";
10701 request.url = GURL("https://www.google.com/");
10702
10703 // Since we have proxy, should try to establish tunnel.
10704 MockWrite data_writes1[] = {
10705 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
10706 "Host: www.google.com\r\n"
10707 "Proxy-Connection: keep-alive\r\n\r\n"),
10708
10709 MockWrite("GET / HTTP/1.1\r\n"
10710 "Host: www.google.com\r\n"
10711 "Connection: keep-alive\r\n\r\n"),
10712 };
10713
10714 MockRead data_reads1[] = {
10715 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
10716
10717 MockRead("HTTP/1.1 200 OK\r\n"),
10718 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10719 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610720 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0010721 };
10722
10723 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10724 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710725 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0610726 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710727 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0010728
[email protected]49639fa2011-12-20 23:22:4110729 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0010730
[email protected]262eec82013-03-19 21:01:3610731 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010732 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5010733
[email protected]49639fa2011-12-20 23:22:4110734 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0010735 EXPECT_EQ(ERR_IO_PENDING, rv);
10736
10737 rv = callback1.WaitForResult();
10738 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:5710739 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:4010740 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0010741 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010742 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0010743 NetLog::PHASE_NONE);
10744 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010745 entries, pos,
[email protected]76a505b2010-08-25 06:23:0010746 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
10747 NetLog::PHASE_NONE);
10748
10749 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010750 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:0010751
10752 EXPECT_TRUE(response->headers->IsKeepAlive());
10753 EXPECT_EQ(200, response->headers->response_code());
10754 EXPECT_EQ(100, response->headers->GetContentLength());
10755 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10756 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]d8fc4722014-06-13 13:17:1510757 EXPECT_TRUE(
10758 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
[email protected]029c83b62013-01-24 05:28:2010759
10760 LoadTimingInfo load_timing_info;
10761 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10762 TestLoadTimingNotReusedWithPac(load_timing_info,
10763 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0010764}
10765
10766// Test a basic HTTPS GET request through a proxy, but the server hangs up
10767// while establishing the tunnel.
[email protected]23e482282013-06-14 16:08:0210768TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
[email protected]bb88e1d32013-05-03 23:11:0710769 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]333bdf62012-06-08 22:57:2910770 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710771 session_deps_.net_log = log.bound().net_log();
10772 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0010773
[email protected]76a505b2010-08-25 06:23:0010774 HttpRequestInfo request;
10775 request.method = "GET";
10776 request.url = GURL("https://www.google.com/");
10777
10778 // Since we have proxy, should try to establish tunnel.
10779 MockWrite data_writes1[] = {
10780 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
10781 "Host: www.google.com\r\n"
10782 "Proxy-Connection: keep-alive\r\n\r\n"),
10783
10784 MockWrite("GET / HTTP/1.1\r\n"
10785 "Host: www.google.com\r\n"
10786 "Connection: keep-alive\r\n\r\n"),
10787 };
10788
10789 MockRead data_reads1[] = {
[email protected]8ddf8322012-02-23 18:08:0610790 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:0010791 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610792 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0010793 };
10794
10795 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10796 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710797 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0610798 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710799 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0010800
[email protected]49639fa2011-12-20 23:22:4110801 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0010802
[email protected]262eec82013-03-19 21:01:3610803 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010804 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5010805
[email protected]49639fa2011-12-20 23:22:4110806 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0010807 EXPECT_EQ(ERR_IO_PENDING, rv);
10808
10809 rv = callback1.WaitForResult();
10810 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
[email protected]f3da152d2012-06-02 01:00:5710811 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:4010812 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0010813 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010814 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0010815 NetLog::PHASE_NONE);
10816 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010817 entries, pos,
[email protected]76a505b2010-08-25 06:23:0010818 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
10819 NetLog::PHASE_NONE);
10820}
10821
[email protected]749eefa82010-09-13 22:14:0310822// Test for crbug.com/55424.
[email protected]23e482282013-06-14 16:08:0210823TEST_P(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
[email protected]cdf8f7e72013-05-23 10:56:4610824 scoped_ptr<SpdyFrame> req(
10825 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
[email protected]749eefa82010-09-13 22:14:0310826 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
10827
[email protected]23e482282013-06-14 16:08:0210828 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10829 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0310830 MockRead spdy_reads[] = {
10831 CreateMockRead(*resp),
10832 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:0610833 MockRead(ASYNC, 0, 0),
[email protected]749eefa82010-09-13 22:14:0310834 };
10835
[email protected]dd54bd82012-07-19 23:44:5710836 DelayedSocketData spdy_data(
10837 1, // wait for one write to finish before reading.
10838 spdy_reads, arraysize(spdy_reads),
10839 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710840 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0310841
[email protected]8ddf8322012-02-23 18:08:0610842 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210843 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710844 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0310845
[email protected]bb88e1d32013-05-03 23:11:0710846 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0310847
10848 // Set up an initial SpdySession in the pool to reuse.
[email protected]02b0c342010-09-25 21:09:3810849 HostPortPair host_port_pair("www.google.com", 443);
[email protected]e6d017652013-05-17 18:01:4010850 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5310851 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2710852 base::WeakPtr<SpdySession> spdy_session =
[email protected]41d64e82013-07-03 22:44:2610853 CreateInsecureSpdySession(session, key, BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0310854
10855 HttpRequestInfo request;
10856 request.method = "GET";
10857 request.url = GURL("https://www.google.com/");
10858 request.load_flags = 0;
10859
10860 // This is the important line that marks this as a preconnect.
10861 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
10862
[email protected]262eec82013-03-19 21:01:3610863 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010864 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]749eefa82010-09-13 22:14:0310865
[email protected]41d64e82013-07-03 22:44:2610866 TestCompletionCallback callback;
[email protected]49639fa2011-12-20 23:22:4110867 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0310868 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110869 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]749eefa82010-09-13 22:14:0310870}
10871
[email protected]73b8dd222010-11-11 19:55:2410872// Given a net error, cause that error to be returned from the first Write()
10873// call and verify that the HttpTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0210874void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0710875 int error, IoMode mode) {
[email protected]cb9bf6ca2011-01-28 13:15:2710876 net::HttpRequestInfo request_info;
10877 request_info.url = GURL("https://www.example.com/");
10878 request_info.method = "GET";
10879 request_info.load_flags = net::LOAD_NORMAL;
10880
[email protected]8ddf8322012-02-23 18:08:0610881 SSLSocketDataProvider ssl_data(mode, OK);
[email protected]73b8dd222010-11-11 19:55:2410882 net::MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:0610883 net::MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2410884 };
10885 net::StaticSocketDataProvider data(NULL, 0,
10886 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0710887 session_deps_.socket_factory->AddSocketDataProvider(&data);
10888 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2410889
[email protected]bb88e1d32013-05-03 23:11:0710890 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610891 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010892 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]73b8dd222010-11-11 19:55:2410893
[email protected]49639fa2011-12-20 23:22:4110894 TestCompletionCallback callback;
10895 int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
[email protected]73b8dd222010-11-11 19:55:2410896 if (rv == net::ERR_IO_PENDING)
10897 rv = callback.WaitForResult();
10898 ASSERT_EQ(error, rv);
10899}
10900
[email protected]23e482282013-06-14 16:08:0210901TEST_P(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2410902 // Just check a grab bag of cert errors.
10903 static const int kErrors[] = {
10904 ERR_CERT_COMMON_NAME_INVALID,
10905 ERR_CERT_AUTHORITY_INVALID,
10906 ERR_CERT_DATE_INVALID,
10907 };
10908 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0610909 CheckErrorIsPassedBack(kErrors[i], ASYNC);
10910 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2410911 }
10912}
10913
[email protected]bd0b6772011-01-11 19:59:3010914// Ensure that a client certificate is removed from the SSL client auth
10915// cache when:
10916// 1) No proxy is involved.
10917// 2) TLS False Start is disabled.
10918// 3) The initial TLS handshake requests a client certificate.
10919// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0210920TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310921 ClientAuthCertCache_Direct_NoFalseStart) {
[email protected]cb9bf6ca2011-01-28 13:15:2710922 net::HttpRequestInfo request_info;
10923 request_info.url = GURL("https://www.example.com/");
10924 request_info.method = "GET";
10925 request_info.load_flags = net::LOAD_NORMAL;
10926
[email protected]bd0b6772011-01-11 19:59:3010927 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4110928 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3010929
10930 // [ssl_]data1 contains the data for the first SSL handshake. When a
10931 // CertificateRequest is received for the first time, the handshake will
10932 // be aborted to allow the caller to provide a certificate.
[email protected]8ddf8322012-02-23 18:08:0610933 SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3010934 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710935 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
[email protected]bd0b6772011-01-11 19:59:3010936 net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710937 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3010938
10939 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
10940 // False Start is not being used, the result of the SSL handshake will be
10941 // returned as part of the SSLClientSocket::Connect() call. This test
10942 // matches the result of a server sending a handshake_failure alert,
10943 // rather than a Finished message, because it requires a client
10944 // certificate and none was supplied.
[email protected]8ddf8322012-02-23 18:08:0610945 SSLSocketDataProvider ssl_data2(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3010946 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710947 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
[email protected]bd0b6772011-01-11 19:59:3010948 net::StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710949 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3010950
10951 // [ssl_]data3 contains the data for the third SSL handshake. When a
10952 // connection to a server fails during an SSL handshake,
[email protected]80c75f682012-05-26 16:22:1710953 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
10954 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3010955 // of the HttpNetworkTransaction. Because this test failure is due to
10956 // requiring a client certificate, this fallback handshake should also
10957 // fail.
[email protected]8ddf8322012-02-23 18:08:0610958 SSLSocketDataProvider ssl_data3(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3010959 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710960 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
[email protected]bd0b6772011-01-11 19:59:3010961 net::StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710962 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3010963
[email protected]80c75f682012-05-26 16:22:1710964 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
10965 // connection to a server fails during an SSL handshake,
10966 // HttpNetworkTransaction will attempt to fallback to SSLv3 if the previous
10967 // connection was attempted with TLSv1. This is transparent to the caller
10968 // of the HttpNetworkTransaction. Because this test failure is due to
10969 // requiring a client certificate, this fallback handshake should also
10970 // fail.
10971 SSLSocketDataProvider ssl_data4(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
10972 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710973 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
[email protected]80c75f682012-05-26 16:22:1710974 net::StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710975 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1710976
[email protected]7799de12013-05-30 05:52:5110977 // Need one more if TLSv1.2 is enabled.
10978 SSLSocketDataProvider ssl_data5(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
10979 ssl_data5.cert_request_info = cert_request.get();
10980 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
10981 net::StaticSocketDataProvider data5(NULL, 0, NULL, 0);
10982 session_deps_.socket_factory->AddSocketDataProvider(&data5);
10983
[email protected]bb88e1d32013-05-03 23:11:0710984 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610985 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010986 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3010987
[email protected]bd0b6772011-01-11 19:59:3010988 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4110989 TestCompletionCallback callback;
10990 int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
[email protected]bd0b6772011-01-11 19:59:3010991 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10992
10993 // Complete the SSL handshake, which should abort due to requiring a
10994 // client certificate.
10995 rv = callback.WaitForResult();
10996 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
10997
10998 // Indicate that no certificate should be supplied. From the perspective
10999 // of SSLClientCertCache, NULL is just as meaningful as a real
11000 // certificate, so this is the same as supply a
11001 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4111002 rv = trans->RestartWithCertificate(NULL, callback.callback());
[email protected]bd0b6772011-01-11 19:59:3011003 ASSERT_EQ(net::ERR_IO_PENDING, rv);
11004
11005 // Ensure the certificate was added to the client auth cache before
11006 // allowing the connection to continue restarting.
11007 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4111008 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
11009 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3011010 ASSERT_EQ(NULL, client_cert.get());
11011
11012 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1711013 // then consume ssl_data3 and ssl_data4, both of which should also fail.
11014 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3011015 rv = callback.WaitForResult();
11016 ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
11017
11018 // Ensure that the client certificate is removed from the cache on a
11019 // handshake failure.
[email protected]791879c2013-12-17 07:22:4111020 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11021 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3011022}
11023
11024// Ensure that a client certificate is removed from the SSL client auth
11025// cache when:
11026// 1) No proxy is involved.
11027// 2) TLS False Start is enabled.
11028// 3) The initial TLS handshake requests a client certificate.
11029// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0211030TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2311031 ClientAuthCertCache_Direct_FalseStart) {
[email protected]cb9bf6ca2011-01-28 13:15:2711032 net::HttpRequestInfo request_info;
11033 request_info.url = GURL("https://www.example.com/");
11034 request_info.method = "GET";
11035 request_info.load_flags = net::LOAD_NORMAL;
11036
[email protected]bd0b6772011-01-11 19:59:3011037 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4111038 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3011039
11040 // When TLS False Start is used, SSLClientSocket::Connect() calls will
11041 // return successfully after reading up to the peer's Certificate message.
11042 // This is to allow the caller to call SSLClientSocket::Write(), which can
11043 // enqueue application data to be sent in the same packet as the
11044 // ChangeCipherSpec and Finished messages.
11045 // The actual handshake will be finished when SSLClientSocket::Read() is
11046 // called, which expects to process the peer's ChangeCipherSpec and
11047 // Finished messages. If there was an error negotiating with the peer,
11048 // such as due to the peer requiring a client certificate when none was
11049 // supplied, the alert sent by the peer won't be processed until Read() is
11050 // called.
11051
11052 // Like the non-False Start case, when a client certificate is requested by
11053 // the peer, the handshake is aborted during the Connect() call.
11054 // [ssl_]data1 represents the initial SSL handshake with the peer.
[email protected]8ddf8322012-02-23 18:08:0611055 SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3011056 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711057 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
[email protected]bd0b6772011-01-11 19:59:3011058 net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711059 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3011060
11061 // When a client certificate is supplied, Connect() will not be aborted
11062 // when the peer requests the certificate. Instead, the handshake will
11063 // artificially succeed, allowing the caller to write the HTTP request to
11064 // the socket. The handshake messages are not processed until Read() is
11065 // called, which then detects that the handshake was aborted, due to the
11066 // peer sending a handshake_failure because it requires a client
11067 // certificate.
[email protected]8ddf8322012-02-23 18:08:0611068 SSLSocketDataProvider ssl_data2(ASYNC, net::OK);
[email protected]bd0b6772011-01-11 19:59:3011069 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711070 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
[email protected]bd0b6772011-01-11 19:59:3011071 net::MockRead data2_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0611072 net::MockRead(ASYNC /* async */, net::ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3011073 };
11074 net::StaticSocketDataProvider data2(
11075 data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711076 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3011077
11078 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1711079 // the data for the SSL handshake once the TLSv1.1 connection falls back to
11080 // TLSv1. It has the same behaviour as [ssl_]data2.
[email protected]8ddf8322012-02-23 18:08:0611081 SSLSocketDataProvider ssl_data3(ASYNC, net::OK);
[email protected]bd0b6772011-01-11 19:59:3011082 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711083 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
[email protected]bd0b6772011-01-11 19:59:3011084 net::StaticSocketDataProvider data3(
11085 data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711086 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3011087
[email protected]80c75f682012-05-26 16:22:1711088 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
11089 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
11090 SSLSocketDataProvider ssl_data4(ASYNC, net::OK);
11091 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711092 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
[email protected]80c75f682012-05-26 16:22:1711093 net::StaticSocketDataProvider data4(
11094 data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711095 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1711096
[email protected]7799de12013-05-30 05:52:5111097 // Need one more if TLSv1.2 is enabled.
11098 SSLSocketDataProvider ssl_data5(ASYNC, net::OK);
11099 ssl_data5.cert_request_info = cert_request.get();
11100 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
11101 net::StaticSocketDataProvider data5(
11102 data2_reads, arraysize(data2_reads), NULL, 0);
11103 session_deps_.socket_factory->AddSocketDataProvider(&data5);
11104
[email protected]bb88e1d32013-05-03 23:11:0711105 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3611106 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011107 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3011108
[email protected]bd0b6772011-01-11 19:59:3011109 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4111110 TestCompletionCallback callback;
11111 int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
[email protected]bd0b6772011-01-11 19:59:3011112 ASSERT_EQ(net::ERR_IO_PENDING, rv);
11113
11114 // Complete the SSL handshake, which should abort due to requiring a
11115 // client certificate.
11116 rv = callback.WaitForResult();
11117 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
11118
11119 // Indicate that no certificate should be supplied. From the perspective
11120 // of SSLClientCertCache, NULL is just as meaningful as a real
11121 // certificate, so this is the same as supply a
11122 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4111123 rv = trans->RestartWithCertificate(NULL, callback.callback());
[email protected]bd0b6772011-01-11 19:59:3011124 ASSERT_EQ(net::ERR_IO_PENDING, rv);
11125
11126 // Ensure the certificate was added to the client auth cache before
11127 // allowing the connection to continue restarting.
11128 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4111129 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
11130 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3011131 ASSERT_EQ(NULL, client_cert.get());
11132
[email protected]bd0b6772011-01-11 19:59:3011133 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1711134 // then consume ssl_data3 and ssl_data4, both of which should also fail.
11135 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3011136 rv = callback.WaitForResult();
11137 ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
11138
11139 // Ensure that the client certificate is removed from the cache on a
11140 // handshake failure.
[email protected]791879c2013-12-17 07:22:4111141 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11142 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3011143}
11144
[email protected]8c405132011-01-11 22:03:1811145// Ensure that a client certificate is removed from the SSL client auth
11146// cache when:
11147// 1) An HTTPS proxy is involved.
11148// 3) The HTTPS proxy requests a client certificate.
11149// 4) The client supplies an invalid/unacceptable certificate for the
11150// proxy.
11151// The test is repeated twice, first for connecting to an HTTPS endpoint,
11152// then for connecting to an HTTP endpoint.
[email protected]23e482282013-06-14 16:08:0211153TEST_P(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
[email protected]bb88e1d32013-05-03 23:11:0711154 session_deps_.proxy_service.reset(
[email protected]8c405132011-01-11 22:03:1811155 ProxyService::CreateFixed("https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:2911156 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0711157 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1811158
11159 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4111160 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1811161
11162 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
11163 // [ssl_]data[1-3]. Rather than represending the endpoint
11164 // (www.example.com:443), they represent failures with the HTTPS proxy
11165 // (proxy:70).
[email protected]8ddf8322012-02-23 18:08:0611166 SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1811167 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711168 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
[email protected]8c405132011-01-11 22:03:1811169 net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711170 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1811171
[email protected]8ddf8322012-02-23 18:08:0611172 SSLSocketDataProvider ssl_data2(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1811173 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711174 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
[email protected]8c405132011-01-11 22:03:1811175 net::StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711176 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1811177
[email protected]80c75f682012-05-26 16:22:1711178 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
11179#if 0
[email protected]8ddf8322012-02-23 18:08:0611180 SSLSocketDataProvider ssl_data3(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1811181 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711182 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
[email protected]8c405132011-01-11 22:03:1811183 net::StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711184 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1711185#endif
[email protected]8c405132011-01-11 22:03:1811186
11187 net::HttpRequestInfo requests[2];
11188 requests[0].url = GURL("https://www.example.com/");
11189 requests[0].method = "GET";
11190 requests[0].load_flags = net::LOAD_NORMAL;
11191
11192 requests[1].url = GURL("http://www.example.com/");
11193 requests[1].method = "GET";
11194 requests[1].load_flags = net::LOAD_NORMAL;
11195
11196 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0711197 session_deps_.socket_factory->ResetNextMockIndexes();
11198 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c405132011-01-11 22:03:1811199 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5011200 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c405132011-01-11 22:03:1811201
11202 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4111203 TestCompletionCallback callback;
11204 int rv = trans->Start(
11205 &requests[i], callback.callback(), net::BoundNetLog());
[email protected]8c405132011-01-11 22:03:1811206 ASSERT_EQ(net::ERR_IO_PENDING, rv);
11207
11208 // Complete the SSL handshake, which should abort due to requiring a
11209 // client certificate.
11210 rv = callback.WaitForResult();
11211 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
11212
11213 // Indicate that no certificate should be supplied. From the perspective
11214 // of SSLClientCertCache, NULL is just as meaningful as a real
11215 // certificate, so this is the same as supply a
11216 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4111217 rv = trans->RestartWithCertificate(NULL, callback.callback());
[email protected]8c405132011-01-11 22:03:1811218 ASSERT_EQ(net::ERR_IO_PENDING, rv);
11219
11220 // Ensure the certificate was added to the client auth cache before
11221 // allowing the connection to continue restarting.
11222 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4111223 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
11224 HostPortPair("proxy", 70), &client_cert));
[email protected]8c405132011-01-11 22:03:1811225 ASSERT_EQ(NULL, client_cert.get());
11226 // Ensure the certificate was NOT cached for the endpoint. This only
11227 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4111228 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11229 HostPortPair("www.example.com", 443), &client_cert));
[email protected]8c405132011-01-11 22:03:1811230
11231 // Restart the handshake. This will consume ssl_data2, which fails, and
11232 // then consume ssl_data3, which should also fail. The result code is
11233 // checked against what ssl_data3 should return.
11234 rv = callback.WaitForResult();
11235 ASSERT_EQ(net::ERR_PROXY_CONNECTION_FAILED, rv);
11236
11237 // Now that the new handshake has failed, ensure that the client
11238 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4111239 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11240 HostPortPair("proxy", 70), &client_cert));
11241 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11242 HostPortPair("www.example.com", 443), &client_cert));
[email protected]8c405132011-01-11 22:03:1811243 }
11244}
11245
[email protected]23e482282013-06-14 16:08:0211246// Unlike TEST/TEST_F, which are macros that expand to further macros,
11247// TEST_P is a macro that expands directly to code that stringizes the
11248// arguments. As a result, macros passed as parameters (such as prefix
11249// or test_case_name) will not be expanded by the preprocessor. To
11250// work around this, indirect the macro for TEST_P, so that the
11251// pre-processor will expand macros such as MAYBE_test_name before
11252// instantiating the test.
11253#define WRAPPED_TEST_P(test_case_name, test_name) \
11254 TEST_P(test_case_name, test_name)
11255
[email protected]45b170822012-05-04 21:18:1411256// Times out on Win7 dbg(2) bot. http://crbug.com/124776
11257#if defined(OS_WIN)
11258#define MAYBE_UseIPConnectionPooling DISABLED_UseIPConnectionPooling
11259#else
11260#define MAYBE_UseIPConnectionPooling UseIPConnectionPooling
11261#endif
[email protected]23e482282013-06-14 16:08:0211262WRAPPED_TEST_P(HttpNetworkTransactionTest, MAYBE_UseIPConnectionPooling) {
[email protected]d7599122014-05-24 03:37:2311263 session_deps_.use_alternate_protocols = true;
11264 session_deps_.next_protos = SpdyNextProtos();
[email protected]e3ceb682011-06-28 23:55:4611265
11266 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0711267 session_deps_.host_resolver.reset(new MockCachingHostResolver());
11268 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2611269 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
11270 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4611271
[email protected]8ddf8322012-02-23 18:08:0611272 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211273 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711274 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4611275
[email protected]cdf8f7e72013-05-23 10:56:4611276 scoped_ptr<SpdyFrame> host1_req(
11277 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
11278 scoped_ptr<SpdyFrame> host2_req(
11279 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4611280 MockWrite spdy_writes[] = {
11281 CreateMockWrite(*host1_req, 1),
11282 CreateMockWrite(*host2_req, 4),
11283 };
[email protected]23e482282013-06-14 16:08:0211284 scoped_ptr<SpdyFrame> host1_resp(
11285 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11286 scoped_ptr<SpdyFrame> host1_resp_body(
11287 spdy_util_.ConstructSpdyBodyFrame(1, true));
11288 scoped_ptr<SpdyFrame> host2_resp(
11289 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11290 scoped_ptr<SpdyFrame> host2_resp_body(
11291 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4611292 MockRead spdy_reads[] = {
11293 CreateMockRead(*host1_resp, 2),
11294 CreateMockRead(*host1_resp_body, 3),
11295 CreateMockRead(*host2_resp, 5),
11296 CreateMockRead(*host2_resp_body, 6),
[email protected]8ddf8322012-02-23 18:08:0611297 MockRead(ASYNC, 0, 7),
[email protected]e3ceb682011-06-28 23:55:4611298 };
11299
[email protected]d2b5f092012-06-08 23:55:0211300 IPAddressNumber ip;
11301 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
11302 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11303 MockConnect connect(ASYNC, OK, peer_addr);
[email protected]dd54bd82012-07-19 23:44:5711304 OrderedSocketData spdy_data(
11305 connect,
11306 spdy_reads, arraysize(spdy_reads),
11307 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711308 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4611309
[email protected]aa22b242011-11-16 18:58:2911310 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4611311 HttpRequestInfo request1;
11312 request1.method = "GET";
11313 request1.url = GURL("https://www.google.com/");
11314 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011315 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611316
[email protected]49639fa2011-12-20 23:22:4111317 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611318 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111319 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611320
11321 const HttpResponseInfo* response = trans1.GetResponseInfo();
11322 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011323 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611324 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11325
11326 std::string response_data;
11327 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
11328 EXPECT_EQ("hello!", response_data);
11329
11330 // Preload www.gmail.com into HostCache.
11331 HostPortPair host_port("www.gmail.com", 443);
[email protected]5109c1952013-08-20 18:44:1011332 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4611333 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1011334 rv = session_deps_.host_resolver->Resolve(resolve_info,
11335 DEFAULT_PRIORITY,
11336 &ignored,
11337 callback.callback(),
11338 NULL,
11339 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4711340 EXPECT_EQ(ERR_IO_PENDING, rv);
11341 rv = callback.WaitForResult();
11342 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4611343
11344 HttpRequestInfo request2;
11345 request2.method = "GET";
11346 request2.url = GURL("https://www.gmail.com/");
11347 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011348 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611349
[email protected]49639fa2011-12-20 23:22:4111350 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611351 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111352 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611353
11354 response = trans2.GetResponseInfo();
11355 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011356 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611357 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11358 EXPECT_TRUE(response->was_fetched_via_spdy);
11359 EXPECT_TRUE(response->was_npn_negotiated);
11360 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
11361 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4611362}
[email protected]45b170822012-05-04 21:18:1411363#undef MAYBE_UseIPConnectionPooling
[email protected]e3ceb682011-06-28 23:55:4611364
[email protected]23e482282013-06-14 16:08:0211365TEST_P(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d7599122014-05-24 03:37:2311366 session_deps_.use_alternate_protocols = true;
11367 session_deps_.next_protos = SpdyNextProtos();
[email protected]d2b5f092012-06-08 23:55:0211368
11369 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0711370 session_deps_.host_resolver.reset(new MockCachingHostResolver());
11371 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0211372 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
11373 pool_peer.DisableDomainAuthenticationVerification();
11374
11375 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211376 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711377 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]d2b5f092012-06-08 23:55:0211378
[email protected]cdf8f7e72013-05-23 10:56:4611379 scoped_ptr<SpdyFrame> host1_req(
11380 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
11381 scoped_ptr<SpdyFrame> host2_req(
11382 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0211383 MockWrite spdy_writes[] = {
11384 CreateMockWrite(*host1_req, 1),
11385 CreateMockWrite(*host2_req, 4),
11386 };
[email protected]23e482282013-06-14 16:08:0211387 scoped_ptr<SpdyFrame> host1_resp(
11388 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11389 scoped_ptr<SpdyFrame> host1_resp_body(
11390 spdy_util_.ConstructSpdyBodyFrame(1, true));
11391 scoped_ptr<SpdyFrame> host2_resp(
11392 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11393 scoped_ptr<SpdyFrame> host2_resp_body(
11394 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0211395 MockRead spdy_reads[] = {
11396 CreateMockRead(*host1_resp, 2),
11397 CreateMockRead(*host1_resp_body, 3),
11398 CreateMockRead(*host2_resp, 5),
11399 CreateMockRead(*host2_resp_body, 6),
11400 MockRead(ASYNC, 0, 7),
11401 };
11402
11403 IPAddressNumber ip;
11404 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
11405 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11406 MockConnect connect(ASYNC, OK, peer_addr);
[email protected]dd54bd82012-07-19 23:44:5711407 OrderedSocketData spdy_data(
11408 connect,
11409 spdy_reads, arraysize(spdy_reads),
11410 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711411 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0211412
11413 TestCompletionCallback callback;
11414 HttpRequestInfo request1;
11415 request1.method = "GET";
11416 request1.url = GURL("https://www.google.com/");
11417 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011418 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0211419
11420 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
11421 EXPECT_EQ(ERR_IO_PENDING, rv);
11422 EXPECT_EQ(OK, callback.WaitForResult());
11423
11424 const HttpResponseInfo* response = trans1.GetResponseInfo();
11425 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011426 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d2b5f092012-06-08 23:55:0211427 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11428
11429 std::string response_data;
11430 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
11431 EXPECT_EQ("hello!", response_data);
11432
11433 HttpRequestInfo request2;
11434 request2.method = "GET";
11435 request2.url = GURL("https://www.gmail.com/");
11436 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011437 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0211438
11439 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
11440 EXPECT_EQ(ERR_IO_PENDING, rv);
11441 EXPECT_EQ(OK, callback.WaitForResult());
11442
11443 response = trans2.GetResponseInfo();
11444 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011445 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d2b5f092012-06-08 23:55:0211446 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11447 EXPECT_TRUE(response->was_fetched_via_spdy);
11448 EXPECT_TRUE(response->was_npn_negotiated);
11449 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
11450 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0211451}
11452
[email protected]e3ceb682011-06-28 23:55:4611453class OneTimeCachingHostResolver : public net::HostResolver {
11454 public:
11455 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
11456 : host_port_(host_port) {}
dchengb03027d2014-10-21 12:00:2011457 ~OneTimeCachingHostResolver() override {}
[email protected]e3ceb682011-06-28 23:55:4611458
11459 RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); }
11460
11461 // HostResolver methods:
dchengb03027d2014-10-21 12:00:2011462 int Resolve(const RequestInfo& info,
11463 RequestPriority priority,
11464 AddressList* addresses,
11465 const CompletionCallback& callback,
11466 RequestHandle* out_req,
11467 const BoundNetLog& net_log) override {
[email protected]95a214c2011-08-04 21:50:4011468 return host_resolver_.Resolve(
[email protected]5109c1952013-08-20 18:44:1011469 info, priority, addresses, callback, out_req, net_log);
[email protected]95a214c2011-08-04 21:50:4011470 }
11471
dchengb03027d2014-10-21 12:00:2011472 int ResolveFromCache(const RequestInfo& info,
11473 AddressList* addresses,
11474 const BoundNetLog& net_log) override {
[email protected]95a214c2011-08-04 21:50:4011475 int rv = host_resolver_.ResolveFromCache(info, addresses, net_log);
11476 if (rv == OK && info.host_port_pair().Equals(host_port_))
[email protected]98e1cd012011-11-08 15:33:0911477 host_resolver_.GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4611478 return rv;
11479 }
11480
dchengb03027d2014-10-21 12:00:2011481 void CancelRequest(RequestHandle req) override {
[email protected]e3ceb682011-06-28 23:55:4611482 host_resolver_.CancelRequest(req);
11483 }
11484
[email protected]46da33be2011-07-19 21:58:0411485 MockCachingHostResolver* GetMockHostResolver() {
11486 return &host_resolver_;
11487 }
11488
[email protected]e3ceb682011-06-28 23:55:4611489 private:
11490 MockCachingHostResolver host_resolver_;
11491 const HostPortPair host_port_;
11492};
11493
[email protected]45b170822012-05-04 21:18:1411494// Times out on Win7 dbg(2) bot. http://crbug.com/124776
11495#if defined(OS_WIN)
[email protected]bb88e1d32013-05-03 23:11:0711496#define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \
11497 DISABLED_UseIPConnectionPoolingWithHostCacheExpiration
[email protected]45b170822012-05-04 21:18:1411498#else
[email protected]bb88e1d32013-05-03 23:11:0711499#define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \
11500 UseIPConnectionPoolingWithHostCacheExpiration
[email protected]45b170822012-05-04 21:18:1411501#endif
[email protected]23e482282013-06-14 16:08:0211502WRAPPED_TEST_P(HttpNetworkTransactionTest,
11503 MAYBE_UseIPConnectionPoolingWithHostCacheExpiration) {
[email protected]23e482282013-06-14 16:08:0211504// Times out on Win7 dbg(2) bot. http://crbug.com/124776 . (MAYBE_
11505// prefix doesn't work with parametrized tests).
11506#if defined(OS_WIN)
11507 return;
[email protected]88c7b4be2014-03-19 23:04:0111508#else
[email protected]d7599122014-05-24 03:37:2311509 session_deps_.use_alternate_protocols = true;
11510 session_deps_.next_protos = SpdyNextProtos();
[email protected]e3ceb682011-06-28 23:55:4611511
11512 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
[email protected]e3ceb682011-06-28 23:55:4611513 OneTimeCachingHostResolver host_resolver(HostPortPair("www.gmail.com", 443));
[email protected]c6bf8152012-12-02 07:43:3411514 HttpNetworkSession::Params params =
[email protected]bb88e1d32013-05-03 23:11:0711515 SpdySessionDependencies::CreateSessionParams(&session_deps_);
[email protected]e3ceb682011-06-28 23:55:4611516 params.host_resolver = &host_resolver;
[email protected]bb88e1d32013-05-03 23:11:0711517 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2611518 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
11519 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4611520
[email protected]8ddf8322012-02-23 18:08:0611521 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211522 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711523 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4611524
[email protected]cdf8f7e72013-05-23 10:56:4611525 scoped_ptr<SpdyFrame> host1_req(
11526 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
11527 scoped_ptr<SpdyFrame> host2_req(
11528 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4611529 MockWrite spdy_writes[] = {
11530 CreateMockWrite(*host1_req, 1),
11531 CreateMockWrite(*host2_req, 4),
11532 };
[email protected]23e482282013-06-14 16:08:0211533 scoped_ptr<SpdyFrame> host1_resp(
11534 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11535 scoped_ptr<SpdyFrame> host1_resp_body(
11536 spdy_util_.ConstructSpdyBodyFrame(1, true));
11537 scoped_ptr<SpdyFrame> host2_resp(
11538 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11539 scoped_ptr<SpdyFrame> host2_resp_body(
11540 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4611541 MockRead spdy_reads[] = {
11542 CreateMockRead(*host1_resp, 2),
11543 CreateMockRead(*host1_resp_body, 3),
11544 CreateMockRead(*host2_resp, 5),
11545 CreateMockRead(*host2_resp_body, 6),
[email protected]8ddf8322012-02-23 18:08:0611546 MockRead(ASYNC, 0, 7),
[email protected]e3ceb682011-06-28 23:55:4611547 };
11548
[email protected]d2b5f092012-06-08 23:55:0211549 IPAddressNumber ip;
11550 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
11551 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11552 MockConnect connect(ASYNC, OK, peer_addr);
[email protected]dd54bd82012-07-19 23:44:5711553 OrderedSocketData spdy_data(
11554 connect,
11555 spdy_reads, arraysize(spdy_reads),
11556 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711557 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4611558
[email protected]aa22b242011-11-16 18:58:2911559 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4611560 HttpRequestInfo request1;
11561 request1.method = "GET";
11562 request1.url = GURL("https://www.google.com/");
11563 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011564 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611565
[email protected]49639fa2011-12-20 23:22:4111566 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611567 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111568 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611569
11570 const HttpResponseInfo* response = trans1.GetResponseInfo();
11571 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011572 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611573 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11574
11575 std::string response_data;
11576 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
11577 EXPECT_EQ("hello!", response_data);
11578
11579 // Preload cache entries into HostCache.
[email protected]5109c1952013-08-20 18:44:1011580 HostResolver::RequestInfo resolve_info(HostPortPair("www.gmail.com", 443));
[email protected]e3ceb682011-06-28 23:55:4611581 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1011582 rv = host_resolver.Resolve(resolve_info,
11583 DEFAULT_PRIORITY,
11584 &ignored,
11585 callback.callback(),
11586 NULL,
11587 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4711588 EXPECT_EQ(ERR_IO_PENDING, rv);
11589 rv = callback.WaitForResult();
11590 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4611591
11592 HttpRequestInfo request2;
11593 request2.method = "GET";
11594 request2.url = GURL("https://www.gmail.com/");
11595 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011596 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611597
[email protected]49639fa2011-12-20 23:22:4111598 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611599 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111600 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611601
11602 response = trans2.GetResponseInfo();
11603 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011604 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611605 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11606 EXPECT_TRUE(response->was_fetched_via_spdy);
11607 EXPECT_TRUE(response->was_npn_negotiated);
11608 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
11609 EXPECT_EQ("hello!", response_data);
[email protected]88c7b4be2014-03-19 23:04:0111610#endif
[email protected]e3ceb682011-06-28 23:55:4611611}
[email protected]45b170822012-05-04 21:18:1411612#undef MAYBE_UseIPConnectionPoolingWithHostCacheExpiration
[email protected]e3ceb682011-06-28 23:55:4611613
[email protected]23e482282013-06-14 16:08:0211614TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
lgarrona91df87f2014-12-05 00:51:3411615 const std::string https_url = "https://www.google.com:8080/";
11616 const std::string http_url = "http://www.google.com:8080/";
[email protected]8450d722012-07-02 19:14:0411617
11618 // SPDY GET for HTTPS URL
[email protected]cdf8f7e72013-05-23 10:56:4611619 scoped_ptr<SpdyFrame> req1(
11620 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0411621
11622 MockWrite writes1[] = {
11623 CreateMockWrite(*req1, 0),
11624 };
11625
[email protected]23e482282013-06-14 16:08:0211626 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11627 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8450d722012-07-02 19:14:0411628 MockRead reads1[] = {
11629 CreateMockRead(*resp1, 1),
11630 CreateMockRead(*body1, 2),
11631 MockRead(ASYNC, ERR_IO_PENDING, 3)
11632 };
11633
[email protected]dd54bd82012-07-19 23:44:5711634 DelayedSocketData data1(
11635 1, reads1, arraysize(reads1),
11636 writes1, arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0411637 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5711638 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0411639
11640 // HTTP GET for the HTTP URL
11641 MockWrite writes2[] = {
lgarrona91df87f2014-12-05 00:51:3411642 MockWrite(ASYNC, 4,
11643 "GET / HTTP/1.1\r\n"
11644 "Host: www.google.com:8080\r\n"
11645 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0411646 };
11647
11648 MockRead reads2[] = {
11649 MockRead(ASYNC, 5, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
11650 MockRead(ASYNC, 6, "hello"),
11651 MockRead(ASYNC, 7, OK),
11652 };
11653
[email protected]dd54bd82012-07-19 23:44:5711654 DelayedSocketData data2(
11655 1, reads2, arraysize(reads2),
11656 writes2, arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0411657
[email protected]8450d722012-07-02 19:14:0411658 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211659 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711660 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11661 session_deps_.socket_factory->AddSocketDataProvider(&data1);
11662 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0411663
[email protected]bb88e1d32013-05-03 23:11:0711664 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0411665
11666 // Start the first transaction to set up the SpdySession
11667 HttpRequestInfo request1;
11668 request1.method = "GET";
11669 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0411670 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011671 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0411672 TestCompletionCallback callback1;
11673 EXPECT_EQ(ERR_IO_PENDING,
11674 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411675 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411676
11677 EXPECT_EQ(OK, callback1.WaitForResult());
11678 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11679
11680 // Now, start the HTTP request
11681 HttpRequestInfo request2;
11682 request2.method = "GET";
11683 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0411684 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011685 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0411686 TestCompletionCallback callback2;
11687 EXPECT_EQ(ERR_IO_PENDING,
11688 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411689 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411690
11691 EXPECT_EQ(OK, callback2.WaitForResult());
11692 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11693}
11694
[email protected]23e482282013-06-14 16:08:0211695TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
lgarrona91df87f2014-12-05 00:51:3411696 const std::string https_url = "https://www.google.com:8080/";
11697 const std::string http_url = "http://www.google.com:8080/";
[email protected]8450d722012-07-02 19:14:0411698
11699 // SPDY GET for HTTPS URL (through CONNECT tunnel)
lgarrona91df87f2014-12-05 00:51:3411700 const HostPortPair host_port_pair("www.google.com", 8080);
11701 scoped_ptr<SpdyFrame> connect(
11702 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
[email protected]cdf8f7e72013-05-23 10:56:4611703 scoped_ptr<SpdyFrame> req1(
11704 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]23e482282013-06-14 16:08:0211705 scoped_ptr<SpdyFrame> wrapped_req1(
11706 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3911707
11708 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
[email protected]745aa9c2014-06-27 02:21:2911709 SpdyHeaderBlock req2_block;
11710 req2_block[spdy_util_.GetMethodKey()] = "GET";
bnc33b8cef42014-11-19 17:30:3811711 req2_block[spdy_util_.GetPathKey()] = "/";
lgarrona91df87f2014-12-05 00:51:3411712 req2_block[spdy_util_.GetHostKey()] = "www.google.com:8080";
[email protected]745aa9c2014-06-27 02:21:2911713 req2_block[spdy_util_.GetSchemeKey()] = "http";
11714 spdy_util_.MaybeAddVersionHeader(&req2_block);
[email protected]601e03f12014-04-06 16:26:3911715 scoped_ptr<SpdyFrame> req2(
[email protected]745aa9c2014-06-27 02:21:2911716 spdy_util_.ConstructSpdySyn(3, req2_block, MEDIUM, false, true));
[email protected]8450d722012-07-02 19:14:0411717
11718 MockWrite writes1[] = {
11719 CreateMockWrite(*connect, 0),
11720 CreateMockWrite(*wrapped_req1, 2),
11721 CreateMockWrite(*req2, 5),
11722 };
11723
[email protected]23e482282013-06-14 16:08:0211724 scoped_ptr<SpdyFrame> conn_resp(
11725 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11726 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11727 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
11728 scoped_ptr<SpdyFrame> wrapped_resp1(
11729 spdy_util_.ConstructWrappedSpdyFrame(resp1, 1));
11730 scoped_ptr<SpdyFrame> wrapped_body1(
11731 spdy_util_.ConstructWrappedSpdyFrame(body1, 1));
11732 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11733 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]8450d722012-07-02 19:14:0411734 MockRead reads1[] = {
11735 CreateMockRead(*conn_resp, 1),
11736 CreateMockRead(*wrapped_resp1, 3),
11737 CreateMockRead(*wrapped_body1, 4),
11738 CreateMockRead(*resp2, 6),
11739 CreateMockRead(*body2, 7),
11740 MockRead(ASYNC, ERR_IO_PENDING, 8)
11741 };
11742
[email protected]dd54bd82012-07-19 23:44:5711743 DeterministicSocketData data1(reads1, arraysize(reads1),
11744 writes1, arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0411745 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5711746 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0411747
[email protected]bb88e1d32013-05-03 23:11:0711748 session_deps_.proxy_service.reset(
[email protected]f6c63db52013-02-02 00:35:2211749 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
11750 CapturingNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0711751 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0411752 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
[email protected]23e482282013-06-14 16:08:0211753 ssl1.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711754 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0411755 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
[email protected]23e482282013-06-14 16:08:0211756 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711757 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11758 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0411759
11760 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0711761 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]8450d722012-07-02 19:14:0411762
11763 // Start the first transaction to set up the SpdySession
11764 HttpRequestInfo request1;
11765 request1.method = "GET";
11766 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0411767 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011768 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0411769 TestCompletionCallback callback1;
11770 EXPECT_EQ(ERR_IO_PENDING,
11771 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411772 base::MessageLoop::current()->RunUntilIdle();
[email protected]dd54bd82012-07-19 23:44:5711773 data1.RunFor(4);
[email protected]8450d722012-07-02 19:14:0411774
11775 EXPECT_EQ(OK, callback1.WaitForResult());
11776 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11777
[email protected]f6c63db52013-02-02 00:35:2211778 LoadTimingInfo load_timing_info1;
11779 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
11780 TestLoadTimingNotReusedWithPac(load_timing_info1,
11781 CONNECT_TIMING_HAS_SSL_TIMES);
11782
[email protected]8450d722012-07-02 19:14:0411783 // Now, start the HTTP request
11784 HttpRequestInfo request2;
11785 request2.method = "GET";
11786 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0411787 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011788 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0411789 TestCompletionCallback callback2;
11790 EXPECT_EQ(ERR_IO_PENDING,
11791 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411792 base::MessageLoop::current()->RunUntilIdle();
[email protected]dd54bd82012-07-19 23:44:5711793 data1.RunFor(3);
[email protected]8450d722012-07-02 19:14:0411794
11795 EXPECT_EQ(OK, callback2.WaitForResult());
11796 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2211797
11798 LoadTimingInfo load_timing_info2;
11799 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
11800 // The established SPDY sessions is considered reused by the HTTP request.
11801 TestLoadTimingReusedWithPac(load_timing_info2);
11802 // HTTP requests over a SPDY session should have a different connection
11803 // socket_log_id than requests over a tunnel.
11804 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0411805}
11806
[email protected]23e482282013-06-14 16:08:0211807TEST_P(HttpNetworkTransactionTest, UseSpdySessionForHttpWhenForced) {
[email protected]d7599122014-05-24 03:37:2311808 session_deps_.force_spdy_always = true;
lgarrona91df87f2014-12-05 00:51:3411809 const std::string https_url = "https://www.google.com:8080/";
11810 const std::string http_url = "http://www.google.com:8080/";
[email protected]8450d722012-07-02 19:14:0411811
11812 // SPDY GET for HTTPS URL
[email protected]cdf8f7e72013-05-23 10:56:4611813 scoped_ptr<SpdyFrame> req1(
11814 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0411815 // SPDY GET for the HTTP URL
[email protected]cdf8f7e72013-05-23 10:56:4611816 scoped_ptr<SpdyFrame> req2(
11817 spdy_util_.ConstructSpdyGet(http_url.c_str(), false, 3, MEDIUM));
[email protected]8450d722012-07-02 19:14:0411818
11819 MockWrite writes[] = {
11820 CreateMockWrite(*req1, 1),
11821 CreateMockWrite(*req2, 4),
11822 };
11823
[email protected]23e482282013-06-14 16:08:0211824 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11825 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
11826 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11827 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]8450d722012-07-02 19:14:0411828 MockRead reads[] = {
11829 CreateMockRead(*resp1, 2),
11830 CreateMockRead(*body1, 3),
11831 CreateMockRead(*resp2, 5),
11832 CreateMockRead(*body2, 6),
11833 MockRead(ASYNC, ERR_IO_PENDING, 7)
11834 };
11835
[email protected]dd54bd82012-07-19 23:44:5711836 OrderedSocketData data(reads, arraysize(reads),
11837 writes, arraysize(writes));
[email protected]8450d722012-07-02 19:14:0411838
[email protected]8450d722012-07-02 19:14:0411839 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211840 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711841 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11842 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8450d722012-07-02 19:14:0411843
[email protected]bb88e1d32013-05-03 23:11:0711844 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0411845
11846 // Start the first transaction to set up the SpdySession
11847 HttpRequestInfo request1;
11848 request1.method = "GET";
11849 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0411850 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011851 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0411852 TestCompletionCallback callback1;
11853 EXPECT_EQ(ERR_IO_PENDING,
11854 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411855 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411856
11857 EXPECT_EQ(OK, callback1.WaitForResult());
11858 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11859
11860 // Now, start the HTTP request
11861 HttpRequestInfo request2;
11862 request2.method = "GET";
11863 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0411864 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011865 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0411866 TestCompletionCallback callback2;
11867 EXPECT_EQ(ERR_IO_PENDING,
11868 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411869 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411870
11871 EXPECT_EQ(OK, callback2.WaitForResult());
11872 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11873}
11874
[email protected]2d88e7d2012-07-19 17:55:1711875// Test that in the case where we have a SPDY session to a SPDY proxy
11876// that we do not pool other origins that resolve to the same IP when
11877// the certificate does not match the new origin.
11878// http://crbug.com/134690
[email protected]23e482282013-06-14 16:08:0211879TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
[email protected]2d88e7d2012-07-19 17:55:1711880 const std::string url1 = "http://www.google.com/";
11881 const std::string url2 = "https://mail.google.com/";
11882 const std::string ip_addr = "1.2.3.4";
11883
11884 // SPDY GET for HTTP URL (through SPDY proxy)
[email protected]23e482282013-06-14 16:08:0211885 scoped_ptr<SpdyHeaderBlock> headers(
11886 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/"));
[email protected]745aa9c2014-06-27 02:21:2911887 scoped_ptr<SpdyFrame> req1(
11888 spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, false, true));
[email protected]2d88e7d2012-07-19 17:55:1711889
11890 MockWrite writes1[] = {
11891 CreateMockWrite(*req1, 0),
11892 };
11893
[email protected]23e482282013-06-14 16:08:0211894 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11895 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1711896 MockRead reads1[] = {
11897 CreateMockRead(*resp1, 1),
11898 CreateMockRead(*body1, 2),
11899 MockRead(ASYNC, OK, 3) // EOF
11900 };
11901
11902 scoped_ptr<DeterministicSocketData> data1(
11903 new DeterministicSocketData(reads1, arraysize(reads1),
11904 writes1, arraysize(writes1)));
11905 IPAddressNumber ip;
11906 ASSERT_TRUE(ParseIPLiteralToNumber(ip_addr, &ip));
11907 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11908 MockConnect connect_data1(ASYNC, OK, peer_addr);
11909 data1->set_connect_data(connect_data1);
11910
11911 // SPDY GET for HTTPS URL (direct)
[email protected]cdf8f7e72013-05-23 10:56:4611912 scoped_ptr<SpdyFrame> req2(
11913 spdy_util_.ConstructSpdyGet(url2.c_str(), false, 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1711914
11915 MockWrite writes2[] = {
11916 CreateMockWrite(*req2, 0),
11917 };
11918
[email protected]23e482282013-06-14 16:08:0211919 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11920 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1711921 MockRead reads2[] = {
11922 CreateMockRead(*resp2, 1),
11923 CreateMockRead(*body2, 2),
11924 MockRead(ASYNC, OK, 3) // EOF
11925 };
11926
11927 scoped_ptr<DeterministicSocketData> data2(
11928 new DeterministicSocketData(reads2, arraysize(reads2),
11929 writes2, arraysize(writes2)));
11930 MockConnect connect_data2(ASYNC, OK);
11931 data2->set_connect_data(connect_data2);
11932
11933 // Set up a proxy config that sends HTTP requests to a proxy, and
11934 // all others direct.
11935 ProxyConfig proxy_config;
11936 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
11937 CapturingProxyResolver* capturing_proxy_resolver =
11938 new CapturingProxyResolver();
[email protected]bb88e1d32013-05-03 23:11:0711939 session_deps_.proxy_service.reset(new ProxyService(
[email protected]2d88e7d2012-07-19 17:55:1711940 new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver,
11941 NULL));
11942
11943 // Load a valid cert. Note, that this does not need to
11944 // be valid for proxy because the MockSSLClientSocket does
11945 // not actually verify it. But SpdySession will use this
11946 // to see if it is valid for the new origin
[email protected]6cdfd7f2013-02-08 20:40:1511947 base::FilePath certs_dir = GetTestCertsDirectory();
[email protected]2d88e7d2012-07-19 17:55:1711948 scoped_refptr<X509Certificate> server_cert(
11949 ImportCertFromFile(certs_dir, "ok_cert.pem"));
dcheng48459ac22014-08-26 00:46:4111950 ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert.get());
[email protected]2d88e7d2012-07-19 17:55:1711951
11952 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
[email protected]23e482282013-06-14 16:08:0211953 ssl1.SetNextProto(GetParam());
[email protected]2d88e7d2012-07-19 17:55:1711954 ssl1.cert = server_cert;
[email protected]bb88e1d32013-05-03 23:11:0711955 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
11956 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11957 data1.get());
[email protected]2d88e7d2012-07-19 17:55:1711958
11959 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
[email protected]23e482282013-06-14 16:08:0211960 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711961 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11962 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11963 data2.get());
[email protected]2d88e7d2012-07-19 17:55:1711964
[email protected]bb88e1d32013-05-03 23:11:0711965 session_deps_.host_resolver.reset(new MockCachingHostResolver());
11966 session_deps_.host_resolver->rules()->AddRule("mail.google.com", ip_addr);
11967 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1711968
11969 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0711970 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]2d88e7d2012-07-19 17:55:1711971
11972 // Start the first transaction to set up the SpdySession
11973 HttpRequestInfo request1;
11974 request1.method = "GET";
11975 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1711976 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011977 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1711978 TestCompletionCallback callback1;
11979 ASSERT_EQ(ERR_IO_PENDING,
11980 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
11981 data1->RunFor(3);
11982
11983 ASSERT_TRUE(callback1.have_result());
11984 EXPECT_EQ(OK, callback1.WaitForResult());
11985 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11986
11987 // Now, start the HTTP request
11988 HttpRequestInfo request2;
11989 request2.method = "GET";
11990 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1711991 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011992 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1711993 TestCompletionCallback callback2;
11994 EXPECT_EQ(ERR_IO_PENDING,
11995 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411996 base::MessageLoop::current()->RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1711997 data2->RunFor(3);
11998
11999 ASSERT_TRUE(callback2.have_result());
12000 EXPECT_EQ(OK, callback2.WaitForResult());
12001 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
12002}
12003
[email protected]85f97342013-04-17 06:12:2412004// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
12005// error) in SPDY session, removes the socket from pool and closes the SPDY
12006// session. Verify that new url's from the same HttpNetworkSession (and a new
12007// SpdySession) do work. http://crbug.com/224701
[email protected]23e482282013-06-14 16:08:0212008TEST_P(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
[email protected]85f97342013-04-17 06:12:2412009 const std::string https_url = "https://www.google.com/";
12010
12011 MockRead reads1[] = {
12012 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
12013 };
12014
12015 scoped_ptr<DeterministicSocketData> data1(
12016 new DeterministicSocketData(reads1, arraysize(reads1), NULL, 0));
12017 data1->SetStop(1);
12018
[email protected]cdf8f7e72013-05-23 10:56:4612019 scoped_ptr<SpdyFrame> req2(
12020 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2412021 MockWrite writes2[] = {
12022 CreateMockWrite(*req2, 0),
12023 };
12024
[email protected]23e482282013-06-14 16:08:0212025 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12026 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]85f97342013-04-17 06:12:2412027 MockRead reads2[] = {
12028 CreateMockRead(*resp2, 1),
12029 CreateMockRead(*body2, 2),
12030 MockRead(ASYNC, OK, 3) // EOF
12031 };
12032
12033 scoped_ptr<DeterministicSocketData> data2(
12034 new DeterministicSocketData(reads2, arraysize(reads2),
12035 writes2, arraysize(writes2)));
12036
[email protected]85f97342013-04-17 06:12:2412037 SSLSocketDataProvider ssl1(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212038 ssl1.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0712039 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
12040 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
12041 data1.get());
[email protected]85f97342013-04-17 06:12:2412042
12043 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212044 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0712045 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
12046 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
12047 data2.get());
[email protected]85f97342013-04-17 06:12:2412048
12049 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0712050 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]85f97342013-04-17 06:12:2412051
12052 // Start the first transaction to set up the SpdySession and verify that
12053 // connection was closed.
12054 HttpRequestInfo request1;
12055 request1.method = "GET";
12056 request1.url = GURL(https_url);
12057 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012058 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2412059 TestCompletionCallback callback1;
12060 EXPECT_EQ(ERR_IO_PENDING,
12061 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412062 base::MessageLoop::current()->RunUntilIdle();
[email protected]85f97342013-04-17 06:12:2412063 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback1.WaitForResult());
12064
12065 // Now, start the second request and make sure it succeeds.
12066 HttpRequestInfo request2;
12067 request2.method = "GET";
12068 request2.url = GURL(https_url);
12069 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012070 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2412071 TestCompletionCallback callback2;
12072 EXPECT_EQ(ERR_IO_PENDING,
12073 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412074 base::MessageLoop::current()->RunUntilIdle();
[email protected]85f97342013-04-17 06:12:2412075 data2->RunFor(3);
12076
12077 ASSERT_TRUE(callback2.have_result());
12078 EXPECT_EQ(OK, callback2.WaitForResult());
12079 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
12080}
12081
[email protected]23e482282013-06-14 16:08:0212082TEST_P(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]d7599122014-05-24 03:37:2312083 session_deps_.next_protos = SpdyNextProtos();
[email protected]483fa202013-05-14 01:07:0312084 ClientSocketPoolManager::set_max_sockets_per_group(
12085 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12086 ClientSocketPoolManager::set_max_sockets_per_pool(
12087 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12088
12089 // Use two different hosts with different IPs so they don't get pooled.
12090 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
12091 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
12092 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12093
12094 SSLSocketDataProvider ssl1(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212095 ssl1.SetNextProto(GetParam());
[email protected]483fa202013-05-14 01:07:0312096 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212097 ssl2.SetNextProto(GetParam());
[email protected]483fa202013-05-14 01:07:0312098 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
12099 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
12100
[email protected]cdf8f7e72013-05-23 10:56:4612101 scoped_ptr<SpdyFrame> host1_req(spdy_util_.ConstructSpdyGet(
[email protected]483fa202013-05-14 01:07:0312102 "https://www.a.com", false, 1, DEFAULT_PRIORITY));
12103 MockWrite spdy1_writes[] = {
12104 CreateMockWrite(*host1_req, 1),
12105 };
[email protected]23e482282013-06-14 16:08:0212106 scoped_ptr<SpdyFrame> host1_resp(
12107 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12108 scoped_ptr<SpdyFrame> host1_resp_body(
12109 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0312110 MockRead spdy1_reads[] = {
12111 CreateMockRead(*host1_resp, 2),
12112 CreateMockRead(*host1_resp_body, 3),
12113 MockRead(ASYNC, ERR_IO_PENDING, 4),
12114 };
12115
12116 scoped_ptr<OrderedSocketData> spdy1_data(
12117 new OrderedSocketData(
12118 spdy1_reads, arraysize(spdy1_reads),
12119 spdy1_writes, arraysize(spdy1_writes)));
12120 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
12121
[email protected]cdf8f7e72013-05-23 10:56:4612122 scoped_ptr<SpdyFrame> host2_req(spdy_util_.ConstructSpdyGet(
[email protected]483fa202013-05-14 01:07:0312123 "https://www.b.com", false, 1, DEFAULT_PRIORITY));
12124 MockWrite spdy2_writes[] = {
12125 CreateMockWrite(*host2_req, 1),
12126 };
[email protected]23e482282013-06-14 16:08:0212127 scoped_ptr<SpdyFrame> host2_resp(
12128 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12129 scoped_ptr<SpdyFrame> host2_resp_body(
12130 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0312131 MockRead spdy2_reads[] = {
12132 CreateMockRead(*host2_resp, 2),
12133 CreateMockRead(*host2_resp_body, 3),
12134 MockRead(ASYNC, ERR_IO_PENDING, 4),
12135 };
12136
12137 scoped_ptr<OrderedSocketData> spdy2_data(
12138 new OrderedSocketData(
12139 spdy2_reads, arraysize(spdy2_reads),
12140 spdy2_writes, arraysize(spdy2_writes)));
12141 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
12142
12143 MockWrite http_write[] = {
12144 MockWrite("GET / HTTP/1.1\r\n"
12145 "Host: www.a.com\r\n"
12146 "Connection: keep-alive\r\n\r\n"),
12147 };
12148
12149 MockRead http_read[] = {
12150 MockRead("HTTP/1.1 200 OK\r\n"),
12151 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12152 MockRead("Content-Length: 6\r\n\r\n"),
12153 MockRead("hello!"),
12154 };
12155 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
12156 http_write, arraysize(http_write));
12157 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12158
12159 HostPortPair host_port_pair_a("www.a.com", 443);
[email protected]e6d017652013-05-17 18:01:4012160 SpdySessionKey spdy_session_key_a(
[email protected]314b03992014-04-01 01:28:5312161 host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0312162 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2612163 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0312164
12165 TestCompletionCallback callback;
12166 HttpRequestInfo request1;
12167 request1.method = "GET";
12168 request1.url = GURL("https://www.a.com/");
12169 request1.load_flags = 0;
12170 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5012171 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0312172
12173 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
12174 EXPECT_EQ(ERR_IO_PENDING, rv);
12175 EXPECT_EQ(OK, callback.WaitForResult());
12176
12177 const HttpResponseInfo* response = trans->GetResponseInfo();
12178 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5012179 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0312180 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12181 EXPECT_TRUE(response->was_fetched_via_spdy);
12182 EXPECT_TRUE(response->was_npn_negotiated);
12183
12184 std::string response_data;
12185 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
12186 EXPECT_EQ("hello!", response_data);
12187 trans.reset();
12188 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2612189 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0312190
12191 HostPortPair host_port_pair_b("www.b.com", 443);
[email protected]e6d017652013-05-17 18:01:4012192 SpdySessionKey spdy_session_key_b(
[email protected]314b03992014-04-01 01:28:5312193 host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0312194 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2612195 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0312196 HttpRequestInfo request2;
12197 request2.method = "GET";
12198 request2.url = GURL("https://www.b.com/");
12199 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012200 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0312201
12202 rv = trans->Start(&request2, callback.callback(), BoundNetLog());
12203 EXPECT_EQ(ERR_IO_PENDING, rv);
12204 EXPECT_EQ(OK, callback.WaitForResult());
12205
12206 response = trans->GetResponseInfo();
12207 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5012208 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0312209 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12210 EXPECT_TRUE(response->was_fetched_via_spdy);
12211 EXPECT_TRUE(response->was_npn_negotiated);
12212 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
12213 EXPECT_EQ("hello!", response_data);
12214 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2612215 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0312216 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2612217 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0312218
12219 HostPortPair host_port_pair_a1("www.a.com", 80);
[email protected]e6d017652013-05-17 18:01:4012220 SpdySessionKey spdy_session_key_a1(
[email protected]314b03992014-04-01 01:28:5312221 host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0312222 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2612223 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0312224 HttpRequestInfo request3;
12225 request3.method = "GET";
12226 request3.url = GURL("http://www.a.com/");
12227 request3.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012228 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0312229
12230 rv = trans->Start(&request3, callback.callback(), BoundNetLog());
12231 EXPECT_EQ(ERR_IO_PENDING, rv);
12232 EXPECT_EQ(OK, callback.WaitForResult());
12233
12234 response = trans->GetResponseInfo();
12235 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5012236 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0312237 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12238 EXPECT_FALSE(response->was_fetched_via_spdy);
12239 EXPECT_FALSE(response->was_npn_negotiated);
12240 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
12241 EXPECT_EQ("hello!", response_data);
12242 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2612243 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0312244 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2612245 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0312246}
12247
[email protected]79e1fd62013-06-20 06:50:0412248TEST_P(HttpNetworkTransactionTest, HttpSyncConnectError) {
12249 HttpRequestInfo request;
12250 request.method = "GET";
12251 request.url = GURL("http://www.google.com/");
12252 request.load_flags = 0;
12253
[email protected]3fe8d2f82013-10-17 08:56:0712254 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412255 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112256 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412257
12258 MockConnect mock_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
12259 StaticSocketDataProvider data;
12260 data.set_connect_data(mock_connect);
12261 session_deps_.socket_factory->AddSocketDataProvider(&data);
12262
12263 TestCompletionCallback callback;
12264
12265 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12266 EXPECT_EQ(ERR_IO_PENDING, rv);
12267
12268 rv = callback.WaitForResult();
12269 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
12270
12271 EXPECT_EQ(NULL, trans->GetResponseInfo());
12272
12273 // We don't care whether this succeeds or fails, but it shouldn't crash.
12274 HttpRequestHeaders request_headers;
12275 trans->GetFullRequestHeaders(&request_headers);
12276}
12277
12278TEST_P(HttpNetworkTransactionTest, HttpAsyncConnectError) {
12279 HttpRequestInfo request;
12280 request.method = "GET";
12281 request.url = GURL("http://www.google.com/");
12282 request.load_flags = 0;
12283
[email protected]3fe8d2f82013-10-17 08:56:0712284 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412285 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112286 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412287
12288 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
12289 StaticSocketDataProvider data;
12290 data.set_connect_data(mock_connect);
12291 session_deps_.socket_factory->AddSocketDataProvider(&data);
12292
12293 TestCompletionCallback callback;
12294
12295 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12296 EXPECT_EQ(ERR_IO_PENDING, rv);
12297
12298 rv = callback.WaitForResult();
12299 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
12300
12301 EXPECT_EQ(NULL, trans->GetResponseInfo());
12302
12303 // We don't care whether this succeeds or fails, but it shouldn't crash.
12304 HttpRequestHeaders request_headers;
12305 trans->GetFullRequestHeaders(&request_headers);
12306}
12307
12308TEST_P(HttpNetworkTransactionTest, HttpSyncWriteError) {
12309 HttpRequestInfo request;
12310 request.method = "GET";
12311 request.url = GURL("http://www.google.com/");
12312 request.load_flags = 0;
12313
[email protected]3fe8d2f82013-10-17 08:56:0712314 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412315 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112316 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412317
12318 MockWrite data_writes[] = {
12319 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
12320 };
12321 MockRead data_reads[] = {
12322 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
12323 };
12324
12325 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12326 data_writes, arraysize(data_writes));
12327 session_deps_.socket_factory->AddSocketDataProvider(&data);
12328
12329 TestCompletionCallback callback;
12330
12331 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12332 EXPECT_EQ(ERR_IO_PENDING, rv);
12333
12334 rv = callback.WaitForResult();
12335 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12336
12337 EXPECT_EQ(NULL, trans->GetResponseInfo());
12338
12339 HttpRequestHeaders request_headers;
12340 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12341 EXPECT_TRUE(request_headers.HasHeader("Host"));
12342}
12343
12344TEST_P(HttpNetworkTransactionTest, HttpAsyncWriteError) {
12345 HttpRequestInfo request;
12346 request.method = "GET";
12347 request.url = GURL("http://www.google.com/");
12348 request.load_flags = 0;
12349
[email protected]3fe8d2f82013-10-17 08:56:0712350 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412351 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112352 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412353
12354 MockWrite data_writes[] = {
12355 MockWrite(ASYNC, ERR_CONNECTION_RESET),
12356 };
12357 MockRead data_reads[] = {
12358 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
12359 };
12360
12361 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12362 data_writes, arraysize(data_writes));
12363 session_deps_.socket_factory->AddSocketDataProvider(&data);
12364
12365 TestCompletionCallback callback;
12366
12367 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12368 EXPECT_EQ(ERR_IO_PENDING, rv);
12369
12370 rv = callback.WaitForResult();
12371 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12372
12373 EXPECT_EQ(NULL, trans->GetResponseInfo());
12374
12375 HttpRequestHeaders request_headers;
12376 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12377 EXPECT_TRUE(request_headers.HasHeader("Host"));
12378}
12379
12380TEST_P(HttpNetworkTransactionTest, HttpSyncReadError) {
12381 HttpRequestInfo request;
12382 request.method = "GET";
12383 request.url = GURL("http://www.google.com/");
12384 request.load_flags = 0;
12385
[email protected]3fe8d2f82013-10-17 08:56:0712386 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412387 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112388 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412389
12390 MockWrite data_writes[] = {
12391 MockWrite("GET / HTTP/1.1\r\n"
12392 "Host: www.google.com\r\n"
12393 "Connection: keep-alive\r\n\r\n"),
12394 };
12395 MockRead data_reads[] = {
12396 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
12397 };
12398
12399 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12400 data_writes, arraysize(data_writes));
12401 session_deps_.socket_factory->AddSocketDataProvider(&data);
12402
12403 TestCompletionCallback callback;
12404
12405 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12406 EXPECT_EQ(ERR_IO_PENDING, rv);
12407
12408 rv = callback.WaitForResult();
12409 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12410
12411 EXPECT_EQ(NULL, trans->GetResponseInfo());
12412
12413 HttpRequestHeaders request_headers;
12414 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12415 EXPECT_TRUE(request_headers.HasHeader("Host"));
12416}
12417
12418TEST_P(HttpNetworkTransactionTest, HttpAsyncReadError) {
12419 HttpRequestInfo request;
12420 request.method = "GET";
12421 request.url = GURL("http://www.google.com/");
12422 request.load_flags = 0;
12423
[email protected]3fe8d2f82013-10-17 08:56:0712424 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412425 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112426 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412427
12428 MockWrite data_writes[] = {
12429 MockWrite("GET / HTTP/1.1\r\n"
12430 "Host: www.google.com\r\n"
12431 "Connection: keep-alive\r\n\r\n"),
12432 };
12433 MockRead data_reads[] = {
12434 MockRead(ASYNC, ERR_CONNECTION_RESET),
12435 };
12436
12437 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12438 data_writes, arraysize(data_writes));
12439 session_deps_.socket_factory->AddSocketDataProvider(&data);
12440
12441 TestCompletionCallback callback;
12442
12443 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12444 EXPECT_EQ(ERR_IO_PENDING, rv);
12445
12446 rv = callback.WaitForResult();
12447 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12448
12449 EXPECT_EQ(NULL, trans->GetResponseInfo());
12450
12451 HttpRequestHeaders request_headers;
12452 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12453 EXPECT_TRUE(request_headers.HasHeader("Host"));
12454}
12455
12456TEST_P(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
12457 HttpRequestInfo request;
12458 request.method = "GET";
12459 request.url = GURL("http://www.google.com/");
12460 request.load_flags = 0;
12461 request.extra_headers.SetHeader("X-Foo", "bar");
12462
[email protected]3fe8d2f82013-10-17 08:56:0712463 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412464 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112465 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412466
12467 MockWrite data_writes[] = {
12468 MockWrite("GET / HTTP/1.1\r\n"
12469 "Host: www.google.com\r\n"
12470 "Connection: keep-alive\r\n"
12471 "X-Foo: bar\r\n\r\n"),
12472 };
12473 MockRead data_reads[] = {
12474 MockRead("HTTP/1.1 200 OK\r\n"
12475 "Content-Length: 5\r\n\r\n"
12476 "hello"),
12477 MockRead(ASYNC, ERR_UNEXPECTED),
12478 };
12479
12480 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12481 data_writes, arraysize(data_writes));
12482 session_deps_.socket_factory->AddSocketDataProvider(&data);
12483
12484 TestCompletionCallback callback;
12485
12486 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12487 EXPECT_EQ(ERR_IO_PENDING, rv);
12488
12489 rv = callback.WaitForResult();
12490 EXPECT_EQ(OK, rv);
12491
12492 HttpRequestHeaders request_headers;
12493 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12494 std::string foo;
12495 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
12496 EXPECT_EQ("bar", foo);
12497}
12498
[email protected]bf828982013-08-14 18:01:4712499namespace {
12500
yhiranoa7e05bb2014-11-06 05:40:3912501// Fake HttpStream that simply records calls to SetPriority().
12502class FakeStream : public HttpStream,
[email protected]e86839fd2013-08-14 18:29:0312503 public base::SupportsWeakPtr<FakeStream> {
12504 public:
12505 explicit FakeStream(RequestPriority priority) : priority_(priority) {}
dchengb03027d2014-10-21 12:00:2012506 ~FakeStream() override {}
[email protected]e86839fd2013-08-14 18:29:0312507
12508 RequestPriority priority() const { return priority_; }
12509
dchengb03027d2014-10-21 12:00:2012510 int InitializeStream(const HttpRequestInfo* request_info,
12511 RequestPriority priority,
12512 const BoundNetLog& net_log,
12513 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0312514 return ERR_IO_PENDING;
12515 }
12516
dchengb03027d2014-10-21 12:00:2012517 int SendRequest(const HttpRequestHeaders& request_headers,
12518 HttpResponseInfo* response,
12519 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0312520 ADD_FAILURE();
12521 return ERR_UNEXPECTED;
12522 }
12523
dchengb03027d2014-10-21 12:00:2012524 int ReadResponseHeaders(const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0312525 ADD_FAILURE();
12526 return ERR_UNEXPECTED;
12527 }
12528
dchengb03027d2014-10-21 12:00:2012529 int ReadResponseBody(IOBuffer* buf,
12530 int buf_len,
12531 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0312532 ADD_FAILURE();
12533 return ERR_UNEXPECTED;
12534 }
12535
dchengb03027d2014-10-21 12:00:2012536 void Close(bool not_reusable) override {}
[email protected]e86839fd2013-08-14 18:29:0312537
dchengb03027d2014-10-21 12:00:2012538 bool IsResponseBodyComplete() const override {
[email protected]e86839fd2013-08-14 18:29:0312539 ADD_FAILURE();
12540 return false;
12541 }
12542
dchengb03027d2014-10-21 12:00:2012543 bool CanFindEndOfResponse() const override { return false; }
[email protected]e86839fd2013-08-14 18:29:0312544
dchengb03027d2014-10-21 12:00:2012545 bool IsConnectionReused() const override {
[email protected]e86839fd2013-08-14 18:29:0312546 ADD_FAILURE();
12547 return false;
12548 }
12549
dchengb03027d2014-10-21 12:00:2012550 void SetConnectionReused() override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0312551
dchengb03027d2014-10-21 12:00:2012552 bool IsConnectionReusable() const override {
[email protected]e86839fd2013-08-14 18:29:0312553 ADD_FAILURE();
12554 return false;
12555 }
12556
dchengb03027d2014-10-21 12:00:2012557 int64 GetTotalReceivedBytes() const override {
[email protected]bc92bc972013-12-13 08:32:5912558 ADD_FAILURE();
12559 return 0;
12560 }
12561
dchengb03027d2014-10-21 12:00:2012562 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
[email protected]e86839fd2013-08-14 18:29:0312563 ADD_FAILURE();
12564 return false;
12565 }
12566
dchengb03027d2014-10-21 12:00:2012567 void GetSSLInfo(SSLInfo* ssl_info) override { ADD_FAILURE(); }
12568
12569 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
[email protected]e86839fd2013-08-14 18:29:0312570 ADD_FAILURE();
12571 }
12572
dchengb03027d2014-10-21 12:00:2012573 bool IsSpdyHttpStream() const override {
[email protected]e86839fd2013-08-14 18:29:0312574 ADD_FAILURE();
12575 return false;
12576 }
12577
dchengb03027d2014-10-21 12:00:2012578 void Drain(HttpNetworkSession* session) override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0312579
dchengb03027d2014-10-21 12:00:2012580 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]e86839fd2013-08-14 18:29:0312581
yhiranoa7e05bb2014-11-06 05:40:3912582 UploadProgress GetUploadProgress() const override { return UploadProgress(); }
12583
12584 HttpStream* RenewStreamForAuth() override { return NULL; }
12585
[email protected]e86839fd2013-08-14 18:29:0312586 private:
12587 RequestPriority priority_;
12588
12589 DISALLOW_COPY_AND_ASSIGN(FakeStream);
12590};
12591
12592// Fake HttpStreamRequest that simply records calls to SetPriority()
12593// and vends FakeStreams with its current priority.
[email protected]bf828982013-08-14 18:01:4712594class FakeStreamRequest : public HttpStreamRequest,
12595 public base::SupportsWeakPtr<FakeStreamRequest> {
12596 public:
[email protected]e86839fd2013-08-14 18:29:0312597 FakeStreamRequest(RequestPriority priority,
12598 HttpStreamRequest::Delegate* delegate)
12599 : priority_(priority),
[email protected]831e4a32013-11-14 02:14:4412600 delegate_(delegate),
12601 websocket_stream_create_helper_(NULL) {}
12602
12603 FakeStreamRequest(RequestPriority priority,
12604 HttpStreamRequest::Delegate* delegate,
12605 WebSocketHandshakeStreamBase::CreateHelper* create_helper)
12606 : priority_(priority),
12607 delegate_(delegate),
12608 websocket_stream_create_helper_(create_helper) {}
[email protected]e86839fd2013-08-14 18:29:0312609
dchengb03027d2014-10-21 12:00:2012610 ~FakeStreamRequest() override {}
[email protected]bf828982013-08-14 18:01:4712611
12612 RequestPriority priority() const { return priority_; }
12613
[email protected]831e4a32013-11-14 02:14:4412614 const WebSocketHandshakeStreamBase::CreateHelper*
12615 websocket_stream_create_helper() const {
12616 return websocket_stream_create_helper_;
12617 }
12618
[email protected]e86839fd2013-08-14 18:29:0312619 // Create a new FakeStream and pass it to the request's
12620 // delegate. Returns a weak pointer to the FakeStream.
12621 base::WeakPtr<FakeStream> FinishStreamRequest() {
12622 FakeStream* fake_stream = new FakeStream(priority_);
12623 // Do this before calling OnStreamReady() as OnStreamReady() may
12624 // immediately delete |fake_stream|.
12625 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
12626 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), fake_stream);
12627 return weak_stream;
12628 }
12629
dchengb03027d2014-10-21 12:00:2012630 int RestartTunnelWithProxyAuth(const AuthCredentials& credentials) override {
[email protected]bf828982013-08-14 18:01:4712631 ADD_FAILURE();
12632 return ERR_UNEXPECTED;
12633 }
12634
dchengb03027d2014-10-21 12:00:2012635 LoadState GetLoadState() const override {
[email protected]bf828982013-08-14 18:01:4712636 ADD_FAILURE();
12637 return LoadState();
12638 }
12639
dchengb03027d2014-10-21 12:00:2012640 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]bf828982013-08-14 18:01:4712641
dchengb03027d2014-10-21 12:00:2012642 bool was_npn_negotiated() const override { return false; }
[email protected]bf828982013-08-14 18:01:4712643
dchengb03027d2014-10-21 12:00:2012644 NextProto protocol_negotiated() const override { return kProtoUnknown; }
[email protected]bf828982013-08-14 18:01:4712645
dchengb03027d2014-10-21 12:00:2012646 bool using_spdy() const override { return false; }
[email protected]bf828982013-08-14 18:01:4712647
12648 private:
12649 RequestPriority priority_;
[email protected]e86839fd2013-08-14 18:29:0312650 HttpStreamRequest::Delegate* const delegate_;
[email protected]831e4a32013-11-14 02:14:4412651 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
[email protected]bf828982013-08-14 18:01:4712652
12653 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
12654};
12655
12656// Fake HttpStreamFactory that vends FakeStreamRequests.
12657class FakeStreamFactory : public HttpStreamFactory {
12658 public:
12659 FakeStreamFactory() {}
dchengb03027d2014-10-21 12:00:2012660 ~FakeStreamFactory() override {}
[email protected]bf828982013-08-14 18:01:4712661
12662 // Returns a WeakPtr<> to the last HttpStreamRequest returned by
12663 // RequestStream() (which may be NULL if it was destroyed already).
12664 base::WeakPtr<FakeStreamRequest> last_stream_request() {
12665 return last_stream_request_;
12666 }
12667
dchengb03027d2014-10-21 12:00:2012668 HttpStreamRequest* RequestStream(const HttpRequestInfo& info,
12669 RequestPriority priority,
12670 const SSLConfig& server_ssl_config,
12671 const SSLConfig& proxy_ssl_config,
12672 HttpStreamRequest::Delegate* delegate,
12673 const BoundNetLog& net_log) override {
[email protected]e86839fd2013-08-14 18:29:0312674 FakeStreamRequest* fake_request = new FakeStreamRequest(priority, delegate);
[email protected]bf828982013-08-14 18:01:4712675 last_stream_request_ = fake_request->AsWeakPtr();
12676 return fake_request;
12677 }
12678
dchengb03027d2014-10-21 12:00:2012679 HttpStreamRequest* RequestWebSocketHandshakeStream(
[email protected]bf828982013-08-14 18:01:4712680 const HttpRequestInfo& info,
12681 RequestPriority priority,
12682 const SSLConfig& server_ssl_config,
12683 const SSLConfig& proxy_ssl_config,
12684 HttpStreamRequest::Delegate* delegate,
[email protected]467086b2013-11-12 08:19:4612685 WebSocketHandshakeStreamBase::CreateHelper* create_helper,
mostynbba063d6032014-10-09 11:01:1312686 const BoundNetLog& net_log) override {
[email protected]831e4a32013-11-14 02:14:4412687 FakeStreamRequest* fake_request =
12688 new FakeStreamRequest(priority, delegate, create_helper);
12689 last_stream_request_ = fake_request->AsWeakPtr();
12690 return fake_request;
[email protected]bf828982013-08-14 18:01:4712691 }
12692
dchengb03027d2014-10-21 12:00:2012693 void PreconnectStreams(int num_streams,
12694 const HttpRequestInfo& info,
12695 RequestPriority priority,
12696 const SSLConfig& server_ssl_config,
12697 const SSLConfig& proxy_ssl_config) override {
[email protected]bf828982013-08-14 18:01:4712698 ADD_FAILURE();
12699 }
12700
dchengb03027d2014-10-21 12:00:2012701 const HostMappingRules* GetHostMappingRules() const override {
[email protected]bf828982013-08-14 18:01:4712702 ADD_FAILURE();
12703 return NULL;
12704 }
12705
12706 private:
12707 base::WeakPtr<FakeStreamRequest> last_stream_request_;
12708
12709 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
12710};
12711
Adam Rice425cf122015-01-19 06:18:2412712// TODO(ricea): Maybe unify this with the one in
12713// url_request_http_job_unittest.cc ?
12714class FakeWebSocketBasicHandshakeStream : public WebSocketHandshakeStreamBase {
12715 public:
12716 FakeWebSocketBasicHandshakeStream(scoped_ptr<ClientSocketHandle> connection,
12717 bool using_proxy)
12718 : state_(connection.release(), using_proxy) {}
12719
12720 // Fake implementation of HttpStreamBase methods.
12721 // This ends up being quite "real" because this object has to really send data
12722 // on the mock socket. It might be easier to use the real implementation, but
12723 // the fact that the WebSocket code is not compiled on iOS makes that
12724 // difficult.
12725 int InitializeStream(const HttpRequestInfo* request_info,
12726 RequestPriority priority,
12727 const BoundNetLog& net_log,
12728 const CompletionCallback& callback) override {
12729 state_.Initialize(request_info, priority, net_log, callback);
12730 return OK;
12731 }
12732
12733 int SendRequest(const HttpRequestHeaders& request_headers,
12734 HttpResponseInfo* response,
12735 const CompletionCallback& callback) override {
12736 return parser()->SendRequest(state_.GenerateRequestLine(), request_headers,
12737 response, callback);
12738 }
12739
12740 int ReadResponseHeaders(const CompletionCallback& callback) override {
12741 return parser()->ReadResponseHeaders(callback);
12742 }
12743
12744 int ReadResponseBody(IOBuffer* buf,
12745 int buf_len,
12746 const CompletionCallback& callback) override {
12747 NOTREACHED();
12748 return ERR_IO_PENDING;
12749 }
12750
12751 void Close(bool not_reusable) override {
12752 if (parser())
12753 parser()->Close(true);
12754 }
12755
12756 bool IsResponseBodyComplete() const override {
12757 NOTREACHED();
12758 return false;
12759 }
12760
12761 bool CanFindEndOfResponse() const override {
12762 return parser()->CanFindEndOfResponse();
12763 }
12764
12765 bool IsConnectionReused() const override {
12766 NOTREACHED();
12767 return false;
12768 }
12769 void SetConnectionReused() override { NOTREACHED(); }
12770
12771 bool IsConnectionReusable() const override {
12772 NOTREACHED();
12773 return false;
12774 }
12775
12776 int64 GetTotalReceivedBytes() const override {
12777 NOTREACHED();
12778 return 0;
12779 }
12780
12781 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
12782 NOTREACHED();
12783 return false;
12784 }
12785
Adam Ricecb76ac62015-02-20 05:33:2512786 void GetSSLInfo(SSLInfo* ssl_info) override {}
Adam Rice425cf122015-01-19 06:18:2412787
12788 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
12789 NOTREACHED();
12790 }
12791
12792 bool IsSpdyHttpStream() const override {
12793 NOTREACHED();
12794 return false;
12795 }
12796
12797 void Drain(HttpNetworkSession* session) override { NOTREACHED(); }
12798
12799 void SetPriority(RequestPriority priority) override { NOTREACHED(); }
12800
12801 UploadProgress GetUploadProgress() const override {
12802 NOTREACHED();
12803 return UploadProgress();
12804 }
12805
12806 HttpStream* RenewStreamForAuth() override {
12807 NOTREACHED();
12808 return nullptr;
12809 }
12810
12811 // Fake implementation of WebSocketHandshakeStreamBase method(s)
12812 scoped_ptr<WebSocketStream> Upgrade() override {
12813 NOTREACHED();
12814 return scoped_ptr<WebSocketStream>();
12815 }
12816
12817 private:
12818 HttpStreamParser* parser() const { return state_.parser(); }
12819 HttpBasicState state_;
12820
12821 DISALLOW_COPY_AND_ASSIGN(FakeWebSocketBasicHandshakeStream);
12822};
12823
[email protected]831e4a32013-11-14 02:14:4412824// TODO(yhirano): Split this class out into a net/websockets file, if it is
12825// worth doing.
12826class FakeWebSocketStreamCreateHelper :
12827 public WebSocketHandshakeStreamBase::CreateHelper {
12828 public:
dchengb03027d2014-10-21 12:00:2012829 WebSocketHandshakeStreamBase* CreateBasicStream(
[email protected]7e841a52013-11-22 09:04:2112830 scoped_ptr<ClientSocketHandle> connection,
mostynbba063d6032014-10-09 11:01:1312831 bool using_proxy) override {
Adam Rice425cf122015-01-19 06:18:2412832 return new FakeWebSocketBasicHandshakeStream(connection.Pass(),
12833 using_proxy);
[email protected]831e4a32013-11-14 02:14:4412834 }
12835
dchengb03027d2014-10-21 12:00:2012836 WebSocketHandshakeStreamBase* CreateSpdyStream(
[email protected]831e4a32013-11-14 02:14:4412837 const base::WeakPtr<SpdySession>& session,
mostynbba063d6032014-10-09 11:01:1312838 bool use_relative_url) override {
[email protected]831e4a32013-11-14 02:14:4412839 NOTREACHED();
12840 return NULL;
12841 };
12842
dchengb03027d2014-10-21 12:00:2012843 ~FakeWebSocketStreamCreateHelper() override {}
[email protected]831e4a32013-11-14 02:14:4412844
12845 virtual scoped_ptr<WebSocketStream> Upgrade() {
12846 NOTREACHED();
12847 return scoped_ptr<WebSocketStream>();
12848 }
12849};
12850
[email protected]bf828982013-08-14 18:01:4712851} // namespace
12852
12853// Make sure that HttpNetworkTransaction passes on its priority to its
12854// stream request on start.
12855TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
12856 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12857 HttpNetworkSessionPeer peer(session);
12858 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4412859 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4712860
dcheng48459ac22014-08-26 00:46:4112861 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4712862
12863 ASSERT_TRUE(fake_factory->last_stream_request() == NULL);
12864
12865 HttpRequestInfo request;
12866 TestCompletionCallback callback;
12867 EXPECT_EQ(ERR_IO_PENDING,
12868 trans.Start(&request, callback.callback(), BoundNetLog()));
12869
12870 base::WeakPtr<FakeStreamRequest> fake_request =
12871 fake_factory->last_stream_request();
12872 ASSERT_TRUE(fake_request != NULL);
12873 EXPECT_EQ(LOW, fake_request->priority());
12874}
12875
12876// Make sure that HttpNetworkTransaction passes on its priority
12877// updates to its stream request.
12878TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriority) {
12879 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12880 HttpNetworkSessionPeer peer(session);
12881 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4412882 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4712883
dcheng48459ac22014-08-26 00:46:4112884 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4712885
12886 HttpRequestInfo request;
12887 TestCompletionCallback callback;
12888 EXPECT_EQ(ERR_IO_PENDING,
12889 trans.Start(&request, callback.callback(), BoundNetLog()));
12890
12891 base::WeakPtr<FakeStreamRequest> fake_request =
12892 fake_factory->last_stream_request();
12893 ASSERT_TRUE(fake_request != NULL);
12894 EXPECT_EQ(LOW, fake_request->priority());
12895
12896 trans.SetPriority(LOWEST);
12897 ASSERT_TRUE(fake_request != NULL);
12898 EXPECT_EQ(LOWEST, fake_request->priority());
12899}
12900
[email protected]e86839fd2013-08-14 18:29:0312901// Make sure that HttpNetworkTransaction passes on its priority
12902// updates to its stream.
12903TEST_P(HttpNetworkTransactionTest, SetStreamPriority) {
12904 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12905 HttpNetworkSessionPeer peer(session);
12906 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4412907 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]e86839fd2013-08-14 18:29:0312908
dcheng48459ac22014-08-26 00:46:4112909 HttpNetworkTransaction trans(LOW, session.get());
[email protected]e86839fd2013-08-14 18:29:0312910
12911 HttpRequestInfo request;
12912 TestCompletionCallback callback;
12913 EXPECT_EQ(ERR_IO_PENDING,
12914 trans.Start(&request, callback.callback(), BoundNetLog()));
12915
12916 base::WeakPtr<FakeStreamRequest> fake_request =
12917 fake_factory->last_stream_request();
12918 ASSERT_TRUE(fake_request != NULL);
12919 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
12920 ASSERT_TRUE(fake_stream != NULL);
12921 EXPECT_EQ(LOW, fake_stream->priority());
12922
12923 trans.SetPriority(LOWEST);
12924 EXPECT_EQ(LOWEST, fake_stream->priority());
12925}
12926
[email protected]831e4a32013-11-14 02:14:4412927TEST_P(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
12928 // The same logic needs to be tested for both ws: and wss: schemes, but this
12929 // test is already parameterised on NextProto, so it uses a loop to verify
12930 // that the different schemes work.
12931 std::string test_cases[] = {"ws://www.google.com/", "wss://www.google.com/"};
12932 for (size_t i = 0; i < arraysize(test_cases); ++i) {
12933 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12934 HttpNetworkSessionPeer peer(session);
12935 FakeStreamFactory* fake_factory = new FakeStreamFactory();
12936 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
[email protected]0191b51c2013-11-18 10:55:2312937 peer.SetHttpStreamFactoryForWebSocket(
[email protected]831e4a32013-11-14 02:14:4412938 scoped_ptr<HttpStreamFactory>(fake_factory));
12939
dcheng48459ac22014-08-26 00:46:4112940 HttpNetworkTransaction trans(LOW, session.get());
[email protected]831e4a32013-11-14 02:14:4412941 trans.SetWebSocketHandshakeStreamCreateHelper(
12942 &websocket_stream_create_helper);
12943
12944 HttpRequestInfo request;
12945 TestCompletionCallback callback;
12946 request.method = "GET";
12947 request.url = GURL(test_cases[i]);
12948
12949 EXPECT_EQ(ERR_IO_PENDING,
12950 trans.Start(&request, callback.callback(), BoundNetLog()));
12951
12952 base::WeakPtr<FakeStreamRequest> fake_request =
12953 fake_factory->last_stream_request();
12954 ASSERT_TRUE(fake_request != NULL);
12955 EXPECT_EQ(&websocket_stream_create_helper,
12956 fake_request->websocket_stream_create_helper());
12957 }
12958}
12959
[email protected]043b68c82013-08-22 23:41:5212960// Tests that when a used socket is returned to the SSL socket pool, it's closed
12961// if the transport socket pool is stalled on the global socket limit.
12962TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
12963 ClientSocketPoolManager::set_max_sockets_per_group(
12964 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12965 ClientSocketPoolManager::set_max_sockets_per_pool(
12966 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12967
12968 // Set up SSL request.
12969
12970 HttpRequestInfo ssl_request;
12971 ssl_request.method = "GET";
12972 ssl_request.url = GURL("https://www.google.com/");
12973
12974 MockWrite ssl_writes[] = {
12975 MockWrite("GET / HTTP/1.1\r\n"
12976 "Host: www.google.com\r\n"
12977 "Connection: keep-alive\r\n\r\n"),
12978 };
12979 MockRead ssl_reads[] = {
12980 MockRead("HTTP/1.1 200 OK\r\n"),
12981 MockRead("Content-Length: 11\r\n\r\n"),
12982 MockRead("hello world"),
12983 MockRead(SYNCHRONOUS, OK),
12984 };
12985 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
12986 ssl_writes, arraysize(ssl_writes));
12987 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
12988
12989 SSLSocketDataProvider ssl(ASYNC, OK);
12990 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12991
12992 // Set up HTTP request.
12993
12994 HttpRequestInfo http_request;
12995 http_request.method = "GET";
12996 http_request.url = GURL("http://www.google.com/");
12997
12998 MockWrite http_writes[] = {
12999 MockWrite("GET / HTTP/1.1\r\n"
13000 "Host: www.google.com\r\n"
13001 "Connection: keep-alive\r\n\r\n"),
13002 };
13003 MockRead http_reads[] = {
13004 MockRead("HTTP/1.1 200 OK\r\n"),
13005 MockRead("Content-Length: 7\r\n\r\n"),
13006 MockRead("falafel"),
13007 MockRead(SYNCHRONOUS, OK),
13008 };
13009 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
13010 http_writes, arraysize(http_writes));
13011 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13012
13013 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13014
13015 // Start the SSL request.
13016 TestCompletionCallback ssl_callback;
13017 scoped_ptr<HttpTransaction> ssl_trans(
13018 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13019 ASSERT_EQ(ERR_IO_PENDING,
13020 ssl_trans->Start(&ssl_request, ssl_callback.callback(),
13021 BoundNetLog()));
13022
13023 // Start the HTTP request. Pool should stall.
13024 TestCompletionCallback http_callback;
13025 scoped_ptr<HttpTransaction> http_trans(
13026 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13027 ASSERT_EQ(ERR_IO_PENDING,
13028 http_trans->Start(&http_request, http_callback.callback(),
13029 BoundNetLog()));
dcheng48459ac22014-08-26 00:46:4113030 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5213031
13032 // Wait for response from SSL request.
13033 ASSERT_EQ(OK, ssl_callback.WaitForResult());
13034 std::string response_data;
13035 ASSERT_EQ(OK, ReadTransaction(ssl_trans.get(), &response_data));
13036 EXPECT_EQ("hello world", response_data);
13037
13038 // The SSL socket should automatically be closed, so the HTTP request can
13039 // start.
dcheng48459ac22014-08-26 00:46:4113040 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
13041 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5213042
13043 // The HTTP request can now complete.
13044 ASSERT_EQ(OK, http_callback.WaitForResult());
13045 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
13046 EXPECT_EQ("falafel", response_data);
13047
dcheng48459ac22014-08-26 00:46:4113048 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5213049}
13050
13051// Tests that when a SSL connection is established but there's no corresponding
13052// request that needs it, the new socket is closed if the transport socket pool
13053// is stalled on the global socket limit.
13054TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
13055 ClientSocketPoolManager::set_max_sockets_per_group(
13056 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13057 ClientSocketPoolManager::set_max_sockets_per_pool(
13058 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13059
13060 // Set up an ssl request.
13061
13062 HttpRequestInfo ssl_request;
13063 ssl_request.method = "GET";
13064 ssl_request.url = GURL("https://www.foopy.com/");
13065
13066 // No data will be sent on the SSL socket.
13067 StaticSocketDataProvider ssl_data;
13068 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
13069
13070 SSLSocketDataProvider ssl(ASYNC, OK);
13071 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13072
13073 // Set up HTTP request.
13074
13075 HttpRequestInfo http_request;
13076 http_request.method = "GET";
13077 http_request.url = GURL("http://www.google.com/");
13078
13079 MockWrite http_writes[] = {
13080 MockWrite("GET / HTTP/1.1\r\n"
13081 "Host: www.google.com\r\n"
13082 "Connection: keep-alive\r\n\r\n"),
13083 };
13084 MockRead http_reads[] = {
13085 MockRead("HTTP/1.1 200 OK\r\n"),
13086 MockRead("Content-Length: 7\r\n\r\n"),
13087 MockRead("falafel"),
13088 MockRead(SYNCHRONOUS, OK),
13089 };
13090 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
13091 http_writes, arraysize(http_writes));
13092 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13093
13094 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13095
13096 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
13097 // cancelled when a normal transaction is cancelled.
13098 net::HttpStreamFactory* http_stream_factory = session->http_stream_factory();
13099 net::SSLConfig ssl_config;
13100 session->ssl_config_service()->GetSSLConfig(&ssl_config);
13101 http_stream_factory->PreconnectStreams(1, ssl_request, DEFAULT_PRIORITY,
13102 ssl_config, ssl_config);
dcheng48459ac22014-08-26 00:46:4113103 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5213104
13105 // Start the HTTP request. Pool should stall.
13106 TestCompletionCallback http_callback;
13107 scoped_ptr<HttpTransaction> http_trans(
13108 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13109 ASSERT_EQ(ERR_IO_PENDING,
13110 http_trans->Start(&http_request, http_callback.callback(),
13111 BoundNetLog()));
dcheng48459ac22014-08-26 00:46:4113112 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5213113
13114 // The SSL connection will automatically be closed once the connection is
13115 // established, to let the HTTP request start.
13116 ASSERT_EQ(OK, http_callback.WaitForResult());
13117 std::string response_data;
13118 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
13119 EXPECT_EQ("falafel", response_data);
13120
dcheng48459ac22014-08-26 00:46:4113121 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5213122}
13123
[email protected]02d74a02014-04-23 18:10:5413124TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
13125 ScopedVector<UploadElementReader> element_readers;
13126 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713127 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413128
13129 HttpRequestInfo request;
13130 request.method = "POST";
13131 request.url = GURL("http://www.foo.com/");
13132 request.upload_data_stream = &upload_data_stream;
13133 request.load_flags = 0;
13134
13135 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13136 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113137 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413138 // Send headers successfully, but get an error while sending the body.
13139 MockWrite data_writes[] = {
13140 MockWrite("POST / HTTP/1.1\r\n"
13141 "Host: www.foo.com\r\n"
13142 "Connection: keep-alive\r\n"
13143 "Content-Length: 3\r\n\r\n"),
13144 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13145 };
13146
13147 MockRead data_reads[] = {
13148 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
13149 MockRead("hello world"),
13150 MockRead(SYNCHRONOUS, OK),
13151 };
13152 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13153 arraysize(data_writes));
13154 session_deps_.socket_factory->AddSocketDataProvider(&data);
13155
13156 TestCompletionCallback callback;
13157
13158 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13159 EXPECT_EQ(ERR_IO_PENDING, rv);
13160
13161 rv = callback.WaitForResult();
13162 EXPECT_EQ(OK, rv);
13163
13164 const HttpResponseInfo* response = trans->GetResponseInfo();
13165 ASSERT_TRUE(response != NULL);
13166
13167 EXPECT_TRUE(response->headers.get() != NULL);
13168 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
13169
13170 std::string response_data;
13171 rv = ReadTransaction(trans.get(), &response_data);
13172 EXPECT_EQ(OK, rv);
13173 EXPECT_EQ("hello world", response_data);
13174}
13175
13176// This test makes sure the retry logic doesn't trigger when reading an error
13177// response from a server that rejected a POST with a CONNECTION_RESET.
13178TEST_P(HttpNetworkTransactionTest,
13179 PostReadsErrorResponseAfterResetOnReusedSocket) {
13180 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13181 MockWrite data_writes[] = {
13182 MockWrite("GET / HTTP/1.1\r\n"
13183 "Host: www.foo.com\r\n"
13184 "Connection: keep-alive\r\n\r\n"),
13185 MockWrite("POST / HTTP/1.1\r\n"
13186 "Host: www.foo.com\r\n"
13187 "Connection: keep-alive\r\n"
13188 "Content-Length: 3\r\n\r\n"),
13189 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13190 };
13191
13192 MockRead data_reads[] = {
13193 MockRead("HTTP/1.1 200 Peachy\r\n"
13194 "Content-Length: 14\r\n\r\n"),
13195 MockRead("first response"),
13196 MockRead("HTTP/1.1 400 Not OK\r\n"
13197 "Content-Length: 15\r\n\r\n"),
13198 MockRead("second response"),
13199 MockRead(SYNCHRONOUS, OK),
13200 };
13201 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13202 arraysize(data_writes));
13203 session_deps_.socket_factory->AddSocketDataProvider(&data);
13204
13205 TestCompletionCallback callback;
13206 HttpRequestInfo request1;
13207 request1.method = "GET";
13208 request1.url = GURL("http://www.foo.com/");
13209 request1.load_flags = 0;
13210
13211 scoped_ptr<HttpTransaction> trans1(
dcheng48459ac22014-08-26 00:46:4113212 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413213 int rv = trans1->Start(&request1, callback.callback(), BoundNetLog());
13214 EXPECT_EQ(ERR_IO_PENDING, rv);
13215
13216 rv = callback.WaitForResult();
13217 EXPECT_EQ(OK, rv);
13218
13219 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
13220 ASSERT_TRUE(response1 != NULL);
13221
13222 EXPECT_TRUE(response1->headers.get() != NULL);
13223 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
13224
13225 std::string response_data1;
13226 rv = ReadTransaction(trans1.get(), &response_data1);
13227 EXPECT_EQ(OK, rv);
13228 EXPECT_EQ("first response", response_data1);
13229 // Delete the transaction to release the socket back into the socket pool.
13230 trans1.reset();
13231
13232 ScopedVector<UploadElementReader> element_readers;
13233 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713234 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413235
13236 HttpRequestInfo request2;
13237 request2.method = "POST";
13238 request2.url = GURL("http://www.foo.com/");
13239 request2.upload_data_stream = &upload_data_stream;
13240 request2.load_flags = 0;
13241
13242 scoped_ptr<HttpTransaction> trans2(
dcheng48459ac22014-08-26 00:46:4113243 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413244 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
13245 EXPECT_EQ(ERR_IO_PENDING, rv);
13246
13247 rv = callback.WaitForResult();
13248 EXPECT_EQ(OK, rv);
13249
13250 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
13251 ASSERT_TRUE(response2 != NULL);
13252
13253 EXPECT_TRUE(response2->headers.get() != NULL);
13254 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
13255
13256 std::string response_data2;
13257 rv = ReadTransaction(trans2.get(), &response_data2);
13258 EXPECT_EQ(OK, rv);
13259 EXPECT_EQ("second response", response_data2);
13260}
13261
13262TEST_P(HttpNetworkTransactionTest,
13263 PostReadsErrorResponseAfterResetPartialBodySent) {
13264 ScopedVector<UploadElementReader> element_readers;
13265 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713266 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413267
13268 HttpRequestInfo request;
13269 request.method = "POST";
13270 request.url = GURL("http://www.foo.com/");
13271 request.upload_data_stream = &upload_data_stream;
13272 request.load_flags = 0;
13273
13274 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13275 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113276 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413277 // Send headers successfully, but get an error while sending the body.
13278 MockWrite data_writes[] = {
13279 MockWrite("POST / HTTP/1.1\r\n"
13280 "Host: www.foo.com\r\n"
13281 "Connection: keep-alive\r\n"
13282 "Content-Length: 3\r\n\r\n"
13283 "fo"),
13284 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13285 };
13286
13287 MockRead data_reads[] = {
13288 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
13289 MockRead("hello world"),
13290 MockRead(SYNCHRONOUS, OK),
13291 };
13292 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13293 arraysize(data_writes));
13294 session_deps_.socket_factory->AddSocketDataProvider(&data);
13295
13296 TestCompletionCallback callback;
13297
13298 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13299 EXPECT_EQ(ERR_IO_PENDING, rv);
13300
13301 rv = callback.WaitForResult();
13302 EXPECT_EQ(OK, rv);
13303
13304 const HttpResponseInfo* response = trans->GetResponseInfo();
13305 ASSERT_TRUE(response != NULL);
13306
13307 EXPECT_TRUE(response->headers.get() != NULL);
13308 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
13309
13310 std::string response_data;
13311 rv = ReadTransaction(trans.get(), &response_data);
13312 EXPECT_EQ(OK, rv);
13313 EXPECT_EQ("hello world", response_data);
13314}
13315
13316// This tests the more common case than the previous test, where headers and
13317// body are not merged into a single request.
13318TEST_P(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
13319 ScopedVector<UploadElementReader> element_readers;
13320 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713321 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5413322
13323 HttpRequestInfo request;
13324 request.method = "POST";
13325 request.url = GURL("http://www.foo.com/");
13326 request.upload_data_stream = &upload_data_stream;
13327 request.load_flags = 0;
13328
13329 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13330 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113331 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413332 // Send headers successfully, but get an error while sending the body.
13333 MockWrite data_writes[] = {
13334 MockWrite("POST / HTTP/1.1\r\n"
13335 "Host: www.foo.com\r\n"
13336 "Connection: keep-alive\r\n"
13337 "Transfer-Encoding: chunked\r\n\r\n"),
13338 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13339 };
13340
13341 MockRead data_reads[] = {
13342 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
13343 MockRead("hello world"),
13344 MockRead(SYNCHRONOUS, OK),
13345 };
13346 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13347 arraysize(data_writes));
13348 session_deps_.socket_factory->AddSocketDataProvider(&data);
13349
13350 TestCompletionCallback callback;
13351
13352 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13353 EXPECT_EQ(ERR_IO_PENDING, rv);
13354 // Make sure the headers are sent before adding a chunk. This ensures that
13355 // they can't be merged with the body in a single send. Not currently
13356 // necessary since a chunked body is never merged with headers, but this makes
13357 // the test more future proof.
13358 base::RunLoop().RunUntilIdle();
13359
mmenkecbc2b712014-10-09 20:29:0713360 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5413361
13362 rv = callback.WaitForResult();
13363 EXPECT_EQ(OK, rv);
13364
13365 const HttpResponseInfo* response = trans->GetResponseInfo();
13366 ASSERT_TRUE(response != NULL);
13367
13368 EXPECT_TRUE(response->headers.get() != NULL);
13369 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
13370
13371 std::string response_data;
13372 rv = ReadTransaction(trans.get(), &response_data);
13373 EXPECT_EQ(OK, rv);
13374 EXPECT_EQ("hello world", response_data);
13375}
13376
13377TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
13378 ScopedVector<UploadElementReader> element_readers;
13379 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713380 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413381
13382 HttpRequestInfo request;
13383 request.method = "POST";
13384 request.url = GURL("http://www.foo.com/");
13385 request.upload_data_stream = &upload_data_stream;
13386 request.load_flags = 0;
13387
13388 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13389 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113390 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413391
13392 MockWrite data_writes[] = {
13393 MockWrite("POST / HTTP/1.1\r\n"
13394 "Host: www.foo.com\r\n"
13395 "Connection: keep-alive\r\n"
13396 "Content-Length: 3\r\n\r\n"),
13397 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13398 };
13399
13400 MockRead data_reads[] = {
13401 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
13402 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
13403 MockRead("hello world"),
13404 MockRead(SYNCHRONOUS, OK),
13405 };
13406 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13407 arraysize(data_writes));
13408 session_deps_.socket_factory->AddSocketDataProvider(&data);
13409
13410 TestCompletionCallback callback;
13411
13412 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13413 EXPECT_EQ(ERR_IO_PENDING, rv);
13414
13415 rv = callback.WaitForResult();
13416 EXPECT_EQ(OK, rv);
13417
13418 const HttpResponseInfo* response = trans->GetResponseInfo();
13419 ASSERT_TRUE(response != NULL);
13420
13421 EXPECT_TRUE(response->headers.get() != NULL);
13422 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
13423
13424 std::string response_data;
13425 rv = ReadTransaction(trans.get(), &response_data);
13426 EXPECT_EQ(OK, rv);
13427 EXPECT_EQ("hello world", response_data);
13428}
13429
13430TEST_P(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
13431 ScopedVector<UploadElementReader> element_readers;
13432 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713433 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413434
13435 HttpRequestInfo request;
13436 request.method = "POST";
13437 request.url = GURL("http://www.foo.com/");
13438 request.upload_data_stream = &upload_data_stream;
13439 request.load_flags = 0;
13440
13441 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13442 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113443 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413444 // Send headers successfully, but get an error while sending the body.
13445 MockWrite data_writes[] = {
13446 MockWrite("POST / HTTP/1.1\r\n"
13447 "Host: www.foo.com\r\n"
13448 "Connection: keep-alive\r\n"
13449 "Content-Length: 3\r\n\r\n"),
13450 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13451 };
13452
13453 MockRead data_reads[] = {
13454 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
13455 MockRead("hello world"),
13456 MockRead(SYNCHRONOUS, OK),
13457 };
13458 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13459 arraysize(data_writes));
13460 session_deps_.socket_factory->AddSocketDataProvider(&data);
13461
13462 TestCompletionCallback callback;
13463
13464 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13465 EXPECT_EQ(ERR_IO_PENDING, rv);
13466
13467 rv = callback.WaitForResult();
13468 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13469
13470 const HttpResponseInfo* response = trans->GetResponseInfo();
13471 EXPECT_TRUE(response == NULL);
13472}
13473
13474TEST_P(HttpNetworkTransactionTest,
13475 PostIgnoresNonErrorResponseAfterResetAnd100) {
13476 ScopedVector<UploadElementReader> element_readers;
13477 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713478 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413479
13480 HttpRequestInfo request;
13481 request.method = "POST";
13482 request.url = GURL("http://www.foo.com/");
13483 request.upload_data_stream = &upload_data_stream;
13484 request.load_flags = 0;
13485
13486 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13487 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113488 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413489 // Send headers successfully, but get an error while sending the body.
13490 MockWrite data_writes[] = {
13491 MockWrite("POST / HTTP/1.1\r\n"
13492 "Host: www.foo.com\r\n"
13493 "Connection: keep-alive\r\n"
13494 "Content-Length: 3\r\n\r\n"),
13495 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13496 };
13497
13498 MockRead data_reads[] = {
13499 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
13500 MockRead("HTTP/1.0 302 Redirect\r\n"),
13501 MockRead("Location: http://somewhere-else.com/\r\n"),
13502 MockRead("Content-Length: 0\r\n\r\n"),
13503 MockRead(SYNCHRONOUS, OK),
13504 };
13505 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13506 arraysize(data_writes));
13507 session_deps_.socket_factory->AddSocketDataProvider(&data);
13508
13509 TestCompletionCallback callback;
13510
13511 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13512 EXPECT_EQ(ERR_IO_PENDING, rv);
13513
13514 rv = callback.WaitForResult();
13515 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13516
13517 const HttpResponseInfo* response = trans->GetResponseInfo();
13518 EXPECT_TRUE(response == NULL);
13519}
13520
13521TEST_P(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
13522 ScopedVector<UploadElementReader> element_readers;
13523 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713524 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413525
13526 HttpRequestInfo request;
13527 request.method = "POST";
13528 request.url = GURL("http://www.foo.com/");
13529 request.upload_data_stream = &upload_data_stream;
13530 request.load_flags = 0;
13531
13532 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13533 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113534 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413535 // Send headers successfully, but get an error while sending the body.
13536 MockWrite data_writes[] = {
13537 MockWrite("POST / HTTP/1.1\r\n"
13538 "Host: www.foo.com\r\n"
13539 "Connection: keep-alive\r\n"
13540 "Content-Length: 3\r\n\r\n"),
13541 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13542 };
13543
13544 MockRead data_reads[] = {
13545 MockRead("HTTP 0.9 rocks!"),
13546 MockRead(SYNCHRONOUS, OK),
13547 };
13548 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13549 arraysize(data_writes));
13550 session_deps_.socket_factory->AddSocketDataProvider(&data);
13551
13552 TestCompletionCallback callback;
13553
13554 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13555 EXPECT_EQ(ERR_IO_PENDING, rv);
13556
13557 rv = callback.WaitForResult();
13558 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13559
13560 const HttpResponseInfo* response = trans->GetResponseInfo();
13561 EXPECT_TRUE(response == NULL);
13562}
13563
13564TEST_P(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
13565 ScopedVector<UploadElementReader> element_readers;
13566 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713567 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413568
13569 HttpRequestInfo request;
13570 request.method = "POST";
13571 request.url = GURL("http://www.foo.com/");
13572 request.upload_data_stream = &upload_data_stream;
13573 request.load_flags = 0;
13574
13575 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13576 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113577 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413578 // Send headers successfully, but get an error while sending the body.
13579 MockWrite data_writes[] = {
13580 MockWrite("POST / HTTP/1.1\r\n"
13581 "Host: www.foo.com\r\n"
13582 "Connection: keep-alive\r\n"
13583 "Content-Length: 3\r\n\r\n"),
13584 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13585 };
13586
13587 MockRead data_reads[] = {
13588 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
13589 MockRead(SYNCHRONOUS, OK),
13590 };
13591 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13592 arraysize(data_writes));
13593 session_deps_.socket_factory->AddSocketDataProvider(&data);
13594
13595 TestCompletionCallback callback;
13596
13597 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13598 EXPECT_EQ(ERR_IO_PENDING, rv);
13599
13600 rv = callback.WaitForResult();
13601 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13602
13603 const HttpResponseInfo* response = trans->GetResponseInfo();
13604 EXPECT_TRUE(response == NULL);
13605}
13606
Adam Rice425cf122015-01-19 06:18:2413607// Verify that proxy headers are not sent to the destination server when
13608// establishing a tunnel for a secure WebSocket connection.
13609TEST_P(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
13610 HttpRequestInfo request;
13611 request.method = "GET";
13612 request.url = GURL("wss://www.google.com/");
13613 AddWebSocketHeaders(&request.extra_headers);
13614
13615 // Configure against proxy server "myproxy:70".
13616 session_deps_.proxy_service.reset(
13617 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
13618
13619 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13620
13621 // Since a proxy is configured, try to establish a tunnel.
13622 MockWrite data_writes[] = {
13623 MockWrite(
13624 "CONNECT www.google.com:443 HTTP/1.1\r\n"
13625 "Host: www.google.com\r\n"
13626 "Proxy-Connection: keep-alive\r\n\r\n"),
13627
13628 // After calling trans->RestartWithAuth(), this is the request we should
13629 // be issuing -- the final header line contains the credentials.
13630 MockWrite(
13631 "CONNECT www.google.com:443 HTTP/1.1\r\n"
13632 "Host: www.google.com\r\n"
13633 "Proxy-Connection: keep-alive\r\n"
13634 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
13635
13636 MockWrite(
13637 "GET / HTTP/1.1\r\n"
13638 "Host: www.google.com\r\n"
13639 "Connection: Upgrade\r\n"
13640 "Upgrade: websocket\r\n"
13641 "Origin: http://www.google.com\r\n"
13642 "Sec-WebSocket-Version: 13\r\n"
13643 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
13644 };
13645
13646 // The proxy responds to the connect with a 407, using a persistent
13647 // connection.
13648 MockRead data_reads[] = {
13649 // No credentials.
13650 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
13651 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
13652 MockRead("Proxy-Connection: close\r\n\r\n"),
13653
13654 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
13655
13656 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
13657 MockRead("Upgrade: websocket\r\n"),
13658 MockRead("Connection: Upgrade\r\n"),
13659 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
13660 };
13661
13662 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13663 arraysize(data_writes));
13664 session_deps_.socket_factory->AddSocketDataProvider(&data);
13665 SSLSocketDataProvider ssl(ASYNC, OK);
13666 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13667
13668 scoped_ptr<HttpTransaction> trans(
13669 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13670 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
13671 trans->SetWebSocketHandshakeStreamCreateHelper(
13672 &websocket_stream_create_helper);
13673
13674 {
13675 TestCompletionCallback callback;
13676
13677 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13678 EXPECT_EQ(ERR_IO_PENDING, rv);
13679
13680 rv = callback.WaitForResult();
13681 EXPECT_EQ(OK, rv);
13682 }
13683
13684 const HttpResponseInfo* response = trans->GetResponseInfo();
13685 ASSERT_TRUE(response);
13686 ASSERT_TRUE(response->headers.get());
13687 EXPECT_EQ(407, response->headers->response_code());
13688
13689 {
13690 TestCompletionCallback callback;
13691
13692 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
13693 callback.callback());
13694 EXPECT_EQ(ERR_IO_PENDING, rv);
13695
13696 rv = callback.WaitForResult();
13697 EXPECT_EQ(OK, rv);
13698 }
13699
13700 response = trans->GetResponseInfo();
13701 ASSERT_TRUE(response);
13702 ASSERT_TRUE(response->headers.get());
13703
13704 EXPECT_EQ(101, response->headers->response_code());
13705
13706 trans.reset();
13707 session->CloseAllConnections();
13708}
13709
13710// Verify that proxy headers are not sent to the destination server when
13711// establishing a tunnel for an insecure WebSocket connection.
13712// This requires the authentication info to be injected into the auth cache
13713// due to crbug.com/395064
13714// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
13715TEST_P(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
13716 HttpRequestInfo request;
13717 request.method = "GET";
13718 request.url = GURL("ws://www.google.com/");
13719 AddWebSocketHeaders(&request.extra_headers);
13720
13721 // Configure against proxy server "myproxy:70".
13722 session_deps_.proxy_service.reset(
13723 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
13724
13725 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13726
13727 MockWrite data_writes[] = {
13728 // Try to establish a tunnel for the WebSocket connection, with
13729 // credentials. Because WebSockets have a separate set of socket pools,
13730 // they cannot and will not use the same TCP/IP connection as the
13731 // preflight HTTP request.
13732 MockWrite(
13733 "CONNECT www.google.com:80 HTTP/1.1\r\n"
13734 "Host: www.google.com\r\n"
13735 "Proxy-Connection: keep-alive\r\n"
13736 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
13737
13738 MockWrite(
13739 "GET / HTTP/1.1\r\n"
13740 "Host: www.google.com\r\n"
13741 "Connection: Upgrade\r\n"
13742 "Upgrade: websocket\r\n"
13743 "Origin: http://www.google.com\r\n"
13744 "Sec-WebSocket-Version: 13\r\n"
13745 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
13746 };
13747
13748 MockRead data_reads[] = {
13749 // HTTP CONNECT with credentials.
13750 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
13751
13752 // WebSocket connection established inside tunnel.
13753 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
13754 MockRead("Upgrade: websocket\r\n"),
13755 MockRead("Connection: Upgrade\r\n"),
13756 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
13757 };
13758
13759 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13760 arraysize(data_writes));
13761 session_deps_.socket_factory->AddSocketDataProvider(&data);
13762
13763 session->http_auth_cache()->Add(
13764 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
13765 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
13766
13767 scoped_ptr<HttpTransaction> trans(
13768 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13769 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
13770 trans->SetWebSocketHandshakeStreamCreateHelper(
13771 &websocket_stream_create_helper);
13772
13773 TestCompletionCallback callback;
13774
13775 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13776 EXPECT_EQ(ERR_IO_PENDING, rv);
13777
13778 rv = callback.WaitForResult();
13779 EXPECT_EQ(OK, rv);
13780
13781 const HttpResponseInfo* response = trans->GetResponseInfo();
13782 ASSERT_TRUE(response);
13783 ASSERT_TRUE(response->headers.get());
13784
13785 EXPECT_EQ(101, response->headers->response_code());
13786
13787 trans.reset();
13788 session->CloseAllConnections();
13789}
13790
[email protected]89ceba9a2009-03-21 03:46:0613791} // namespace net