blob: be94493558b4b68e045781d923632249df4c4c27 [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"
[email protected]3b63f8f42011-03-28 01:54:1517#include "base/memory/scoped_ptr.h"
[email protected]bf828982013-08-14 18:01:4718#include "base/memory/weak_ptr.h"
[email protected]a34f61ee2014-03-18 20:59:4919#include "base/run_loop.h"
[email protected]125ef482013-06-11 18:32:4720#include "base/strings/string_util.h"
[email protected]750b2f3c2013-06-07 18:41:0521#include "base/strings/utf_string_conversions.h"
[email protected]f36a8132011-09-02 18:36:3322#include "base/test/test_file_util.h"
[email protected]277d5942010-08-11 21:02:3523#include "net/base/auth.h"
[email protected]169d0012010-05-10 23:20:1224#include "net/base/capturing_net_log.h"
mmenkecbc2b712014-10-09 20:29:0725#include "net/base/chunked_upload_data_stream.h"
[email protected]bacff652009-03-31 17:50:3326#include "net/base/completion_callback.h"
mmenkecbc2b712014-10-09 20:29:0727#include "net/base/elements_upload_data_stream.h"
[email protected]58e32bb2013-01-21 18:23:2528#include "net/base/load_timing_info.h"
29#include "net/base/load_timing_info_test_util.h"
[email protected]169d0012010-05-10 23:20:1230#include "net/base/net_log.h"
31#include "net/base/net_log_unittest.h"
[email protected]ac790b42009-12-02 04:31:3132#include "net/base/request_priority.h"
initial.commit586acc5fe2008-07-26 22:42:5233#include "net/base/test_completion_callback.h"
[email protected]42fdb452012-11-01 12:44:4034#include "net/base/test_data_directory.h"
[email protected]b2d26cfd2012-12-11 10:36:0635#include "net/base/upload_bytes_element_reader.h"
[email protected]d98961652012-09-11 20:27:2136#include "net/base/upload_file_element_reader.h"
[email protected]6e7845ae2013-03-29 21:48:1137#include "net/cert/mock_cert_verifier.h"
[email protected]bc71b8772013-04-10 20:55:1638#include "net/dns/host_cache.h"
[email protected]f2cb3cf2013-03-21 01:40:5339#include "net/dns/mock_host_resolver.h"
[email protected]df41d0d82014-03-13 00:43:2440#include "net/http/http_auth_challenge_tokenizer.h"
[email protected]3c32c5f2010-05-18 15:18:1241#include "net/http/http_auth_handler_digest.h"
[email protected]3fd9dae2010-06-21 11:39:0042#include "net/http/http_auth_handler_mock.h"
[email protected]385a4672009-03-11 22:21:2943#include "net/http/http_auth_handler_ntlm.h"
[email protected]0877e3d2009-10-17 22:29:5744#include "net/http/http_basic_stream.h"
initial.commit586acc5fe2008-07-26 22:42:5245#include "net/http/http_network_session.h"
[email protected]87bfa3f2010-09-30 14:54:5646#include "net/http/http_network_session_peer.h"
[email protected]17291a022011-10-10 07:32:5347#include "net/http/http_server_properties_impl.h"
[email protected]0877e3d2009-10-17 22:29:5748#include "net/http/http_stream.h"
[email protected]8e6441ca2010-08-19 05:56:3849#include "net/http/http_stream_factory.h"
[email protected]c41737d2014-05-14 07:47:1950#include "net/http/http_transaction_test_util.h"
[email protected]51fff29d2008-12-19 22:17:5351#include "net/proxy/proxy_config_service_fixed.h"
[email protected]e86839fd2013-08-14 18:29:0352#include "net/proxy/proxy_info.h"
[email protected]631f1322010-04-30 17:59:1153#include "net/proxy/proxy_resolver.h"
54#include "net/proxy/proxy_service.h"
[email protected]f7984fc62009-06-22 23:26:4455#include "net/socket/client_socket_factory.h"
[email protected]483fa202013-05-14 01:07:0356#include "net/socket/client_socket_pool_manager.h"
[email protected]a42dbd142011-11-17 16:42:0257#include "net/socket/mock_client_socket_pool_manager.h"
[email protected]bb88e1d32013-05-03 23:11:0758#include "net/socket/next_proto.h"
[email protected]f7984fc62009-06-22 23:26:4459#include "net/socket/socket_test_util.h"
60#include "net/socket/ssl_client_socket.h"
[email protected]2ff8b312010-04-26 22:20:5461#include "net/spdy/spdy_framer.h"
62#include "net/spdy/spdy_session.h"
63#include "net/spdy/spdy_session_pool.h"
[email protected]23e482282013-06-14 16:08:0264#include "net/spdy/spdy_test_util_common.h"
[email protected]536fd0b2013-03-14 17:41:5765#include "net/ssl/ssl_cert_request_info.h"
[email protected]e86839fd2013-08-14 18:29:0366#include "net/ssl/ssl_config_service.h"
[email protected]536fd0b2013-03-14 17:41:5767#include "net/ssl/ssl_config_service_defaults.h"
68#include "net/ssl/ssl_info.h"
[email protected]6e7845ae2013-03-29 21:48:1169#include "net/test/cert_test_util.h"
[email protected]831e4a32013-11-14 02:14:4470#include "net/websockets/websocket_handshake_stream_base.h"
initial.commit586acc5fe2008-07-26 22:42:5271#include "testing/gtest/include/gtest/gtest.h"
[email protected]23887f04f2008-12-02 19:20:1572#include "testing/platform_test.h"
[email protected]795cbf82013-07-22 09:37:2773#include "url/gurl.h"
initial.commit586acc5fe2008-07-26 22:42:5274
[email protected]ad65a3e2013-12-25 18:18:0175using base::ASCIIToUTF16;
76
initial.commit586acc5fe2008-07-26 22:42:5277//-----------------------------------------------------------------------------
78
[email protected]13c8a092010-07-29 06:15:4479namespace {
80
[email protected]42cba2fb2013-03-29 19:58:5781const base::string16 kBar(ASCIIToUTF16("bar"));
82const base::string16 kBar2(ASCIIToUTF16("bar2"));
83const base::string16 kBar3(ASCIIToUTF16("bar3"));
84const base::string16 kBaz(ASCIIToUTF16("baz"));
85const base::string16 kFirst(ASCIIToUTF16("first"));
86const base::string16 kFoo(ASCIIToUTF16("foo"));
87const base::string16 kFoo2(ASCIIToUTF16("foo2"));
88const base::string16 kFoo3(ASCIIToUTF16("foo3"));
89const base::string16 kFou(ASCIIToUTF16("fou"));
90const base::string16 kSecond(ASCIIToUTF16("second"));
91const base::string16 kTestingNTLM(ASCIIToUTF16("testing-ntlm"));
92const base::string16 kWrongPassword(ASCIIToUTF16("wrongpassword"));
[email protected]13c8a092010-07-29 06:15:4493
[email protected]e5c026642012-03-17 00:14:0294int GetIdleSocketCountInTransportSocketPool(net::HttpNetworkSession* session) {
95 return session->GetTransportSocketPool(
96 net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IdleSocketCount();
97}
98
99int GetIdleSocketCountInSSLSocketPool(net::HttpNetworkSession* session) {
100 return session->GetSSLSocketPool(
101 net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IdleSocketCount();
102}
103
[email protected]043b68c82013-08-22 23:41:52104bool IsTransportSocketPoolStalled(net::HttpNetworkSession* session) {
105 return session->GetTransportSocketPool(
106 net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IsStalled();
107}
108
[email protected]f3da152d2012-06-02 01:00:57109// Takes in a Value created from a NetLogHttpResponseParameter, and returns
110// a JSONified list of headers as a single string. Uses single quotes instead
111// of double quotes for easier comparison. Returns false on failure.
[email protected]ea5ef4c2013-06-13 22:50:27112bool GetHeaders(base::DictionaryValue* params, std::string* headers) {
[email protected]f3da152d2012-06-02 01:00:57113 if (!params)
114 return false;
[email protected]ea5ef4c2013-06-13 22:50:27115 base::ListValue* header_list;
[email protected]f3da152d2012-06-02 01:00:57116 if (!params->GetList("headers", &header_list))
117 return false;
118 std::string double_quote_headers;
119 base::JSONWriter::Write(header_list, &double_quote_headers);
[email protected]466c9862013-12-03 22:05:28120 base::ReplaceChars(double_quote_headers, "\"", "'", headers);
[email protected]f3da152d2012-06-02 01:00:57121 return true;
122}
123
[email protected]029c83b62013-01-24 05:28:20124// Tests LoadTimingInfo in the case a socket is reused and no PAC script is
125// used.
126void TestLoadTimingReused(const net::LoadTimingInfo& load_timing_info) {
127 EXPECT_TRUE(load_timing_info.socket_reused);
[email protected]58e32bb2013-01-21 18:23:25128 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
129
[email protected]029c83b62013-01-24 05:28:20130 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
131 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
132
133 net::ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
134 EXPECT_FALSE(load_timing_info.send_start.is_null());
[email protected]58e32bb2013-01-21 18:23:25135
136 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]58e32bb2013-01-21 18:23:25137
[email protected]3b23a222013-05-15 21:33:25138 // Set at a higher level.
[email protected]58e32bb2013-01-21 18:23:25139 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
140 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25141 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25142}
143
[email protected]029c83b62013-01-24 05:28:20144// Tests LoadTimingInfo in the case a new socket is used and no PAC script is
145// used.
[email protected]58e32bb2013-01-21 18:23:25146void TestLoadTimingNotReused(const net::LoadTimingInfo& load_timing_info,
147 int connect_timing_flags) {
[email protected]029c83b62013-01-24 05:28:20148 EXPECT_FALSE(load_timing_info.socket_reused);
149 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
150
151 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
152 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
153
154 net::ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
[email protected]3b23a222013-05-15 21:33:25155 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20156 EXPECT_LE(load_timing_info.connect_timing.connect_end,
157 load_timing_info.send_start);
158
159 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20160
[email protected]3b23a222013-05-15 21:33:25161 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20162 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
163 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25164 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20165}
166
167// Tests LoadTimingInfo in the case a socket is reused and a PAC script is
168// used.
169void TestLoadTimingReusedWithPac(const net::LoadTimingInfo& load_timing_info) {
170 EXPECT_TRUE(load_timing_info.socket_reused);
171 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
172
173 net::ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
174
175 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
176 EXPECT_LE(load_timing_info.proxy_resolve_start,
177 load_timing_info.proxy_resolve_end);
178 EXPECT_LE(load_timing_info.proxy_resolve_end,
179 load_timing_info.send_start);
180 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20181
[email protected]3b23a222013-05-15 21:33:25182 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20183 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
184 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25185 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20186}
187
188// Tests LoadTimingInfo in the case a new socket is used and a PAC script is
189// used.
190void TestLoadTimingNotReusedWithPac(const net::LoadTimingInfo& load_timing_info,
191 int connect_timing_flags) {
192 EXPECT_FALSE(load_timing_info.socket_reused);
193 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
194
195 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
196 EXPECT_LE(load_timing_info.proxy_resolve_start,
197 load_timing_info.proxy_resolve_end);
198 EXPECT_LE(load_timing_info.proxy_resolve_end,
199 load_timing_info.connect_timing.connect_start);
200 net::ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
201 connect_timing_flags);
202 EXPECT_LE(load_timing_info.connect_timing.connect_end,
203 load_timing_info.send_start);
204
205 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20206
[email protected]3b23a222013-05-15 21:33:25207 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20208 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
209 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25210 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25211}
212
[email protected]13c8a092010-07-29 06:15:44213} // namespace
214
[email protected]89ceba9a2009-03-21 03:46:06215namespace net {
216
[email protected]448d4ca52012-03-04 04:12:23217namespace {
218
[email protected]c6bf8152012-12-02 07:43:34219HttpNetworkSession* CreateSession(SpdySessionDependencies* session_deps) {
220 return SpdySessionDependencies::SpdyCreateSession(session_deps);
[email protected]e8d536192008-10-17 22:21:14221}
222
[email protected]448d4ca52012-03-04 04:12:23223} // namespace
224
[email protected]23e482282013-06-14 16:08:02225class HttpNetworkTransactionTest
226 : public PlatformTest,
227 public ::testing::WithParamInterface<NextProto> {
[email protected]483fa202013-05-14 01:07:03228 public:
[email protected]23e482282013-06-14 16:08:02229 virtual ~HttpNetworkTransactionTest() {
[email protected]483fa202013-05-14 01:07:03230 // Important to restore the per-pool limit first, since the pool limit must
231 // always be greater than group limit, and the tests reduce both limits.
232 ClientSocketPoolManager::set_max_sockets_per_pool(
233 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
234 ClientSocketPoolManager::set_max_sockets_per_group(
235 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
236 }
237
[email protected]e3ceb682011-06-28 23:55:46238 protected:
[email protected]23e482282013-06-14 16:08:02239 HttpNetworkTransactionTest()
240 : spdy_util_(GetParam()),
241 session_deps_(GetParam()),
[email protected]483fa202013-05-14 01:07:03242 old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
243 HttpNetworkSession::NORMAL_SOCKET_POOL)),
244 old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
245 HttpNetworkSession::NORMAL_SOCKET_POOL)) {
246 }
[email protected]bb88e1d32013-05-03 23:11:07247
[email protected]e3ceb682011-06-28 23:55:46248 struct SimpleGetHelperResult {
249 int rv;
250 std::string status_line;
251 std::string response_data;
[email protected]b8015c42013-12-24 15:18:19252 int64 totalReceivedBytes;
[email protected]58e32bb2013-01-21 18:23:25253 LoadTimingInfo load_timing_info;
[email protected]e3ceb682011-06-28 23:55:46254 };
255
dcheng67be2b1f2014-10-27 21:47:29256 void SetUp() override {
[email protected]0b0bf032010-09-21 18:08:50257 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:34258 base::MessageLoop::current()->RunUntilIdle();
[email protected]2ff8b312010-04-26 22:20:54259 }
260
dcheng67be2b1f2014-10-27 21:47:29261 void TearDown() override {
[email protected]0b0bf032010-09-21 18:08:50262 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:34263 base::MessageLoop::current()->RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09264 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:34265 base::MessageLoop::current()->RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09266 PlatformTest::TearDown();
[email protected]0b0bf032010-09-21 18:08:50267 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:34268 base::MessageLoop::current()->RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09269 }
270
[email protected]8a0fc822013-06-27 20:52:43271 // This is the expected return from a current server advertising SPDY.
272 std::string GetAlternateProtocolHttpHeader() {
273 return
274 std::string("Alternate-Protocol: 443:") +
275 AlternateProtocolToString(AlternateProtocolFromNextProto(GetParam())) +
276 "\r\n\r\n";
277 }
278
[email protected]202965992011-12-07 23:04:51279 // Either |write_failure| specifies a write failure or |read_failure|
280 // specifies a read failure when using a reused socket. In either case, the
281 // failure should cause the network transaction to resend the request, and the
282 // other argument should be NULL.
283 void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
284 const MockRead* read_failure);
initial.commit586acc5fe2008-07-26 22:42:52285
[email protected]a34f61ee2014-03-18 20:59:49286 // Either |write_failure| specifies a write failure or |read_failure|
287 // specifies a read failure when using a reused socket. In either case, the
288 // failure should cause the network transaction to resend the request, and the
289 // other argument should be NULL.
290 void PreconnectErrorResendRequestTest(const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:10291 const MockRead* read_failure,
292 bool use_spdy);
[email protected]a34f61ee2014-03-18 20:59:49293
[email protected]5a60c8b2011-10-19 20:14:29294 SimpleGetHelperResult SimpleGetHelperForData(StaticSocketDataProvider* data[],
295 size_t data_count) {
[email protected]ff007e162009-05-23 09:13:15296 SimpleGetHelperResult out;
initial.commit586acc5fe2008-07-26 22:42:52297
[email protected]ff007e162009-05-23 09:13:15298 HttpRequestInfo request;
299 request.method = "GET";
300 request.url = GURL("http://www.google.com/");
301 request.load_flags = 0;
initial.commit586acc5fe2008-07-26 22:42:52302
[email protected]58e32bb2013-01-21 18:23:25303 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:07304 session_deps_.net_log = log.bound().net_log();
[email protected]3fe8d2f82013-10-17 08:56:07305 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:27306 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:41307 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:27308
[email protected]5a60c8b2011-10-19 20:14:29309 for (size_t i = 0; i < data_count; ++i) {
[email protected]bb88e1d32013-05-03 23:11:07310 session_deps_.socket_factory->AddSocketDataProvider(data[i]);
[email protected]5a60c8b2011-10-19 20:14:29311 }
initial.commit586acc5fe2008-07-26 22:42:52312
[email protected]49639fa2011-12-20 23:22:41313 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52314
[email protected]c47c0372014-03-12 23:07:02315 EXPECT_TRUE(log.bound().IsLogging());
[email protected]49639fa2011-12-20 23:22:41316 int rv = trans->Start(&request, callback.callback(), log.bound());
[email protected]ff007e162009-05-23 09:13:15317 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:52318
[email protected]ff007e162009-05-23 09:13:15319 out.rv = callback.WaitForResult();
[email protected]58e32bb2013-01-21 18:23:25320
321 // Even in the failure cases that use this function, connections are always
322 // successfully established before the error.
323 EXPECT_TRUE(trans->GetLoadTimingInfo(&out.load_timing_info));
324 TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
325
[email protected]ff007e162009-05-23 09:13:15326 if (out.rv != OK)
327 return out;
328
329 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50330 // Can't use ASSERT_* inside helper functions like this, so
331 // return an error.
[email protected]90499482013-06-01 00:39:50332 if (response == NULL || response->headers.get() == NULL) {
[email protected]fe2255a2011-09-20 19:37:50333 out.rv = ERR_UNEXPECTED;
334 return out;
335 }
[email protected]ff007e162009-05-23 09:13:15336 out.status_line = response->headers->GetStatusLine();
337
[email protected]80a09a82012-11-16 17:40:06338 EXPECT_EQ("127.0.0.1", response->socket_address.host());
339 EXPECT_EQ(80, response->socket_address.port());
[email protected]6d81b482011-02-22 19:47:19340
[email protected]ff007e162009-05-23 09:13:15341 rv = ReadTransaction(trans.get(), &out.response_data);
342 EXPECT_EQ(OK, rv);
[email protected]b2fcd0e2010-12-01 15:19:40343
[email protected]f3da152d2012-06-02 01:00:57344 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:40345 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:39346 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:40347 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
[email protected]169d0012010-05-10 23:20:12348 NetLog::PHASE_NONE);
[email protected]dbb83db2010-05-11 18:13:39349 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:40350 entries, pos,
[email protected]dbb83db2010-05-11 18:13:39351 NetLog::TYPE_HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
352 NetLog::PHASE_NONE);
[email protected]ff007e162009-05-23 09:13:15353
[email protected]f3da152d2012-06-02 01:00:57354 std::string line;
355 EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
356 EXPECT_EQ("GET / HTTP/1.1\r\n", line);
357
[email protected]79e1fd62013-06-20 06:50:04358 HttpRequestHeaders request_headers;
359 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
360 std::string value;
361 EXPECT_TRUE(request_headers.GetHeader("Host", &value));
362 EXPECT_EQ("www.google.com", value);
363 EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
364 EXPECT_EQ("keep-alive", value);
365
366 std::string response_headers;
367 EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
368 EXPECT_EQ("['Host: www.google.com','Connection: keep-alive']",
369 response_headers);
[email protected]3deb9a52010-11-11 00:24:40370
[email protected]b8015c42013-12-24 15:18:19371 out.totalReceivedBytes = trans->GetTotalReceivedBytes();
[email protected]aecfbf22008-10-16 02:02:47372 return out;
[email protected]ff007e162009-05-23 09:13:15373 }
initial.commit586acc5fe2008-07-26 22:42:52374
[email protected]5a60c8b2011-10-19 20:14:29375 SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[],
376 size_t reads_count) {
377 StaticSocketDataProvider reads(data_reads, reads_count, NULL, 0);
378 StaticSocketDataProvider* data[] = { &reads };
379 return SimpleGetHelperForData(data, 1);
380 }
381
[email protected]b8015c42013-12-24 15:18:19382 int64 ReadsSize(MockRead data_reads[], size_t reads_count) {
383 int64 size = 0;
384 for (size_t i = 0; i < reads_count; ++i)
385 size += data_reads[i].data_len;
386 return size;
387 }
388
[email protected]ff007e162009-05-23 09:13:15389 void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
390 int expected_status);
initial.commit586acc5fe2008-07-26 22:42:52391
[email protected]ff007e162009-05-23 09:13:15392 void ConnectStatusHelper(const MockRead& status);
[email protected]bb88e1d32013-05-03 23:11:07393
394 void BypassHostCacheOnRefreshHelper(int load_flags);
395
396 void CheckErrorIsPassedBack(int error, IoMode mode);
397
[email protected]4bd46222013-05-14 19:32:23398 SpdyTestUtil spdy_util_;
[email protected]bb88e1d32013-05-03 23:11:07399 SpdySessionDependencies session_deps_;
[email protected]483fa202013-05-14 01:07:03400
401 // Original socket limits. Some tests set these. Safest to always restore
402 // them once each test has been run.
403 int old_max_group_sockets_;
404 int old_max_pool_sockets_;
[email protected]ff007e162009-05-23 09:13:15405};
[email protected]231d5a32008-09-13 00:45:27406
[email protected]23e482282013-06-14 16:08:02407INSTANTIATE_TEST_CASE_P(
408 NextProto,
409 HttpNetworkTransactionTest,
[email protected]b05bcaa32013-10-06 05:26:02410 testing::Values(kProtoDeprecatedSPDY2,
[email protected]d10833bc2014-04-14 17:50:46411 kProtoSPDY3, kProtoSPDY31, kProtoSPDY4));
[email protected]23e482282013-06-14 16:08:02412
[email protected]448d4ca52012-03-04 04:12:23413namespace {
414
[email protected]1826a402014-01-08 15:40:48415class BeforeNetworkStartHandler {
416 public:
417 explicit BeforeNetworkStartHandler(bool defer)
418 : defer_on_before_network_start_(defer),
419 observed_before_network_start_(false) {}
420
421 void OnBeforeNetworkStart(bool* defer) {
422 *defer = defer_on_before_network_start_;
423 observed_before_network_start_ = true;
424 }
425
426 bool observed_before_network_start() const {
427 return observed_before_network_start_;
428 }
429
430 private:
431 const bool defer_on_before_network_start_;
432 bool observed_before_network_start_;
433
434 DISALLOW_COPY_AND_ASSIGN(BeforeNetworkStartHandler);
435};
436
[email protected]597a1ab2014-06-26 08:12:27437class BeforeProxyHeadersSentHandler {
438 public:
439 BeforeProxyHeadersSentHandler()
440 : observed_before_proxy_headers_sent_(false) {}
441
[email protected]1252d42f2014-07-01 21:20:20442 void OnBeforeProxyHeadersSent(const ProxyInfo& proxy_info,
443 HttpRequestHeaders* request_headers) {
[email protected]597a1ab2014-06-26 08:12:27444 observed_before_proxy_headers_sent_ = true;
445 observed_proxy_server_uri_ = proxy_info.proxy_server().ToURI();
446 }
447
448 bool observed_before_proxy_headers_sent() const {
449 return observed_before_proxy_headers_sent_;
450 }
451
452 std::string observed_proxy_server_uri() const {
453 return observed_proxy_server_uri_;
454 }
455
456 private:
457 bool observed_before_proxy_headers_sent_;
458 std::string observed_proxy_server_uri_;
459
460 DISALLOW_COPY_AND_ASSIGN(BeforeProxyHeadersSentHandler);
461};
462
[email protected]15a5ccf82008-10-23 19:57:43463// Fill |str| with a long header list that consumes >= |size| bytes.
464void FillLargeHeadersString(std::string* str, int size) {
[email protected]4ddaf2502008-10-23 18:26:19465 const char* row =
466 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
467 const int sizeof_row = strlen(row);
468 const int num_rows = static_cast<int>(
469 ceil(static_cast<float>(size) / sizeof_row));
470 const int sizeof_data = num_rows * sizeof_row;
471 DCHECK(sizeof_data >= size);
[email protected]15a5ccf82008-10-23 19:57:43472 str->reserve(sizeof_data);
[email protected]372d34a2008-11-05 21:30:51473
[email protected]4ddaf2502008-10-23 18:26:19474 for (int i = 0; i < num_rows; ++i)
[email protected]15a5ccf82008-10-23 19:57:43475 str->append(row, sizeof_row);
[email protected]4ddaf2502008-10-23 18:26:19476}
477
[email protected]385a4672009-03-11 22:21:29478// Alternative functions that eliminate randomness and dependency on the local
479// host name so that the generated NTLM messages are reproducible.
[email protected]fe2bc6a2009-03-23 16:52:20480void MockGenerateRandom1(uint8* output, size_t n) {
[email protected]385a4672009-03-11 22:21:29481 static const uint8 bytes[] = {
482 0x55, 0x29, 0x66, 0x26, 0x6b, 0x9c, 0x73, 0x54
483 };
484 static size_t current_byte = 0;
485 for (size_t i = 0; i < n; ++i) {
486 output[i] = bytes[current_byte++];
487 current_byte %= arraysize(bytes);
488 }
489}
490
[email protected]fe2bc6a2009-03-23 16:52:20491void MockGenerateRandom2(uint8* output, size_t n) {
[email protected]385a4672009-03-11 22:21:29492 static const uint8 bytes[] = {
493 0x96, 0x79, 0x85, 0xe7, 0x49, 0x93, 0x70, 0xa1,
494 0x4e, 0xe7, 0x87, 0x45, 0x31, 0x5b, 0xd3, 0x1f
495 };
496 static size_t current_byte = 0;
497 for (size_t i = 0; i < n; ++i) {
498 output[i] = bytes[current_byte++];
499 current_byte %= arraysize(bytes);
500 }
501}
502
[email protected]fe2bc6a2009-03-23 16:52:20503std::string MockGetHostName() {
504 return "WTC-WIN7";
[email protected]385a4672009-03-11 22:21:29505}
506
[email protected]e60e47a2010-07-14 03:37:18507template<typename ParentPool>
508class CaptureGroupNameSocketPool : public ParentPool {
[email protected]04e5be32009-06-26 20:00:31509 public:
[email protected]9e1bdd32011-02-03 21:48:34510 CaptureGroupNameSocketPool(HostResolver* host_resolver,
511 CertVerifier* cert_verifier);
[email protected]e60e47a2010-07-14 03:37:18512
[email protected]d80a4322009-08-14 07:07:49513 const std::string last_group_name_received() const {
514 return last_group_name_;
515 }
516
[email protected]684970b2009-08-14 04:54:46517 virtual int RequestSocket(const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49518 const void* socket_params,
[email protected]ac790b42009-12-02 04:31:31519 RequestPriority priority,
[email protected]04e5be32009-06-26 20:00:31520 ClientSocketHandle* handle,
[email protected]49639fa2011-12-20 23:22:41521 const CompletionCallback& callback,
[email protected]9e743cd2010-03-16 07:03:53522 const BoundNetLog& net_log) {
[email protected]04e5be32009-06-26 20:00:31523 last_group_name_ = group_name;
524 return ERR_IO_PENDING;
525 }
[email protected]04e5be32009-06-26 20:00:31526 virtual void CancelRequest(const std::string& group_name,
[email protected]05ea9ff2010-07-15 19:08:21527 ClientSocketHandle* handle) {}
[email protected]04e5be32009-06-26 20:00:31528 virtual void ReleaseSocket(const std::string& group_name,
[email protected]18ccfdb2013-08-15 00:13:44529 scoped_ptr<StreamSocket> socket,
[email protected]9f95c692011-02-11 19:20:19530 int id) {}
[email protected]04e5be32009-06-26 20:00:31531 virtual void CloseIdleSockets() {}
[email protected]04e5be32009-06-26 20:00:31532 virtual int IdleSocketCount() const {
533 return 0;
534 }
535 virtual int IdleSocketCountInGroup(const std::string& group_name) const {
536 return 0;
537 }
538 virtual LoadState GetLoadState(const std::string& group_name,
539 const ClientSocketHandle* handle) const {
540 return LOAD_STATE_IDLE;
541 }
[email protected]a796bcec2010-03-22 17:17:26542 virtual base::TimeDelta ConnectionTimeout() const {
543 return base::TimeDelta();
544 }
[email protected]d80a4322009-08-14 07:07:49545
546 private:
[email protected]04e5be32009-06-26 20:00:31547 std::string last_group_name_;
548};
549
[email protected]ab739042011-04-07 15:22:28550typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
551CaptureGroupNameTransportSocketPool;
[email protected]e772db3f2010-07-12 18:11:13552typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
553CaptureGroupNameHttpProxySocketPool;
[email protected]2d731a32010-04-29 01:04:06554typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
[email protected]2227c692010-05-04 15:36:11555CaptureGroupNameSOCKSSocketPool;
[email protected]e60e47a2010-07-14 03:37:18556typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
557CaptureGroupNameSSLSocketPool;
558
559template<typename ParentPool>
560CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34561 HostResolver* host_resolver,
562 CertVerifier* /* cert_verifier */)
563 : ParentPool(0, 0, NULL, host_resolver, NULL, NULL) {}
[email protected]e60e47a2010-07-14 03:37:18564
565template<>
[email protected]2df19bb2010-08-25 20:13:46566CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34567 HostResolver* host_resolver,
568 CertVerifier* /* cert_verifier */)
bengr39e406102014-09-10 23:04:46569 : HttpProxyClientSocketPool(
570 0, 0, NULL, host_resolver, NULL, NULL, NULL, NULL) {}
[email protected]2df19bb2010-08-25 20:13:46571
[email protected]007b3f82013-04-09 08:46:45572template <>
[email protected]e60e47a2010-07-14 03:37:18573CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34574 HostResolver* host_resolver,
575 CertVerifier* cert_verifier)
[email protected]007b3f82013-04-09 08:46:45576 : SSLClientSocketPool(0,
577 0,
578 NULL,
579 host_resolver,
580 cert_verifier,
581 NULL,
582 NULL,
[email protected]284303b62013-11-28 15:11:54583 NULL,
[email protected]007b3f82013-04-09 08:46:45584 std::string(),
585 NULL,
586 NULL,
587 NULL,
588 NULL,
589 NULL,
[email protected]8e458552014-08-05 00:02:15590 false,
591 NULL) {
592}
[email protected]2227c692010-05-04 15:36:11593
[email protected]231d5a32008-09-13 00:45:27594//-----------------------------------------------------------------------------
595
[email protected]79cb5c12011-09-12 13:12:04596// Helper functions for validating that AuthChallengeInfo's are correctly
597// configured for common cases.
598bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
599 if (!auth_challenge)
600 return false;
601 EXPECT_FALSE(auth_challenge->is_proxy);
602 EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString());
603 EXPECT_EQ("MyRealm1", auth_challenge->realm);
604 EXPECT_EQ("basic", auth_challenge->scheme);
605 return true;
606}
607
608bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
609 if (!auth_challenge)
610 return false;
611 EXPECT_TRUE(auth_challenge->is_proxy);
612 EXPECT_EQ("myproxy:70", auth_challenge->challenger.ToString());
613 EXPECT_EQ("MyRealm1", auth_challenge->realm);
614 EXPECT_EQ("basic", auth_challenge->scheme);
615 return true;
616}
617
618bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
619 if (!auth_challenge)
620 return false;
621 EXPECT_FALSE(auth_challenge->is_proxy);
622 EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString());
623 EXPECT_EQ("digestive", auth_challenge->realm);
624 EXPECT_EQ("digest", auth_challenge->scheme);
625 return true;
626}
627
628bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
629 if (!auth_challenge)
630 return false;
631 EXPECT_FALSE(auth_challenge->is_proxy);
632 EXPECT_EQ("172.22.68.17:80", auth_challenge->challenger.ToString());
633 EXPECT_EQ(std::string(), auth_challenge->realm);
634 EXPECT_EQ("ntlm", auth_challenge->scheme);
635 return true;
636}
637
[email protected]448d4ca52012-03-04 04:12:23638} // namespace
639
[email protected]23e482282013-06-14 16:08:02640TEST_P(HttpNetworkTransactionTest, Basic) {
[email protected]3fe8d2f82013-10-17 08:56:07641 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:40642 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:41643 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]231d5a32008-09-13 00:45:27644}
645
[email protected]23e482282013-06-14 16:08:02646TEST_P(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27647 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35648 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
649 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06650 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27651 };
[email protected]31a2bfe2010-02-09 08:03:39652 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
653 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42654 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27655 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
656 EXPECT_EQ("hello world", out.response_data);
[email protected]b8015c42013-12-24 15:18:19657 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
658 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27659}
660
661// Response with no status line.
[email protected]23e482282013-06-14 16:08:02662TEST_P(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27663 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35664 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06665 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27666 };
[email protected]31a2bfe2010-02-09 08:03:39667 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
668 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42669 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27670 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
671 EXPECT_EQ("hello world", out.response_data);
[email protected]b8015c42013-12-24 15:18:19672 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
673 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27674}
675
676// Allow up to 4 bytes of junk to precede status line.
[email protected]23e482282013-06-14 16:08:02677TEST_P(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27678 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35679 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06680 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27681 };
[email protected]31a2bfe2010-02-09 08:03:39682 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
683 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42684 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27685 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
686 EXPECT_EQ("DATA", out.response_data);
[email protected]b8015c42013-12-24 15:18:19687 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
688 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27689}
690
691// Allow up to 4 bytes of junk to precede status line.
[email protected]23e482282013-06-14 16:08:02692TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27693 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35694 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06695 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27696 };
[email protected]31a2bfe2010-02-09 08:03:39697 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
698 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42699 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27700 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
701 EXPECT_EQ("DATA", out.response_data);
[email protected]b8015c42013-12-24 15:18:19702 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
703 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27704}
705
706// Beyond 4 bytes of slop and it should fail to find a status line.
[email protected]23e482282013-06-14 16:08:02707TEST_P(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27708 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35709 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06710 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27711 };
[email protected]31a2bfe2010-02-09 08:03:39712 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
713 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42714 EXPECT_EQ(OK, out.rv);
[email protected]3d2a59b2008-09-26 19:44:25715 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
716 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
[email protected]b8015c42013-12-24 15:18:19717 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
718 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27719}
720
721// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
[email protected]23e482282013-06-14 16:08:02722TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27723 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35724 MockRead("\n"),
725 MockRead("\n"),
726 MockRead("Q"),
727 MockRead("J"),
728 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06729 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27730 };
[email protected]31a2bfe2010-02-09 08:03:39731 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
732 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42733 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27734 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
735 EXPECT_EQ("DATA", out.response_data);
[email protected]b8015c42013-12-24 15:18:19736 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
737 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27738}
739
740// Close the connection before enough bytes to have a status line.
[email protected]23e482282013-06-14 16:08:02741TEST_P(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:27742 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35743 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:06744 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27745 };
[email protected]31a2bfe2010-02-09 08:03:39746 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
747 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42748 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27749 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
750 EXPECT_EQ("HTT", out.response_data);
[email protected]b8015c42013-12-24 15:18:19751 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
752 EXPECT_EQ(reads_size, out.totalReceivedBytes);
initial.commit586acc5fe2008-07-26 22:42:52753}
754
[email protected]f9d44aa2008-09-23 23:57:17755// Simulate a 204 response, lacking a Content-Length header, sent over a
756// persistent connection. The response should still terminate since a 204
757// cannot have a response body.
[email protected]23e482282013-06-14 16:08:02758TEST_P(HttpNetworkTransactionTest, StopsReading204) {
[email protected]b8015c42013-12-24 15:18:19759 char junk[] = "junk";
[email protected]f9d44aa2008-09-23 23:57:17760 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35761 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
[email protected]b8015c42013-12-24 15:18:19762 MockRead(junk), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:06763 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:17764 };
[email protected]31a2bfe2010-02-09 08:03:39765 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
766 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42767 EXPECT_EQ(OK, out.rv);
[email protected]f9d44aa2008-09-23 23:57:17768 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
769 EXPECT_EQ("", out.response_data);
[email protected]b8015c42013-12-24 15:18:19770 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
771 int64 response_size = reads_size - strlen(junk);
772 EXPECT_EQ(response_size, out.totalReceivedBytes);
[email protected]f9d44aa2008-09-23 23:57:17773}
774
[email protected]0877e3d2009-10-17 22:29:57775// A simple request using chunked encoding with some extra data after.
[email protected]23e482282013-06-14 16:08:02776TEST_P(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]b8015c42013-12-24 15:18:19777 std::string final_chunk = "0\r\n\r\n";
778 std::string extra_data = "HTTP/1.1 200 OK\r\n";
779 std::string last_read = final_chunk + extra_data;
[email protected]0877e3d2009-10-17 22:29:57780 MockRead data_reads[] = {
781 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
782 MockRead("5\r\nHello\r\n"),
783 MockRead("1\r\n"),
784 MockRead(" \r\n"),
785 MockRead("5\r\nworld\r\n"),
[email protected]b8015c42013-12-24 15:18:19786 MockRead(last_read.data()),
[email protected]8ddf8322012-02-23 18:08:06787 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:57788 };
[email protected]31a2bfe2010-02-09 08:03:39789 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
790 arraysize(data_reads));
[email protected]0877e3d2009-10-17 22:29:57791 EXPECT_EQ(OK, out.rv);
792 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
793 EXPECT_EQ("Hello world", out.response_data);
[email protected]b8015c42013-12-24 15:18:19794 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
795 int64 response_size = reads_size - extra_data.size();
796 EXPECT_EQ(response_size, out.totalReceivedBytes);
[email protected]0877e3d2009-10-17 22:29:57797}
798
[email protected]9fe44f52010-09-23 18:36:00799// Next tests deal with http://crbug.com/56344.
800
[email protected]23e482282013-06-14 16:08:02801TEST_P(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00802 MultipleContentLengthHeadersNoTransferEncoding) {
803 MockRead data_reads[] = {
804 MockRead("HTTP/1.1 200 OK\r\n"),
805 MockRead("Content-Length: 10\r\n"),
806 MockRead("Content-Length: 5\r\n\r\n"),
807 };
808 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
809 arraysize(data_reads));
810 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
811}
812
[email protected]23e482282013-06-14 16:08:02813TEST_P(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04814 DuplicateContentLengthHeadersNoTransferEncoding) {
815 MockRead data_reads[] = {
816 MockRead("HTTP/1.1 200 OK\r\n"),
817 MockRead("Content-Length: 5\r\n"),
818 MockRead("Content-Length: 5\r\n\r\n"),
819 MockRead("Hello"),
820 };
821 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
822 arraysize(data_reads));
823 EXPECT_EQ(OK, out.rv);
824 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
825 EXPECT_EQ("Hello", out.response_data);
826}
827
[email protected]23e482282013-06-14 16:08:02828TEST_P(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04829 ComplexContentLengthHeadersNoTransferEncoding) {
830 // More than 2 dupes.
831 {
832 MockRead data_reads[] = {
833 MockRead("HTTP/1.1 200 OK\r\n"),
834 MockRead("Content-Length: 5\r\n"),
835 MockRead("Content-Length: 5\r\n"),
836 MockRead("Content-Length: 5\r\n\r\n"),
837 MockRead("Hello"),
838 };
839 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
840 arraysize(data_reads));
841 EXPECT_EQ(OK, out.rv);
842 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
843 EXPECT_EQ("Hello", out.response_data);
844 }
845 // HTTP/1.0
846 {
847 MockRead data_reads[] = {
848 MockRead("HTTP/1.0 200 OK\r\n"),
849 MockRead("Content-Length: 5\r\n"),
850 MockRead("Content-Length: 5\r\n"),
851 MockRead("Content-Length: 5\r\n\r\n"),
852 MockRead("Hello"),
853 };
854 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
855 arraysize(data_reads));
856 EXPECT_EQ(OK, out.rv);
857 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
858 EXPECT_EQ("Hello", out.response_data);
859 }
860 // 2 dupes and one mismatched.
861 {
862 MockRead data_reads[] = {
863 MockRead("HTTP/1.1 200 OK\r\n"),
864 MockRead("Content-Length: 10\r\n"),
865 MockRead("Content-Length: 10\r\n"),
866 MockRead("Content-Length: 5\r\n\r\n"),
867 };
868 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
869 arraysize(data_reads));
870 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
871 }
872}
873
[email protected]23e482282013-06-14 16:08:02874TEST_P(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00875 MultipleContentLengthHeadersTransferEncoding) {
876 MockRead data_reads[] = {
877 MockRead("HTTP/1.1 200 OK\r\n"),
878 MockRead("Content-Length: 666\r\n"),
879 MockRead("Content-Length: 1337\r\n"),
880 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
881 MockRead("5\r\nHello\r\n"),
882 MockRead("1\r\n"),
883 MockRead(" \r\n"),
884 MockRead("5\r\nworld\r\n"),
885 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:06886 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:00887 };
888 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
889 arraysize(data_reads));
890 EXPECT_EQ(OK, out.rv);
891 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
892 EXPECT_EQ("Hello world", out.response_data);
893}
894
[email protected]1628fe92011-10-04 23:04:55895// Next tests deal with http://crbug.com/98895.
896
897// Checks that a single Content-Disposition header results in no error.
[email protected]23e482282013-06-14 16:08:02898TEST_P(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:55899 MockRead data_reads[] = {
900 MockRead("HTTP/1.1 200 OK\r\n"),
901 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
902 MockRead("Content-Length: 5\r\n\r\n"),
903 MockRead("Hello"),
904 };
905 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
906 arraysize(data_reads));
907 EXPECT_EQ(OK, out.rv);
908 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
909 EXPECT_EQ("Hello", out.response_data);
910}
911
[email protected]54a9c6e52012-03-21 20:10:59912// Checks that two identical Content-Disposition headers result in no error.
[email protected]23e482282013-06-14 16:08:02913TEST_P(HttpNetworkTransactionTest,
[email protected]54a9c6e52012-03-21 20:10:59914 TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:55915 MockRead data_reads[] = {
916 MockRead("HTTP/1.1 200 OK\r\n"),
917 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
918 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
919 MockRead("Content-Length: 5\r\n\r\n"),
920 MockRead("Hello"),
921 };
922 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
923 arraysize(data_reads));
[email protected]54a9c6e52012-03-21 20:10:59924 EXPECT_EQ(OK, out.rv);
925 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
926 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:55927}
928
929// Checks that two distinct Content-Disposition headers result in an error.
[email protected]23e482282013-06-14 16:08:02930TEST_P(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:55931 MockRead data_reads[] = {
932 MockRead("HTTP/1.1 200 OK\r\n"),
933 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
934 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
935 MockRead("Content-Length: 5\r\n\r\n"),
936 MockRead("Hello"),
937 };
938 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
939 arraysize(data_reads));
940 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION, out.rv);
941}
942
[email protected]54a9c6e52012-03-21 20:10:59943// Checks that two identical Location headers result in no error.
944// Also tests Location header behavior.
[email protected]23e482282013-06-14 16:08:02945TEST_P(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:55946 MockRead data_reads[] = {
947 MockRead("HTTP/1.1 302 Redirect\r\n"),
948 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:59949 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:55950 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:06951 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:55952 };
953
954 HttpRequestInfo request;
955 request.method = "GET";
956 request.url = GURL("http://redirect.com/");
957 request.load_flags = 0;
958
[email protected]3fe8d2f82013-10-17 08:56:07959 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1628fe92011-10-04 23:04:55960 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:41961 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]1628fe92011-10-04 23:04:55962
963 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:07964 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:55965
[email protected]49639fa2011-12-20 23:22:41966 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:55967
[email protected]49639fa2011-12-20 23:22:41968 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1628fe92011-10-04 23:04:55969 EXPECT_EQ(ERR_IO_PENDING, rv);
970
971 EXPECT_EQ(OK, callback.WaitForResult());
972
973 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]90499482013-06-01 00:39:50974 ASSERT_TRUE(response != NULL && response->headers.get() != NULL);
[email protected]1628fe92011-10-04 23:04:55975 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
976 std::string url;
977 EXPECT_TRUE(response->headers->IsRedirect(&url));
978 EXPECT_EQ("http://good.com/", url);
[email protected]d8fc4722014-06-13 13:17:15979 EXPECT_TRUE(response->proxy_server.IsEmpty());
[email protected]1628fe92011-10-04 23:04:55980}
981
[email protected]1628fe92011-10-04 23:04:55982// Checks that two distinct Location headers result in an error.
[email protected]23e482282013-06-14 16:08:02983TEST_P(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:55984 MockRead data_reads[] = {
985 MockRead("HTTP/1.1 302 Redirect\r\n"),
986 MockRead("Location: http://good.com/\r\n"),
987 MockRead("Location: http://evil.com/\r\n"),
988 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:06989 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:55990 };
991 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
992 arraysize(data_reads));
993 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION, out.rv);
994}
995
[email protected]ef0faf2e72009-03-05 23:27:23996// Do a request using the HEAD method. Verify that we don't try to read the
997// message body (since HEAD has none).
[email protected]23e482282013-06-14 16:08:02998TEST_P(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:42999 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:231000 request.method = "HEAD";
1001 request.url = GURL("http://www.google.com/");
1002 request.load_flags = 0;
1003
[email protected]3fe8d2f82013-10-17 08:56:071004 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271005 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411006 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]597a1ab2014-06-26 08:12:271007 BeforeProxyHeadersSentHandler proxy_headers_handler;
1008 trans->SetBeforeProxyHeadersSentCallback(
1009 base::Bind(&BeforeProxyHeadersSentHandler::OnBeforeProxyHeadersSent,
1010 base::Unretained(&proxy_headers_handler)));
[email protected]cb9bf6ca2011-01-28 13:15:271011
[email protected]ef0faf2e72009-03-05 23:27:231012 MockWrite data_writes1[] = {
1013 MockWrite("HEAD / HTTP/1.1\r\n"
1014 "Host: www.google.com\r\n"
1015 "Connection: keep-alive\r\n"
1016 "Content-Length: 0\r\n\r\n"),
1017 };
1018 MockRead data_reads1[] = {
1019 MockRead("HTTP/1.1 404 Not Found\r\n"),
1020 MockRead("Server: Blah\r\n"),
1021 MockRead("Content-Length: 1234\r\n\r\n"),
1022
1023 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:061024 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]ef0faf2e72009-03-05 23:27:231025 };
1026
[email protected]31a2bfe2010-02-09 08:03:391027 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1028 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:071029 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:231030
[email protected]49639fa2011-12-20 23:22:411031 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:231032
[email protected]49639fa2011-12-20 23:22:411033 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421034 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]ef0faf2e72009-03-05 23:27:231035
1036 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421037 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:231038
[email protected]1c773ea12009-04-28 19:58:421039 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501040 ASSERT_TRUE(response != NULL);
[email protected]ef0faf2e72009-03-05 23:27:231041
1042 // Check that the headers got parsed.
[email protected]90499482013-06-01 00:39:501043 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]ef0faf2e72009-03-05 23:27:231044 EXPECT_EQ(1234, response->headers->GetContentLength());
1045 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
[email protected]d8fc4722014-06-13 13:17:151046 EXPECT_TRUE(response->proxy_server.IsEmpty());
[email protected]597a1ab2014-06-26 08:12:271047 EXPECT_FALSE(proxy_headers_handler.observed_before_proxy_headers_sent());
[email protected]ef0faf2e72009-03-05 23:27:231048
1049 std::string server_header;
1050 void* iter = NULL;
1051 bool has_server_header = response->headers->EnumerateHeader(
1052 &iter, "Server", &server_header);
1053 EXPECT_TRUE(has_server_header);
1054 EXPECT_EQ("Blah", server_header);
1055
1056 // Reading should give EOF right away, since there is no message body
1057 // (despite non-zero content-length).
1058 std::string response_data;
1059 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421060 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:231061 EXPECT_EQ("", response_data);
1062}
1063
[email protected]23e482282013-06-14 16:08:021064TEST_P(HttpNetworkTransactionTest, ReuseConnection) {
[email protected]bb88e1d32013-05-03 23:11:071065 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:521066
1067 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351068 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1069 MockRead("hello"),
1070 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1071 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061072 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521073 };
[email protected]31a2bfe2010-02-09 08:03:391074 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071075 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521076
[email protected]0b0bf032010-09-21 18:08:501077 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521078 "hello", "world"
1079 };
1080
1081 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:421082 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521083 request.method = "GET";
1084 request.url = GURL("http://www.google.com/");
1085 request.load_flags = 0;
1086
[email protected]262eec82013-03-19 21:01:361087 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501088 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271089
[email protected]49639fa2011-12-20 23:22:411090 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521091
[email protected]49639fa2011-12-20 23:22:411092 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421093 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521094
1095 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421096 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521097
[email protected]1c773ea12009-04-28 19:58:421098 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501099 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521100
[email protected]90499482013-06-01 00:39:501101 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251102 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]d8fc4722014-06-13 13:17:151103 EXPECT_TRUE(response->proxy_server.IsEmpty());
initial.commit586acc5fe2008-07-26 22:42:521104
1105 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571106 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421107 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251108 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521109 }
1110}
1111
[email protected]23e482282013-06-14 16:08:021112TEST_P(HttpNetworkTransactionTest, Ignores100) {
[email protected]b2d26cfd2012-12-11 10:36:061113 ScopedVector<UploadElementReader> element_readers;
1114 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:071115 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:271116
[email protected]1c773ea12009-04-28 19:58:421117 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521118 request.method = "POST";
1119 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271120 request.upload_data_stream = &upload_data_stream;
initial.commit586acc5fe2008-07-26 22:42:521121 request.load_flags = 0;
1122
[email protected]3fe8d2f82013-10-17 08:56:071123 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271124 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411125 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271126
initial.commit586acc5fe2008-07-26 22:42:521127 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351128 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1129 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1130 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061131 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521132 };
[email protected]31a2bfe2010-02-09 08:03:391133 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071134 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521135
[email protected]49639fa2011-12-20 23:22:411136 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521137
[email protected]49639fa2011-12-20 23:22:411138 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421139 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521140
1141 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421142 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521143
[email protected]1c773ea12009-04-28 19:58:421144 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501145 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521146
[email protected]90499482013-06-01 00:39:501147 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251148 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521149
1150 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571151 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421152 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251153 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521154}
1155
[email protected]3a2d3662009-03-27 03:49:141156// This test is almost the same as Ignores100 above, but the response contains
1157// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571158// HTTP/1.1 and the two status headers are read in one read.
[email protected]23e482282013-06-14 16:08:021159TEST_P(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421160 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141161 request.method = "GET";
1162 request.url = GURL("http://www.foo.com/");
1163 request.load_flags = 0;
1164
[email protected]3fe8d2f82013-10-17 08:56:071165 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271166 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411167 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271168
[email protected]3a2d3662009-03-27 03:49:141169 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571170 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1171 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141172 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061173 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141174 };
[email protected]31a2bfe2010-02-09 08:03:391175 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071176 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141177
[email protected]49639fa2011-12-20 23:22:411178 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141179
[email protected]49639fa2011-12-20 23:22:411180 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421181 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3a2d3662009-03-27 03:49:141182
1183 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421184 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:141185
[email protected]1c773ea12009-04-28 19:58:421186 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501187 ASSERT_TRUE(response != NULL);
[email protected]3a2d3662009-03-27 03:49:141188
[email protected]90499482013-06-01 00:39:501189 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3a2d3662009-03-27 03:49:141190 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1191
1192 std::string response_data;
1193 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421194 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:141195 EXPECT_EQ("hello world", response_data);
1196}
1197
[email protected]23e482282013-06-14 16:08:021198TEST_P(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
[email protected]ee9410e72010-01-07 01:42:381199 HttpRequestInfo request;
1200 request.method = "POST";
1201 request.url = GURL("http://www.foo.com/");
1202 request.load_flags = 0;
1203
[email protected]3fe8d2f82013-10-17 08:56:071204 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271205 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411206 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271207
[email protected]ee9410e72010-01-07 01:42:381208 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061209 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1210 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381211 };
[email protected]31a2bfe2010-02-09 08:03:391212 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071213 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381214
[email protected]49639fa2011-12-20 23:22:411215 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381216
[email protected]49639fa2011-12-20 23:22:411217 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]ee9410e72010-01-07 01:42:381218 EXPECT_EQ(ERR_IO_PENDING, rv);
1219
1220 rv = callback.WaitForResult();
1221 EXPECT_EQ(OK, rv);
1222
1223 std::string response_data;
1224 rv = ReadTransaction(trans.get(), &response_data);
1225 EXPECT_EQ(OK, rv);
1226 EXPECT_EQ("", response_data);
1227}
1228
[email protected]23e482282013-06-14 16:08:021229TEST_P(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381230 HttpRequestInfo request;
1231 request.method = "POST";
1232 request.url = GURL("http://www.foo.com/");
1233 request.load_flags = 0;
1234
[email protected]3fe8d2f82013-10-17 08:56:071235 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271236 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411237 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271238
[email protected]ee9410e72010-01-07 01:42:381239 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061240 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381241 };
[email protected]31a2bfe2010-02-09 08:03:391242 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071243 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381244
[email protected]49639fa2011-12-20 23:22:411245 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381246
[email protected]49639fa2011-12-20 23:22:411247 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]ee9410e72010-01-07 01:42:381248 EXPECT_EQ(ERR_IO_PENDING, rv);
1249
1250 rv = callback.WaitForResult();
1251 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
1252}
1253
[email protected]23e482282013-06-14 16:08:021254void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511255 const MockWrite* write_failure,
1256 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421257 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521258 request.method = "GET";
1259 request.url = GURL("http://www.foo.com/");
1260 request.load_flags = 0;
1261
[email protected]58e32bb2013-01-21 18:23:251262 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071263 session_deps_.net_log = &net_log;
1264 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271265
[email protected]202965992011-12-07 23:04:511266 // Written data for successfully sending both requests.
1267 MockWrite data1_writes[] = {
1268 MockWrite("GET / HTTP/1.1\r\n"
1269 "Host: www.foo.com\r\n"
1270 "Connection: keep-alive\r\n\r\n"),
1271 MockWrite("GET / HTTP/1.1\r\n"
1272 "Host: www.foo.com\r\n"
1273 "Connection: keep-alive\r\n\r\n")
1274 };
1275
1276 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521277 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351278 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1279 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061280 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521281 };
[email protected]202965992011-12-07 23:04:511282
1283 if (write_failure) {
[email protected]a34f61ee2014-03-18 20:59:491284 ASSERT_FALSE(read_failure);
[email protected]202965992011-12-07 23:04:511285 data1_writes[1] = *write_failure;
1286 } else {
1287 ASSERT_TRUE(read_failure);
1288 data1_reads[2] = *read_failure;
1289 }
1290
1291 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
1292 data1_writes, arraysize(data1_writes));
[email protected]bb88e1d32013-05-03 23:11:071293 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521294
1295 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351296 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1297 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061298 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521299 };
[email protected]31a2bfe2010-02-09 08:03:391300 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071301 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521302
1303 const char* kExpectedResponseData[] = {
1304 "hello", "world"
1305 };
1306
[email protected]58e32bb2013-01-21 18:23:251307 uint32 first_socket_log_id = NetLog::Source::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521308 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411309 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521310
[email protected]262eec82013-03-19 21:01:361311 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501312 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
initial.commit586acc5fe2008-07-26 22:42:521313
[email protected]49639fa2011-12-20 23:22:411314 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421315 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521316
1317 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421318 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521319
[email protected]58e32bb2013-01-21 18:23:251320 LoadTimingInfo load_timing_info;
1321 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1322 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1323 if (i == 0) {
1324 first_socket_log_id = load_timing_info.socket_log_id;
1325 } else {
1326 // The second request should be using a new socket.
1327 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1328 }
1329
[email protected]1c773ea12009-04-28 19:58:421330 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501331 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521332
[email protected]90499482013-06-01 00:39:501333 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251334 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521335
1336 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571337 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421338 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251339 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521340 }
1341}
[email protected]3d2a59b2008-09-26 19:44:251342
[email protected]a34f61ee2014-03-18 20:59:491343void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1344 const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:101345 const MockRead* read_failure,
1346 bool use_spdy) {
[email protected]a34f61ee2014-03-18 20:59:491347 HttpRequestInfo request;
1348 request.method = "GET";
[email protected]09356c652014-03-25 15:36:101349 request.url = GURL("https://www.foo.com/");
[email protected]a34f61ee2014-03-18 20:59:491350 request.load_flags = 0;
1351
1352 CapturingNetLog net_log;
1353 session_deps_.net_log = &net_log;
1354 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1355
[email protected]09356c652014-03-25 15:36:101356 SSLSocketDataProvider ssl1(ASYNC, OK);
1357 SSLSocketDataProvider ssl2(ASYNC, OK);
1358 if (use_spdy) {
1359 ssl1.SetNextProto(GetParam());
1360 ssl2.SetNextProto(GetParam());
1361 }
1362 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1363 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]a34f61ee2014-03-18 20:59:491364
[email protected]09356c652014-03-25 15:36:101365 // SPDY versions of the request and response.
1366 scoped_ptr<SpdyFrame> spdy_request(spdy_util_.ConstructSpdyGet(
1367 request.url.spec().c_str(), false, 1, DEFAULT_PRIORITY));
1368 scoped_ptr<SpdyFrame> spdy_response(
1369 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
1370 scoped_ptr<SpdyFrame> spdy_data(
1371 spdy_util_.ConstructSpdyBodyFrame(1, "hello", 5, true));
[email protected]a34f61ee2014-03-18 20:59:491372
[email protected]09356c652014-03-25 15:36:101373 // HTTP/1.1 versions of the request and response.
1374 const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1375 "Host: www.foo.com\r\n"
1376 "Connection: keep-alive\r\n\r\n";
1377 const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1378 const char kHttpData[] = "hello";
1379
1380 std::vector<MockRead> data1_reads;
1381 std::vector<MockWrite> data1_writes;
[email protected]a34f61ee2014-03-18 20:59:491382 if (write_failure) {
1383 ASSERT_FALSE(read_failure);
[email protected]09356c652014-03-25 15:36:101384 data1_writes.push_back(*write_failure);
1385 data1_reads.push_back(MockRead(ASYNC, OK));
[email protected]a34f61ee2014-03-18 20:59:491386 } else {
1387 ASSERT_TRUE(read_failure);
[email protected]09356c652014-03-25 15:36:101388 if (use_spdy) {
1389 data1_writes.push_back(CreateMockWrite(*spdy_request));
1390 } else {
1391 data1_writes.push_back(MockWrite(kHttpRequest));
1392 }
1393 data1_reads.push_back(*read_failure);
[email protected]a34f61ee2014-03-18 20:59:491394 }
1395
[email protected]09356c652014-03-25 15:36:101396 StaticSocketDataProvider data1(&data1_reads[0], data1_reads.size(),
1397 &data1_writes[0], data1_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491398 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1399
[email protected]09356c652014-03-25 15:36:101400 std::vector<MockRead> data2_reads;
1401 std::vector<MockWrite> data2_writes;
1402
1403 if (use_spdy) {
1404 data2_writes.push_back(CreateMockWrite(*spdy_request, 0, ASYNC));
1405
1406 data2_reads.push_back(CreateMockRead(*spdy_response, 1, ASYNC));
1407 data2_reads.push_back(CreateMockRead(*spdy_data, 2, ASYNC));
1408 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1409 } else {
1410 data2_writes.push_back(
1411 MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1412
1413 data2_reads.push_back(
1414 MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1415 data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1416 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1417 }
1418 OrderedSocketData data2(&data2_reads[0], data2_reads.size(),
1419 &data2_writes[0], data2_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491420 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1421
1422 // Preconnect a socket.
1423 net::SSLConfig ssl_config;
1424 session->ssl_config_service()->GetSSLConfig(&ssl_config);
[email protected]d7599122014-05-24 03:37:231425 session->GetNextProtos(&ssl_config.next_protos);
[email protected]a34f61ee2014-03-18 20:59:491426 session->http_stream_factory()->PreconnectStreams(
1427 1, request, DEFAULT_PRIORITY, ssl_config, ssl_config);
1428 // Wait for the preconnect to complete.
1429 // TODO(davidben): Some way to wait for an idle socket count might be handy.
1430 base::RunLoop().RunUntilIdle();
[email protected]09356c652014-03-25 15:36:101431 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]a34f61ee2014-03-18 20:59:491432
1433 // Make the request.
1434 TestCompletionCallback callback;
1435
1436 scoped_ptr<HttpTransaction> trans(
1437 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1438
1439 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1440 EXPECT_EQ(ERR_IO_PENDING, rv);
1441
1442 rv = callback.WaitForResult();
1443 EXPECT_EQ(OK, rv);
1444
1445 LoadTimingInfo load_timing_info;
1446 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
[email protected]09356c652014-03-25 15:36:101447 TestLoadTimingNotReused(
1448 load_timing_info,
1449 CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]a34f61ee2014-03-18 20:59:491450
1451 const HttpResponseInfo* response = trans->GetResponseInfo();
1452 ASSERT_TRUE(response != NULL);
1453
1454 EXPECT_TRUE(response->headers.get() != NULL);
1455 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1456
1457 std::string response_data;
1458 rv = ReadTransaction(trans.get(), &response_data);
1459 EXPECT_EQ(OK, rv);
[email protected]09356c652014-03-25 15:36:101460 EXPECT_EQ(kHttpData, response_data);
[email protected]a34f61ee2014-03-18 20:59:491461}
1462
[email protected]23e482282013-06-14 16:08:021463TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:231464 KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061465 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]202965992011-12-07 23:04:511466 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1467}
1468
[email protected]23e482282013-06-14 16:08:021469TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061470 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]202965992011-12-07 23:04:511471 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251472}
1473
[email protected]23e482282013-06-14 16:08:021474TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061475 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]202965992011-12-07 23:04:511476 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251477}
1478
[email protected]d58ceea82014-06-04 10:55:541479// Make sure that on a 408 response (Request Timeout), the request is retried,
1480// if the socket was a reused keep alive socket.
1481TEST_P(HttpNetworkTransactionTest, KeepAlive408) {
1482 MockRead read_failure(SYNCHRONOUS,
1483 "HTTP/1.1 408 Request Timeout\r\n"
1484 "Connection: Keep-Alive\r\n"
1485 "Content-Length: 6\r\n\r\n"
1486 "Pickle");
1487 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1488}
1489
[email protected]a34f61ee2014-03-18 20:59:491490TEST_P(HttpNetworkTransactionTest,
1491 PreconnectErrorNotConnectedOnWrite) {
1492 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]09356c652014-03-25 15:36:101493 PreconnectErrorResendRequestTest(&write_failure, NULL, false);
[email protected]a34f61ee2014-03-18 20:59:491494}
1495
1496TEST_P(HttpNetworkTransactionTest, PreconnectErrorReset) {
1497 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]09356c652014-03-25 15:36:101498 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
[email protected]a34f61ee2014-03-18 20:59:491499}
1500
1501TEST_P(HttpNetworkTransactionTest, PreconnectErrorEOF) {
1502 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]09356c652014-03-25 15:36:101503 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1504}
1505
1506TEST_P(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
1507 MockRead read_failure(ASYNC, OK); // EOF
1508 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1509}
1510
[email protected]d58ceea82014-06-04 10:55:541511// Make sure that on a 408 response (Request Timeout), the request is retried,
1512// if the socket was a preconnected (UNUSED_IDLE) socket.
1513TEST_P(HttpNetworkTransactionTest, RetryOnIdle408) {
1514 MockRead read_failure(SYNCHRONOUS,
1515 "HTTP/1.1 408 Request Timeout\r\n"
1516 "Connection: Keep-Alive\r\n"
1517 "Content-Length: 6\r\n\r\n"
1518 "Pickle");
1519 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1520 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1521}
1522
[email protected]09356c652014-03-25 15:36:101523TEST_P(HttpNetworkTransactionTest,
1524 SpdyPreconnectErrorNotConnectedOnWrite) {
1525 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1526 PreconnectErrorResendRequestTest(&write_failure, NULL, true);
1527}
1528
1529TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
1530 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1531 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1532}
1533
1534TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
1535 MockRead read_failure(SYNCHRONOUS, OK); // EOF
1536 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1537}
1538
1539TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
1540 MockRead read_failure(ASYNC, OK); // EOF
1541 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
[email protected]a34f61ee2014-03-18 20:59:491542}
1543
[email protected]23e482282013-06-14 16:08:021544TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:421545 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:251546 request.method = "GET";
1547 request.url = GURL("http://www.google.com/");
1548 request.load_flags = 0;
1549
[email protected]3fe8d2f82013-10-17 08:56:071550 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271551 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411552 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271553
[email protected]3d2a59b2008-09-26 19:44:251554 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061555 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:351556 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1557 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061558 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251559 };
[email protected]31a2bfe2010-02-09 08:03:391560 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071561 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:251562
[email protected]49639fa2011-12-20 23:22:411563 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:251564
[email protected]49639fa2011-12-20 23:22:411565 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421566 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3d2a59b2008-09-26 19:44:251567
1568 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421569 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]3d2a59b2008-09-26 19:44:251570
[email protected]1c773ea12009-04-28 19:58:421571 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]3d2a59b2008-09-26 19:44:251572 EXPECT_TRUE(response == NULL);
[email protected]3d2a59b2008-09-26 19:44:251573}
1574
1575// What do various browsers do when the server closes a non-keepalive
1576// connection without sending any response header or body?
1577//
1578// IE7: error page
1579// Safari 3.1.2 (Windows): error page
1580// Firefox 3.0.1: blank page
1581// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:421582// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1583// Us: error page (EMPTY_RESPONSE)
[email protected]23e482282013-06-14 16:08:021584TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:251585 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061586 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:351587 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1588 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061589 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251590 };
[email protected]31a2bfe2010-02-09 08:03:391591 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1592 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:421593 EXPECT_EQ(ERR_EMPTY_RESPONSE, out.rv);
[email protected]3d2a59b2008-09-26 19:44:251594}
[email protected]038e9a32008-10-08 22:40:161595
[email protected]1826a402014-01-08 15:40:481596// Test that network access can be deferred and resumed.
1597TEST_P(HttpNetworkTransactionTest, ThrottleBeforeNetworkStart) {
1598 HttpRequestInfo request;
1599 request.method = "GET";
1600 request.url = GURL("http://www.google.com/");
1601 request.load_flags = 0;
1602
1603 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1604 scoped_ptr<HttpTransaction> trans(
1605 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1606
1607 // Defer on OnBeforeNetworkStart.
1608 BeforeNetworkStartHandler net_start_handler(true); // defer
1609 trans->SetBeforeNetworkStartCallback(
1610 base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
1611 base::Unretained(&net_start_handler)));
1612
1613 MockRead data_reads[] = {
1614 MockRead("HTTP/1.0 200 OK\r\n"),
1615 MockRead("Content-Length: 5\r\n\r\n"),
1616 MockRead("hello"),
1617 MockRead(SYNCHRONOUS, 0),
1618 };
1619 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1620 session_deps_.socket_factory->AddSocketDataProvider(&data);
1621
1622 TestCompletionCallback callback;
1623
1624 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1625 EXPECT_EQ(ERR_IO_PENDING, rv);
1626 base::MessageLoop::current()->RunUntilIdle();
1627
1628 // Should have deferred for network start.
1629 EXPECT_TRUE(net_start_handler.observed_before_network_start());
1630 EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
1631 EXPECT_TRUE(trans->GetResponseInfo() == NULL);
1632
1633 trans->ResumeNetworkStart();
1634 rv = callback.WaitForResult();
1635 EXPECT_EQ(OK, rv);
1636 EXPECT_TRUE(trans->GetResponseInfo() != NULL);
1637
1638 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
1639 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
1640 if (rv == ERR_IO_PENDING)
1641 rv = callback.WaitForResult();
1642 EXPECT_EQ(5, rv);
1643 trans.reset();
1644}
1645
1646// Test that network use can be deferred and canceled.
1647TEST_P(HttpNetworkTransactionTest, ThrottleAndCancelBeforeNetworkStart) {
1648 HttpRequestInfo request;
1649 request.method = "GET";
1650 request.url = GURL("http://www.google.com/");
1651 request.load_flags = 0;
1652
1653 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1654 scoped_ptr<HttpTransaction> trans(
1655 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1656
1657 // Defer on OnBeforeNetworkStart.
1658 BeforeNetworkStartHandler net_start_handler(true); // defer
1659 trans->SetBeforeNetworkStartCallback(
1660 base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
1661 base::Unretained(&net_start_handler)));
1662
1663 TestCompletionCallback callback;
1664
1665 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1666 EXPECT_EQ(ERR_IO_PENDING, rv);
1667 base::MessageLoop::current()->RunUntilIdle();
1668
1669 // Should have deferred for network start.
1670 EXPECT_TRUE(net_start_handler.observed_before_network_start());
1671 EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
1672 EXPECT_TRUE(trans->GetResponseInfo() == NULL);
1673}
1674
[email protected]7a5378b2012-11-04 03:25:171675// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
1676// tests. There was a bug causing HttpNetworkTransaction to hang in the
1677// destructor in such situations.
1678// See http://crbug.com/154712 and http://crbug.com/156609.
[email protected]23e482282013-06-14 16:08:021679TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:171680 HttpRequestInfo request;
1681 request.method = "GET";
1682 request.url = GURL("http://www.google.com/");
1683 request.load_flags = 0;
1684
[email protected]bb88e1d32013-05-03 23:11:071685 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:361686 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501687 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171688
1689 MockRead data_reads[] = {
1690 MockRead("HTTP/1.0 200 OK\r\n"),
1691 MockRead("Connection: keep-alive\r\n"),
1692 MockRead("Content-Length: 100\r\n\r\n"),
1693 MockRead("hello"),
1694 MockRead(SYNCHRONOUS, 0),
1695 };
1696 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071697 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171698
1699 TestCompletionCallback callback;
1700
1701 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1702 EXPECT_EQ(ERR_IO_PENDING, rv);
1703
1704 rv = callback.WaitForResult();
1705 EXPECT_EQ(OK, rv);
1706
1707 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501708 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171709 if (rv == ERR_IO_PENDING)
1710 rv = callback.WaitForResult();
1711 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:501712 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171713 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1714
1715 trans.reset();
[email protected]2da659e2013-05-23 20:51:341716 base::MessageLoop::current()->RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171717 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1718}
1719
[email protected]23e482282013-06-14 16:08:021720TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:171721 HttpRequestInfo request;
1722 request.method = "GET";
1723 request.url = GURL("http://www.google.com/");
1724 request.load_flags = 0;
1725
[email protected]bb88e1d32013-05-03 23:11:071726 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:361727 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501728 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171729
1730 MockRead data_reads[] = {
1731 MockRead("HTTP/1.0 200 OK\r\n"),
1732 MockRead("Connection: keep-alive\r\n"),
1733 MockRead("Content-Length: 100\r\n\r\n"),
1734 MockRead(SYNCHRONOUS, 0),
1735 };
1736 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071737 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171738
1739 TestCompletionCallback callback;
1740
1741 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1742 EXPECT_EQ(ERR_IO_PENDING, rv);
1743
1744 rv = callback.WaitForResult();
1745 EXPECT_EQ(OK, rv);
1746
1747 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501748 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171749 if (rv == ERR_IO_PENDING)
1750 rv = callback.WaitForResult();
1751 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1752
1753 trans.reset();
[email protected]2da659e2013-05-23 20:51:341754 base::MessageLoop::current()->RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171755 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1756}
1757
[email protected]0b0bf032010-09-21 18:08:501758// Test that we correctly reuse a keep-alive connection after not explicitly
1759// reading the body.
[email protected]23e482282013-06-14 16:08:021760TEST_P(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:131761 HttpRequestInfo request;
1762 request.method = "GET";
1763 request.url = GURL("http://www.foo.com/");
1764 request.load_flags = 0;
1765
[email protected]58e32bb2013-01-21 18:23:251766 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071767 session_deps_.net_log = &net_log;
1768 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271769
[email protected]0b0bf032010-09-21 18:08:501770 // Note that because all these reads happen in the same
1771 // StaticSocketDataProvider, it shows that the same socket is being reused for
1772 // all transactions.
[email protected]fc31d6a42010-06-24 18:05:131773 MockRead data1_reads[] = {
[email protected]0b0bf032010-09-21 18:08:501774 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
1775 MockRead("HTTP/1.1 205 Reset Content\r\n\r\n"),
[email protected]fc31d6a42010-06-24 18:05:131776 MockRead("HTTP/1.1 304 Not Modified\r\n\r\n"),
[email protected]0b0bf032010-09-21 18:08:501777 MockRead("HTTP/1.1 302 Found\r\n"
1778 "Content-Length: 0\r\n\r\n"),
1779 MockRead("HTTP/1.1 302 Found\r\n"
1780 "Content-Length: 5\r\n\r\n"
1781 "hello"),
1782 MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1783 "Content-Length: 0\r\n\r\n"),
1784 MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1785 "Content-Length: 5\r\n\r\n"
1786 "hello"),
[email protected]fc31d6a42010-06-24 18:05:131787 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1788 MockRead("hello"),
1789 };
1790 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071791 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]fc31d6a42010-06-24 18:05:131792
1793 MockRead data2_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061794 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]fc31d6a42010-06-24 18:05:131795 };
1796 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071797 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]fc31d6a42010-06-24 18:05:131798
[email protected]0b0bf032010-09-21 18:08:501799 const int kNumUnreadBodies = arraysize(data1_reads) - 2;
1800 std::string response_lines[kNumUnreadBodies];
1801
[email protected]58e32bb2013-01-21 18:23:251802 uint32 first_socket_log_id = NetLog::Source::kInvalidId;
[email protected]0b0bf032010-09-21 18:08:501803 for (size_t i = 0; i < arraysize(data1_reads) - 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411804 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:131805
[email protected]262eec82013-03-19 21:01:361806 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501807 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]fc31d6a42010-06-24 18:05:131808
[email protected]49639fa2011-12-20 23:22:411809 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]fc31d6a42010-06-24 18:05:131810 EXPECT_EQ(ERR_IO_PENDING, rv);
1811
1812 rv = callback.WaitForResult();
1813 EXPECT_EQ(OK, rv);
1814
[email protected]58e32bb2013-01-21 18:23:251815 LoadTimingInfo load_timing_info;
1816 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1817 if (i == 0) {
1818 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1819 first_socket_log_id = load_timing_info.socket_log_id;
1820 } else {
1821 TestLoadTimingReused(load_timing_info);
1822 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
1823 }
1824
[email protected]fc31d6a42010-06-24 18:05:131825 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]0b0bf032010-09-21 18:08:501826 ASSERT_TRUE(response != NULL);
[email protected]fc31d6a42010-06-24 18:05:131827
[email protected]90499482013-06-01 00:39:501828 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]0b0bf032010-09-21 18:08:501829 response_lines[i] = response->headers->GetStatusLine();
1830
1831 // We intentionally don't read the response bodies.
[email protected]fc31d6a42010-06-24 18:05:131832 }
[email protected]0b0bf032010-09-21 18:08:501833
1834 const char* const kStatusLines[] = {
1835 "HTTP/1.1 204 No Content",
1836 "HTTP/1.1 205 Reset Content",
1837 "HTTP/1.1 304 Not Modified",
1838 "HTTP/1.1 302 Found",
1839 "HTTP/1.1 302 Found",
1840 "HTTP/1.1 301 Moved Permanently",
1841 "HTTP/1.1 301 Moved Permanently",
1842 };
1843
1844 COMPILE_ASSERT(kNumUnreadBodies == arraysize(kStatusLines),
1845 forgot_to_update_kStatusLines);
1846
1847 for (int i = 0; i < kNumUnreadBodies; ++i)
1848 EXPECT_EQ(kStatusLines[i], response_lines[i]);
1849
[email protected]49639fa2011-12-20 23:22:411850 TestCompletionCallback callback;
[email protected]262eec82013-03-19 21:01:361851 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501852 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:411853 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0b0bf032010-09-21 18:08:501854 EXPECT_EQ(ERR_IO_PENDING, rv);
1855 rv = callback.WaitForResult();
1856 EXPECT_EQ(OK, rv);
1857 const HttpResponseInfo* response = trans->GetResponseInfo();
1858 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:501859 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]0b0bf032010-09-21 18:08:501860 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1861 std::string response_data;
1862 rv = ReadTransaction(trans.get(), &response_data);
1863 EXPECT_EQ(OK, rv);
1864 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:131865}
1866
[email protected]038e9a32008-10-08 22:40:161867// Test the request-challenge-retry sequence for basic auth.
1868// (basic auth is the easiest to mock, because it has no randomness).
[email protected]23e482282013-06-14 16:08:021869TEST_P(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:421870 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:161871 request.method = "GET";
1872 request.url = GURL("http://www.google.com/");
1873 request.load_flags = 0;
1874
[email protected]58e32bb2013-01-21 18:23:251875 CapturingNetLog log;
[email protected]bb88e1d32013-05-03 23:11:071876 session_deps_.net_log = &log;
[email protected]3fe8d2f82013-10-17 08:56:071877 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271878 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411879 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271880
[email protected]f9ee6b52008-11-08 06:46:231881 MockWrite data_writes1[] = {
1882 MockWrite("GET / HTTP/1.1\r\n"
1883 "Host: www.google.com\r\n"
1884 "Connection: keep-alive\r\n\r\n"),
1885 };
1886
[email protected]038e9a32008-10-08 22:40:161887 MockRead data_reads1[] = {
1888 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
1889 // Give a couple authenticate options (only the middle one is actually
1890 // supported).
[email protected]22927ad2009-09-21 19:56:191891 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:161892 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1893 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
1894 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1895 // Large content-length -- won't matter, as connection will be reset.
1896 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061897 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:161898 };
1899
1900 // After calling trans->RestartWithAuth(), this is the request we should
1901 // be issuing -- the final header line contains the credentials.
1902 MockWrite data_writes2[] = {
1903 MockWrite("GET / HTTP/1.1\r\n"
1904 "Host: www.google.com\r\n"
1905 "Connection: keep-alive\r\n"
1906 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1907 };
1908
1909 // Lastly, the server responds with the actual content.
1910 MockRead data_reads2[] = {
1911 MockRead("HTTP/1.0 200 OK\r\n"),
1912 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1913 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061914 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:161915 };
1916
[email protected]31a2bfe2010-02-09 08:03:391917 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1918 data_writes1, arraysize(data_writes1));
1919 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1920 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:071921 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1922 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:161923
[email protected]49639fa2011-12-20 23:22:411924 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:161925
[email protected]49639fa2011-12-20 23:22:411926 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421927 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:161928
1929 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421930 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:161931
[email protected]58e32bb2013-01-21 18:23:251932 LoadTimingInfo load_timing_info1;
1933 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
1934 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
1935
[email protected]b8015c42013-12-24 15:18:191936 int64 reads_size1 = ReadsSize(data_reads1, arraysize(data_reads1));
1937 EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
1938
[email protected]1c773ea12009-04-28 19:58:421939 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501940 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:041941 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:161942
[email protected]49639fa2011-12-20 23:22:411943 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:161944
[email protected]49639fa2011-12-20 23:22:411945 rv = trans->RestartWithAuth(
1946 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:421947 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:161948
1949 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421950 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:161951
[email protected]58e32bb2013-01-21 18:23:251952 LoadTimingInfo load_timing_info2;
1953 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
1954 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
1955 // The load timing after restart should have a new socket ID, and times after
1956 // those of the first load timing.
1957 EXPECT_LE(load_timing_info1.receive_headers_end,
1958 load_timing_info2.connect_timing.connect_start);
1959 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
1960
[email protected]b8015c42013-12-24 15:18:191961 int64 reads_size2 = ReadsSize(data_reads2, arraysize(data_reads2));
1962 EXPECT_EQ(reads_size1 + reads_size2, trans->GetTotalReceivedBytes());
1963
[email protected]038e9a32008-10-08 22:40:161964 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501965 ASSERT_TRUE(response != NULL);
[email protected]038e9a32008-10-08 22:40:161966 EXPECT_TRUE(response->auth_challenge.get() == NULL);
1967 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:161968}
1969
[email protected]23e482282013-06-14 16:08:021970TEST_P(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:461971 HttpRequestInfo request;
1972 request.method = "GET";
1973 request.url = GURL("http://www.google.com/");
1974 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
1975
[email protected]3fe8d2f82013-10-17 08:56:071976 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271977 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411978 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271979
[email protected]861fcd52009-08-26 02:33:461980 MockWrite data_writes[] = {
1981 MockWrite("GET / HTTP/1.1\r\n"
1982 "Host: www.google.com\r\n"
1983 "Connection: keep-alive\r\n\r\n"),
1984 };
1985
1986 MockRead data_reads[] = {
1987 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
1988 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1989 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1990 // Large content-length -- won't matter, as connection will be reset.
1991 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061992 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:461993 };
1994
[email protected]31a2bfe2010-02-09 08:03:391995 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
1996 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:071997 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:411998 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:461999
[email protected]49639fa2011-12-20 23:22:412000 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]861fcd52009-08-26 02:33:462001 EXPECT_EQ(ERR_IO_PENDING, rv);
2002
2003 rv = callback.WaitForResult();
2004 EXPECT_EQ(0, rv);
2005
[email protected]b8015c42013-12-24 15:18:192006 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
2007 EXPECT_EQ(reads_size, trans->GetTotalReceivedBytes());
2008
[email protected]861fcd52009-08-26 02:33:462009 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502010 ASSERT_TRUE(response != NULL);
[email protected]861fcd52009-08-26 02:33:462011 EXPECT_TRUE(response->auth_challenge.get() == NULL);
2012}
2013
[email protected]2d2697f92009-02-18 21:00:322014// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2015// connection.
[email protected]23e482282013-06-14 16:08:022016TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
[email protected]1c773ea12009-04-28 19:58:422017 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322018 request.method = "GET";
2019 request.url = GURL("http://www.google.com/");
2020 request.load_flags = 0;
2021
[email protected]58e32bb2013-01-21 18:23:252022 CapturingNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072023 session_deps_.net_log = &log;
2024 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272025
[email protected]2d2697f92009-02-18 21:00:322026 MockWrite data_writes1[] = {
2027 MockWrite("GET / HTTP/1.1\r\n"
2028 "Host: www.google.com\r\n"
2029 "Connection: keep-alive\r\n\r\n"),
2030
2031 // After calling trans->RestartWithAuth(), this is the request we should
2032 // be issuing -- the final header line contains the credentials.
2033 MockWrite("GET / HTTP/1.1\r\n"
2034 "Host: www.google.com\r\n"
2035 "Connection: keep-alive\r\n"
2036 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2037 };
2038
2039 MockRead data_reads1[] = {
2040 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2041 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2042 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2043 MockRead("Content-Length: 14\r\n\r\n"),
2044 MockRead("Unauthorized\r\n"),
2045
2046 // Lastly, the server responds with the actual content.
2047 MockRead("HTTP/1.1 200 OK\r\n"),
2048 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502049 MockRead("Content-Length: 5\r\n\r\n"),
2050 MockRead("Hello"),
[email protected]2d2697f92009-02-18 21:00:322051 };
2052
[email protected]2d0a4f92011-05-05 16:38:462053 // If there is a regression where we disconnect a Keep-Alive
2054 // connection during an auth roundtrip, we'll end up reading this.
2055 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062056 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462057 };
2058
[email protected]31a2bfe2010-02-09 08:03:392059 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2060 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462061 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2062 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072063 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2064 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322065
[email protected]49639fa2011-12-20 23:22:412066 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322067
[email protected]262eec82013-03-19 21:01:362068 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502069 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412070 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422071 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322072
2073 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422074 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322075
[email protected]58e32bb2013-01-21 18:23:252076 LoadTimingInfo load_timing_info1;
2077 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
2078 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2079
[email protected]1c773ea12009-04-28 19:58:422080 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502081 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042082 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322083
[email protected]49639fa2011-12-20 23:22:412084 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322085
[email protected]49639fa2011-12-20 23:22:412086 rv = trans->RestartWithAuth(
2087 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422088 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322089
2090 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422091 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322092
[email protected]58e32bb2013-01-21 18:23:252093 LoadTimingInfo load_timing_info2;
2094 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
2095 TestLoadTimingReused(load_timing_info2);
2096 // The load timing after restart should have the same socket ID, and times
2097 // those of the first load timing.
2098 EXPECT_LE(load_timing_info1.receive_headers_end,
2099 load_timing_info2.send_start);
2100 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2101
[email protected]2d2697f92009-02-18 21:00:322102 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502103 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322104 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502105 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]b8015c42013-12-24 15:18:192106
2107 std::string response_data;
2108 rv = ReadTransaction(trans.get(), &response_data);
2109 EXPECT_EQ(OK, rv);
2110 int64 reads_size1 = ReadsSize(data_reads1, arraysize(data_reads1));
2111 EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
[email protected]2d2697f92009-02-18 21:00:322112}
2113
2114// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2115// connection and with no response body to drain.
[email protected]23e482282013-06-14 16:08:022116TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:422117 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322118 request.method = "GET";
2119 request.url = GURL("http://www.google.com/");
2120 request.load_flags = 0;
2121
[email protected]bb88e1d32013-05-03 23:11:072122 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272123
[email protected]2d2697f92009-02-18 21:00:322124 MockWrite data_writes1[] = {
2125 MockWrite("GET / HTTP/1.1\r\n"
2126 "Host: www.google.com\r\n"
2127 "Connection: keep-alive\r\n\r\n"),
2128
2129 // After calling trans->RestartWithAuth(), this is the request we should
2130 // be issuing -- the final header line contains the credentials.
2131 MockWrite("GET / HTTP/1.1\r\n"
2132 "Host: www.google.com\r\n"
2133 "Connection: keep-alive\r\n"
2134 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2135 };
2136
[email protected]2d2697f92009-02-18 21:00:322137 MockRead data_reads1[] = {
2138 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2139 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:312140 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:322141
2142 // Lastly, the server responds with the actual content.
2143 MockRead("HTTP/1.1 200 OK\r\n"),
2144 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502145 MockRead("Content-Length: 5\r\n\r\n"),
2146 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322147 };
2148
[email protected]2d0a4f92011-05-05 16:38:462149 // An incorrect reconnect would cause this to be read.
2150 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062151 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462152 };
2153
[email protected]31a2bfe2010-02-09 08:03:392154 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2155 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462156 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2157 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072158 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2159 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322160
[email protected]49639fa2011-12-20 23:22:412161 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322162
[email protected]262eec82013-03-19 21:01:362163 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502164 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412165 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422166 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322167
2168 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422169 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322170
[email protected]1c773ea12009-04-28 19:58:422171 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502172 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042173 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322174
[email protected]49639fa2011-12-20 23:22:412175 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322176
[email protected]49639fa2011-12-20 23:22:412177 rv = trans->RestartWithAuth(
2178 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422179 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322180
2181 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422182 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322183
2184 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502185 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322186 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502187 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322188}
2189
2190// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2191// connection and with a large response body to drain.
[email protected]23e482282013-06-14 16:08:022192TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:422193 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322194 request.method = "GET";
2195 request.url = GURL("http://www.google.com/");
2196 request.load_flags = 0;
2197
[email protected]bb88e1d32013-05-03 23:11:072198 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272199
[email protected]2d2697f92009-02-18 21:00:322200 MockWrite data_writes1[] = {
2201 MockWrite("GET / HTTP/1.1\r\n"
2202 "Host: www.google.com\r\n"
2203 "Connection: keep-alive\r\n\r\n"),
2204
2205 // After calling trans->RestartWithAuth(), this is the request we should
2206 // be issuing -- the final header line contains the credentials.
2207 MockWrite("GET / HTTP/1.1\r\n"
2208 "Host: www.google.com\r\n"
2209 "Connection: keep-alive\r\n"
2210 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2211 };
2212
2213 // Respond with 5 kb of response body.
2214 std::string large_body_string("Unauthorized");
2215 large_body_string.append(5 * 1024, ' ');
2216 large_body_string.append("\r\n");
2217
2218 MockRead data_reads1[] = {
2219 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2220 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2221 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2222 // 5134 = 12 + 5 * 1024 + 2
2223 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062224 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:322225
2226 // Lastly, the server responds with the actual content.
2227 MockRead("HTTP/1.1 200 OK\r\n"),
2228 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502229 MockRead("Content-Length: 5\r\n\r\n"),
2230 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322231 };
2232
[email protected]2d0a4f92011-05-05 16:38:462233 // An incorrect reconnect would cause this to be read.
2234 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062235 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462236 };
2237
[email protected]31a2bfe2010-02-09 08:03:392238 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2239 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462240 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2241 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072242 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2243 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322244
[email protected]49639fa2011-12-20 23:22:412245 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322246
[email protected]262eec82013-03-19 21:01:362247 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502248 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412249 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422250 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322251
2252 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422253 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322254
[email protected]1c773ea12009-04-28 19:58:422255 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502256 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042257 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322258
[email protected]49639fa2011-12-20 23:22:412259 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322260
[email protected]49639fa2011-12-20 23:22:412261 rv = trans->RestartWithAuth(
2262 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422263 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322264
2265 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422266 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322267
2268 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502269 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322270 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502271 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322272}
2273
2274// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:312275// connection, but the server gets impatient and closes the connection.
[email protected]23e482282013-06-14 16:08:022276TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:312277 HttpRequestInfo request;
2278 request.method = "GET";
2279 request.url = GURL("http://www.google.com/");
2280 request.load_flags = 0;
2281
[email protected]bb88e1d32013-05-03 23:11:072282 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272283
[email protected]11203f012009-11-12 23:02:312284 MockWrite data_writes1[] = {
2285 MockWrite("GET / HTTP/1.1\r\n"
2286 "Host: www.google.com\r\n"
2287 "Connection: keep-alive\r\n\r\n"),
2288 // This simulates the seemingly successful write to a closed connection
2289 // if the bug is not fixed.
2290 MockWrite("GET / HTTP/1.1\r\n"
2291 "Host: www.google.com\r\n"
2292 "Connection: keep-alive\r\n"
2293 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2294 };
2295
2296 MockRead data_reads1[] = {
2297 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2298 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2299 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2300 MockRead("Content-Length: 14\r\n\r\n"),
2301 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:062302 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:312303 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:062304 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:312305 };
2306
2307 // After calling trans->RestartWithAuth(), this is the request we should
2308 // be issuing -- the final header line contains the credentials.
2309 MockWrite data_writes2[] = {
2310 MockWrite("GET / HTTP/1.1\r\n"
2311 "Host: www.google.com\r\n"
2312 "Connection: keep-alive\r\n"
2313 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2314 };
2315
2316 // Lastly, the server responds with the actual content.
2317 MockRead data_reads2[] = {
2318 MockRead("HTTP/1.1 200 OK\r\n"),
2319 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502320 MockRead("Content-Length: 5\r\n\r\n"),
2321 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:312322 };
2323
[email protected]31a2bfe2010-02-09 08:03:392324 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2325 data_writes1, arraysize(data_writes1));
2326 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2327 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072328 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2329 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:312330
[email protected]49639fa2011-12-20 23:22:412331 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:312332
[email protected]262eec82013-03-19 21:01:362333 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502334 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412335 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]11203f012009-11-12 23:02:312336 EXPECT_EQ(ERR_IO_PENDING, rv);
2337
2338 rv = callback1.WaitForResult();
2339 EXPECT_EQ(OK, rv);
2340
2341 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502342 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042343 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:312344
[email protected]49639fa2011-12-20 23:22:412345 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:312346
[email protected]49639fa2011-12-20 23:22:412347 rv = trans->RestartWithAuth(
2348 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]11203f012009-11-12 23:02:312349 EXPECT_EQ(ERR_IO_PENDING, rv);
2350
2351 rv = callback2.WaitForResult();
2352 EXPECT_EQ(OK, rv);
2353
2354 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502355 ASSERT_TRUE(response != NULL);
[email protected]11203f012009-11-12 23:02:312356 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502357 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:312358}
2359
[email protected]394816e92010-08-03 07:38:592360// Test the request-challenge-retry sequence for basic auth, over a connection
2361// that requires a restart when setting up an SSL tunnel.
[email protected]23e482282013-06-14 16:08:022362TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAlive) {
[email protected]394816e92010-08-03 07:38:592363 HttpRequestInfo request;
2364 request.method = "GET";
2365 request.url = GURL("https://www.google.com/");
2366 // when the no authentication data flag is set.
2367 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
2368
[email protected]cb9bf6ca2011-01-28 13:15:272369 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072370 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:202371 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
[email protected]333bdf62012-06-08 22:57:292372 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072373 session_deps_.net_log = log.bound().net_log();
2374 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272375
[email protected]394816e92010-08-03 07:38:592376 // Since we have proxy, should try to establish tunnel.
2377 MockWrite data_writes1[] = {
2378 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2379 "Host: www.google.com\r\n"
2380 "Proxy-Connection: keep-alive\r\n\r\n"),
2381
2382 // After calling trans->RestartWithAuth(), this is the request we should
2383 // be issuing -- the final header line contains the credentials.
2384 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2385 "Host: www.google.com\r\n"
2386 "Proxy-Connection: keep-alive\r\n"
2387 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2388
2389 MockWrite("GET / HTTP/1.1\r\n"
2390 "Host: www.google.com\r\n"
2391 "Connection: keep-alive\r\n\r\n"),
2392 };
2393
2394 // The proxy responds to the connect with a 407, using a persistent
2395 // connection.
2396 MockRead data_reads1[] = {
2397 // No credentials.
2398 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2399 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2400 MockRead("Proxy-Connection: close\r\n\r\n"),
2401
2402 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2403
2404 MockRead("HTTP/1.1 200 OK\r\n"),
2405 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502406 MockRead("Content-Length: 5\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062407 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:592408 };
2409
2410 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2411 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072412 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:062413 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072414 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:592415
[email protected]49639fa2011-12-20 23:22:412416 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:592417
[email protected]262eec82013-03-19 21:01:362418 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502419 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:502420
[email protected]49639fa2011-12-20 23:22:412421 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]394816e92010-08-03 07:38:592422 EXPECT_EQ(ERR_IO_PENDING, rv);
2423
2424 rv = callback1.WaitForResult();
2425 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:572426 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:402427 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:592428 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402429 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]394816e92010-08-03 07:38:592430 NetLog::PHASE_NONE);
2431 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402432 entries, pos,
[email protected]394816e92010-08-03 07:38:592433 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2434 NetLog::PHASE_NONE);
2435
2436 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502437 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502438 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]394816e92010-08-03 07:38:592439 EXPECT_EQ(407, response->headers->response_code());
2440 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042441 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:592442
[email protected]029c83b62013-01-24 05:28:202443 LoadTimingInfo load_timing_info;
2444 // CONNECT requests and responses are handled at the connect job level, so
2445 // the transaction does not yet have a connection.
2446 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
2447
[email protected]49639fa2011-12-20 23:22:412448 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:592449
[email protected]49639fa2011-12-20 23:22:412450 rv = trans->RestartWithAuth(
2451 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]394816e92010-08-03 07:38:592452 EXPECT_EQ(ERR_IO_PENDING, rv);
2453
2454 rv = callback2.WaitForResult();
2455 EXPECT_EQ(OK, rv);
2456
2457 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502458 ASSERT_TRUE(response != NULL);
[email protected]394816e92010-08-03 07:38:592459
2460 EXPECT_TRUE(response->headers->IsKeepAlive());
2461 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:502462 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:592463 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2464
2465 // The password prompt info should not be set.
2466 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502467
[email protected]029c83b62013-01-24 05:28:202468 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2469 TestLoadTimingNotReusedWithPac(load_timing_info,
2470 CONNECT_TIMING_HAS_SSL_TIMES);
2471
[email protected]0b0bf032010-09-21 18:08:502472 trans.reset();
[email protected]102e27c2011-02-23 01:01:312473 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:592474}
2475
[email protected]11203f012009-11-12 23:02:312476// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]2d2697f92009-02-18 21:00:322477// proxy connection, when setting up an SSL tunnel.
[email protected]23e482282013-06-14 16:08:022478TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAlive) {
[email protected]cb9bf6ca2011-01-28 13:15:272479 HttpRequestInfo request;
2480 request.method = "GET";
2481 request.url = GURL("https://www.google.com/");
2482 // Ensure that proxy authentication is attempted even
2483 // when the no authentication data flag is set.
2484 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
2485
[email protected]2d2697f92009-02-18 21:00:322486 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072487 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]333bdf62012-06-08 22:57:292488 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072489 session_deps_.net_log = log.bound().net_log();
2490 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:322491
[email protected]262eec82013-03-19 21:01:362492 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502493 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d2697f92009-02-18 21:00:322494
[email protected]2d2697f92009-02-18 21:00:322495 // Since we have proxy, should try to establish tunnel.
2496 MockWrite data_writes1[] = {
2497 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:452498 "Host: www.google.com\r\n"
2499 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322500
2501 // After calling trans->RestartWithAuth(), this is the request we should
2502 // be issuing -- the final header line contains the credentials.
2503 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2504 "Host: www.google.com\r\n"
[email protected]e44de5d2009-06-05 20:12:452505 "Proxy-Connection: keep-alive\r\n"
[email protected]2d2697f92009-02-18 21:00:322506 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
2507 };
2508
2509 // The proxy responds to the connect with a 407, using a persistent
2510 // connection.
2511 MockRead data_reads1[] = {
2512 // No credentials.
2513 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2514 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2515 MockRead("Content-Length: 10\r\n\r\n"),
2516 MockRead("0123456789"),
2517
2518 // Wrong credentials (wrong password).
2519 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2520 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2521 MockRead("Content-Length: 10\r\n\r\n"),
2522 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:062523 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]2d2697f92009-02-18 21:00:322524 };
2525
[email protected]31a2bfe2010-02-09 08:03:392526 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2527 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072528 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d2697f92009-02-18 21:00:322529
[email protected]49639fa2011-12-20 23:22:412530 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322531
[email protected]49639fa2011-12-20 23:22:412532 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]1c773ea12009-04-28 19:58:422533 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322534
2535 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422536 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:572537 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:402538 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:392539 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402540 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]dbb83db2010-05-11 18:13:392541 NetLog::PHASE_NONE);
2542 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402543 entries, pos,
[email protected]dbb83db2010-05-11 18:13:392544 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2545 NetLog::PHASE_NONE);
[email protected]2d2697f92009-02-18 21:00:322546
[email protected]1c773ea12009-04-28 19:58:422547 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502548 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502549 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]2d2697f92009-02-18 21:00:322550 EXPECT_TRUE(response->headers->IsKeepAlive());
2551 EXPECT_EQ(407, response->headers->response_code());
2552 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422553 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042554 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322555
[email protected]49639fa2011-12-20 23:22:412556 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322557
2558 // Wrong password (should be "bar").
[email protected]49639fa2011-12-20 23:22:412559 rv = trans->RestartWithAuth(
2560 AuthCredentials(kFoo, kBaz), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422561 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322562
2563 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422564 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322565
2566 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502567 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502568 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]2d2697f92009-02-18 21:00:322569 EXPECT_TRUE(response->headers->IsKeepAlive());
2570 EXPECT_EQ(407, response->headers->response_code());
2571 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422572 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042573 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]e772db3f2010-07-12 18:11:132574
[email protected]e60e47a2010-07-14 03:37:182575 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
2576 // out of scope.
[email protected]102e27c2011-02-23 01:01:312577 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:322578}
2579
[email protected]a8e9b162009-03-12 00:06:442580// Test that we don't read the response body when we fail to establish a tunnel,
2581// even if the user cancels the proxy's auth attempt.
[email protected]23e482282013-06-14 16:08:022582TEST_P(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:272583 HttpRequestInfo request;
2584 request.method = "GET";
2585 request.url = GURL("https://www.google.com/");
2586 request.load_flags = 0;
2587
[email protected]a8e9b162009-03-12 00:06:442588 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072589 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]a8e9b162009-03-12 00:06:442590
[email protected]bb88e1d32013-05-03 23:11:072591 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:442592
[email protected]262eec82013-03-19 21:01:362593 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502594 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]a8e9b162009-03-12 00:06:442595
[email protected]a8e9b162009-03-12 00:06:442596 // Since we have proxy, should try to establish tunnel.
2597 MockWrite data_writes[] = {
2598 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:452599 "Host: www.google.com\r\n"
2600 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:442601 };
2602
2603 // The proxy responds to the connect with a 407.
2604 MockRead data_reads[] = {
2605 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2606 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2607 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062608 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]a8e9b162009-03-12 00:06:442609 };
2610
[email protected]31a2bfe2010-02-09 08:03:392611 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2612 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072613 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:442614
[email protected]49639fa2011-12-20 23:22:412615 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:442616
[email protected]49639fa2011-12-20 23:22:412617 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422618 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a8e9b162009-03-12 00:06:442619
2620 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422621 EXPECT_EQ(OK, rv);
[email protected]a8e9b162009-03-12 00:06:442622
[email protected]1c773ea12009-04-28 19:58:422623 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502624 ASSERT_TRUE(response != NULL);
[email protected]a8e9b162009-03-12 00:06:442625
2626 EXPECT_TRUE(response->headers->IsKeepAlive());
2627 EXPECT_EQ(407, response->headers->response_code());
2628 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422629 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:442630
2631 std::string response_data;
2632 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:422633 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]e60e47a2010-07-14 03:37:182634
2635 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:312636 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:442637}
2638
[email protected]8fdbcd22010-05-05 02:54:522639// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
2640// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
[email protected]23e482282013-06-14 16:08:022641TEST_P(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:522642 HttpRequestInfo request;
2643 request.method = "GET";
2644 request.url = GURL("http://www.google.com/");
2645 request.load_flags = 0;
2646
[email protected]cb9bf6ca2011-01-28 13:15:272647 // We are using a DIRECT connection (i.e. no proxy) for this session.
[email protected]3fe8d2f82013-10-17 08:56:072648 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272649 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:412650 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:272651
[email protected]8fdbcd22010-05-05 02:54:522652 MockWrite data_writes1[] = {
2653 MockWrite("GET / HTTP/1.1\r\n"
2654 "Host: www.google.com\r\n"
2655 "Connection: keep-alive\r\n\r\n"),
2656 };
2657
2658 MockRead data_reads1[] = {
2659 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
2660 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2661 // Large content-length -- won't matter, as connection will be reset.
2662 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062663 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:522664 };
2665
2666 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2667 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072668 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:522669
[email protected]49639fa2011-12-20 23:22:412670 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:522671
[email protected]49639fa2011-12-20 23:22:412672 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]8fdbcd22010-05-05 02:54:522673 EXPECT_EQ(ERR_IO_PENDING, rv);
2674
2675 rv = callback.WaitForResult();
2676 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
2677}
2678
[email protected]7a67a8152010-11-05 18:31:102679// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
2680// through a non-authenticating proxy. The request should fail with
2681// ERR_UNEXPECTED_PROXY_AUTH.
2682// Note that it is impossible to detect if an HTTP server returns a 407 through
2683// a non-authenticating proxy - there is nothing to indicate whether the
2684// response came from the proxy or the server, so it is treated as if the proxy
2685// issued the challenge.
[email protected]23e482282013-06-14 16:08:022686TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:232687 HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:272688 HttpRequestInfo request;
2689 request.method = "GET";
2690 request.url = GURL("https://www.google.com/");
2691
[email protected]bb88e1d32013-05-03 23:11:072692 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]333bdf62012-06-08 22:57:292693 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072694 session_deps_.net_log = log.bound().net_log();
2695 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:102696
[email protected]7a67a8152010-11-05 18:31:102697 // Since we have proxy, should try to establish tunnel.
2698 MockWrite data_writes1[] = {
2699 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2700 "Host: www.google.com\r\n"
2701 "Proxy-Connection: keep-alive\r\n\r\n"),
2702
2703 MockWrite("GET / HTTP/1.1\r\n"
2704 "Host: www.google.com\r\n"
2705 "Connection: keep-alive\r\n\r\n"),
2706 };
2707
2708 MockRead data_reads1[] = {
2709 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2710
2711 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
2712 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2713 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:062714 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:102715 };
2716
2717 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2718 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072719 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:062720 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072721 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:102722
[email protected]49639fa2011-12-20 23:22:412723 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:102724
[email protected]262eec82013-03-19 21:01:362725 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502726 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a67a8152010-11-05 18:31:102727
[email protected]49639fa2011-12-20 23:22:412728 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7a67a8152010-11-05 18:31:102729 EXPECT_EQ(ERR_IO_PENDING, rv);
2730
2731 rv = callback1.WaitForResult();
2732 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
[email protected]f3da152d2012-06-02 01:00:572733 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:402734 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:102735 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402736 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]7a67a8152010-11-05 18:31:102737 NetLog::PHASE_NONE);
2738 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402739 entries, pos,
[email protected]7a67a8152010-11-05 18:31:102740 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2741 NetLog::PHASE_NONE);
2742}
[email protected]2df19bb2010-08-25 20:13:462743
[email protected]029c83b62013-01-24 05:28:202744// Test the load timing for HTTPS requests with an HTTP proxy.
[email protected]23e482282013-06-14 16:08:022745TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:202746 HttpRequestInfo request1;
2747 request1.method = "GET";
2748 request1.url = GURL("https://www.google.com/1");
2749
2750 HttpRequestInfo request2;
2751 request2.method = "GET";
2752 request2.url = GURL("https://www.google.com/2");
2753
2754 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072755 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:202756 ProxyService::CreateFixed("PROXY myproxy:70"));
2757 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072758 session_deps_.net_log = log.bound().net_log();
2759 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:202760
2761 // Since we have proxy, should try to establish tunnel.
2762 MockWrite data_writes1[] = {
2763 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2764 "Host: www.google.com\r\n"
2765 "Proxy-Connection: keep-alive\r\n\r\n"),
2766
2767 MockWrite("GET /1 HTTP/1.1\r\n"
2768 "Host: www.google.com\r\n"
2769 "Connection: keep-alive\r\n\r\n"),
2770
2771 MockWrite("GET /2 HTTP/1.1\r\n"
2772 "Host: www.google.com\r\n"
2773 "Connection: keep-alive\r\n\r\n"),
2774 };
2775
2776 // The proxy responds to the connect with a 407, using a persistent
2777 // connection.
2778 MockRead data_reads1[] = {
2779 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2780
2781 MockRead("HTTP/1.1 200 OK\r\n"),
2782 MockRead("Content-Length: 1\r\n\r\n"),
2783 MockRead(SYNCHRONOUS, "1"),
2784
2785 MockRead("HTTP/1.1 200 OK\r\n"),
2786 MockRead("Content-Length: 2\r\n\r\n"),
2787 MockRead(SYNCHRONOUS, "22"),
2788 };
2789
2790 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2791 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072792 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:202793 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072794 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:202795
2796 TestCompletionCallback callback1;
[email protected]262eec82013-03-19 21:01:362797 scoped_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:502798 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:202799
2800 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
2801 EXPECT_EQ(ERR_IO_PENDING, rv);
2802
2803 rv = callback1.WaitForResult();
2804 EXPECT_EQ(OK, rv);
2805
2806 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2807 ASSERT_TRUE(response1 != NULL);
[email protected]90499482013-06-01 00:39:502808 ASSERT_TRUE(response1->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:202809 EXPECT_EQ(1, response1->headers->GetContentLength());
2810
2811 LoadTimingInfo load_timing_info1;
2812 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
2813 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
2814
2815 trans1.reset();
2816
2817 TestCompletionCallback callback2;
[email protected]262eec82013-03-19 21:01:362818 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:502819 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:202820
2821 rv = trans2->Start(&request2, callback2.callback(), log.bound());
2822 EXPECT_EQ(ERR_IO_PENDING, rv);
2823
2824 rv = callback2.WaitForResult();
2825 EXPECT_EQ(OK, rv);
2826
2827 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2828 ASSERT_TRUE(response2 != NULL);
[email protected]90499482013-06-01 00:39:502829 ASSERT_TRUE(response2->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:202830 EXPECT_EQ(2, response2->headers->GetContentLength());
2831
2832 LoadTimingInfo load_timing_info2;
2833 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
2834 TestLoadTimingReused(load_timing_info2);
2835
2836 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2837
2838 trans2.reset();
2839 session->CloseAllConnections();
2840}
2841
2842// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
[email protected]23e482282013-06-14 16:08:022843TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:202844 HttpRequestInfo request1;
2845 request1.method = "GET";
2846 request1.url = GURL("https://www.google.com/1");
2847
2848 HttpRequestInfo request2;
2849 request2.method = "GET";
2850 request2.url = GURL("https://www.google.com/2");
2851
2852 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072853 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:202854 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
2855 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072856 session_deps_.net_log = log.bound().net_log();
2857 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:202858
2859 // Since we have proxy, should try to establish tunnel.
2860 MockWrite data_writes1[] = {
2861 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2862 "Host: www.google.com\r\n"
2863 "Proxy-Connection: keep-alive\r\n\r\n"),
2864
2865 MockWrite("GET /1 HTTP/1.1\r\n"
2866 "Host: www.google.com\r\n"
2867 "Connection: keep-alive\r\n\r\n"),
2868
2869 MockWrite("GET /2 HTTP/1.1\r\n"
2870 "Host: www.google.com\r\n"
2871 "Connection: keep-alive\r\n\r\n"),
2872 };
2873
2874 // The proxy responds to the connect with a 407, using a persistent
2875 // connection.
2876 MockRead data_reads1[] = {
2877 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2878
2879 MockRead("HTTP/1.1 200 OK\r\n"),
2880 MockRead("Content-Length: 1\r\n\r\n"),
2881 MockRead(SYNCHRONOUS, "1"),
2882
2883 MockRead("HTTP/1.1 200 OK\r\n"),
2884 MockRead("Content-Length: 2\r\n\r\n"),
2885 MockRead(SYNCHRONOUS, "22"),
2886 };
2887
2888 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2889 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072890 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:202891 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072892 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:202893
2894 TestCompletionCallback callback1;
[email protected]262eec82013-03-19 21:01:362895 scoped_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:502896 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:202897
2898 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
2899 EXPECT_EQ(ERR_IO_PENDING, rv);
2900
2901 rv = callback1.WaitForResult();
2902 EXPECT_EQ(OK, rv);
2903
2904 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2905 ASSERT_TRUE(response1 != NULL);
[email protected]90499482013-06-01 00:39:502906 ASSERT_TRUE(response1->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:202907 EXPECT_EQ(1, response1->headers->GetContentLength());
2908
2909 LoadTimingInfo load_timing_info1;
2910 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
2911 TestLoadTimingNotReusedWithPac(load_timing_info1,
2912 CONNECT_TIMING_HAS_SSL_TIMES);
2913
2914 trans1.reset();
2915
2916 TestCompletionCallback callback2;
[email protected]262eec82013-03-19 21:01:362917 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:502918 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:202919
2920 rv = trans2->Start(&request2, callback2.callback(), log.bound());
2921 EXPECT_EQ(ERR_IO_PENDING, rv);
2922
2923 rv = callback2.WaitForResult();
2924 EXPECT_EQ(OK, rv);
2925
2926 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2927 ASSERT_TRUE(response2 != NULL);
[email protected]90499482013-06-01 00:39:502928 ASSERT_TRUE(response2->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:202929 EXPECT_EQ(2, response2->headers->GetContentLength());
2930
2931 LoadTimingInfo load_timing_info2;
2932 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
2933 TestLoadTimingReusedWithPac(load_timing_info2);
2934
2935 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2936
2937 trans2.reset();
2938 session->CloseAllConnections();
2939}
2940
[email protected]2df19bb2010-08-25 20:13:462941// Test a simple get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:022942TEST_P(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:272943 HttpRequestInfo request;
2944 request.method = "GET";
2945 request.url = GURL("http://www.google.com/");
2946
[email protected]2df19bb2010-08-25 20:13:462947 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:072948 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:112949 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:292950 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072951 session_deps_.net_log = log.bound().net_log();
2952 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:462953
[email protected]2df19bb2010-08-25 20:13:462954 // Since we have proxy, should use full url
2955 MockWrite data_writes1[] = {
2956 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
2957 "Host: www.google.com\r\n"
2958 "Proxy-Connection: keep-alive\r\n\r\n"),
2959 };
2960
2961 MockRead data_reads1[] = {
2962 MockRead("HTTP/1.1 200 OK\r\n"),
2963 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2964 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062965 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:462966 };
2967
2968 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2969 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072970 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:062971 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072972 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:462973
[email protected]49639fa2011-12-20 23:22:412974 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:462975
[email protected]262eec82013-03-19 21:01:362976 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502977 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:502978
[email protected]49639fa2011-12-20 23:22:412979 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:462980 EXPECT_EQ(ERR_IO_PENDING, rv);
2981
2982 rv = callback1.WaitForResult();
2983 EXPECT_EQ(OK, rv);
2984
[email protected]58e32bb2013-01-21 18:23:252985 LoadTimingInfo load_timing_info;
2986 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2987 TestLoadTimingNotReused(load_timing_info,
2988 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
2989
[email protected]2df19bb2010-08-25 20:13:462990 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502991 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:462992
2993 EXPECT_TRUE(response->headers->IsKeepAlive());
2994 EXPECT_EQ(200, response->headers->response_code());
2995 EXPECT_EQ(100, response->headers->GetContentLength());
2996 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2997
2998 // The password prompt info should not be set.
2999 EXPECT_TRUE(response->auth_challenge.get() == NULL);
3000}
3001
[email protected]7642b5ae2010-09-01 20:55:173002// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023003TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:273004 HttpRequestInfo request;
3005 request.method = "GET";
3006 request.url = GURL("http://www.google.com/");
3007 request.load_flags = 0;
3008
[email protected]7642b5ae2010-09-01 20:55:173009 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073010 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113011 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:293012 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073013 session_deps_.net_log = log.bound().net_log();
3014 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:173015
[email protected]7642b5ae2010-09-01 20:55:173016 // fetch http://www.google.com/ via SPDY
[email protected]cdf8f7e72013-05-23 10:56:463017 scoped_ptr<SpdyFrame> req(
3018 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]7642b5ae2010-09-01 20:55:173019 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
3020
[email protected]23e482282013-06-14 16:08:023021 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3022 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:173023 MockRead spdy_reads[] = {
3024 CreateMockRead(*resp),
3025 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:063026 MockRead(ASYNC, 0, 0),
[email protected]7642b5ae2010-09-01 20:55:173027 };
3028
[email protected]dd54bd82012-07-19 23:44:573029 DelayedSocketData spdy_data(
3030 1, // wait for one write to finish before reading.
3031 spdy_reads, arraysize(spdy_reads),
3032 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073033 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:173034
[email protected]8ddf8322012-02-23 18:08:063035 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023036 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073037 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:173038
[email protected]49639fa2011-12-20 23:22:413039 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:173040
[email protected]262eec82013-03-19 21:01:363041 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503042 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503043
[email protected]49639fa2011-12-20 23:22:413044 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7642b5ae2010-09-01 20:55:173045 EXPECT_EQ(ERR_IO_PENDING, rv);
3046
3047 rv = callback1.WaitForResult();
3048 EXPECT_EQ(OK, rv);
3049
[email protected]58e32bb2013-01-21 18:23:253050 LoadTimingInfo load_timing_info;
3051 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3052 TestLoadTimingNotReused(load_timing_info,
3053 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3054
[email protected]7642b5ae2010-09-01 20:55:173055 const HttpResponseInfo* response = trans->GetResponseInfo();
3056 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503057 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]7642b5ae2010-09-01 20:55:173058 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3059
3060 std::string response_data;
3061 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:233062 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:173063}
3064
[email protected]1c173852014-06-19 12:51:503065// Verifies that a session which races and wins against the owning transaction
3066// (completing prior to host resolution), doesn't fail the transaction.
3067// Regression test for crbug.com/334413.
3068TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
3069 HttpRequestInfo request;
3070 request.method = "GET";
3071 request.url = GURL("http://www.google.com/");
3072 request.load_flags = 0;
3073
3074 // Configure SPDY proxy server "proxy:70".
3075 session_deps_.proxy_service.reset(
3076 ProxyService::CreateFixed("https://proxy:70"));
3077 CapturingBoundNetLog log;
3078 session_deps_.net_log = log.bound().net_log();
3079 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3080
3081 // Fetch http://www.google.com/ through the SPDY proxy.
3082 scoped_ptr<SpdyFrame> req(
3083 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
3084 MockWrite spdy_writes[] = {CreateMockWrite(*req)};
3085
3086 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3087 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
3088 MockRead spdy_reads[] = {
3089 CreateMockRead(*resp), CreateMockRead(*data), MockRead(ASYNC, 0, 0),
3090 };
3091
3092 DelayedSocketData spdy_data(
3093 1, // wait for one write to finish before reading.
3094 spdy_reads,
3095 arraysize(spdy_reads),
3096 spdy_writes,
3097 arraysize(spdy_writes));
3098 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
3099
3100 SSLSocketDataProvider ssl(ASYNC, OK);
3101 ssl.SetNextProto(GetParam());
3102 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3103
3104 TestCompletionCallback callback1;
3105
3106 scoped_ptr<HttpTransaction> trans(
3107 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3108
3109 // Stall the hostname resolution begun by the transaction.
3110 session_deps_.host_resolver->set_synchronous_mode(false);
3111 session_deps_.host_resolver->set_ondemand_mode(true);
3112
3113 int rv = trans->Start(&request, callback1.callback(), log.bound());
3114 EXPECT_EQ(ERR_IO_PENDING, rv);
3115
3116 // Race a session to the proxy, which completes first.
3117 session_deps_.host_resolver->set_ondemand_mode(false);
3118 SpdySessionKey key(
3119 HostPortPair("proxy", 70), ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
3120 base::WeakPtr<SpdySession> spdy_session =
3121 CreateSecureSpdySession(session, key, log.bound());
3122
3123 // Unstall the resolution begun by the transaction.
3124 session_deps_.host_resolver->set_ondemand_mode(true);
3125 session_deps_.host_resolver->ResolveAllPending();
3126
3127 EXPECT_FALSE(callback1.have_result());
3128 rv = callback1.WaitForResult();
3129 EXPECT_EQ(OK, rv);
3130
3131 const HttpResponseInfo* response = trans->GetResponseInfo();
3132 ASSERT_TRUE(response != NULL);
3133 ASSERT_TRUE(response->headers.get() != NULL);
3134 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3135
3136 std::string response_data;
3137 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
3138 EXPECT_EQ(kUploadData, response_data);
3139}
3140
[email protected]dc7bd1c52010-11-12 00:01:133141// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023142TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:273143 HttpRequestInfo request;
3144 request.method = "GET";
3145 request.url = GURL("http://www.google.com/");
3146 request.load_flags = 0;
3147
[email protected]79cb5c12011-09-12 13:12:043148 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073149 session_deps_.proxy_service.reset(
[email protected]79cb5c12011-09-12 13:12:043150 ProxyService::CreateFixed("https://myproxy:70"));
[email protected]333bdf62012-06-08 22:57:293151 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073152 session_deps_.net_log = log.bound().net_log();
3153 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:133154
[email protected]dc7bd1c52010-11-12 00:01:133155 // The first request will be a bare GET, the second request will be a
3156 // GET with a Proxy-Authorization header.
[email protected]ff98d7f02012-03-22 21:44:193157 scoped_ptr<SpdyFrame> req_get(
[email protected]cdf8f7e72013-05-23 10:56:463158 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]dc7bd1c52010-11-12 00:01:133159 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:463160 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:133161 };
[email protected]ff98d7f02012-03-22 21:44:193162 scoped_ptr<SpdyFrame> req_get_authorization(
[email protected]cdf8f7e72013-05-23 10:56:463163 spdy_util_.ConstructSpdyGet(kExtraAuthorizationHeaders,
3164 arraysize(kExtraAuthorizationHeaders) / 2,
3165 false,
3166 3,
3167 LOWEST,
3168 false));
[email protected]dc7bd1c52010-11-12 00:01:133169 MockWrite spdy_writes[] = {
3170 CreateMockWrite(*req_get, 1),
3171 CreateMockWrite(*req_get_authorization, 4),
3172 };
3173
3174 // The first response is a 407 proxy authentication challenge, and the second
3175 // response will be a 200 response since the second request includes a valid
3176 // Authorization header.
3177 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:463178 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:133179 };
[email protected]ff98d7f02012-03-22 21:44:193180 scoped_ptr<SpdyFrame> resp_authentication(
[email protected]23e482282013-06-14 16:08:023181 spdy_util_.ConstructSpdySynReplyError(
[email protected]dc7bd1c52010-11-12 00:01:133182 "407 Proxy Authentication Required",
3183 kExtraAuthenticationHeaders, arraysize(kExtraAuthenticationHeaders)/2,
3184 1));
[email protected]ff98d7f02012-03-22 21:44:193185 scoped_ptr<SpdyFrame> body_authentication(
[email protected]23e482282013-06-14 16:08:023186 spdy_util_.ConstructSpdyBodyFrame(1, true));
3187 scoped_ptr<SpdyFrame> resp_data(
3188 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
3189 scoped_ptr<SpdyFrame> body_data(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:133190 MockRead spdy_reads[] = {
3191 CreateMockRead(*resp_authentication, 2),
3192 CreateMockRead(*body_authentication, 3),
3193 CreateMockRead(*resp_data, 5),
3194 CreateMockRead(*body_data, 6),
[email protected]8ddf8322012-02-23 18:08:063195 MockRead(ASYNC, 0, 7),
[email protected]dc7bd1c52010-11-12 00:01:133196 };
3197
[email protected]dd54bd82012-07-19 23:44:573198 OrderedSocketData data(
3199 spdy_reads, arraysize(spdy_reads),
3200 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073201 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:133202
[email protected]8ddf8322012-02-23 18:08:063203 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023204 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073205 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:133206
[email protected]49639fa2011-12-20 23:22:413207 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:133208
[email protected]262eec82013-03-19 21:01:363209 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503210 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]dc7bd1c52010-11-12 00:01:133211
[email protected]49639fa2011-12-20 23:22:413212 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]dc7bd1c52010-11-12 00:01:133213 EXPECT_EQ(ERR_IO_PENDING, rv);
3214
3215 rv = callback1.WaitForResult();
3216 EXPECT_EQ(OK, rv);
3217
3218 const HttpResponseInfo* const response = trans->GetResponseInfo();
3219
3220 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503221 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]dc7bd1c52010-11-12 00:01:133222 EXPECT_EQ(407, response->headers->response_code());
3223 EXPECT_TRUE(response->was_fetched_via_spdy);
[email protected]79cb5c12011-09-12 13:12:043224 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:133225
[email protected]49639fa2011-12-20 23:22:413226 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:133227
[email protected]49639fa2011-12-20 23:22:413228 rv = trans->RestartWithAuth(
3229 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]dc7bd1c52010-11-12 00:01:133230 EXPECT_EQ(ERR_IO_PENDING, rv);
3231
3232 rv = callback2.WaitForResult();
3233 EXPECT_EQ(OK, rv);
3234
3235 const HttpResponseInfo* const response_restart = trans->GetResponseInfo();
3236
3237 ASSERT_TRUE(response_restart != NULL);
[email protected]90499482013-06-01 00:39:503238 ASSERT_TRUE(response_restart->headers.get() != NULL);
[email protected]dc7bd1c52010-11-12 00:01:133239 EXPECT_EQ(200, response_restart->headers->response_code());
3240 // The password prompt info should not be set.
3241 EXPECT_TRUE(response_restart->auth_challenge.get() == NULL);
3242}
3243
[email protected]d9da5fe2010-10-13 22:37:163244// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
[email protected]23e482282013-06-14 16:08:023245TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:273246 HttpRequestInfo request;
3247 request.method = "GET";
3248 request.url = GURL("https://www.google.com/");
3249 request.load_flags = 0;
3250
[email protected]d9da5fe2010-10-13 22:37:163251 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073252 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113253 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:293254 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073255 session_deps_.net_log = log.bound().net_log();
3256 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:163257
[email protected]262eec82013-03-19 21:01:363258 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503259 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:163260
[email protected]d9da5fe2010-10-13 22:37:163261 // CONNECT to www.google.com:443 via SPDY
[email protected]9075f51c2013-08-15 17:53:543262 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
3263 LOWEST));
[email protected]d9da5fe2010-10-13 22:37:163264 // fetch https://www.google.com/ via HTTP
3265
3266 const char get[] = "GET / HTTP/1.1\r\n"
3267 "Host: www.google.com\r\n"
3268 "Connection: keep-alive\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:193269 scoped_ptr<SpdyFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:023270 spdy_util_.ConstructSpdyBodyFrame(1, get, strlen(get), false));
3271 scoped_ptr<SpdyFrame> conn_resp(
3272 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:163273 const char resp[] = "HTTP/1.1 200 OK\r\n"
3274 "Content-Length: 10\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:193275 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:023276 spdy_util_.ConstructSpdyBodyFrame(1, resp, strlen(resp), false));
[email protected]ff98d7f02012-03-22 21:44:193277 scoped_ptr<SpdyFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:023278 spdy_util_.ConstructSpdyBodyFrame(1, "1234567890", 10, false));
[email protected]ff98d7f02012-03-22 21:44:193279 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203280 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
[email protected]8d2f7012012-02-16 00:08:043281
3282 MockWrite spdy_writes[] = {
3283 CreateMockWrite(*connect, 1),
3284 CreateMockWrite(*wrapped_get, 3),
[email protected]cdf8f7e72013-05-23 10:56:463285 CreateMockWrite(*window_update, 5),
[email protected]8d2f7012012-02-16 00:08:043286 };
3287
[email protected]d9da5fe2010-10-13 22:37:163288 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:063289 CreateMockRead(*conn_resp, 2, ASYNC),
3290 CreateMockRead(*wrapped_get_resp, 4, ASYNC),
3291 CreateMockRead(*wrapped_body, 6, ASYNC),
3292 CreateMockRead(*wrapped_body, 7, ASYNC),
3293 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:163294 };
3295
[email protected]dd54bd82012-07-19 23:44:573296 OrderedSocketData spdy_data(
3297 spdy_reads, arraysize(spdy_reads),
3298 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073299 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163300
[email protected]8ddf8322012-02-23 18:08:063301 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023302 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073303 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063304 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]d9da5fe2010-10-13 22:37:163305 ssl2.was_npn_negotiated = false;
[email protected]8e3c78cb2012-03-31 03:58:463306 ssl2.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:073307 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163308
[email protected]49639fa2011-12-20 23:22:413309 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163310
[email protected]49639fa2011-12-20 23:22:413311 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163312 EXPECT_EQ(ERR_IO_PENDING, rv);
3313
3314 rv = callback1.WaitForResult();
3315 EXPECT_EQ(OK, rv);
3316
[email protected]58e32bb2013-01-21 18:23:253317 LoadTimingInfo load_timing_info;
3318 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3319 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3320
[email protected]d9da5fe2010-10-13 22:37:163321 const HttpResponseInfo* response = trans->GetResponseInfo();
3322 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503323 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d9da5fe2010-10-13 22:37:163324 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3325
3326 std::string response_data;
3327 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
3328 EXPECT_EQ("1234567890", response_data);
3329}
3330
3331// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
[email protected]23e482282013-06-14 16:08:023332TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
[email protected]cb9bf6ca2011-01-28 13:15:273333 HttpRequestInfo request;
3334 request.method = "GET";
3335 request.url = GURL("https://www.google.com/");
3336 request.load_flags = 0;
3337
[email protected]d9da5fe2010-10-13 22:37:163338 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073339 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113340 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:293341 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073342 session_deps_.net_log = log.bound().net_log();
3343 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:163344
[email protected]262eec82013-03-19 21:01:363345 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503346 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:163347
[email protected]d9da5fe2010-10-13 22:37:163348 // CONNECT to www.google.com:443 via SPDY
[email protected]9075f51c2013-08-15 17:53:543349 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
3350 LOWEST));
[email protected]d9da5fe2010-10-13 22:37:163351 // fetch https://www.google.com/ via SPDY
3352 const char* const kMyUrl = "https://www.google.com/";
[email protected]cdf8f7e72013-05-23 10:56:463353 scoped_ptr<SpdyFrame> get(
3354 spdy_util_.ConstructSpdyGet(kMyUrl, false, 1, LOWEST));
[email protected]23e482282013-06-14 16:08:023355 scoped_ptr<SpdyFrame> wrapped_get(
3356 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
3357 scoped_ptr<SpdyFrame> conn_resp(
3358 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3359 scoped_ptr<SpdyFrame> get_resp(
3360 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]ff98d7f02012-03-22 21:44:193361 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:023362 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
3363 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
3364 scoped_ptr<SpdyFrame> wrapped_body(
3365 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
[email protected]ff98d7f02012-03-22 21:44:193366 scoped_ptr<SpdyFrame> window_update_get_resp(
[email protected]c10b20852013-05-15 21:29:203367 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
[email protected]ff98d7f02012-03-22 21:44:193368 scoped_ptr<SpdyFrame> window_update_body(
[email protected]c10b20852013-05-15 21:29:203369 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body->size()));
[email protected]8d2f7012012-02-16 00:08:043370
3371 MockWrite spdy_writes[] = {
3372 CreateMockWrite(*connect, 1),
3373 CreateMockWrite(*wrapped_get, 3),
3374 CreateMockWrite(*window_update_get_resp, 5),
3375 CreateMockWrite(*window_update_body, 7),
3376 };
3377
[email protected]d9da5fe2010-10-13 22:37:163378 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:063379 CreateMockRead(*conn_resp, 2, ASYNC),
3380 CreateMockRead(*wrapped_get_resp, 4, ASYNC),
3381 CreateMockRead(*wrapped_body, 6, ASYNC),
3382 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:163383 };
3384
[email protected]dd54bd82012-07-19 23:44:573385 OrderedSocketData spdy_data(
3386 spdy_reads, arraysize(spdy_reads),
3387 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073388 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163389
[email protected]8ddf8322012-02-23 18:08:063390 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023391 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073392 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063393 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023394 ssl2.SetNextProto(GetParam());
3395 ssl2.protocol_negotiated = GetParam();
[email protected]bb88e1d32013-05-03 23:11:073396 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163397
[email protected]49639fa2011-12-20 23:22:413398 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163399
[email protected]49639fa2011-12-20 23:22:413400 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163401 EXPECT_EQ(ERR_IO_PENDING, rv);
3402
3403 rv = callback1.WaitForResult();
3404 EXPECT_EQ(OK, rv);
3405
[email protected]58e32bb2013-01-21 18:23:253406 LoadTimingInfo load_timing_info;
3407 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3408 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3409
[email protected]d9da5fe2010-10-13 22:37:163410 const HttpResponseInfo* response = trans->GetResponseInfo();
3411 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503412 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d9da5fe2010-10-13 22:37:163413 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3414
3415 std::string response_data;
3416 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:233417 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:163418}
3419
3420// Test a SPDY CONNECT failure through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023421TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:273422 HttpRequestInfo request;
3423 request.method = "GET";
3424 request.url = GURL("https://www.google.com/");
3425 request.load_flags = 0;
3426
[email protected]d9da5fe2010-10-13 22:37:163427 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073428 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113429 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:293430 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073431 session_deps_.net_log = log.bound().net_log();
3432 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:163433
[email protected]262eec82013-03-19 21:01:363434 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503435 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:163436
[email protected]d9da5fe2010-10-13 22:37:163437 // CONNECT to www.google.com:443 via SPDY
[email protected]9075f51c2013-08-15 17:53:543438 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
3439 LOWEST));
[email protected]c10b20852013-05-15 21:29:203440 scoped_ptr<SpdyFrame> get(
3441 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:163442
3443 MockWrite spdy_writes[] = {
3444 CreateMockWrite(*connect, 1),
3445 CreateMockWrite(*get, 3),
3446 };
3447
[email protected]23e482282013-06-14 16:08:023448 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdySynReplyError(1));
3449 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:163450 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:063451 CreateMockRead(*resp, 2, ASYNC),
3452 MockRead(ASYNC, 0, 4),
[email protected]d9da5fe2010-10-13 22:37:163453 };
3454
[email protected]dd54bd82012-07-19 23:44:573455 OrderedSocketData spdy_data(
3456 spdy_reads, arraysize(spdy_reads),
3457 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073458 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163459
[email protected]8ddf8322012-02-23 18:08:063460 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023461 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073462 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063463 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023464 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073465 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163466
[email protected]49639fa2011-12-20 23:22:413467 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163468
[email protected]49639fa2011-12-20 23:22:413469 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163470 EXPECT_EQ(ERR_IO_PENDING, rv);
3471
3472 rv = callback1.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:173473 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]d9da5fe2010-10-13 22:37:163474
[email protected]4eddbc732012-08-09 05:40:173475 // TODO(ttuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:163476}
3477
[email protected]f6c63db52013-02-02 00:35:223478// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
3479// HTTPS Proxy to different servers.
[email protected]23e482282013-06-14 16:08:023480TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:223481 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
3482 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073483 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:223484 "https://proxy:70"));
3485 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073486 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:223487 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:073488 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:223489
3490 HttpRequestInfo request1;
3491 request1.method = "GET";
3492 request1.url = GURL("https://www.google.com/");
3493 request1.load_flags = 0;
3494
3495 HttpRequestInfo request2;
3496 request2.method = "GET";
3497 request2.url = GURL("https://news.google.com/");
3498 request2.load_flags = 0;
3499
3500 // CONNECT to www.google.com:443 via SPDY.
[email protected]9075f51c2013-08-15 17:53:543501 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
3502 LOWEST));
[email protected]23e482282013-06-14 16:08:023503 scoped_ptr<SpdyFrame> conn_resp1(
3504 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:223505
3506 // Fetch https://www.google.com/ via HTTP.
3507 const char get1[] = "GET / HTTP/1.1\r\n"
3508 "Host: www.google.com\r\n"
3509 "Connection: keep-alive\r\n\r\n";
3510 scoped_ptr<SpdyFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:023511 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:223512 const char resp1[] = "HTTP/1.1 200 OK\r\n"
3513 "Content-Length: 1\r\n\r\n";
3514 scoped_ptr<SpdyFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:023515 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
3516 scoped_ptr<SpdyFrame> wrapped_body1(
3517 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
[email protected]f6c63db52013-02-02 00:35:223518 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203519 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:223520
3521 // CONNECT to news.google.com:443 via SPDY.
[email protected]745aa9c2014-06-27 02:21:293522 SpdyHeaderBlock connect2_block;
3523 connect2_block[spdy_util_.GetMethodKey()] = "CONNECT";
3524 connect2_block[spdy_util_.GetPathKey()] = "news.google.com:443";
3525 connect2_block[spdy_util_.GetHostKey()] = "news.google.com";
3526 spdy_util_.MaybeAddVersionHeader(&connect2_block);
[email protected]f6c63db52013-02-02 00:35:223527 scoped_ptr<SpdyFrame> connect2(
[email protected]745aa9c2014-06-27 02:21:293528 spdy_util_.ConstructSpdySyn(3, connect2_block, LOWEST, false, false));
[email protected]601e03f12014-04-06 16:26:393529
[email protected]23e482282013-06-14 16:08:023530 scoped_ptr<SpdyFrame> conn_resp2(
3531 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:223532
3533 // Fetch https://news.google.com/ via HTTP.
3534 const char get2[] = "GET / HTTP/1.1\r\n"
3535 "Host: news.google.com\r\n"
3536 "Connection: keep-alive\r\n\r\n";
3537 scoped_ptr<SpdyFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:023538 spdy_util_.ConstructSpdyBodyFrame(3, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:223539 const char resp2[] = "HTTP/1.1 200 OK\r\n"
3540 "Content-Length: 2\r\n\r\n";
3541 scoped_ptr<SpdyFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:023542 spdy_util_.ConstructSpdyBodyFrame(3, resp2, strlen(resp2), false));
[email protected]f6c63db52013-02-02 00:35:223543 scoped_ptr<SpdyFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:023544 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:223545
3546 MockWrite spdy_writes[] = {
3547 CreateMockWrite(*connect1, 0),
3548 CreateMockWrite(*wrapped_get1, 2),
3549 CreateMockWrite(*connect2, 5),
3550 CreateMockWrite(*wrapped_get2, 7),
3551 };
3552
3553 MockRead spdy_reads[] = {
3554 CreateMockRead(*conn_resp1, 1, ASYNC),
3555 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
3556 CreateMockRead(*wrapped_body1, 4, ASYNC),
3557 CreateMockRead(*conn_resp2, 6, ASYNC),
3558 CreateMockRead(*wrapped_get_resp2, 8, ASYNC),
3559 CreateMockRead(*wrapped_body2, 9, ASYNC),
3560 MockRead(ASYNC, 0, 10),
3561 };
3562
3563 DeterministicSocketData spdy_data(
3564 spdy_reads, arraysize(spdy_reads),
3565 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073566 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:223567
3568 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023569 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073570 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:223571 SSLSocketDataProvider ssl2(ASYNC, OK);
3572 ssl2.was_npn_negotiated = false;
3573 ssl2.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:073574 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:223575 SSLSocketDataProvider ssl3(ASYNC, OK);
3576 ssl3.was_npn_negotiated = false;
3577 ssl3.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:073578 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:223579
3580 TestCompletionCallback callback;
3581
[email protected]262eec82013-03-19 21:01:363582 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503583 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223584 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
3585 EXPECT_EQ(ERR_IO_PENDING, rv);
3586 // The first connect and request, each of their responses, and the body.
3587 spdy_data.RunFor(5);
3588
3589 rv = callback.WaitForResult();
3590 EXPECT_EQ(OK, rv);
3591
3592 LoadTimingInfo load_timing_info;
3593 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3594 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3595
3596 const HttpResponseInfo* response = trans->GetResponseInfo();
3597 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503598 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:223599 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3600
3601 std::string response_data;
3602 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
[email protected]90499482013-06-01 00:39:503603 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223604
[email protected]262eec82013-03-19 21:01:363605 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503606 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223607 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
3608 EXPECT_EQ(ERR_IO_PENDING, rv);
3609
3610 // The second connect and request, each of their responses, and the body.
3611 spdy_data.RunFor(5);
3612 rv = callback.WaitForResult();
3613 EXPECT_EQ(OK, rv);
3614
3615 LoadTimingInfo load_timing_info2;
3616 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3617 // Even though the SPDY connection is reused, a new tunnelled connection has
3618 // to be created, so the socket's load timing looks like a fresh connection.
3619 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
3620
3621 // The requests should have different IDs, since they each are using their own
3622 // separate stream.
3623 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
3624
[email protected]90499482013-06-01 00:39:503625 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223626}
3627
3628// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
3629// HTTPS Proxy to the same server.
[email protected]23e482282013-06-14 16:08:023630TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:223631 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
3632 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073633 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:223634 "https://proxy:70"));
3635 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073636 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:223637 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:073638 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:223639
3640 HttpRequestInfo request1;
3641 request1.method = "GET";
3642 request1.url = GURL("https://www.google.com/");
3643 request1.load_flags = 0;
3644
3645 HttpRequestInfo request2;
3646 request2.method = "GET";
3647 request2.url = GURL("https://www.google.com/2");
3648 request2.load_flags = 0;
3649
3650 // CONNECT to www.google.com:443 via SPDY.
[email protected]9075f51c2013-08-15 17:53:543651 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
3652 LOWEST));
[email protected]23e482282013-06-14 16:08:023653 scoped_ptr<SpdyFrame> conn_resp1(
3654 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:223655
3656 // Fetch https://www.google.com/ via HTTP.
3657 const char get1[] = "GET / HTTP/1.1\r\n"
3658 "Host: www.google.com\r\n"
3659 "Connection: keep-alive\r\n\r\n";
3660 scoped_ptr<SpdyFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:023661 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:223662 const char resp1[] = "HTTP/1.1 200 OK\r\n"
3663 "Content-Length: 1\r\n\r\n";
3664 scoped_ptr<SpdyFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:023665 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
3666 scoped_ptr<SpdyFrame> wrapped_body1(
3667 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
[email protected]f6c63db52013-02-02 00:35:223668 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203669 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:223670
3671 // Fetch https://www.google.com/2 via HTTP.
3672 const char get2[] = "GET /2 HTTP/1.1\r\n"
3673 "Host: www.google.com\r\n"
3674 "Connection: keep-alive\r\n\r\n";
3675 scoped_ptr<SpdyFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:023676 spdy_util_.ConstructSpdyBodyFrame(1, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:223677 const char resp2[] = "HTTP/1.1 200 OK\r\n"
3678 "Content-Length: 2\r\n\r\n";
3679 scoped_ptr<SpdyFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:023680 spdy_util_.ConstructSpdyBodyFrame(1, resp2, strlen(resp2), false));
[email protected]f6c63db52013-02-02 00:35:223681 scoped_ptr<SpdyFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:023682 spdy_util_.ConstructSpdyBodyFrame(1, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:223683
3684 MockWrite spdy_writes[] = {
3685 CreateMockWrite(*connect1, 0),
3686 CreateMockWrite(*wrapped_get1, 2),
3687 CreateMockWrite(*wrapped_get2, 5),
3688 };
3689
3690 MockRead spdy_reads[] = {
3691 CreateMockRead(*conn_resp1, 1, ASYNC),
3692 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
3693 CreateMockRead(*wrapped_body1, 4, ASYNC),
3694 CreateMockRead(*wrapped_get_resp2, 6, ASYNC),
3695 CreateMockRead(*wrapped_body2, 7, ASYNC),
3696 MockRead(ASYNC, 0, 8),
3697 };
3698
3699 DeterministicSocketData spdy_data(
3700 spdy_reads, arraysize(spdy_reads),
3701 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073702 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:223703
3704 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023705 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073706 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:223707 SSLSocketDataProvider ssl2(ASYNC, OK);
3708 ssl2.was_npn_negotiated = false;
3709 ssl2.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:073710 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:223711
3712 TestCompletionCallback callback;
3713
[email protected]262eec82013-03-19 21:01:363714 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503715 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223716 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
3717 EXPECT_EQ(ERR_IO_PENDING, rv);
3718 // The first connect and request, each of their responses, and the body.
3719 spdy_data.RunFor(5);
3720
3721 rv = callback.WaitForResult();
3722 EXPECT_EQ(OK, rv);
3723
3724 LoadTimingInfo load_timing_info;
3725 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3726 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3727
3728 const HttpResponseInfo* response = trans->GetResponseInfo();
3729 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503730 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:223731 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3732
3733 std::string response_data;
3734 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
[email protected]90499482013-06-01 00:39:503735 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223736 trans.reset();
3737
[email protected]262eec82013-03-19 21:01:363738 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503739 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223740 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
3741 EXPECT_EQ(ERR_IO_PENDING, rv);
3742
3743 // The second request, response, and body. There should not be a second
3744 // connect.
3745 spdy_data.RunFor(3);
3746 rv = callback.WaitForResult();
3747 EXPECT_EQ(OK, rv);
3748
3749 LoadTimingInfo load_timing_info2;
3750 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3751 TestLoadTimingReused(load_timing_info2);
3752
3753 // The requests should have the same ID.
3754 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
3755
[email protected]90499482013-06-01 00:39:503756 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223757}
3758
3759// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
3760// Proxy to different servers.
[email protected]23e482282013-06-14 16:08:023761TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:223762 HttpsProxySpdyLoadTimingTwoHttpRequests) {
3763 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073764 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:223765 "https://proxy:70"));
3766 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073767 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:223768 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:073769 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:223770
3771 HttpRequestInfo request1;
3772 request1.method = "GET";
3773 request1.url = GURL("http://www.google.com/");
3774 request1.load_flags = 0;
3775
3776 HttpRequestInfo request2;
3777 request2.method = "GET";
3778 request2.url = GURL("http://news.google.com/");
3779 request2.load_flags = 0;
3780
3781 // http://www.google.com/
[email protected]23e482282013-06-14 16:08:023782 scoped_ptr<SpdyHeaderBlock> headers(
3783 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/"));
[email protected]745aa9c2014-06-27 02:21:293784 scoped_ptr<SpdyFrame> get1(
3785 spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, false, true));
[email protected]23e482282013-06-14 16:08:023786 scoped_ptr<SpdyFrame> get_resp1(
3787 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3788 scoped_ptr<SpdyFrame> body1(
3789 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, true));
[email protected]f6c63db52013-02-02 00:35:223790
3791 // http://news.google.com/
[email protected]23e482282013-06-14 16:08:023792 scoped_ptr<SpdyHeaderBlock> headers2(
3793 spdy_util_.ConstructGetHeaderBlockForProxy("http://news.google.com/"));
[email protected]745aa9c2014-06-27 02:21:293794 scoped_ptr<SpdyFrame> get2(
3795 spdy_util_.ConstructSpdySyn(3, *headers2, LOWEST, false, true));
[email protected]23e482282013-06-14 16:08:023796 scoped_ptr<SpdyFrame> get_resp2(
3797 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
3798 scoped_ptr<SpdyFrame> body2(
3799 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, true));
[email protected]f6c63db52013-02-02 00:35:223800
3801 MockWrite spdy_writes[] = {
3802 CreateMockWrite(*get1, 0),
3803 CreateMockWrite(*get2, 3),
3804 };
3805
3806 MockRead spdy_reads[] = {
3807 CreateMockRead(*get_resp1, 1, ASYNC),
3808 CreateMockRead(*body1, 2, ASYNC),
3809 CreateMockRead(*get_resp2, 4, ASYNC),
3810 CreateMockRead(*body2, 5, ASYNC),
3811 MockRead(ASYNC, 0, 6),
3812 };
3813
3814 DeterministicSocketData spdy_data(
3815 spdy_reads, arraysize(spdy_reads),
3816 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073817 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:223818
3819 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023820 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073821 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:223822
3823 TestCompletionCallback callback;
3824
[email protected]262eec82013-03-19 21:01:363825 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503826 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223827 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
3828 EXPECT_EQ(ERR_IO_PENDING, rv);
3829 spdy_data.RunFor(2);
3830
3831 rv = callback.WaitForResult();
3832 EXPECT_EQ(OK, rv);
3833
3834 LoadTimingInfo load_timing_info;
3835 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3836 TestLoadTimingNotReused(load_timing_info,
3837 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3838
3839 const HttpResponseInfo* response = trans->GetResponseInfo();
3840 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503841 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:223842 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3843
3844 std::string response_data;
3845 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
[email protected]90499482013-06-01 00:39:503846 EXPECT_EQ(ERR_IO_PENDING, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223847 spdy_data.RunFor(1);
3848 EXPECT_EQ(1, callback.WaitForResult());
3849 // Delete the first request, so the second one can reuse the socket.
3850 trans.reset();
3851
[email protected]262eec82013-03-19 21:01:363852 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503853 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223854 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
3855 EXPECT_EQ(ERR_IO_PENDING, rv);
3856
3857 spdy_data.RunFor(2);
3858 rv = callback.WaitForResult();
3859 EXPECT_EQ(OK, rv);
3860
3861 LoadTimingInfo load_timing_info2;
3862 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3863 TestLoadTimingReused(load_timing_info2);
3864
3865 // The requests should have the same ID.
3866 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
3867
[email protected]90499482013-06-01 00:39:503868 EXPECT_EQ(ERR_IO_PENDING, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223869 spdy_data.RunFor(1);
3870 EXPECT_EQ(2, callback.WaitForResult());
3871}
3872
[email protected]2df19bb2010-08-25 20:13:463873// Test the challenge-response-retry sequence through an HTTPS Proxy
[email protected]23e482282013-06-14 16:08:023874TEST_P(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:463875 HttpRequestInfo request;
3876 request.method = "GET";
3877 request.url = GURL("http://www.google.com/");
3878 // when the no authentication data flag is set.
3879 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
3880
[email protected]79cb5c12011-09-12 13:12:043881 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073882 session_deps_.proxy_service.reset(
[email protected]79cb5c12011-09-12 13:12:043883 ProxyService::CreateFixed("https://myproxy:70"));
[email protected]333bdf62012-06-08 22:57:293884 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073885 session_deps_.net_log = log.bound().net_log();
3886 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273887
[email protected]2df19bb2010-08-25 20:13:463888 // Since we have proxy, should use full url
3889 MockWrite data_writes1[] = {
3890 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
3891 "Host: www.google.com\r\n"
3892 "Proxy-Connection: keep-alive\r\n\r\n"),
3893
3894 // After calling trans->RestartWithAuth(), this is the request we should
3895 // be issuing -- the final header line contains the credentials.
3896 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
3897 "Host: www.google.com\r\n"
3898 "Proxy-Connection: keep-alive\r\n"
3899 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3900 };
3901
3902 // The proxy responds to the GET with a 407, using a persistent
3903 // connection.
3904 MockRead data_reads1[] = {
3905 // No credentials.
3906 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3907 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3908 MockRead("Proxy-Connection: keep-alive\r\n"),
3909 MockRead("Content-Length: 0\r\n\r\n"),
3910
3911 MockRead("HTTP/1.1 200 OK\r\n"),
3912 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3913 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063914 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:463915 };
3916
3917 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3918 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073919 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063920 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073921 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:463922
[email protected]49639fa2011-12-20 23:22:413923 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:463924
[email protected]262eec82013-03-19 21:01:363925 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503926 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503927
[email protected]49639fa2011-12-20 23:22:413928 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:463929 EXPECT_EQ(ERR_IO_PENDING, rv);
3930
3931 rv = callback1.WaitForResult();
3932 EXPECT_EQ(OK, rv);
3933
[email protected]58e32bb2013-01-21 18:23:253934 LoadTimingInfo load_timing_info;
3935 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3936 TestLoadTimingNotReused(load_timing_info,
3937 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3938
[email protected]2df19bb2010-08-25 20:13:463939 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503940 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503941 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]2df19bb2010-08-25 20:13:463942 EXPECT_EQ(407, response->headers->response_code());
3943 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043944 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:463945
[email protected]49639fa2011-12-20 23:22:413946 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:463947
[email protected]49639fa2011-12-20 23:22:413948 rv = trans->RestartWithAuth(
3949 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]2df19bb2010-08-25 20:13:463950 EXPECT_EQ(ERR_IO_PENDING, rv);
3951
3952 rv = callback2.WaitForResult();
3953 EXPECT_EQ(OK, rv);
3954
[email protected]58e32bb2013-01-21 18:23:253955 load_timing_info = LoadTimingInfo();
3956 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3957 // Retrying with HTTP AUTH is considered to be reusing a socket.
3958 TestLoadTimingReused(load_timing_info);
3959
[email protected]2df19bb2010-08-25 20:13:463960 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503961 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:463962
3963 EXPECT_TRUE(response->headers->IsKeepAlive());
3964 EXPECT_EQ(200, response->headers->response_code());
3965 EXPECT_EQ(100, response->headers->GetContentLength());
3966 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3967
3968 // The password prompt info should not be set.
3969 EXPECT_TRUE(response->auth_challenge.get() == NULL);
3970}
3971
[email protected]23e482282013-06-14 16:08:023972void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:083973 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:423974 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:083975 request.method = "GET";
3976 request.url = GURL("https://www.google.com/");
3977 request.load_flags = 0;
3978
[email protected]cb9bf6ca2011-01-28 13:15:273979 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073980 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]bb88e1d32013-05-03 23:11:073981 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273982
[email protected]c744cf22009-02-27 07:28:083983 // Since we have proxy, should try to establish tunnel.
3984 MockWrite data_writes[] = {
3985 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:453986 "Host: www.google.com\r\n"
3987 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:083988 };
3989
3990 MockRead data_reads[] = {
3991 status,
3992 MockRead("Content-Length: 10\r\n\r\n"),
3993 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:063994 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]c744cf22009-02-27 07:28:083995 };
3996
[email protected]31a2bfe2010-02-09 08:03:393997 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
3998 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:073999 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:084000
[email protected]49639fa2011-12-20 23:22:414001 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:084002
[email protected]262eec82013-03-19 21:01:364003 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504004 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504005
[email protected]49639fa2011-12-20 23:22:414006 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424007 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]c744cf22009-02-27 07:28:084008
4009 rv = callback.WaitForResult();
4010 EXPECT_EQ(expected_status, rv);
4011}
4012
[email protected]23e482282013-06-14 16:08:024013void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:234014 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:084015 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:424016 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:084017}
4018
[email protected]23e482282013-06-14 16:08:024019TEST_P(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:084020 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
4021}
4022
[email protected]23e482282013-06-14 16:08:024023TEST_P(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:084024 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
4025}
4026
[email protected]23e482282013-06-14 16:08:024027TEST_P(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:084028 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
4029}
4030
[email protected]23e482282013-06-14 16:08:024031TEST_P(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:084032 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
4033}
4034
[email protected]23e482282013-06-14 16:08:024035TEST_P(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:084036 ConnectStatusHelper(
4037 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
4038}
4039
[email protected]23e482282013-06-14 16:08:024040TEST_P(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:084041 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
4042}
4043
[email protected]23e482282013-06-14 16:08:024044TEST_P(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:084045 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
4046}
4047
[email protected]23e482282013-06-14 16:08:024048TEST_P(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:084049 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
4050}
4051
[email protected]23e482282013-06-14 16:08:024052TEST_P(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:084053 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
4054}
4055
[email protected]23e482282013-06-14 16:08:024056TEST_P(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:084057 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
4058}
4059
[email protected]23e482282013-06-14 16:08:024060TEST_P(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:084061 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
4062}
4063
[email protected]23e482282013-06-14 16:08:024064TEST_P(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:084065 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
4066}
4067
[email protected]23e482282013-06-14 16:08:024068TEST_P(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:084069 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
4070}
4071
[email protected]23e482282013-06-14 16:08:024072TEST_P(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:084073 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
4074}
4075
[email protected]23e482282013-06-14 16:08:024076TEST_P(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:084077 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
4078}
4079
[email protected]23e482282013-06-14 16:08:024080TEST_P(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:084081 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
4082}
4083
[email protected]0a17aab32014-04-24 03:32:374084TEST_P(HttpNetworkTransactionTest, ConnectStatus308) {
4085 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
4086}
4087
[email protected]23e482282013-06-14 16:08:024088TEST_P(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:084089 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
4090}
4091
[email protected]23e482282013-06-14 16:08:024092TEST_P(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:084093 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
4094}
4095
[email protected]23e482282013-06-14 16:08:024096TEST_P(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:084097 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
4098}
4099
[email protected]23e482282013-06-14 16:08:024100TEST_P(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:084101 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
4102}
4103
[email protected]23e482282013-06-14 16:08:024104TEST_P(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:084105 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
4106}
4107
[email protected]23e482282013-06-14 16:08:024108TEST_P(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:084109 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
4110}
4111
[email protected]23e482282013-06-14 16:08:024112TEST_P(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:084113 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
4114}
4115
[email protected]23e482282013-06-14 16:08:024116TEST_P(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:084117 ConnectStatusHelperWithExpectedStatus(
4118 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:544119 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:084120}
4121
[email protected]23e482282013-06-14 16:08:024122TEST_P(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:084123 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
4124}
4125
[email protected]23e482282013-06-14 16:08:024126TEST_P(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:084127 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
4128}
4129
[email protected]23e482282013-06-14 16:08:024130TEST_P(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:084131 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
4132}
4133
[email protected]23e482282013-06-14 16:08:024134TEST_P(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:084135 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
4136}
4137
[email protected]23e482282013-06-14 16:08:024138TEST_P(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:084139 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
4140}
4141
[email protected]23e482282013-06-14 16:08:024142TEST_P(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:084143 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
4144}
4145
[email protected]23e482282013-06-14 16:08:024146TEST_P(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:084147 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
4148}
4149
[email protected]23e482282013-06-14 16:08:024150TEST_P(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:084151 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
4152}
4153
[email protected]23e482282013-06-14 16:08:024154TEST_P(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:084155 ConnectStatusHelper(
4156 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
4157}
4158
[email protected]23e482282013-06-14 16:08:024159TEST_P(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:084160 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
4161}
4162
[email protected]23e482282013-06-14 16:08:024163TEST_P(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:084164 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
4165}
4166
[email protected]23e482282013-06-14 16:08:024167TEST_P(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:084168 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
4169}
4170
[email protected]23e482282013-06-14 16:08:024171TEST_P(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:084172 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
4173}
4174
[email protected]23e482282013-06-14 16:08:024175TEST_P(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:084176 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
4177}
4178
[email protected]23e482282013-06-14 16:08:024179TEST_P(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:084180 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
4181}
4182
[email protected]23e482282013-06-14 16:08:024183TEST_P(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:084184 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
4185}
4186
[email protected]038e9a32008-10-08 22:40:164187// Test the flow when both the proxy server AND origin server require
4188// authentication. Again, this uses basic auth for both since that is
4189// the simplest to mock.
[email protected]23e482282013-06-14 16:08:024190TEST_P(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:274191 HttpRequestInfo request;
4192 request.method = "GET";
4193 request.url = GURL("http://www.google.com/");
4194 request.load_flags = 0;
4195
[email protected]038e9a32008-10-08 22:40:164196 // Configure against proxy server "myproxy:70".
[email protected]3fe8d2f82013-10-17 08:56:074197 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
4198 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4199
4200 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:414201 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]038e9a32008-10-08 22:40:164202
[email protected]f9ee6b52008-11-08 06:46:234203 MockWrite data_writes1[] = {
4204 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
4205 "Host: www.google.com\r\n"
4206 "Proxy-Connection: keep-alive\r\n\r\n"),
4207 };
4208
[email protected]038e9a32008-10-08 22:40:164209 MockRead data_reads1[] = {
4210 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
4211 // Give a couple authenticate options (only the middle one is actually
4212 // supported).
[email protected]22927ad2009-09-21 19:56:194213 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:164214 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4215 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
4216 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4217 // Large content-length -- won't matter, as connection will be reset.
4218 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064219 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:164220 };
4221
4222 // After calling trans->RestartWithAuth() the first time, this is the
4223 // request we should be issuing -- the final header line contains the
4224 // proxy's credentials.
4225 MockWrite data_writes2[] = {
4226 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
4227 "Host: www.google.com\r\n"
4228 "Proxy-Connection: keep-alive\r\n"
4229 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
4230 };
4231
4232 // Now the proxy server lets the request pass through to origin server.
4233 // The origin server responds with a 401.
4234 MockRead data_reads2[] = {
4235 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4236 // Note: We are using the same realm-name as the proxy server. This is
4237 // completely valid, as realms are unique across hosts.
4238 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4239 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4240 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064241 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:164242 };
4243
4244 // After calling trans->RestartWithAuth() the second time, we should send
4245 // the credentials for both the proxy and origin server.
4246 MockWrite data_writes3[] = {
4247 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
4248 "Host: www.google.com\r\n"
4249 "Proxy-Connection: keep-alive\r\n"
4250 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
4251 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
4252 };
4253
4254 // Lastly we get the desired content.
4255 MockRead data_reads3[] = {
4256 MockRead("HTTP/1.0 200 OK\r\n"),
4257 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4258 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064259 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:164260 };
4261
[email protected]31a2bfe2010-02-09 08:03:394262 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4263 data_writes1, arraysize(data_writes1));
4264 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4265 data_writes2, arraysize(data_writes2));
4266 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4267 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:074268 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4269 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4270 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:164271
[email protected]49639fa2011-12-20 23:22:414272 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:164273
[email protected]49639fa2011-12-20 23:22:414274 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424275 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:164276
4277 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424278 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:164279
[email protected]1c773ea12009-04-28 19:58:424280 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504281 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044282 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:164283
[email protected]49639fa2011-12-20 23:22:414284 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:164285
[email protected]49639fa2011-12-20 23:22:414286 rv = trans->RestartWithAuth(
4287 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:424288 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:164289
4290 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424291 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:164292
4293 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504294 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044295 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:164296
[email protected]49639fa2011-12-20 23:22:414297 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:164298
[email protected]49639fa2011-12-20 23:22:414299 rv = trans->RestartWithAuth(
4300 AuthCredentials(kFoo2, kBar2), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424301 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:164302
4303 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424304 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:164305
4306 response = trans->GetResponseInfo();
4307 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4308 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:164309}
[email protected]4ddaf2502008-10-23 18:26:194310
[email protected]ea9dc9a2009-09-05 00:43:324311// For the NTLM implementation using SSPI, we skip the NTLM tests since we
4312// can't hook into its internals to cause it to generate predictable NTLM
4313// authorization headers.
4314#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:294315// The NTLM authentication unit tests were generated by capturing the HTTP
4316// requests and responses using Fiddler 2 and inspecting the generated random
4317// bytes in the debugger.
4318
4319// Enter the correct password and authenticate successfully.
[email protected]23e482282013-06-14 16:08:024320TEST_P(HttpNetworkTransactionTest, NTLMAuth1) {
[email protected]1c773ea12009-04-28 19:58:424321 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:244322 request.method = "GET";
4323 request.url = GURL("http://172.22.68.17/kids/login.aspx");
[email protected]2217aa22013-10-11 03:03:544324
4325 // Ensure load is not disrupted by flags which suppress behaviour specific
4326 // to other auth schemes.
4327 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:244328
[email protected]cb9bf6ca2011-01-28 13:15:274329 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
4330 MockGetHostName);
[email protected]bb88e1d32013-05-03 23:11:074331 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274332
[email protected]3f918782009-02-28 01:29:244333 MockWrite data_writes1[] = {
4334 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4335 "Host: 172.22.68.17\r\n"
4336 "Connection: keep-alive\r\n\r\n"),
4337 };
4338
4339 MockRead data_reads1[] = {
4340 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:044341 // Negotiate and NTLM are often requested together. However, we only want
4342 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
4343 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:244344 MockRead("WWW-Authenticate: NTLM\r\n"),
4345 MockRead("Connection: close\r\n"),
4346 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364347 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:244348 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064349 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]3f918782009-02-28 01:29:244350 };
4351
4352 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:224353 // After restarting with a null identity, this is the
[email protected]3f918782009-02-28 01:29:244354 // request we should be issuing -- the final header line contains a Type
4355 // 1 message.
4356 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4357 "Host: 172.22.68.17\r\n"
4358 "Connection: keep-alive\r\n"
4359 "Authorization: NTLM "
4360 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4361
4362 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4363 // (the credentials for the origin server). The second request continues
4364 // on the same connection.
4365 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4366 "Host: 172.22.68.17\r\n"
4367 "Connection: keep-alive\r\n"
[email protected]385a4672009-03-11 22:21:294368 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4369 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4370 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
4371 "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
4372 "ahlhx5I=\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:244373 };
4374
4375 MockRead data_reads2[] = {
4376 // The origin server responds with a Type 2 message.
4377 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4378 MockRead("WWW-Authenticate: NTLM "
[email protected]385a4672009-03-11 22:21:294379 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
[email protected]3f918782009-02-28 01:29:244380 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4381 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4382 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4383 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4384 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4385 "BtAAAAAAA=\r\n"),
4386 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364387 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:244388 MockRead("You are not authorized to view this page\r\n"),
4389
4390 // Lastly we get the desired content.
4391 MockRead("HTTP/1.1 200 OK\r\n"),
4392 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
4393 MockRead("Content-Length: 13\r\n\r\n"),
4394 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:064395 MockRead(SYNCHRONOUS, OK),
[email protected]3f918782009-02-28 01:29:244396 };
4397
[email protected]31a2bfe2010-02-09 08:03:394398 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4399 data_writes1, arraysize(data_writes1));
4400 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4401 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:074402 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4403 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:244404
[email protected]49639fa2011-12-20 23:22:414405 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:244406
[email protected]262eec82013-03-19 21:01:364407 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504408 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504409
[email protected]49639fa2011-12-20 23:22:414410 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424411 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:244412
4413 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424414 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:244415
[email protected]0757e7702009-03-27 04:00:224416 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4417
[email protected]1c773ea12009-04-28 19:58:424418 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:044419 ASSERT_FALSE(response == NULL);
4420 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:244421
[email protected]49639fa2011-12-20 23:22:414422 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:254423
[email protected]f3cf9802011-10-28 18:44:584424 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:414425 callback2.callback());
[email protected]10af5fe72011-01-31 16:17:254426 EXPECT_EQ(ERR_IO_PENDING, rv);
4427
4428 rv = callback2.WaitForResult();
4429 EXPECT_EQ(OK, rv);
4430
4431 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4432
4433 response = trans->GetResponseInfo();
4434 ASSERT_TRUE(response != NULL);
[email protected]10af5fe72011-01-31 16:17:254435 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4436
[email protected]49639fa2011-12-20 23:22:414437 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:244438
[email protected]49639fa2011-12-20 23:22:414439 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424440 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:244441
[email protected]0757e7702009-03-27 04:00:224442 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424443 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:244444
4445 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504446 ASSERT_TRUE(response != NULL);
[email protected]3f918782009-02-28 01:29:244447 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4448 EXPECT_EQ(13, response->headers->GetContentLength());
4449}
4450
[email protected]385a4672009-03-11 22:21:294451// Enter a wrong password, and then the correct one.
[email protected]23e482282013-06-14 16:08:024452TEST_P(HttpNetworkTransactionTest, NTLMAuth2) {
[email protected]1c773ea12009-04-28 19:58:424453 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:294454 request.method = "GET";
4455 request.url = GURL("http://172.22.68.17/kids/login.aspx");
4456 request.load_flags = 0;
4457
[email protected]cb9bf6ca2011-01-28 13:15:274458 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
4459 MockGetHostName);
[email protected]bb88e1d32013-05-03 23:11:074460 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274461
[email protected]385a4672009-03-11 22:21:294462 MockWrite data_writes1[] = {
4463 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4464 "Host: 172.22.68.17\r\n"
4465 "Connection: keep-alive\r\n\r\n"),
4466 };
4467
4468 MockRead data_reads1[] = {
4469 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:044470 // Negotiate and NTLM are often requested together. However, we only want
4471 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
4472 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:294473 MockRead("WWW-Authenticate: NTLM\r\n"),
4474 MockRead("Connection: close\r\n"),
4475 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364476 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294477 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064478 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:294479 };
4480
4481 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:224482 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:294483 // request we should be issuing -- the final header line contains a Type
4484 // 1 message.
4485 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4486 "Host: 172.22.68.17\r\n"
4487 "Connection: keep-alive\r\n"
4488 "Authorization: NTLM "
4489 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4490
4491 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4492 // (the credentials for the origin server). The second request continues
4493 // on the same connection.
4494 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4495 "Host: 172.22.68.17\r\n"
4496 "Connection: keep-alive\r\n"
4497 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4498 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4499 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
4500 "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
4501 "4Ww7b7E=\r\n\r\n"),
4502 };
4503
4504 MockRead data_reads2[] = {
4505 // The origin server responds with a Type 2 message.
4506 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4507 MockRead("WWW-Authenticate: NTLM "
4508 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
4509 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4510 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4511 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4512 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4513 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4514 "BtAAAAAAA=\r\n"),
4515 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364516 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294517 MockRead("You are not authorized to view this page\r\n"),
4518
4519 // Wrong password.
4520 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]385a4672009-03-11 22:21:294521 MockRead("WWW-Authenticate: NTLM\r\n"),
4522 MockRead("Connection: close\r\n"),
4523 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364524 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294525 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064526 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:294527 };
4528
4529 MockWrite data_writes3[] = {
[email protected]0757e7702009-03-27 04:00:224530 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:294531 // request we should be issuing -- the final header line contains a Type
4532 // 1 message.
4533 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4534 "Host: 172.22.68.17\r\n"
4535 "Connection: keep-alive\r\n"
4536 "Authorization: NTLM "
4537 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4538
4539 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4540 // (the credentials for the origin server). The second request continues
4541 // on the same connection.
4542 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4543 "Host: 172.22.68.17\r\n"
4544 "Connection: keep-alive\r\n"
4545 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4546 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4547 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
4548 "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
4549 "+4MUm7c=\r\n\r\n"),
4550 };
4551
4552 MockRead data_reads3[] = {
4553 // The origin server responds with a Type 2 message.
4554 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4555 MockRead("WWW-Authenticate: NTLM "
4556 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
4557 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4558 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4559 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4560 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4561 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4562 "BtAAAAAAA=\r\n"),
4563 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364564 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294565 MockRead("You are not authorized to view this page\r\n"),
4566
4567 // Lastly we get the desired content.
4568 MockRead("HTTP/1.1 200 OK\r\n"),
4569 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
4570 MockRead("Content-Length: 13\r\n\r\n"),
4571 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:064572 MockRead(SYNCHRONOUS, OK),
[email protected]385a4672009-03-11 22:21:294573 };
4574
[email protected]31a2bfe2010-02-09 08:03:394575 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4576 data_writes1, arraysize(data_writes1));
4577 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4578 data_writes2, arraysize(data_writes2));
4579 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4580 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:074581 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4582 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4583 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:294584
[email protected]49639fa2011-12-20 23:22:414585 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:294586
[email protected]262eec82013-03-19 21:01:364587 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504588 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504589
[email protected]49639fa2011-12-20 23:22:414590 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424591 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:294592
4593 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424594 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:294595
[email protected]0757e7702009-03-27 04:00:224596 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:294597
[email protected]1c773ea12009-04-28 19:58:424598 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504599 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044600 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:294601
[email protected]49639fa2011-12-20 23:22:414602 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:294603
[email protected]0757e7702009-03-27 04:00:224604 // Enter the wrong password.
[email protected]f3cf9802011-10-28 18:44:584605 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword),
[email protected]49639fa2011-12-20 23:22:414606 callback2.callback());
[email protected]1c773ea12009-04-28 19:58:424607 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:294608
[email protected]10af5fe72011-01-31 16:17:254609 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424610 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:294611
[email protected]0757e7702009-03-27 04:00:224612 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:414613 TestCompletionCallback callback3;
4614 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424615 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]10af5fe72011-01-31 16:17:254616 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424617 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:224618 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4619
4620 response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:044621 ASSERT_FALSE(response == NULL);
4622 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:224623
[email protected]49639fa2011-12-20 23:22:414624 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:224625
4626 // Now enter the right password.
[email protected]f3cf9802011-10-28 18:44:584627 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:414628 callback4.callback());
[email protected]10af5fe72011-01-31 16:17:254629 EXPECT_EQ(ERR_IO_PENDING, rv);
4630
4631 rv = callback4.WaitForResult();
4632 EXPECT_EQ(OK, rv);
4633
4634 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4635
[email protected]49639fa2011-12-20 23:22:414636 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:254637
4638 // One more roundtrip
[email protected]49639fa2011-12-20 23:22:414639 rv = trans->RestartWithAuth(AuthCredentials(), callback5.callback());
[email protected]1c773ea12009-04-28 19:58:424640 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:224641
4642 rv = callback5.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424643 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:224644
[email protected]385a4672009-03-11 22:21:294645 response = trans->GetResponseInfo();
4646 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4647 EXPECT_EQ(13, response->headers->GetContentLength());
4648}
[email protected]ea9dc9a2009-09-05 00:43:324649#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:294650
[email protected]4ddaf2502008-10-23 18:26:194651// Test reading a server response which has only headers, and no body.
4652// After some maximum number of bytes is consumed, the transaction should
4653// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
[email protected]23e482282013-06-14 16:08:024654TEST_P(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:424655 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:194656 request.method = "GET";
4657 request.url = GURL("http://www.google.com/");
4658 request.load_flags = 0;
4659
[email protected]3fe8d2f82013-10-17 08:56:074660 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274661 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:414662 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:274663
[email protected]b75b7b2f2009-10-06 00:54:534664 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:434665 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:534666 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:194667
4668 MockRead data_reads[] = {
4669 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:064670 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:194671 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:064672 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:194673 };
[email protected]31a2bfe2010-02-09 08:03:394674 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:074675 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:194676
[email protected]49639fa2011-12-20 23:22:414677 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:194678
[email protected]49639fa2011-12-20 23:22:414679 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424680 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]4ddaf2502008-10-23 18:26:194681
4682 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424683 EXPECT_EQ(ERR_RESPONSE_HEADERS_TOO_BIG, rv);
[email protected]4ddaf2502008-10-23 18:26:194684
[email protected]1c773ea12009-04-28 19:58:424685 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]4ddaf2502008-10-23 18:26:194686 EXPECT_TRUE(response == NULL);
4687}
[email protected]f4e426b2008-11-05 00:24:494688
4689// Make sure that we don't try to reuse a TCPClientSocket when failing to
4690// establish tunnel.
4691// http://code.google.com/p/chromium/issues/detail?id=3772
[email protected]23e482282013-06-14 16:08:024692TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:234693 DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:274694 HttpRequestInfo request;
4695 request.method = "GET";
4696 request.url = GURL("https://www.google.com/");
4697 request.load_flags = 0;
4698
[email protected]f4e426b2008-11-05 00:24:494699 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:074700 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]db8f44c2008-12-13 04:52:014701
[email protected]bb88e1d32013-05-03 23:11:074702 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:494703
[email protected]262eec82013-03-19 21:01:364704 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504705 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f4e426b2008-11-05 00:24:494706
[email protected]f4e426b2008-11-05 00:24:494707 // Since we have proxy, should try to establish tunnel.
4708 MockWrite data_writes1[] = {
4709 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:454710 "Host: www.google.com\r\n"
4711 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:494712 };
4713
[email protected]77848d12008-11-14 00:00:224714 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:494715 // connection. Usually a proxy would return 501 (not implemented),
4716 // or 200 (tunnel established).
4717 MockRead data_reads1[] = {
4718 MockRead("HTTP/1.1 404 Not Found\r\n"),
4719 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064720 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]f4e426b2008-11-05 00:24:494721 };
4722
[email protected]31a2bfe2010-02-09 08:03:394723 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4724 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074725 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:494726
[email protected]49639fa2011-12-20 23:22:414727 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:494728
[email protected]49639fa2011-12-20 23:22:414729 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424730 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f4e426b2008-11-05 00:24:494731
4732 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424733 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]f4e426b2008-11-05 00:24:494734
[email protected]1c773ea12009-04-28 19:58:424735 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]c744cf22009-02-27 07:28:084736 EXPECT_TRUE(response == NULL);
[email protected]f4e426b2008-11-05 00:24:494737
[email protected]b4404c02009-04-10 16:38:524738 // Empty the current queue. This is necessary because idle sockets are
4739 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344740 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:524741
[email protected]f4e426b2008-11-05 00:24:494742 // We now check to make sure the TCPClientSocket was not added back to
4743 // the pool.
[email protected]90499482013-06-01 00:39:504744 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:494745 trans.reset();
[email protected]2da659e2013-05-23 20:51:344746 base::MessageLoop::current()->RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:494747 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:504748 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:494749}
[email protected]372d34a2008-11-05 21:30:514750
[email protected]1b157c02009-04-21 01:55:404751// Make sure that we recycle a socket after reading all of the response body.
[email protected]23e482282013-06-14 16:08:024752TEST_P(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:424753 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:404754 request.method = "GET";
4755 request.url = GURL("http://www.google.com/");
4756 request.load_flags = 0;
4757
[email protected]bb88e1d32013-05-03 23:11:074758 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274759
[email protected]262eec82013-03-19 21:01:364760 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504761 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:274762
[email protected]1b157c02009-04-21 01:55:404763 MockRead data_reads[] = {
4764 // A part of the response body is received with the response headers.
4765 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
4766 // The rest of the response body is received in two parts.
4767 MockRead("lo"),
4768 MockRead(" world"),
4769 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:064770 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:404771 };
4772
[email protected]31a2bfe2010-02-09 08:03:394773 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:074774 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:404775
[email protected]49639fa2011-12-20 23:22:414776 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:404777
[email protected]49639fa2011-12-20 23:22:414778 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424779 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]1b157c02009-04-21 01:55:404780
4781 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424782 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:404783
[email protected]1c773ea12009-04-28 19:58:424784 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504785 ASSERT_TRUE(response != NULL);
[email protected]1b157c02009-04-21 01:55:404786
[email protected]90499482013-06-01 00:39:504787 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]1b157c02009-04-21 01:55:404788 std::string status_line = response->headers->GetStatusLine();
4789 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
4790
[email protected]90499482013-06-01 00:39:504791 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:404792
4793 std::string response_data;
4794 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:424795 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:404796 EXPECT_EQ("hello world", response_data);
4797
4798 // Empty the current queue. This is necessary because idle sockets are
4799 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344800 base::MessageLoop::current()->RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:404801
4802 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504803 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:404804}
4805
[email protected]76a505b2010-08-25 06:23:004806// Make sure that we recycle a SSL socket after reading all of the response
4807// body.
[email protected]23e482282013-06-14 16:08:024808TEST_P(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:004809 HttpRequestInfo request;
4810 request.method = "GET";
4811 request.url = GURL("https://www.google.com/");
4812 request.load_flags = 0;
4813
4814 MockWrite data_writes[] = {
4815 MockWrite("GET / HTTP/1.1\r\n"
4816 "Host: www.google.com\r\n"
4817 "Connection: keep-alive\r\n\r\n"),
4818 };
4819
4820 MockRead data_reads[] = {
4821 MockRead("HTTP/1.1 200 OK\r\n"),
4822 MockRead("Content-Length: 11\r\n\r\n"),
4823 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:064824 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:004825 };
4826
[email protected]8ddf8322012-02-23 18:08:064827 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074828 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:004829
4830 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
4831 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:074832 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:004833
[email protected]49639fa2011-12-20 23:22:414834 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:004835
[email protected]bb88e1d32013-05-03 23:11:074836 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:364837 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504838 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:004839
[email protected]49639fa2011-12-20 23:22:414840 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:004841
4842 EXPECT_EQ(ERR_IO_PENDING, rv);
4843 EXPECT_EQ(OK, callback.WaitForResult());
4844
4845 const HttpResponseInfo* response = trans->GetResponseInfo();
4846 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504847 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:004848 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4849
[email protected]90499482013-06-01 00:39:504850 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004851
4852 std::string response_data;
4853 rv = ReadTransaction(trans.get(), &response_data);
4854 EXPECT_EQ(OK, rv);
4855 EXPECT_EQ("hello world", response_data);
4856
4857 // Empty the current queue. This is necessary because idle sockets are
4858 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344859 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:004860
4861 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504862 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004863}
4864
4865// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
4866// from the pool and make sure that we recover okay.
[email protected]23e482282013-06-14 16:08:024867TEST_P(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:004868 HttpRequestInfo request;
4869 request.method = "GET";
4870 request.url = GURL("https://www.google.com/");
4871 request.load_flags = 0;
4872
4873 MockWrite data_writes[] = {
4874 MockWrite("GET / HTTP/1.1\r\n"
4875 "Host: www.google.com\r\n"
4876 "Connection: keep-alive\r\n\r\n"),
4877 MockWrite("GET / HTTP/1.1\r\n"
4878 "Host: www.google.com\r\n"
4879 "Connection: keep-alive\r\n\r\n"),
4880 };
4881
4882 MockRead data_reads[] = {
4883 MockRead("HTTP/1.1 200 OK\r\n"),
4884 MockRead("Content-Length: 11\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064885 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:004886 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:064887 MockRead(ASYNC, 0, 0) // EOF
[email protected]76a505b2010-08-25 06:23:004888 };
4889
[email protected]8ddf8322012-02-23 18:08:064890 SSLSocketDataProvider ssl(ASYNC, OK);
4891 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074892 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4893 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:004894
4895 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
4896 data_writes, arraysize(data_writes));
4897 StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
4898 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:074899 session_deps_.socket_factory->AddSocketDataProvider(&data);
4900 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:004901
[email protected]49639fa2011-12-20 23:22:414902 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:004903
[email protected]bb88e1d32013-05-03 23:11:074904 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:364905 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504906 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:004907
[email protected]49639fa2011-12-20 23:22:414908 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:004909
4910 EXPECT_EQ(ERR_IO_PENDING, rv);
4911 EXPECT_EQ(OK, callback.WaitForResult());
4912
4913 const HttpResponseInfo* response = trans->GetResponseInfo();
4914 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504915 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:004916 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4917
[email protected]90499482013-06-01 00:39:504918 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004919
4920 std::string response_data;
4921 rv = ReadTransaction(trans.get(), &response_data);
4922 EXPECT_EQ(OK, rv);
4923 EXPECT_EQ("hello world", response_data);
4924
4925 // Empty the current queue. This is necessary because idle sockets are
4926 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344927 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:004928
4929 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504930 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004931
4932 // Now start the second transaction, which should reuse the previous socket.
4933
[email protected]90499482013-06-01 00:39:504934 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:004935
[email protected]49639fa2011-12-20 23:22:414936 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:004937
4938 EXPECT_EQ(ERR_IO_PENDING, rv);
4939 EXPECT_EQ(OK, callback.WaitForResult());
4940
4941 response = trans->GetResponseInfo();
4942 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504943 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:004944 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4945
[email protected]90499482013-06-01 00:39:504946 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004947
4948 rv = ReadTransaction(trans.get(), &response_data);
4949 EXPECT_EQ(OK, rv);
4950 EXPECT_EQ("hello world", response_data);
4951
4952 // Empty the current queue. This is necessary because idle sockets are
4953 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344954 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:004955
4956 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504957 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004958}
4959
[email protected]b4404c02009-04-10 16:38:524960// Make sure that we recycle a socket after a zero-length response.
4961// http://crbug.com/9880
[email protected]23e482282013-06-14 16:08:024962TEST_P(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:424963 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:524964 request.method = "GET";
4965 request.url = GURL("http://www.google.com/csi?v=3&s=web&action=&"
4966 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
4967 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
4968 "rt=prt.2642,ol.2649,xjs.2951");
4969 request.load_flags = 0;
4970
[email protected]bb88e1d32013-05-03 23:11:074971 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274972
[email protected]262eec82013-03-19 21:01:364973 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504974 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:274975
[email protected]b4404c02009-04-10 16:38:524976 MockRead data_reads[] = {
4977 MockRead("HTTP/1.1 204 No Content\r\n"
4978 "Content-Length: 0\r\n"
4979 "Content-Type: text/html\r\n\r\n"),
4980 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:064981 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:524982 };
4983
[email protected]31a2bfe2010-02-09 08:03:394984 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:074985 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:524986
[email protected]49639fa2011-12-20 23:22:414987 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:524988
[email protected]49639fa2011-12-20 23:22:414989 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424990 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]b4404c02009-04-10 16:38:524991
4992 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424993 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:524994
[email protected]1c773ea12009-04-28 19:58:424995 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504996 ASSERT_TRUE(response != NULL);
[email protected]b4404c02009-04-10 16:38:524997
[email protected]90499482013-06-01 00:39:504998 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]b4404c02009-04-10 16:38:524999 std::string status_line = response->headers->GetStatusLine();
5000 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
5001
[email protected]90499482013-06-01 00:39:505002 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:525003
5004 std::string response_data;
5005 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:425006 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:525007 EXPECT_EQ("", response_data);
5008
5009 // Empty the current queue. This is necessary because idle sockets are
5010 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345011 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:525012
5013 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505014 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:525015}
5016
[email protected]23e482282013-06-14 16:08:025017TEST_P(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
[email protected]b2d26cfd2012-12-11 10:36:065018 ScopedVector<UploadElementReader> element_readers;
5019 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:075020 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:275021
[email protected]1c773ea12009-04-28 19:58:425022 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:515023 // Transaction 1: a GET request that succeeds. The socket is recycled
5024 // after use.
5025 request[0].method = "GET";
5026 request[0].url = GURL("http://www.google.com/");
5027 request[0].load_flags = 0;
5028 // Transaction 2: a POST request. Reuses the socket kept alive from
5029 // transaction 1. The first attempts fails when writing the POST data.
5030 // This causes the transaction to retry with a new socket. The second
5031 // attempt succeeds.
5032 request[1].method = "POST";
5033 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:275034 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:515035 request[1].load_flags = 0;
5036
[email protected]bb88e1d32013-05-03 23:11:075037 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:515038
5039 // The first socket is used for transaction 1 and the first attempt of
5040 // transaction 2.
5041
5042 // The response of transaction 1.
5043 MockRead data_reads1[] = {
5044 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
5045 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:065046 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:515047 };
5048 // The mock write results of transaction 1 and the first attempt of
5049 // transaction 2.
5050 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:065051 MockWrite(SYNCHRONOUS, 64), // GET
5052 MockWrite(SYNCHRONOUS, 93), // POST
5053 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:515054 };
[email protected]31a2bfe2010-02-09 08:03:395055 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5056 data_writes1, arraysize(data_writes1));
[email protected]372d34a2008-11-05 21:30:515057
5058 // The second socket is used for the second attempt of transaction 2.
5059
5060 // The response of transaction 2.
5061 MockRead data_reads2[] = {
5062 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
5063 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:065064 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:515065 };
5066 // The mock write results of the second attempt of transaction 2.
5067 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:065068 MockWrite(SYNCHRONOUS, 93), // POST
5069 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:515070 };
[email protected]31a2bfe2010-02-09 08:03:395071 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5072 data_writes2, arraysize(data_writes2));
[email protected]372d34a2008-11-05 21:30:515073
[email protected]bb88e1d32013-05-03 23:11:075074 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5075 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:515076
5077 const char* kExpectedResponseData[] = {
5078 "hello world", "welcome"
5079 };
5080
5081 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:425082 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505083 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]372d34a2008-11-05 21:30:515084
[email protected]49639fa2011-12-20 23:22:415085 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:515086
[email protected]49639fa2011-12-20 23:22:415087 int rv = trans->Start(&request[i], callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425088 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]372d34a2008-11-05 21:30:515089
5090 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425091 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:515092
[email protected]1c773ea12009-04-28 19:58:425093 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505094 ASSERT_TRUE(response != NULL);
[email protected]372d34a2008-11-05 21:30:515095
[email protected]90499482013-06-01 00:39:505096 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]372d34a2008-11-05 21:30:515097 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5098
5099 std::string response_data;
5100 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:425101 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:515102 EXPECT_EQ(kExpectedResponseData[i], response_data);
5103 }
5104}
[email protected]f9ee6b52008-11-08 06:46:235105
5106// Test the request-challenge-retry sequence for basic auth when there is
5107// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:165108// it fails the identity from the URL is used to answer the challenge.
[email protected]23e482282013-06-14 16:08:025109TEST_P(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:425110 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235111 request.method = "GET";
[email protected]a97cca42009-08-14 01:00:295112 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:415113 request.load_flags = LOAD_NORMAL;
[email protected]a97cca42009-08-14 01:00:295114
[email protected]3fe8d2f82013-10-17 08:56:075115 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275116 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415117 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275118
[email protected]a97cca42009-08-14 01:00:295119 // The password contains an escaped character -- for this test to pass it
5120 // will need to be unescaped by HttpNetworkTransaction.
5121 EXPECT_EQ("b%40r", request.url.password());
5122
[email protected]f9ee6b52008-11-08 06:46:235123 MockWrite data_writes1[] = {
5124 MockWrite("GET / HTTP/1.1\r\n"
5125 "Host: www.google.com\r\n"
5126 "Connection: keep-alive\r\n\r\n"),
5127 };
5128
5129 MockRead data_reads1[] = {
5130 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5131 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5132 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065133 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235134 };
5135
[email protected]2262e3a2012-05-22 16:08:165136 // After the challenge above, the transaction will be restarted using the
5137 // identity from the url (foo, b@r) to answer the challenge.
5138 MockWrite data_writes2[] = {
5139 MockWrite("GET / HTTP/1.1\r\n"
5140 "Host: www.google.com\r\n"
5141 "Connection: keep-alive\r\n"
5142 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
5143 };
5144
5145 MockRead data_reads2[] = {
5146 MockRead("HTTP/1.0 200 OK\r\n"),
5147 MockRead("Content-Length: 100\r\n\r\n"),
5148 MockRead(SYNCHRONOUS, OK),
5149 };
5150
[email protected]31a2bfe2010-02-09 08:03:395151 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5152 data_writes1, arraysize(data_writes1));
[email protected]2262e3a2012-05-22 16:08:165153 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5154 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075155 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5156 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235157
[email protected]49639fa2011-12-20 23:22:415158 TestCompletionCallback callback1;
[email protected]49639fa2011-12-20 23:22:415159 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425160 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235161 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425162 EXPECT_EQ(OK, rv);
[email protected]2262e3a2012-05-22 16:08:165163 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5164
5165 TestCompletionCallback callback2;
5166 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
5167 EXPECT_EQ(ERR_IO_PENDING, rv);
5168 rv = callback2.WaitForResult();
5169 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225170 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5171
[email protected]2262e3a2012-05-22 16:08:165172 const HttpResponseInfo* response = trans->GetResponseInfo();
5173 ASSERT_TRUE(response != NULL);
5174
5175 // There is no challenge info, since the identity in URL worked.
5176 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5177
5178 EXPECT_EQ(100, response->headers->GetContentLength());
5179
5180 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:345181 base::MessageLoop::current()->RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:165182}
5183
5184// Test the request-challenge-retry sequence for basic auth when there is an
5185// incorrect identity in the URL. The identity from the URL should be used only
5186// once.
[email protected]23e482282013-06-14 16:08:025187TEST_P(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:165188 HttpRequestInfo request;
5189 request.method = "GET";
5190 // Note: the URL has a username:password in it. The password "baz" is
5191 // wrong (should be "bar").
5192 request.url = GURL("http://foo:[email protected]/");
5193
5194 request.load_flags = LOAD_NORMAL;
5195
[email protected]3fe8d2f82013-10-17 08:56:075196 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2262e3a2012-05-22 16:08:165197 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415198 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2262e3a2012-05-22 16:08:165199
5200 MockWrite data_writes1[] = {
5201 MockWrite("GET / HTTP/1.1\r\n"
5202 "Host: www.google.com\r\n"
5203 "Connection: keep-alive\r\n\r\n"),
5204 };
5205
5206 MockRead data_reads1[] = {
5207 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5208 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5209 MockRead("Content-Length: 10\r\n\r\n"),
5210 MockRead(SYNCHRONOUS, ERR_FAILED),
5211 };
5212
5213 // After the challenge above, the transaction will be restarted using the
5214 // identity from the url (foo, baz) to answer the challenge.
5215 MockWrite data_writes2[] = {
5216 MockWrite("GET / HTTP/1.1\r\n"
5217 "Host: www.google.com\r\n"
5218 "Connection: keep-alive\r\n"
5219 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
5220 };
5221
5222 MockRead data_reads2[] = {
5223 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5224 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5225 MockRead("Content-Length: 10\r\n\r\n"),
5226 MockRead(SYNCHRONOUS, ERR_FAILED),
5227 };
5228
5229 // After the challenge above, the transaction will be restarted using the
5230 // identity supplied by the user (foo, bar) to answer the challenge.
5231 MockWrite data_writes3[] = {
5232 MockWrite("GET / HTTP/1.1\r\n"
5233 "Host: www.google.com\r\n"
5234 "Connection: keep-alive\r\n"
5235 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5236 };
5237
5238 MockRead data_reads3[] = {
5239 MockRead("HTTP/1.0 200 OK\r\n"),
5240 MockRead("Content-Length: 100\r\n\r\n"),
5241 MockRead(SYNCHRONOUS, OK),
5242 };
5243
5244 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5245 data_writes1, arraysize(data_writes1));
5246 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5247 data_writes2, arraysize(data_writes2));
5248 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5249 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075250 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5251 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5252 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:165253
5254 TestCompletionCallback callback1;
5255
5256 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5257 EXPECT_EQ(ERR_IO_PENDING, rv);
5258
5259 rv = callback1.WaitForResult();
5260 EXPECT_EQ(OK, rv);
5261
5262 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5263 TestCompletionCallback callback2;
5264 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
5265 EXPECT_EQ(ERR_IO_PENDING, rv);
5266 rv = callback2.WaitForResult();
5267 EXPECT_EQ(OK, rv);
5268 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5269
5270 const HttpResponseInfo* response = trans->GetResponseInfo();
5271 ASSERT_TRUE(response != NULL);
5272 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
5273
5274 TestCompletionCallback callback3;
5275 rv = trans->RestartWithAuth(
5276 AuthCredentials(kFoo, kBar), callback3.callback());
5277 EXPECT_EQ(ERR_IO_PENDING, rv);
5278 rv = callback3.WaitForResult();
5279 EXPECT_EQ(OK, rv);
5280 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5281
5282 response = trans->GetResponseInfo();
5283 ASSERT_TRUE(response != NULL);
5284
5285 // There is no challenge info, since the identity worked.
5286 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5287
5288 EXPECT_EQ(100, response->headers->GetContentLength());
5289
[email protected]ea9dc9a2009-09-05 00:43:325290 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:345291 base::MessageLoop::current()->RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:325292}
5293
[email protected]2217aa22013-10-11 03:03:545294
5295// Test the request-challenge-retry sequence for basic auth when there is a
5296// correct identity in the URL, but its use is being suppressed. The identity
5297// from the URL should never be used.
5298TEST_P(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
5299 HttpRequestInfo request;
5300 request.method = "GET";
5301 request.url = GURL("http://foo:[email protected]/");
5302 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
5303
[email protected]3fe8d2f82013-10-17 08:56:075304 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2217aa22013-10-11 03:03:545305 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415306 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2217aa22013-10-11 03:03:545307
5308 MockWrite data_writes1[] = {
5309 MockWrite("GET / HTTP/1.1\r\n"
5310 "Host: www.google.com\r\n"
5311 "Connection: keep-alive\r\n\r\n"),
5312 };
5313
5314 MockRead data_reads1[] = {
5315 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5316 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5317 MockRead("Content-Length: 10\r\n\r\n"),
5318 MockRead(SYNCHRONOUS, ERR_FAILED),
5319 };
5320
5321 // After the challenge above, the transaction will be restarted using the
5322 // identity supplied by the user, not the one in the URL, to answer the
5323 // challenge.
5324 MockWrite data_writes3[] = {
5325 MockWrite("GET / HTTP/1.1\r\n"
5326 "Host: www.google.com\r\n"
5327 "Connection: keep-alive\r\n"
5328 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5329 };
5330
5331 MockRead data_reads3[] = {
5332 MockRead("HTTP/1.0 200 OK\r\n"),
5333 MockRead("Content-Length: 100\r\n\r\n"),
5334 MockRead(SYNCHRONOUS, OK),
5335 };
5336
5337 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5338 data_writes1, arraysize(data_writes1));
5339 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5340 data_writes3, arraysize(data_writes3));
5341 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5342 session_deps_.socket_factory->AddSocketDataProvider(&data3);
5343
5344 TestCompletionCallback callback1;
5345 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5346 EXPECT_EQ(ERR_IO_PENDING, rv);
5347 rv = callback1.WaitForResult();
5348 EXPECT_EQ(OK, rv);
5349 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5350
5351 const HttpResponseInfo* response = trans->GetResponseInfo();
5352 ASSERT_TRUE(response != NULL);
5353 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
5354
5355 TestCompletionCallback callback3;
5356 rv = trans->RestartWithAuth(
5357 AuthCredentials(kFoo, kBar), callback3.callback());
5358 EXPECT_EQ(ERR_IO_PENDING, rv);
5359 rv = callback3.WaitForResult();
5360 EXPECT_EQ(OK, rv);
5361 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5362
5363 response = trans->GetResponseInfo();
5364 ASSERT_TRUE(response != NULL);
5365
5366 // There is no challenge info, since the identity worked.
5367 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5368 EXPECT_EQ(100, response->headers->GetContentLength());
5369
5370 // Empty the current queue.
5371 base::MessageLoop::current()->RunUntilIdle();
5372}
5373
[email protected]f9ee6b52008-11-08 06:46:235374// Test that previously tried username/passwords for a realm get re-used.
[email protected]23e482282013-06-14 16:08:025375TEST_P(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
[email protected]bb88e1d32013-05-03 23:11:075376 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:235377
5378 // Transaction 1: authenticate (foo, bar) on MyRealm1
5379 {
[email protected]1c773ea12009-04-28 19:58:425380 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235381 request.method = "GET";
5382 request.url = GURL("http://www.google.com/x/y/z");
5383 request.load_flags = 0;
5384
[email protected]262eec82013-03-19 21:01:365385 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505386 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275387
[email protected]f9ee6b52008-11-08 06:46:235388 MockWrite data_writes1[] = {
5389 MockWrite("GET /x/y/z HTTP/1.1\r\n"
5390 "Host: www.google.com\r\n"
5391 "Connection: keep-alive\r\n\r\n"),
5392 };
5393
5394 MockRead data_reads1[] = {
5395 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5396 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5397 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065398 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235399 };
5400
5401 // Resend with authorization (username=foo, password=bar)
5402 MockWrite data_writes2[] = {
5403 MockWrite("GET /x/y/z HTTP/1.1\r\n"
5404 "Host: www.google.com\r\n"
5405 "Connection: keep-alive\r\n"
5406 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5407 };
5408
5409 // Sever accepts the authorization.
5410 MockRead data_reads2[] = {
5411 MockRead("HTTP/1.0 200 OK\r\n"),
5412 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065413 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235414 };
5415
[email protected]31a2bfe2010-02-09 08:03:395416 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5417 data_writes1, arraysize(data_writes1));
5418 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5419 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075420 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5421 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235422
[email protected]49639fa2011-12-20 23:22:415423 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235424
[email protected]49639fa2011-12-20 23:22:415425 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425426 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235427
5428 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425429 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235430
[email protected]1c773ea12009-04-28 19:58:425431 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505432 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045433 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:235434
[email protected]49639fa2011-12-20 23:22:415435 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:235436
[email protected]49639fa2011-12-20 23:22:415437 rv = trans->RestartWithAuth(
5438 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425439 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235440
5441 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425442 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235443
5444 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505445 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235446 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5447 EXPECT_EQ(100, response->headers->GetContentLength());
5448 }
5449
5450 // ------------------------------------------------------------------------
5451
5452 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
5453 {
[email protected]1c773ea12009-04-28 19:58:425454 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235455 request.method = "GET";
5456 // Note that Transaction 1 was at /x/y/z, so this is in the same
5457 // protection space as MyRealm1.
5458 request.url = GURL("http://www.google.com/x/y/a/b");
5459 request.load_flags = 0;
5460
[email protected]262eec82013-03-19 21:01:365461 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505462 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275463
[email protected]f9ee6b52008-11-08 06:46:235464 MockWrite data_writes1[] = {
5465 MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
5466 "Host: www.google.com\r\n"
5467 "Connection: keep-alive\r\n"
5468 // Send preemptive authorization for MyRealm1
5469 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5470 };
5471
5472 // The server didn't like the preemptive authorization, and
5473 // challenges us for a different realm (MyRealm2).
5474 MockRead data_reads1[] = {
5475 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5476 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
5477 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065478 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235479 };
5480
5481 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
5482 MockWrite data_writes2[] = {
5483 MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
5484 "Host: www.google.com\r\n"
5485 "Connection: keep-alive\r\n"
5486 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
5487 };
5488
5489 // Sever accepts the authorization.
5490 MockRead data_reads2[] = {
5491 MockRead("HTTP/1.0 200 OK\r\n"),
5492 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065493 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235494 };
5495
[email protected]31a2bfe2010-02-09 08:03:395496 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5497 data_writes1, arraysize(data_writes1));
5498 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5499 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075500 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5501 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235502
[email protected]49639fa2011-12-20 23:22:415503 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235504
[email protected]49639fa2011-12-20 23:22:415505 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425506 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235507
5508 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425509 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235510
[email protected]1c773ea12009-04-28 19:58:425511 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505512 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045513 ASSERT_TRUE(response->auth_challenge.get());
5514 EXPECT_FALSE(response->auth_challenge->is_proxy);
5515 EXPECT_EQ("www.google.com:80",
5516 response->auth_challenge->challenger.ToString());
5517 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
5518 EXPECT_EQ("basic", response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:235519
[email protected]49639fa2011-12-20 23:22:415520 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:235521
[email protected]49639fa2011-12-20 23:22:415522 rv = trans->RestartWithAuth(
5523 AuthCredentials(kFoo2, kBar2), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425524 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235525
5526 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425527 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235528
5529 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505530 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235531 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5532 EXPECT_EQ(100, response->headers->GetContentLength());
5533 }
5534
5535 // ------------------------------------------------------------------------
5536
5537 // Transaction 3: Resend a request in MyRealm's protection space --
5538 // succeed with preemptive authorization.
5539 {
[email protected]1c773ea12009-04-28 19:58:425540 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235541 request.method = "GET";
5542 request.url = GURL("http://www.google.com/x/y/z2");
5543 request.load_flags = 0;
5544
[email protected]262eec82013-03-19 21:01:365545 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505546 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275547
[email protected]f9ee6b52008-11-08 06:46:235548 MockWrite data_writes1[] = {
5549 MockWrite("GET /x/y/z2 HTTP/1.1\r\n"
5550 "Host: www.google.com\r\n"
5551 "Connection: keep-alive\r\n"
5552 // The authorization for MyRealm1 gets sent preemptively
5553 // (since the url is in the same protection space)
5554 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5555 };
5556
5557 // Sever accepts the preemptive authorization
5558 MockRead data_reads1[] = {
5559 MockRead("HTTP/1.0 200 OK\r\n"),
5560 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065561 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235562 };
5563
[email protected]31a2bfe2010-02-09 08:03:395564 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5565 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075566 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:235567
[email protected]49639fa2011-12-20 23:22:415568 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235569
[email protected]49639fa2011-12-20 23:22:415570 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425571 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235572
5573 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425574 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235575
[email protected]1c773ea12009-04-28 19:58:425576 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505577 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235578
5579 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5580 EXPECT_EQ(100, response->headers->GetContentLength());
5581 }
5582
5583 // ------------------------------------------------------------------------
5584
5585 // Transaction 4: request another URL in MyRealm (however the
5586 // url is not known to belong to the protection space, so no pre-auth).
5587 {
[email protected]1c773ea12009-04-28 19:58:425588 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235589 request.method = "GET";
5590 request.url = GURL("http://www.google.com/x/1");
5591 request.load_flags = 0;
5592
[email protected]262eec82013-03-19 21:01:365593 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505594 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275595
[email protected]f9ee6b52008-11-08 06:46:235596 MockWrite data_writes1[] = {
5597 MockWrite("GET /x/1 HTTP/1.1\r\n"
5598 "Host: www.google.com\r\n"
5599 "Connection: keep-alive\r\n\r\n"),
5600 };
5601
5602 MockRead data_reads1[] = {
5603 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5604 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5605 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065606 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235607 };
5608
5609 // Resend with authorization from MyRealm's cache.
5610 MockWrite data_writes2[] = {
5611 MockWrite("GET /x/1 HTTP/1.1\r\n"
5612 "Host: www.google.com\r\n"
5613 "Connection: keep-alive\r\n"
5614 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5615 };
5616
5617 // Sever accepts the authorization.
5618 MockRead data_reads2[] = {
5619 MockRead("HTTP/1.0 200 OK\r\n"),
5620 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065621 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235622 };
5623
[email protected]31a2bfe2010-02-09 08:03:395624 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5625 data_writes1, arraysize(data_writes1));
5626 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5627 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075628 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5629 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235630
[email protected]49639fa2011-12-20 23:22:415631 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235632
[email protected]49639fa2011-12-20 23:22:415633 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425634 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235635
5636 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425637 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235638
[email protected]0757e7702009-03-27 04:00:225639 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:415640 TestCompletionCallback callback2;
5641 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425642 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:225643 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425644 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225645 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5646
[email protected]1c773ea12009-04-28 19:58:425647 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505648 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235649 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5650 EXPECT_EQ(100, response->headers->GetContentLength());
5651 }
5652
5653 // ------------------------------------------------------------------------
5654
5655 // Transaction 5: request a URL in MyRealm, but the server rejects the
5656 // cached identity. Should invalidate and re-prompt.
5657 {
[email protected]1c773ea12009-04-28 19:58:425658 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235659 request.method = "GET";
5660 request.url = GURL("http://www.google.com/p/q/t");
5661 request.load_flags = 0;
5662
[email protected]262eec82013-03-19 21:01:365663 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505664 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275665
[email protected]f9ee6b52008-11-08 06:46:235666 MockWrite data_writes1[] = {
5667 MockWrite("GET /p/q/t HTTP/1.1\r\n"
5668 "Host: www.google.com\r\n"
5669 "Connection: keep-alive\r\n\r\n"),
5670 };
5671
5672 MockRead data_reads1[] = {
5673 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5674 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5675 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065676 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235677 };
5678
5679 // Resend with authorization from cache for MyRealm.
5680 MockWrite data_writes2[] = {
5681 MockWrite("GET /p/q/t HTTP/1.1\r\n"
5682 "Host: www.google.com\r\n"
5683 "Connection: keep-alive\r\n"
5684 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5685 };
5686
5687 // Sever rejects the authorization.
5688 MockRead data_reads2[] = {
5689 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5690 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5691 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065692 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235693 };
5694
5695 // At this point we should prompt for new credentials for MyRealm.
5696 // Restart with username=foo3, password=foo4.
5697 MockWrite data_writes3[] = {
5698 MockWrite("GET /p/q/t HTTP/1.1\r\n"
5699 "Host: www.google.com\r\n"
5700 "Connection: keep-alive\r\n"
5701 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
5702 };
5703
5704 // Sever accepts the authorization.
5705 MockRead data_reads3[] = {
5706 MockRead("HTTP/1.0 200 OK\r\n"),
5707 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065708 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235709 };
5710
[email protected]31a2bfe2010-02-09 08:03:395711 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5712 data_writes1, arraysize(data_writes1));
5713 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5714 data_writes2, arraysize(data_writes2));
5715 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5716 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075717 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5718 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5719 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:235720
[email protected]49639fa2011-12-20 23:22:415721 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235722
[email protected]49639fa2011-12-20 23:22:415723 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425724 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235725
5726 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425727 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235728
[email protected]0757e7702009-03-27 04:00:225729 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:415730 TestCompletionCallback callback2;
5731 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425732 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:225733 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425734 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225735 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5736
[email protected]1c773ea12009-04-28 19:58:425737 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505738 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045739 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:235740
[email protected]49639fa2011-12-20 23:22:415741 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:235742
[email protected]49639fa2011-12-20 23:22:415743 rv = trans->RestartWithAuth(
5744 AuthCredentials(kFoo3, kBar3), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:425745 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235746
[email protected]0757e7702009-03-27 04:00:225747 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425748 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235749
5750 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505751 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235752 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5753 EXPECT_EQ(100, response->headers->GetContentLength());
5754 }
5755}
[email protected]89ceba9a2009-03-21 03:46:065756
[email protected]3c32c5f2010-05-18 15:18:125757// Tests that nonce count increments when multiple auth attempts
5758// are started with the same nonce.
[email protected]23e482282013-06-14 16:08:025759TEST_P(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:445760 HttpAuthHandlerDigest::Factory* digest_factory =
5761 new HttpAuthHandlerDigest::Factory();
5762 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
5763 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
5764 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:075765 session_deps_.http_auth_handler_factory.reset(digest_factory);
5766 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:125767
5768 // Transaction 1: authenticate (foo, bar) on MyRealm1
5769 {
[email protected]3c32c5f2010-05-18 15:18:125770 HttpRequestInfo request;
5771 request.method = "GET";
5772 request.url = GURL("http://www.google.com/x/y/z");
5773 request.load_flags = 0;
5774
[email protected]262eec82013-03-19 21:01:365775 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505776 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275777
[email protected]3c32c5f2010-05-18 15:18:125778 MockWrite data_writes1[] = {
5779 MockWrite("GET /x/y/z HTTP/1.1\r\n"
5780 "Host: www.google.com\r\n"
5781 "Connection: keep-alive\r\n\r\n"),
5782 };
5783
5784 MockRead data_reads1[] = {
5785 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5786 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
5787 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065788 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:125789 };
5790
5791 // Resend with authorization (username=foo, password=bar)
5792 MockWrite data_writes2[] = {
5793 MockWrite("GET /x/y/z HTTP/1.1\r\n"
5794 "Host: www.google.com\r\n"
5795 "Connection: keep-alive\r\n"
5796 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
5797 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
5798 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
5799 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
5800 };
5801
5802 // Sever accepts the authorization.
5803 MockRead data_reads2[] = {
5804 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:065805 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:125806 };
5807
5808 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5809 data_writes1, arraysize(data_writes1));
5810 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5811 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075812 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5813 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:125814
[email protected]49639fa2011-12-20 23:22:415815 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:125816
[email protected]49639fa2011-12-20 23:22:415817 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:125818 EXPECT_EQ(ERR_IO_PENDING, rv);
5819
5820 rv = callback1.WaitForResult();
5821 EXPECT_EQ(OK, rv);
5822
5823 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505824 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045825 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:125826
[email protected]49639fa2011-12-20 23:22:415827 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:125828
[email protected]49639fa2011-12-20 23:22:415829 rv = trans->RestartWithAuth(
5830 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]3c32c5f2010-05-18 15:18:125831 EXPECT_EQ(ERR_IO_PENDING, rv);
5832
5833 rv = callback2.WaitForResult();
5834 EXPECT_EQ(OK, rv);
5835
5836 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505837 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:125838 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5839 }
5840
5841 // ------------------------------------------------------------------------
5842
5843 // Transaction 2: Request another resource in digestive's protection space.
5844 // This will preemptively add an Authorization header which should have an
5845 // "nc" value of 2 (as compared to 1 in the first use.
5846 {
[email protected]3c32c5f2010-05-18 15:18:125847 HttpRequestInfo request;
5848 request.method = "GET";
5849 // Note that Transaction 1 was at /x/y/z, so this is in the same
5850 // protection space as digest.
5851 request.url = GURL("http://www.google.com/x/y/a/b");
5852 request.load_flags = 0;
5853
[email protected]262eec82013-03-19 21:01:365854 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505855 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275856
[email protected]3c32c5f2010-05-18 15:18:125857 MockWrite data_writes1[] = {
5858 MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
5859 "Host: www.google.com\r\n"
5860 "Connection: keep-alive\r\n"
5861 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
5862 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
5863 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
5864 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
5865 };
5866
5867 // Sever accepts the authorization.
5868 MockRead data_reads1[] = {
5869 MockRead("HTTP/1.0 200 OK\r\n"),
5870 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065871 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:125872 };
5873
5874 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5875 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075876 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:125877
[email protected]49639fa2011-12-20 23:22:415878 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:125879
[email protected]49639fa2011-12-20 23:22:415880 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:125881 EXPECT_EQ(ERR_IO_PENDING, rv);
5882
5883 rv = callback1.WaitForResult();
5884 EXPECT_EQ(OK, rv);
5885
5886 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505887 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:125888 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5889 }
5890}
5891
[email protected]89ceba9a2009-03-21 03:46:065892// Test the ResetStateForRestart() private method.
[email protected]23e482282013-06-14 16:08:025893TEST_P(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:065894 // Create a transaction (the dependencies aren't important).
[email protected]3fe8d2f82013-10-17 08:56:075895 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:405896 scoped_ptr<HttpNetworkTransaction> trans(
dcheng48459ac22014-08-26 00:46:415897 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]89ceba9a2009-03-21 03:46:065898
5899 // Setup some state (which we expect ResetStateForRestart() will clear).
[email protected]89ceba9a2009-03-21 03:46:065900 trans->read_buf_ = new IOBuffer(15);
5901 trans->read_buf_len_ = 15;
[email protected]b94f92d2010-10-27 16:45:205902 trans->request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:065903
5904 // Setup state in response_
[email protected]a7e41312009-12-16 23:18:145905 HttpResponseInfo* response = &trans->response_;
[email protected]0877e3d2009-10-17 22:29:575906 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:085907 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:575908 response->response_time = base::Time::Now();
5909 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:065910
5911 { // Setup state for response_.vary_data
5912 HttpRequestInfo request;
5913 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
5914 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:275915 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:435916 request.extra_headers.SetHeader("Foo", "1");
5917 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:505918 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:065919 }
5920
5921 // Cause the above state to be reset.
5922 trans->ResetStateForRestart();
5923
5924 // Verify that the state that needed to be reset, has been reset.
[email protected]9b6fee12009-09-29 18:13:075925 EXPECT_TRUE(trans->read_buf_.get() == NULL);
[email protected]89ceba9a2009-03-21 03:46:065926 EXPECT_EQ(0, trans->read_buf_len_);
[email protected]b94f92d2010-10-27 16:45:205927 EXPECT_TRUE(trans->request_headers_.IsEmpty());
[email protected]0877e3d2009-10-17 22:29:575928 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5929 EXPECT_TRUE(response->headers.get() == NULL);
[email protected]34f40942010-10-04 00:34:045930 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:085931 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:575932 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:065933}
5934
[email protected]bacff652009-03-31 17:50:335935// Test HTTPS connections to a site with a bad certificate
[email protected]23e482282013-06-14 16:08:025936TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:335937 HttpRequestInfo request;
5938 request.method = "GET";
5939 request.url = GURL("https://www.google.com/");
5940 request.load_flags = 0;
5941
[email protected]3fe8d2f82013-10-17 08:56:075942 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275943 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415944 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275945
[email protected]bacff652009-03-31 17:50:335946 MockWrite data_writes[] = {
5947 MockWrite("GET / HTTP/1.1\r\n"
5948 "Host: www.google.com\r\n"
5949 "Connection: keep-alive\r\n\r\n"),
5950 };
5951
5952 MockRead data_reads[] = {
5953 MockRead("HTTP/1.0 200 OK\r\n"),
5954 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5955 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065956 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:335957 };
5958
[email protected]5ecc992a42009-11-11 01:41:595959 StaticSocketDataProvider ssl_bad_certificate;
[email protected]31a2bfe2010-02-09 08:03:395960 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5961 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:065962 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
5963 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:335964
[email protected]bb88e1d32013-05-03 23:11:075965 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
5966 session_deps_.socket_factory->AddSocketDataProvider(&data);
5967 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
5968 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:335969
[email protected]49639fa2011-12-20 23:22:415970 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:335971
[email protected]49639fa2011-12-20 23:22:415972 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:335973 EXPECT_EQ(ERR_IO_PENDING, rv);
5974
5975 rv = callback.WaitForResult();
5976 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
5977
[email protected]49639fa2011-12-20 23:22:415978 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:335979 EXPECT_EQ(ERR_IO_PENDING, rv);
5980
5981 rv = callback.WaitForResult();
5982 EXPECT_EQ(OK, rv);
5983
5984 const HttpResponseInfo* response = trans->GetResponseInfo();
5985
[email protected]fe2255a2011-09-20 19:37:505986 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:335987 EXPECT_EQ(100, response->headers->GetContentLength());
5988}
5989
5990// Test HTTPS connections to a site with a bad certificate, going through a
5991// proxy
[email protected]23e482282013-06-14 16:08:025992TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
[email protected]bb88e1d32013-05-03 23:11:075993 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]bacff652009-03-31 17:50:335994
5995 HttpRequestInfo request;
5996 request.method = "GET";
5997 request.url = GURL("https://www.google.com/");
5998 request.load_flags = 0;
5999
6000 MockWrite proxy_writes[] = {
6001 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:456002 "Host: www.google.com\r\n"
6003 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:336004 };
6005
6006 MockRead proxy_reads[] = {
6007 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066008 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:336009 };
6010
6011 MockWrite data_writes[] = {
6012 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:456013 "Host: www.google.com\r\n"
6014 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:336015 MockWrite("GET / HTTP/1.1\r\n"
6016 "Host: www.google.com\r\n"
6017 "Connection: keep-alive\r\n\r\n"),
6018 };
6019
6020 MockRead data_reads[] = {
6021 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
6022 MockRead("HTTP/1.0 200 OK\r\n"),
6023 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6024 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066025 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:336026 };
6027
[email protected]31a2bfe2010-02-09 08:03:396028 StaticSocketDataProvider ssl_bad_certificate(
6029 proxy_reads, arraysize(proxy_reads),
6030 proxy_writes, arraysize(proxy_writes));
6031 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6032 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066033 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
6034 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:336035
[email protected]bb88e1d32013-05-03 23:11:076036 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
6037 session_deps_.socket_factory->AddSocketDataProvider(&data);
6038 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
6039 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:336040
[email protected]49639fa2011-12-20 23:22:416041 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:336042
6043 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:076044 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:336045
[email protected]3fe8d2f82013-10-17 08:56:076046 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:406047 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416048 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bacff652009-03-31 17:50:336049
[email protected]49639fa2011-12-20 23:22:416050 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:336051 EXPECT_EQ(ERR_IO_PENDING, rv);
6052
6053 rv = callback.WaitForResult();
6054 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
6055
[email protected]49639fa2011-12-20 23:22:416056 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:336057 EXPECT_EQ(ERR_IO_PENDING, rv);
6058
6059 rv = callback.WaitForResult();
6060 EXPECT_EQ(OK, rv);
6061
6062 const HttpResponseInfo* response = trans->GetResponseInfo();
6063
[email protected]fe2255a2011-09-20 19:37:506064 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:336065 EXPECT_EQ(100, response->headers->GetContentLength());
6066 }
6067}
6068
[email protected]2df19bb2010-08-25 20:13:466069
6070// Test HTTPS connections to a site, going through an HTTPS proxy
[email protected]23e482282013-06-14 16:08:026071TEST_P(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076072 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206073 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
6074 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076075 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:466076
6077 HttpRequestInfo request;
6078 request.method = "GET";
6079 request.url = GURL("https://www.google.com/");
6080 request.load_flags = 0;
6081
6082 MockWrite data_writes[] = {
6083 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6084 "Host: www.google.com\r\n"
6085 "Proxy-Connection: keep-alive\r\n\r\n"),
6086 MockWrite("GET / HTTP/1.1\r\n"
6087 "Host: www.google.com\r\n"
6088 "Connection: keep-alive\r\n\r\n"),
6089 };
6090
6091 MockRead data_reads[] = {
6092 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
6093 MockRead("HTTP/1.1 200 OK\r\n"),
6094 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6095 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066096 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:466097 };
6098
6099 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6100 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066101 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
6102 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:466103
[email protected]bb88e1d32013-05-03 23:11:076104 session_deps_.socket_factory->AddSocketDataProvider(&data);
6105 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
6106 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:466107
[email protected]49639fa2011-12-20 23:22:416108 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:466109
[email protected]3fe8d2f82013-10-17 08:56:076110 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:466111 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416112 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2df19bb2010-08-25 20:13:466113
[email protected]49639fa2011-12-20 23:22:416114 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:466115 EXPECT_EQ(ERR_IO_PENDING, rv);
6116
6117 rv = callback.WaitForResult();
6118 EXPECT_EQ(OK, rv);
6119 const HttpResponseInfo* response = trans->GetResponseInfo();
6120
[email protected]fe2255a2011-09-20 19:37:506121 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:466122
6123 EXPECT_TRUE(response->headers->IsKeepAlive());
6124 EXPECT_EQ(200, response->headers->response_code());
6125 EXPECT_EQ(100, response->headers->GetContentLength());
6126 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:206127
6128 LoadTimingInfo load_timing_info;
6129 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6130 TestLoadTimingNotReusedWithPac(load_timing_info,
6131 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:466132}
6133
[email protected]511f6f52010-12-17 03:58:296134// Test an HTTPS Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:026135TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076136 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206137 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
6138 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076139 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:296140
6141 HttpRequestInfo request;
6142 request.method = "GET";
6143 request.url = GURL("https://www.google.com/");
6144 request.load_flags = 0;
6145
6146 MockWrite data_writes[] = {
6147 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6148 "Host: www.google.com\r\n"
6149 "Proxy-Connection: keep-alive\r\n\r\n"),
6150 };
6151
6152 MockRead data_reads[] = {
6153 MockRead("HTTP/1.1 302 Redirect\r\n"),
6154 MockRead("Location: http://login.example.com/\r\n"),
6155 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066156 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:296157 };
6158
6159 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6160 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066161 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:296162
[email protected]bb88e1d32013-05-03 23:11:076163 session_deps_.socket_factory->AddSocketDataProvider(&data);
6164 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296165
[email protected]49639fa2011-12-20 23:22:416166 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296167
[email protected]3fe8d2f82013-10-17 08:56:076168 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296169 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416170 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:296171
[email protected]49639fa2011-12-20 23:22:416172 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296173 EXPECT_EQ(ERR_IO_PENDING, rv);
6174
6175 rv = callback.WaitForResult();
6176 EXPECT_EQ(OK, rv);
6177 const HttpResponseInfo* response = trans->GetResponseInfo();
6178
[email protected]fe2255a2011-09-20 19:37:506179 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:296180
6181 EXPECT_EQ(302, response->headers->response_code());
6182 std::string url;
6183 EXPECT_TRUE(response->headers->IsRedirect(&url));
6184 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:206185
6186 // In the case of redirects from proxies, HttpNetworkTransaction returns
6187 // timing for the proxy connection instead of the connection to the host,
6188 // and no send / receive times.
6189 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
6190 LoadTimingInfo load_timing_info;
6191 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6192
6193 EXPECT_FALSE(load_timing_info.socket_reused);
6194 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
6195
6196 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
6197 EXPECT_LE(load_timing_info.proxy_resolve_start,
6198 load_timing_info.proxy_resolve_end);
6199 EXPECT_LE(load_timing_info.proxy_resolve_end,
6200 load_timing_info.connect_timing.connect_start);
6201 ExpectConnectTimingHasTimes(
6202 load_timing_info.connect_timing,
6203 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
6204
6205 EXPECT_TRUE(load_timing_info.send_start.is_null());
6206 EXPECT_TRUE(load_timing_info.send_end.is_null());
6207 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:296208}
6209
6210// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:026211TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
[email protected]bb88e1d32013-05-03 23:11:076212 session_deps_.proxy_service.reset(
[email protected]511f6f52010-12-17 03:58:296213 ProxyService::CreateFixed("https://proxy:70"));
6214
6215 HttpRequestInfo request;
6216 request.method = "GET";
6217 request.url = GURL("https://www.google.com/");
6218 request.load_flags = 0;
6219
[email protected]9075f51c2013-08-15 17:53:546220 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
6221 LOWEST));
[email protected]c10b20852013-05-15 21:29:206222 scoped_ptr<SpdyFrame> goaway(
6223 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:296224 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:066225 CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
[email protected]57d2dfa2013-06-24 06:04:126226 CreateMockWrite(*goaway.get(), 3, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:296227 };
6228
6229 static const char* const kExtraHeaders[] = {
6230 "location",
6231 "http://login.example.com/",
6232 };
[email protected]ff98d7f02012-03-22 21:44:196233 scoped_ptr<SpdyFrame> resp(
[email protected]23e482282013-06-14 16:08:026234 spdy_util_.ConstructSpdySynReplyError("302 Redirect", kExtraHeaders,
[email protected]511f6f52010-12-17 03:58:296235 arraysize(kExtraHeaders)/2, 1));
6236 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:066237 CreateMockRead(*resp.get(), 1, SYNCHRONOUS),
6238 MockRead(ASYNC, 0, 2), // EOF
[email protected]511f6f52010-12-17 03:58:296239 };
6240
[email protected]dd54bd82012-07-19 23:44:576241 DelayedSocketData data(
6242 1, // wait for one write to finish before reading.
6243 data_reads, arraysize(data_reads),
6244 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066245 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]23e482282013-06-14 16:08:026246 proxy_ssl.SetNextProto(GetParam());
[email protected]511f6f52010-12-17 03:58:296247
[email protected]bb88e1d32013-05-03 23:11:076248 session_deps_.socket_factory->AddSocketDataProvider(&data);
6249 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296250
[email protected]49639fa2011-12-20 23:22:416251 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296252
[email protected]3fe8d2f82013-10-17 08:56:076253 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296254 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416255 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:296256
[email protected]49639fa2011-12-20 23:22:416257 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296258 EXPECT_EQ(ERR_IO_PENDING, rv);
6259
6260 rv = callback.WaitForResult();
6261 EXPECT_EQ(OK, rv);
6262 const HttpResponseInfo* response = trans->GetResponseInfo();
6263
[email protected]fe2255a2011-09-20 19:37:506264 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:296265
6266 EXPECT_EQ(302, response->headers->response_code());
6267 std::string url;
6268 EXPECT_TRUE(response->headers->IsRedirect(&url));
6269 EXPECT_EQ("http://login.example.com/", url);
6270}
6271
[email protected]4eddbc732012-08-09 05:40:176272// Test that an HTTPS proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:026273TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:176274 ErrorResponseToHttpsConnectViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076275 session_deps_.proxy_service.reset(
[email protected]511f6f52010-12-17 03:58:296276 ProxyService::CreateFixed("https://proxy:70"));
6277
6278 HttpRequestInfo request;
6279 request.method = "GET";
6280 request.url = GURL("https://www.google.com/");
6281 request.load_flags = 0;
6282
6283 MockWrite data_writes[] = {
6284 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6285 "Host: www.google.com\r\n"
6286 "Proxy-Connection: keep-alive\r\n\r\n"),
6287 };
6288
6289 MockRead data_reads[] = {
6290 MockRead("HTTP/1.1 404 Not Found\r\n"),
6291 MockRead("Content-Length: 23\r\n\r\n"),
6292 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:066293 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:296294 };
6295
6296 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6297 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066298 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:296299
[email protected]bb88e1d32013-05-03 23:11:076300 session_deps_.socket_factory->AddSocketDataProvider(&data);
6301 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296302
[email protected]49639fa2011-12-20 23:22:416303 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296304
[email protected]3fe8d2f82013-10-17 08:56:076305 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296306 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416307 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:296308
[email protected]49639fa2011-12-20 23:22:416309 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296310 EXPECT_EQ(ERR_IO_PENDING, rv);
6311
6312 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:176313 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:296314
[email protected]4eddbc732012-08-09 05:40:176315 // TODO(ttuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:296316}
6317
[email protected]4eddbc732012-08-09 05:40:176318// Test that a SPDY proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:026319TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:176320 ErrorResponseToHttpsConnectViaSpdyProxy) {
[email protected]bb88e1d32013-05-03 23:11:076321 session_deps_.proxy_service.reset(
6322 ProxyService::CreateFixed("https://proxy:70"));
[email protected]511f6f52010-12-17 03:58:296323
6324 HttpRequestInfo request;
6325 request.method = "GET";
6326 request.url = GURL("https://www.google.com/");
6327 request.load_flags = 0;
6328
[email protected]9075f51c2013-08-15 17:53:546329 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
6330 LOWEST));
[email protected]c10b20852013-05-15 21:29:206331 scoped_ptr<SpdyFrame> rst(
6332 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:296333 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:066334 CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
[email protected]4eddbc732012-08-09 05:40:176335 CreateMockWrite(*rst.get(), 3, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:296336 };
6337
6338 static const char* const kExtraHeaders[] = {
6339 "location",
6340 "http://login.example.com/",
6341 };
[email protected]ff98d7f02012-03-22 21:44:196342 scoped_ptr<SpdyFrame> resp(
[email protected]23e482282013-06-14 16:08:026343 spdy_util_.ConstructSpdySynReplyError("404 Not Found", kExtraHeaders,
[email protected]511f6f52010-12-17 03:58:296344 arraysize(kExtraHeaders)/2, 1));
[email protected]ff98d7f02012-03-22 21:44:196345 scoped_ptr<SpdyFrame> body(
[email protected]23e482282013-06-14 16:08:026346 spdy_util_.ConstructSpdyBodyFrame(
6347 1, "The host does not exist", 23, true));
[email protected]511f6f52010-12-17 03:58:296348 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:066349 CreateMockRead(*resp.get(), 1, SYNCHRONOUS),
6350 CreateMockRead(*body.get(), 2, SYNCHRONOUS),
[email protected]4eddbc732012-08-09 05:40:176351 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:296352 };
6353
[email protected]dd54bd82012-07-19 23:44:576354 DelayedSocketData data(
6355 1, // wait for one write to finish before reading.
6356 data_reads, arraysize(data_reads),
6357 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066358 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]23e482282013-06-14 16:08:026359 proxy_ssl.SetNextProto(GetParam());
[email protected]511f6f52010-12-17 03:58:296360
[email protected]bb88e1d32013-05-03 23:11:076361 session_deps_.socket_factory->AddSocketDataProvider(&data);
6362 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296363
[email protected]49639fa2011-12-20 23:22:416364 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296365
[email protected]3fe8d2f82013-10-17 08:56:076366 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296367 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416368 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:296369
[email protected]49639fa2011-12-20 23:22:416370 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296371 EXPECT_EQ(ERR_IO_PENDING, rv);
6372
6373 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:176374 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:296375
[email protected]4eddbc732012-08-09 05:40:176376 // TODO(ttuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:296377}
6378
[email protected]0c5fb722012-02-28 11:50:356379// Test the request-challenge-retry sequence for basic auth, through
6380// a SPDY proxy over a single SPDY session.
[email protected]23e482282013-06-14 16:08:026381TEST_P(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:356382 HttpRequestInfo request;
6383 request.method = "GET";
6384 request.url = GURL("https://www.google.com/");
6385 // when the no authentication data flag is set.
6386 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
6387
6388 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076389 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206390 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
[email protected]333bdf62012-06-08 22:57:296391 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076392 session_deps_.net_log = log.bound().net_log();
6393 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:356394
6395 // Since we have proxy, should try to establish tunnel.
[email protected]9075f51c2013-08-15 17:53:546396 scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
6397 LOWEST));
[email protected]c10b20852013-05-15 21:29:206398 scoped_ptr<SpdyFrame> rst(
6399 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]0c5fb722012-02-28 11:50:356400
6401 // After calling trans->RestartWithAuth(), this is the request we should
6402 // be issuing -- the final header line contains the credentials.
6403 const char* const kAuthCredentials[] = {
6404 "proxy-authorization", "Basic Zm9vOmJhcg==",
6405 };
[email protected]fba2dbde2013-05-24 16:09:016406 scoped_ptr<SpdyFrame> connect2(spdy_util_.ConstructSpdyConnect(
[email protected]9075f51c2013-08-15 17:53:546407 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST));
[email protected]0c5fb722012-02-28 11:50:356408 // fetch https://www.google.com/ via HTTP
6409 const char get[] = "GET / HTTP/1.1\r\n"
6410 "Host: www.google.com\r\n"
6411 "Connection: keep-alive\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:196412 scoped_ptr<SpdyFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:026413 spdy_util_.ConstructSpdyBodyFrame(3, get, strlen(get), false));
[email protected]0c5fb722012-02-28 11:50:356414
6415 MockWrite spdy_writes[] = {
[email protected]3d7c43f2012-07-10 21:26:206416 CreateMockWrite(*req, 1, ASYNC),
[email protected]c92f4b4542012-07-26 23:53:216417 CreateMockWrite(*rst, 4, ASYNC),
6418 CreateMockWrite(*connect2, 5),
[email protected]3d7c43f2012-07-10 21:26:206419 CreateMockWrite(*wrapped_get, 8),
[email protected]0c5fb722012-02-28 11:50:356420 };
6421
6422 // The proxy responds to the connect with a 407, using a persistent
6423 // connection.
[email protected]745aa9c2014-06-27 02:21:296424 const char* const kAuthStatus = "407";
[email protected]0c5fb722012-02-28 11:50:356425 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:356426 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
6427 };
[email protected]745aa9c2014-06-27 02:21:296428 scoped_ptr<SpdyFrame> conn_auth_resp(spdy_util_.ConstructSpdySynReplyError(
6429 kAuthStatus, kAuthChallenge, arraysize(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:356430
[email protected]23e482282013-06-14 16:08:026431 scoped_ptr<SpdyFrame> conn_resp(
6432 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:356433 const char resp[] = "HTTP/1.1 200 OK\r\n"
6434 "Content-Length: 5\r\n\r\n";
6435
[email protected]ff98d7f02012-03-22 21:44:196436 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:026437 spdy_util_.ConstructSpdyBodyFrame(3, resp, strlen(resp), false));
[email protected]ff98d7f02012-03-22 21:44:196438 scoped_ptr<SpdyFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:026439 spdy_util_.ConstructSpdyBodyFrame(3, "hello", 5, false));
[email protected]0c5fb722012-02-28 11:50:356440 MockRead spdy_reads[] = {
[email protected]3d7c43f2012-07-10 21:26:206441 CreateMockRead(*conn_auth_resp, 2, ASYNC),
6442 CreateMockRead(*conn_resp, 6, ASYNC),
6443 CreateMockRead(*wrapped_get_resp, 9, ASYNC),
6444 CreateMockRead(*wrapped_body, 10, ASYNC),
6445 MockRead(ASYNC, OK, 11), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:356446 };
6447
[email protected]dd54bd82012-07-19 23:44:576448 OrderedSocketData spdy_data(
6449 spdy_reads, arraysize(spdy_reads),
6450 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:076451 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:356452 // Negotiate SPDY to the proxy
6453 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:026454 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:076455 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:356456 // Vanilla SSL to the server
6457 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076458 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:356459
6460 TestCompletionCallback callback1;
6461
[email protected]262eec82013-03-19 21:01:366462 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506463 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0c5fb722012-02-28 11:50:356464
6465 int rv = trans->Start(&request, callback1.callback(), log.bound());
6466 EXPECT_EQ(ERR_IO_PENDING, rv);
6467
6468 rv = callback1.WaitForResult();
6469 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:576470 net::CapturingNetLog::CapturedEntryList entries;
[email protected]0c5fb722012-02-28 11:50:356471 log.GetEntries(&entries);
6472 size_t pos = ExpectLogContainsSomewhere(
6473 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
6474 NetLog::PHASE_NONE);
6475 ExpectLogContainsSomewhere(
6476 entries, pos,
6477 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
6478 NetLog::PHASE_NONE);
6479
6480 const HttpResponseInfo* response = trans->GetResponseInfo();
6481 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:506482 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]0c5fb722012-02-28 11:50:356483 EXPECT_EQ(407, response->headers->response_code());
6484 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6485 EXPECT_TRUE(response->auth_challenge.get() != NULL);
6486 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
6487
6488 TestCompletionCallback callback2;
6489
6490 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
6491 callback2.callback());
6492 EXPECT_EQ(ERR_IO_PENDING, rv);
6493
6494 rv = callback2.WaitForResult();
6495 EXPECT_EQ(OK, rv);
6496
6497 response = trans->GetResponseInfo();
6498 ASSERT_TRUE(response != NULL);
6499
6500 EXPECT_TRUE(response->headers->IsKeepAlive());
6501 EXPECT_EQ(200, response->headers->response_code());
6502 EXPECT_EQ(5, response->headers->GetContentLength());
6503 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6504
6505 // The password prompt info should not be set.
6506 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6507
[email protected]029c83b62013-01-24 05:28:206508 LoadTimingInfo load_timing_info;
6509 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6510 TestLoadTimingNotReusedWithPac(load_timing_info,
6511 CONNECT_TIMING_HAS_SSL_TIMES);
6512
[email protected]0c5fb722012-02-28 11:50:356513 trans.reset();
6514 session->CloseAllConnections();
6515}
6516
[email protected]7c6f7ba2012-04-03 04:09:296517// Test that an explicitly trusted SPDY proxy can push a resource from an
6518// origin that is different from that of its associated resource.
[email protected]23e482282013-06-14 16:08:026519TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPush) {
[email protected]7c6f7ba2012-04-03 04:09:296520 HttpRequestInfo request;
6521 HttpRequestInfo push_request;
6522
[email protected]7c6f7ba2012-04-03 04:09:296523 request.method = "GET";
6524 request.url = GURL("http://www.google.com/");
6525 push_request.method = "GET";
6526 push_request.url = GURL("http://www.another-origin.com/foo.dat");
6527
[email protected]7c6f7ba2012-04-03 04:09:296528 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076529 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206530 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
[email protected]333bdf62012-06-08 22:57:296531 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076532 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:506533
6534 // Enable cross-origin push.
[email protected]bb88e1d32013-05-03 23:11:076535 session_deps_.trusted_spdy_proxy = "myproxy:70";
[email protected]61b4efc2012-04-27 18:12:506536
[email protected]bb88e1d32013-05-03 23:11:076537 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:296538
[email protected]cdf8f7e72013-05-23 10:56:466539 scoped_ptr<SpdyFrame> stream1_syn(
6540 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]7c6f7ba2012-04-03 04:09:296541
6542 MockWrite spdy_writes[] = {
[email protected]cdf8f7e72013-05-23 10:56:466543 CreateMockWrite(*stream1_syn, 1, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:296544 };
6545
6546 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026547 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:296548
6549 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026550 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:296551
6552 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026553 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
[email protected]7c6f7ba2012-04-03 04:09:296554 0,
6555 2,
6556 1,
6557 "http://www.another-origin.com/foo.dat"));
[email protected]8a0fc822013-06-27 20:52:436558 const char kPushedData[] = "pushed";
6559 scoped_ptr<SpdyFrame> stream2_body(
6560 spdy_util_.ConstructSpdyBodyFrame(
6561 2, kPushedData, strlen(kPushedData), true));
[email protected]7c6f7ba2012-04-03 04:09:296562
6563 MockRead spdy_reads[] = {
6564 CreateMockRead(*stream1_reply, 2, ASYNC),
6565 CreateMockRead(*stream2_syn, 3, ASYNC),
6566 CreateMockRead(*stream1_body, 4, ASYNC),
[email protected]8a0fc822013-06-27 20:52:436567 CreateMockRead(*stream2_body, 5, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:296568 MockRead(ASYNC, ERR_IO_PENDING, 6), // Force a pause
6569 };
6570
[email protected]dd54bd82012-07-19 23:44:576571 OrderedSocketData spdy_data(
6572 spdy_reads, arraysize(spdy_reads),
6573 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:076574 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:296575 // Negotiate SPDY to the proxy
6576 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:026577 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:076578 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:296579
[email protected]262eec82013-03-19 21:01:366580 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506581 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7c6f7ba2012-04-03 04:09:296582 TestCompletionCallback callback;
6583 int rv = trans->Start(&request, callback.callback(), log.bound());
6584 EXPECT_EQ(ERR_IO_PENDING, rv);
6585
6586 rv = callback.WaitForResult();
6587 EXPECT_EQ(OK, rv);
6588 const HttpResponseInfo* response = trans->GetResponseInfo();
6589
[email protected]262eec82013-03-19 21:01:366590 scoped_ptr<HttpTransaction> push_trans(
[email protected]90499482013-06-01 00:39:506591 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
6592 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
[email protected]7c6f7ba2012-04-03 04:09:296593 EXPECT_EQ(ERR_IO_PENDING, rv);
6594
6595 rv = callback.WaitForResult();
6596 EXPECT_EQ(OK, rv);
6597 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
6598
6599 ASSERT_TRUE(response != NULL);
6600 EXPECT_TRUE(response->headers->IsKeepAlive());
6601
6602 EXPECT_EQ(200, response->headers->response_code());
6603 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6604
6605 std::string response_data;
6606 rv = ReadTransaction(trans.get(), &response_data);
6607 EXPECT_EQ(OK, rv);
6608 EXPECT_EQ("hello!", response_data);
6609
[email protected]029c83b62013-01-24 05:28:206610 LoadTimingInfo load_timing_info;
6611 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6612 TestLoadTimingNotReusedWithPac(load_timing_info,
6613 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6614
[email protected]7c6f7ba2012-04-03 04:09:296615 // Verify the pushed stream.
[email protected]90499482013-06-01 00:39:506616 EXPECT_TRUE(push_response->headers.get() != NULL);
[email protected]7c6f7ba2012-04-03 04:09:296617 EXPECT_EQ(200, push_response->headers->response_code());
6618
6619 rv = ReadTransaction(push_trans.get(), &response_data);
6620 EXPECT_EQ(OK, rv);
6621 EXPECT_EQ("pushed", response_data);
6622
[email protected]029c83b62013-01-24 05:28:206623 LoadTimingInfo push_load_timing_info;
6624 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
6625 TestLoadTimingReusedWithPac(push_load_timing_info);
6626 // The transactions should share a socket ID, despite being for different
6627 // origins.
6628 EXPECT_EQ(load_timing_info.socket_log_id,
6629 push_load_timing_info.socket_log_id);
6630
[email protected]7c6f7ba2012-04-03 04:09:296631 trans.reset();
6632 push_trans.reset();
6633 session->CloseAllConnections();
6634}
6635
[email protected]8c843192012-04-05 07:15:006636// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
[email protected]23e482282013-06-14 16:08:026637TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
[email protected]8c843192012-04-05 07:15:006638 HttpRequestInfo request;
6639
6640 request.method = "GET";
6641 request.url = GURL("http://www.google.com/");
6642
[email protected]8c843192012-04-05 07:15:006643 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076644 session_deps_.proxy_service.reset(
[email protected]8c843192012-04-05 07:15:006645 ProxyService::CreateFixed("https://myproxy:70"));
[email protected]333bdf62012-06-08 22:57:296646 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076647 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:506648
6649 // Enable cross-origin push.
[email protected]bb88e1d32013-05-03 23:11:076650 session_deps_.trusted_spdy_proxy = "myproxy:70";
[email protected]61b4efc2012-04-27 18:12:506651
[email protected]bb88e1d32013-05-03 23:11:076652 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:006653
[email protected]cdf8f7e72013-05-23 10:56:466654 scoped_ptr<SpdyFrame> stream1_syn(
6655 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]8c843192012-04-05 07:15:006656
6657 scoped_ptr<SpdyFrame> push_rst(
[email protected]c10b20852013-05-15 21:29:206658 spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:006659
6660 MockWrite spdy_writes[] = {
6661 CreateMockWrite(*stream1_syn, 1, ASYNC),
6662 CreateMockWrite(*push_rst, 4),
6663 };
6664
6665 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026666 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:006667
6668 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026669 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8c843192012-04-05 07:15:006670
6671 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026672 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
[email protected]8c843192012-04-05 07:15:006673 0,
6674 2,
6675 1,
6676 "https://www.another-origin.com/foo.dat"));
6677
6678 MockRead spdy_reads[] = {
6679 CreateMockRead(*stream1_reply, 2, ASYNC),
6680 CreateMockRead(*stream2_syn, 3, ASYNC),
6681 CreateMockRead(*stream1_body, 5, ASYNC),
6682 MockRead(ASYNC, ERR_IO_PENDING, 6), // Force a pause
6683 };
6684
[email protected]dd54bd82012-07-19 23:44:576685 OrderedSocketData spdy_data(
6686 spdy_reads, arraysize(spdy_reads),
6687 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:076688 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:006689 // Negotiate SPDY to the proxy
6690 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:026691 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:076692 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:006693
[email protected]262eec82013-03-19 21:01:366694 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506695 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c843192012-04-05 07:15:006696 TestCompletionCallback callback;
6697 int rv = trans->Start(&request, callback.callback(), log.bound());
6698 EXPECT_EQ(ERR_IO_PENDING, rv);
6699
6700 rv = callback.WaitForResult();
6701 EXPECT_EQ(OK, rv);
6702 const HttpResponseInfo* response = trans->GetResponseInfo();
6703
6704 ASSERT_TRUE(response != NULL);
6705 EXPECT_TRUE(response->headers->IsKeepAlive());
6706
6707 EXPECT_EQ(200, response->headers->response_code());
6708 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6709
6710 std::string response_data;
6711 rv = ReadTransaction(trans.get(), &response_data);
6712 EXPECT_EQ(OK, rv);
6713 EXPECT_EQ("hello!", response_data);
6714
6715 trans.reset();
6716 session->CloseAllConnections();
6717}
6718
[email protected]2df19bb2010-08-25 20:13:466719// Test HTTPS connections to a site with a bad certificate, going through an
6720// HTTPS proxy
[email protected]23e482282013-06-14 16:08:026721TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076722 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:116723 "https://proxy:70"));
[email protected]2df19bb2010-08-25 20:13:466724
6725 HttpRequestInfo request;
6726 request.method = "GET";
6727 request.url = GURL("https://www.google.com/");
6728 request.load_flags = 0;
6729
6730 // Attempt to fetch the URL from a server with a bad cert
6731 MockWrite bad_cert_writes[] = {
6732 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6733 "Host: www.google.com\r\n"
6734 "Proxy-Connection: keep-alive\r\n\r\n"),
6735 };
6736
6737 MockRead bad_cert_reads[] = {
6738 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066739 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:466740 };
6741
6742 // Attempt to fetch the URL with a good cert
6743 MockWrite good_data_writes[] = {
6744 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6745 "Host: www.google.com\r\n"
6746 "Proxy-Connection: keep-alive\r\n\r\n"),
6747 MockWrite("GET / HTTP/1.1\r\n"
6748 "Host: www.google.com\r\n"
6749 "Connection: keep-alive\r\n\r\n"),
6750 };
6751
6752 MockRead good_cert_reads[] = {
6753 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
6754 MockRead("HTTP/1.0 200 OK\r\n"),
6755 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6756 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066757 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:466758 };
6759
6760 StaticSocketDataProvider ssl_bad_certificate(
6761 bad_cert_reads, arraysize(bad_cert_reads),
6762 bad_cert_writes, arraysize(bad_cert_writes));
6763 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
6764 good_data_writes, arraysize(good_data_writes));
[email protected]8ddf8322012-02-23 18:08:066765 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
6766 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:466767
6768 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:076769 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6770 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
6771 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:466772
6773 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:076774 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6775 session_deps_.socket_factory->AddSocketDataProvider(&data);
6776 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:466777
[email protected]49639fa2011-12-20 23:22:416778 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:466779
[email protected]3fe8d2f82013-10-17 08:56:076780 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:466781 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416782 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2df19bb2010-08-25 20:13:466783
[email protected]49639fa2011-12-20 23:22:416784 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:466785 EXPECT_EQ(ERR_IO_PENDING, rv);
6786
6787 rv = callback.WaitForResult();
6788 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
6789
[email protected]49639fa2011-12-20 23:22:416790 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]2df19bb2010-08-25 20:13:466791 EXPECT_EQ(ERR_IO_PENDING, rv);
6792
6793 rv = callback.WaitForResult();
6794 EXPECT_EQ(OK, rv);
6795
6796 const HttpResponseInfo* response = trans->GetResponseInfo();
6797
[email protected]fe2255a2011-09-20 19:37:506798 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:466799 EXPECT_EQ(100, response->headers->GetContentLength());
6800}
6801
[email protected]23e482282013-06-14 16:08:026802TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:426803 HttpRequestInfo request;
6804 request.method = "GET";
6805 request.url = GURL("http://www.google.com/");
[email protected]8c76ae22010-04-20 22:15:436806 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
6807 "Chromium Ultra Awesome X Edition");
[email protected]1c773ea12009-04-28 19:58:426808
[email protected]3fe8d2f82013-10-17 08:56:076809 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276810 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416811 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276812
[email protected]1c773ea12009-04-28 19:58:426813 MockWrite data_writes[] = {
6814 MockWrite("GET / HTTP/1.1\r\n"
6815 "Host: www.google.com\r\n"
6816 "Connection: keep-alive\r\n"
6817 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
6818 };
6819
6820 // Lastly, the server responds with the actual content.
6821 MockRead data_reads[] = {
6822 MockRead("HTTP/1.0 200 OK\r\n"),
6823 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6824 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066825 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426826 };
6827
[email protected]31a2bfe2010-02-09 08:03:396828 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6829 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076830 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426831
[email protected]49639fa2011-12-20 23:22:416832 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426833
[email protected]49639fa2011-12-20 23:22:416834 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426835 EXPECT_EQ(ERR_IO_PENDING, rv);
6836
6837 rv = callback.WaitForResult();
6838 EXPECT_EQ(OK, rv);
6839}
6840
[email protected]23e482282013-06-14 16:08:026841TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:296842 HttpRequestInfo request;
6843 request.method = "GET";
6844 request.url = GURL("https://www.google.com/");
6845 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
6846 "Chromium Ultra Awesome X Edition");
6847
[email protected]bb88e1d32013-05-03 23:11:076848 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]3fe8d2f82013-10-17 08:56:076849 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276850 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416851 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276852
[email protected]da81f132010-08-18 23:39:296853 MockWrite data_writes[] = {
6854 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6855 "Host: www.google.com\r\n"
6856 "Proxy-Connection: keep-alive\r\n"
6857 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
6858 };
6859 MockRead data_reads[] = {
6860 // Return an error, so the transaction stops here (this test isn't
6861 // interested in the rest).
6862 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
6863 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6864 MockRead("Proxy-Connection: close\r\n\r\n"),
6865 };
6866
6867 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6868 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076869 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:296870
[email protected]49639fa2011-12-20 23:22:416871 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:296872
[email protected]49639fa2011-12-20 23:22:416873 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]da81f132010-08-18 23:39:296874 EXPECT_EQ(ERR_IO_PENDING, rv);
6875
6876 rv = callback.WaitForResult();
6877 EXPECT_EQ(OK, rv);
6878}
6879
[email protected]23e482282013-06-14 16:08:026880TEST_P(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:426881 HttpRequestInfo request;
6882 request.method = "GET";
6883 request.url = GURL("http://www.google.com/");
6884 request.load_flags = 0;
[email protected]c10450102011-06-27 09:06:166885 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
6886 "http://the.previous.site.com/");
[email protected]1c773ea12009-04-28 19:58:426887
[email protected]3fe8d2f82013-10-17 08:56:076888 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276889 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416890 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276891
[email protected]1c773ea12009-04-28 19:58:426892 MockWrite data_writes[] = {
6893 MockWrite("GET / HTTP/1.1\r\n"
6894 "Host: www.google.com\r\n"
6895 "Connection: keep-alive\r\n"
6896 "Referer: http://the.previous.site.com/\r\n\r\n"),
6897 };
6898
6899 // Lastly, the server responds with the actual content.
6900 MockRead data_reads[] = {
6901 MockRead("HTTP/1.0 200 OK\r\n"),
6902 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6903 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066904 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426905 };
6906
[email protected]31a2bfe2010-02-09 08:03:396907 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6908 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076909 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426910
[email protected]49639fa2011-12-20 23:22:416911 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426912
[email protected]49639fa2011-12-20 23:22:416913 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426914 EXPECT_EQ(ERR_IO_PENDING, rv);
6915
6916 rv = callback.WaitForResult();
6917 EXPECT_EQ(OK, rv);
6918}
6919
[email protected]23e482282013-06-14 16:08:026920TEST_P(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:426921 HttpRequestInfo request;
6922 request.method = "POST";
6923 request.url = GURL("http://www.google.com/");
6924
[email protected]3fe8d2f82013-10-17 08:56:076925 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276926 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416927 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276928
[email protected]1c773ea12009-04-28 19:58:426929 MockWrite data_writes[] = {
6930 MockWrite("POST / HTTP/1.1\r\n"
6931 "Host: www.google.com\r\n"
6932 "Connection: keep-alive\r\n"
6933 "Content-Length: 0\r\n\r\n"),
6934 };
6935
6936 // Lastly, the server responds with the actual content.
6937 MockRead data_reads[] = {
6938 MockRead("HTTP/1.0 200 OK\r\n"),
6939 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6940 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066941 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426942 };
6943
[email protected]31a2bfe2010-02-09 08:03:396944 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6945 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076946 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426947
[email protected]49639fa2011-12-20 23:22:416948 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426949
[email protected]49639fa2011-12-20 23:22:416950 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426951 EXPECT_EQ(ERR_IO_PENDING, rv);
6952
6953 rv = callback.WaitForResult();
6954 EXPECT_EQ(OK, rv);
6955}
6956
[email protected]23e482282013-06-14 16:08:026957TEST_P(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:426958 HttpRequestInfo request;
6959 request.method = "PUT";
6960 request.url = GURL("http://www.google.com/");
6961
[email protected]3fe8d2f82013-10-17 08:56:076962 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276963 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416964 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276965
[email protected]1c773ea12009-04-28 19:58:426966 MockWrite data_writes[] = {
6967 MockWrite("PUT / HTTP/1.1\r\n"
6968 "Host: www.google.com\r\n"
6969 "Connection: keep-alive\r\n"
6970 "Content-Length: 0\r\n\r\n"),
6971 };
6972
6973 // Lastly, the server responds with the actual content.
6974 MockRead data_reads[] = {
6975 MockRead("HTTP/1.0 200 OK\r\n"),
6976 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6977 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066978 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426979 };
6980
[email protected]31a2bfe2010-02-09 08:03:396981 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6982 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076983 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426984
[email protected]49639fa2011-12-20 23:22:416985 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426986
[email protected]49639fa2011-12-20 23:22:416987 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426988 EXPECT_EQ(ERR_IO_PENDING, rv);
6989
6990 rv = callback.WaitForResult();
6991 EXPECT_EQ(OK, rv);
6992}
6993
[email protected]23e482282013-06-14 16:08:026994TEST_P(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:426995 HttpRequestInfo request;
6996 request.method = "HEAD";
6997 request.url = GURL("http://www.google.com/");
6998
[email protected]3fe8d2f82013-10-17 08:56:076999 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277000 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417001 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277002
[email protected]1c773ea12009-04-28 19:58:427003 MockWrite data_writes[] = {
7004 MockWrite("HEAD / HTTP/1.1\r\n"
7005 "Host: www.google.com\r\n"
7006 "Connection: keep-alive\r\n"
7007 "Content-Length: 0\r\n\r\n"),
7008 };
7009
7010 // Lastly, the server responds with the actual content.
7011 MockRead data_reads[] = {
7012 MockRead("HTTP/1.0 200 OK\r\n"),
7013 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7014 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067015 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427016 };
7017
[email protected]31a2bfe2010-02-09 08:03:397018 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7019 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077020 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427021
[email protected]49639fa2011-12-20 23:22:417022 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427023
[email protected]49639fa2011-12-20 23:22:417024 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427025 EXPECT_EQ(ERR_IO_PENDING, rv);
7026
7027 rv = callback.WaitForResult();
7028 EXPECT_EQ(OK, rv);
7029}
7030
[email protected]23e482282013-06-14 16:08:027031TEST_P(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:427032 HttpRequestInfo request;
7033 request.method = "GET";
7034 request.url = GURL("http://www.google.com/");
7035 request.load_flags = LOAD_BYPASS_CACHE;
7036
[email protected]3fe8d2f82013-10-17 08:56:077037 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277038 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417039 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277040
[email protected]1c773ea12009-04-28 19:58:427041 MockWrite data_writes[] = {
7042 MockWrite("GET / HTTP/1.1\r\n"
7043 "Host: www.google.com\r\n"
7044 "Connection: keep-alive\r\n"
7045 "Pragma: no-cache\r\n"
7046 "Cache-Control: no-cache\r\n\r\n"),
7047 };
7048
7049 // Lastly, the server responds with the actual content.
7050 MockRead data_reads[] = {
7051 MockRead("HTTP/1.0 200 OK\r\n"),
7052 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7053 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067054 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427055 };
7056
[email protected]31a2bfe2010-02-09 08:03:397057 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7058 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077059 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427060
[email protected]49639fa2011-12-20 23:22:417061 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427062
[email protected]49639fa2011-12-20 23:22:417063 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427064 EXPECT_EQ(ERR_IO_PENDING, rv);
7065
7066 rv = callback.WaitForResult();
7067 EXPECT_EQ(OK, rv);
7068}
7069
[email protected]23e482282013-06-14 16:08:027070TEST_P(HttpNetworkTransactionTest,
[email protected]1c773ea12009-04-28 19:58:427071 BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:427072 HttpRequestInfo request;
7073 request.method = "GET";
7074 request.url = GURL("http://www.google.com/");
7075 request.load_flags = LOAD_VALIDATE_CACHE;
7076
[email protected]3fe8d2f82013-10-17 08:56:077077 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277078 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417079 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277080
[email protected]1c773ea12009-04-28 19:58:427081 MockWrite data_writes[] = {
7082 MockWrite("GET / HTTP/1.1\r\n"
7083 "Host: www.google.com\r\n"
7084 "Connection: keep-alive\r\n"
7085 "Cache-Control: max-age=0\r\n\r\n"),
7086 };
7087
7088 // Lastly, the server responds with the actual content.
7089 MockRead data_reads[] = {
7090 MockRead("HTTP/1.0 200 OK\r\n"),
7091 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7092 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067093 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427094 };
7095
[email protected]31a2bfe2010-02-09 08:03:397096 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7097 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077098 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427099
[email protected]49639fa2011-12-20 23:22:417100 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427101
[email protected]49639fa2011-12-20 23:22:417102 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427103 EXPECT_EQ(ERR_IO_PENDING, rv);
7104
7105 rv = callback.WaitForResult();
7106 EXPECT_EQ(OK, rv);
7107}
7108
[email protected]23e482282013-06-14 16:08:027109TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:427110 HttpRequestInfo request;
7111 request.method = "GET";
7112 request.url = GURL("http://www.google.com/");
[email protected]8c76ae22010-04-20 22:15:437113 request.extra_headers.SetHeader("FooHeader", "Bar");
[email protected]1c773ea12009-04-28 19:58:427114
[email protected]3fe8d2f82013-10-17 08:56:077115 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277116 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417117 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277118
[email protected]1c773ea12009-04-28 19:58:427119 MockWrite data_writes[] = {
7120 MockWrite("GET / HTTP/1.1\r\n"
7121 "Host: www.google.com\r\n"
7122 "Connection: keep-alive\r\n"
7123 "FooHeader: Bar\r\n\r\n"),
7124 };
7125
7126 // Lastly, the server responds with the actual content.
7127 MockRead data_reads[] = {
7128 MockRead("HTTP/1.0 200 OK\r\n"),
7129 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7130 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067131 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427132 };
7133
[email protected]31a2bfe2010-02-09 08:03:397134 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7135 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077136 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427137
[email protected]49639fa2011-12-20 23:22:417138 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427139
[email protected]49639fa2011-12-20 23:22:417140 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427141 EXPECT_EQ(ERR_IO_PENDING, rv);
7142
7143 rv = callback.WaitForResult();
7144 EXPECT_EQ(OK, rv);
7145}
7146
[email protected]23e482282013-06-14 16:08:027147TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:477148 HttpRequestInfo request;
7149 request.method = "GET";
7150 request.url = GURL("http://www.google.com/");
[email protected]8c76ae22010-04-20 22:15:437151 request.extra_headers.SetHeader("referer", "www.foo.com");
7152 request.extra_headers.SetHeader("hEllo", "Kitty");
7153 request.extra_headers.SetHeader("FoO", "bar");
[email protected]270c6412010-03-29 22:02:477154
[email protected]3fe8d2f82013-10-17 08:56:077155 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277156 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417157 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277158
[email protected]270c6412010-03-29 22:02:477159 MockWrite data_writes[] = {
7160 MockWrite("GET / HTTP/1.1\r\n"
7161 "Host: www.google.com\r\n"
7162 "Connection: keep-alive\r\n"
[email protected]c10450102011-06-27 09:06:167163 "referer: www.foo.com\r\n"
[email protected]270c6412010-03-29 22:02:477164 "hEllo: Kitty\r\n"
7165 "FoO: bar\r\n\r\n"),
7166 };
7167
7168 // Lastly, the server responds with the actual content.
7169 MockRead data_reads[] = {
7170 MockRead("HTTP/1.0 200 OK\r\n"),
7171 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7172 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067173 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:477174 };
7175
7176 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7177 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077178 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:477179
[email protected]49639fa2011-12-20 23:22:417180 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:477181
[email protected]49639fa2011-12-20 23:22:417182 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]270c6412010-03-29 22:02:477183 EXPECT_EQ(ERR_IO_PENDING, rv);
7184
7185 rv = callback.WaitForResult();
7186 EXPECT_EQ(OK, rv);
7187}
7188
[email protected]23e482282013-06-14 16:08:027189TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277190 HttpRequestInfo request;
7191 request.method = "GET";
7192 request.url = GURL("http://www.google.com/");
7193 request.load_flags = 0;
7194
[email protected]bb88e1d32013-05-03 23:11:077195 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207196 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
7197 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077198 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:027199
[email protected]3fe8d2f82013-10-17 08:56:077200 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3cd17242009-06-23 02:59:027201 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417202 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3cd17242009-06-23 02:59:027203
[email protected]3cd17242009-06-23 02:59:027204 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
7205 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7206
7207 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:067208 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
[email protected]3cd17242009-06-23 02:59:027209 MockWrite("GET / HTTP/1.1\r\n"
7210 "Host: www.google.com\r\n"
7211 "Connection: keep-alive\r\n\r\n")
7212 };
7213
7214 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:067215 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:027216 MockRead("HTTP/1.0 200 OK\r\n"),
7217 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7218 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067219 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:027220 };
7221
[email protected]31a2bfe2010-02-09 08:03:397222 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7223 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077224 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:027225
[email protected]49639fa2011-12-20 23:22:417226 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:027227
[email protected]49639fa2011-12-20 23:22:417228 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:027229 EXPECT_EQ(ERR_IO_PENDING, rv);
7230
7231 rv = callback.WaitForResult();
7232 EXPECT_EQ(OK, rv);
7233
7234 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507235 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:027236
[email protected]029c83b62013-01-24 05:28:207237 LoadTimingInfo load_timing_info;
7238 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7239 TestLoadTimingNotReusedWithPac(load_timing_info,
7240 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7241
[email protected]3cd17242009-06-23 02:59:027242 std::string response_text;
7243 rv = ReadTransaction(trans.get(), &response_text);
7244 EXPECT_EQ(OK, rv);
7245 EXPECT_EQ("Payload", response_text);
7246}
7247
[email protected]23e482282013-06-14 16:08:027248TEST_P(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277249 HttpRequestInfo request;
7250 request.method = "GET";
7251 request.url = GURL("https://www.google.com/");
7252 request.load_flags = 0;
7253
[email protected]bb88e1d32013-05-03 23:11:077254 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207255 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
7256 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077257 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:027258
[email protected]3fe8d2f82013-10-17 08:56:077259 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3cd17242009-06-23 02:59:027260 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417261 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3cd17242009-06-23 02:59:027262
[email protected]3cd17242009-06-23 02:59:027263 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
7264 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7265
7266 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:067267 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
[email protected]e0c27be2009-07-15 13:09:357268 arraysize(write_buffer)),
[email protected]3cd17242009-06-23 02:59:027269 MockWrite("GET / HTTP/1.1\r\n"
7270 "Host: www.google.com\r\n"
7271 "Connection: keep-alive\r\n\r\n")
7272 };
7273
7274 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:017275 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
7276 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:357277 MockRead("HTTP/1.0 200 OK\r\n"),
7278 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7279 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067280 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:357281 };
7282
[email protected]31a2bfe2010-02-09 08:03:397283 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7284 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077285 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:357286
[email protected]8ddf8322012-02-23 18:08:067287 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077288 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:357289
[email protected]49639fa2011-12-20 23:22:417290 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:357291
[email protected]49639fa2011-12-20 23:22:417292 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:357293 EXPECT_EQ(ERR_IO_PENDING, rv);
7294
7295 rv = callback.WaitForResult();
7296 EXPECT_EQ(OK, rv);
7297
[email protected]029c83b62013-01-24 05:28:207298 LoadTimingInfo load_timing_info;
7299 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7300 TestLoadTimingNotReusedWithPac(load_timing_info,
7301 CONNECT_TIMING_HAS_SSL_TIMES);
7302
[email protected]e0c27be2009-07-15 13:09:357303 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507304 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:357305
7306 std::string response_text;
7307 rv = ReadTransaction(trans.get(), &response_text);
7308 EXPECT_EQ(OK, rv);
7309 EXPECT_EQ("Payload", response_text);
7310}
7311
[email protected]23e482282013-06-14 16:08:027312TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:207313 HttpRequestInfo request;
7314 request.method = "GET";
7315 request.url = GURL("http://www.google.com/");
7316 request.load_flags = 0;
7317
[email protected]bb88e1d32013-05-03 23:11:077318 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207319 ProxyService::CreateFixed("socks4://myproxy:1080"));
7320 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077321 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:207322
[email protected]3fe8d2f82013-10-17 08:56:077323 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:207324 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417325 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:207326
7327 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
7328 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7329
7330 MockWrite data_writes[] = {
7331 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
7332 MockWrite("GET / HTTP/1.1\r\n"
7333 "Host: www.google.com\r\n"
7334 "Connection: keep-alive\r\n\r\n")
7335 };
7336
7337 MockRead data_reads[] = {
7338 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
7339 MockRead("HTTP/1.0 200 OK\r\n"),
7340 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7341 MockRead("Payload"),
7342 MockRead(SYNCHRONOUS, OK)
7343 };
7344
7345 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7346 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077347 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:207348
7349 TestCompletionCallback callback;
7350
7351 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7352 EXPECT_EQ(ERR_IO_PENDING, rv);
7353
7354 rv = callback.WaitForResult();
7355 EXPECT_EQ(OK, rv);
7356
7357 const HttpResponseInfo* response = trans->GetResponseInfo();
7358 ASSERT_TRUE(response != NULL);
7359
7360 LoadTimingInfo load_timing_info;
7361 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7362 TestLoadTimingNotReused(load_timing_info,
7363 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7364
7365 std::string response_text;
7366 rv = ReadTransaction(trans.get(), &response_text);
7367 EXPECT_EQ(OK, rv);
7368 EXPECT_EQ("Payload", response_text);
7369}
7370
[email protected]23e482282013-06-14 16:08:027371TEST_P(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277372 HttpRequestInfo request;
7373 request.method = "GET";
7374 request.url = GURL("http://www.google.com/");
7375 request.load_flags = 0;
7376
[email protected]bb88e1d32013-05-03 23:11:077377 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207378 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
7379 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077380 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:357381
[email protected]3fe8d2f82013-10-17 08:56:077382 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e0c27be2009-07-15 13:09:357383 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417384 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]e0c27be2009-07-15 13:09:357385
[email protected]e0c27be2009-07-15 13:09:357386 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
7387 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:377388 const char kSOCKS5OkRequest[] = {
7389 0x05, // Version
7390 0x01, // Command (CONNECT)
7391 0x00, // Reserved.
7392 0x03, // Address type (DOMAINNAME).
7393 0x0E, // Length of domain (14)
7394 // Domain string:
7395 'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
7396 0x00, 0x50, // 16-bit port (80)
7397 };
[email protected]e0c27be2009-07-15 13:09:357398 const char kSOCKS5OkResponse[] =
7399 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
7400
7401 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:067402 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
7403 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
[email protected]e0c27be2009-07-15 13:09:357404 MockWrite("GET / HTTP/1.1\r\n"
7405 "Host: www.google.com\r\n"
7406 "Connection: keep-alive\r\n\r\n")
7407 };
7408
7409 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:017410 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
7411 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:357412 MockRead("HTTP/1.0 200 OK\r\n"),
7413 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7414 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067415 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:357416 };
7417
[email protected]31a2bfe2010-02-09 08:03:397418 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7419 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077420 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:357421
[email protected]49639fa2011-12-20 23:22:417422 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:357423
[email protected]49639fa2011-12-20 23:22:417424 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:357425 EXPECT_EQ(ERR_IO_PENDING, rv);
7426
7427 rv = callback.WaitForResult();
7428 EXPECT_EQ(OK, rv);
7429
7430 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507431 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:357432
[email protected]029c83b62013-01-24 05:28:207433 LoadTimingInfo load_timing_info;
7434 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7435 TestLoadTimingNotReusedWithPac(load_timing_info,
7436 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7437
[email protected]e0c27be2009-07-15 13:09:357438 std::string response_text;
7439 rv = ReadTransaction(trans.get(), &response_text);
7440 EXPECT_EQ(OK, rv);
7441 EXPECT_EQ("Payload", response_text);
7442}
7443
[email protected]23e482282013-06-14 16:08:027444TEST_P(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277445 HttpRequestInfo request;
7446 request.method = "GET";
7447 request.url = GURL("https://www.google.com/");
7448 request.load_flags = 0;
7449
[email protected]bb88e1d32013-05-03 23:11:077450 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207451 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
7452 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077453 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:357454
[email protected]3fe8d2f82013-10-17 08:56:077455 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e0c27be2009-07-15 13:09:357456 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417457 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]e0c27be2009-07-15 13:09:357458
[email protected]e0c27be2009-07-15 13:09:357459 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
7460 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:377461 const unsigned char kSOCKS5OkRequest[] = {
7462 0x05, // Version
7463 0x01, // Command (CONNECT)
7464 0x00, // Reserved.
7465 0x03, // Address type (DOMAINNAME).
7466 0x0E, // Length of domain (14)
7467 // Domain string:
7468 'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
7469 0x01, 0xBB, // 16-bit port (443)
7470 };
7471
[email protected]e0c27be2009-07-15 13:09:357472 const char kSOCKS5OkResponse[] =
7473 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
7474
7475 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:067476 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
7477 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
[email protected]e0c27be2009-07-15 13:09:357478 arraysize(kSOCKS5OkRequest)),
7479 MockWrite("GET / HTTP/1.1\r\n"
7480 "Host: www.google.com\r\n"
7481 "Connection: keep-alive\r\n\r\n")
7482 };
7483
7484 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:017485 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
7486 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:027487 MockRead("HTTP/1.0 200 OK\r\n"),
7488 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7489 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067490 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:027491 };
7492
[email protected]31a2bfe2010-02-09 08:03:397493 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7494 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077495 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:027496
[email protected]8ddf8322012-02-23 18:08:067497 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077498 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:027499
[email protected]49639fa2011-12-20 23:22:417500 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:027501
[email protected]49639fa2011-12-20 23:22:417502 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:027503 EXPECT_EQ(ERR_IO_PENDING, rv);
7504
7505 rv = callback.WaitForResult();
7506 EXPECT_EQ(OK, rv);
7507
7508 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507509 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:027510
[email protected]029c83b62013-01-24 05:28:207511 LoadTimingInfo load_timing_info;
7512 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7513 TestLoadTimingNotReusedWithPac(load_timing_info,
7514 CONNECT_TIMING_HAS_SSL_TIMES);
7515
[email protected]3cd17242009-06-23 02:59:027516 std::string response_text;
7517 rv = ReadTransaction(trans.get(), &response_text);
7518 EXPECT_EQ(OK, rv);
7519 EXPECT_EQ("Payload", response_text);
7520}
7521
[email protected]448d4ca52012-03-04 04:12:237522namespace {
7523
[email protected]04e5be32009-06-26 20:00:317524// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:067525
7526struct GroupNameTest {
7527 std::string proxy_server;
7528 std::string url;
7529 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:187530 bool ssl;
[email protected]2d731a32010-04-29 01:04:067531};
7532
7533scoped_refptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]8a0fc822013-06-27 20:52:437534 NextProto next_proto,
[email protected]bb88e1d32013-05-03 23:11:077535 SpdySessionDependencies* session_deps_) {
7536 scoped_refptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:067537
[email protected]30d4c022013-07-18 22:58:167538 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:537539 session->http_server_properties();
7540 http_server_properties->SetAlternateProtocol(
[email protected]2d731a32010-04-29 01:04:067541 HostPortPair("host.with.alternate", 80), 443,
[email protected]287d9412014-07-08 23:01:007542 AlternateProtocolFromNextProto(next_proto), 1);
[email protected]2d731a32010-04-29 01:04:067543
7544 return session;
7545}
7546
7547int GroupNameTransactionHelper(
7548 const std::string& url,
7549 const scoped_refptr<HttpNetworkSession>& session) {
[email protected]2d731a32010-04-29 01:04:067550 HttpRequestInfo request;
7551 request.method = "GET";
7552 request.url = GURL(url);
7553 request.load_flags = 0;
7554
[email protected]262eec82013-03-19 21:01:367555 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507556 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277557
[email protected]49639fa2011-12-20 23:22:417558 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:067559
7560 // We do not complete this request, the dtor will clean the transaction up.
[email protected]49639fa2011-12-20 23:22:417561 return trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d731a32010-04-29 01:04:067562}
7563
[email protected]448d4ca52012-03-04 04:12:237564} // namespace
7565
[email protected]23e482282013-06-14 16:08:027566TEST_P(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:067567 const GroupNameTest tests[] = {
[email protected]04e5be32009-06-26 20:00:317568 {
[email protected]2d731a32010-04-29 01:04:067569 "", // unused
[email protected]04e5be32009-06-26 20:00:317570 "http://www.google.com/direct",
[email protected]2ff8b312010-04-26 22:20:547571 "www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:187572 false,
[email protected]2ff8b312010-04-26 22:20:547573 },
7574 {
[email protected]2d731a32010-04-29 01:04:067575 "", // unused
[email protected]2ff8b312010-04-26 22:20:547576 "http://[2001:1418:13:1::25]/direct",
7577 "[2001:1418:13:1::25]:80",
[email protected]e60e47a2010-07-14 03:37:187578 false,
[email protected]04e5be32009-06-26 20:00:317579 },
[email protected]04e5be32009-06-26 20:00:317580
7581 // SSL Tests
7582 {
[email protected]2d731a32010-04-29 01:04:067583 "", // unused
[email protected]04e5be32009-06-26 20:00:317584 "https://www.google.com/direct_ssl",
[email protected]0e88ad602010-05-04 23:47:027585 "ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:187586 true,
[email protected]04e5be32009-06-26 20:00:317587 },
7588 {
[email protected]2d731a32010-04-29 01:04:067589 "", // unused
7590 "https://[2001:1418:13:1::25]/direct",
[email protected]0e88ad602010-05-04 23:47:027591 "ssl/[2001:1418:13:1::25]:443",
[email protected]e60e47a2010-07-14 03:37:187592 true,
[email protected]04e5be32009-06-26 20:00:317593 },
7594 {
[email protected]2d731a32010-04-29 01:04:067595 "", // unused
[email protected]2ff8b312010-04-26 22:20:547596 "http://host.with.alternate/direct",
[email protected]0e88ad602010-05-04 23:47:027597 "ssl/host.with.alternate:443",
[email protected]e60e47a2010-07-14 03:37:187598 true,
[email protected]2ff8b312010-04-26 22:20:547599 },
[email protected]2d731a32010-04-29 01:04:067600 };
[email protected]2ff8b312010-04-26 22:20:547601
[email protected]d7599122014-05-24 03:37:237602 session_deps_.use_alternate_protocols = true;
[email protected]2d731a32010-04-29 01:04:067603
viettrungluue4a8b882014-10-16 06:17:387604 for (size_t i = 0; i < arraysize(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:077605 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:027606 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:067607 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:437608 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:067609
7610 HttpNetworkSessionPeer peer(session);
[email protected]ab739042011-04-07 15:22:287611 CaptureGroupNameTransportSocketPool* transport_conn_pool =
7612 new CaptureGroupNameTransportSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:137613 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347614 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]831e4a32013-11-14 02:14:447615 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
7616 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:027617 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
7618 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
dchenge3d1ddc2014-10-15 19:30:517619 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]2d731a32010-04-29 01:04:067620
7621 EXPECT_EQ(ERR_IO_PENDING,
7622 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:187623 if (tests[i].ssl)
7624 EXPECT_EQ(tests[i].expected_group_name,
7625 ssl_conn_pool->last_group_name_received());
7626 else
7627 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:287628 transport_conn_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:067629 }
7630
[email protected]2d731a32010-04-29 01:04:067631}
7632
[email protected]23e482282013-06-14 16:08:027633TEST_P(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:067634 const GroupNameTest tests[] = {
7635 {
7636 "http_proxy",
7637 "http://www.google.com/http_proxy_normal",
7638 "www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:187639 false,
[email protected]2d731a32010-04-29 01:04:067640 },
7641
7642 // SSL Tests
7643 {
7644 "http_proxy",
7645 "https://www.google.com/http_connect_ssl",
[email protected]0e88ad602010-05-04 23:47:027646 "ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:187647 true,
[email protected]2d731a32010-04-29 01:04:067648 },
[email protected]af3490e2010-10-16 21:02:297649
[email protected]9faeded92010-04-29 20:03:057650 {
7651 "http_proxy",
7652 "http://host.with.alternate/direct",
[email protected]0e88ad602010-05-04 23:47:027653 "ssl/host.with.alternate:443",
[email protected]e60e47a2010-07-14 03:37:187654 true,
[email protected]9faeded92010-04-29 20:03:057655 },
[email protected]45499252013-01-23 17:12:567656
7657 {
7658 "http_proxy",
7659 "ftp://ftp.google.com/http_proxy_normal",
7660 "ftp/ftp.google.com:21",
7661 false,
7662 },
[email protected]2d731a32010-04-29 01:04:067663 };
7664
[email protected]d7599122014-05-24 03:37:237665 session_deps_.use_alternate_protocols = true;
[email protected]2d731a32010-04-29 01:04:067666
viettrungluue4a8b882014-10-16 06:17:387667 for (size_t i = 0; i < arraysize(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:077668 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:027669 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:067670 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:437671 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:067672
7673 HttpNetworkSessionPeer peer(session);
7674
[email protected]e60e47a2010-07-14 03:37:187675 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:137676 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:347677 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:137678 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347679 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:027680
[email protected]831e4a32013-11-14 02:14:447681 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
7682 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:027683 mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool);
7684 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
dchenge3d1ddc2014-10-15 19:30:517685 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]2d731a32010-04-29 01:04:067686
7687 EXPECT_EQ(ERR_IO_PENDING,
7688 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:187689 if (tests[i].ssl)
7690 EXPECT_EQ(tests[i].expected_group_name,
7691 ssl_conn_pool->last_group_name_received());
7692 else
7693 EXPECT_EQ(tests[i].expected_group_name,
7694 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:067695 }
[email protected]2d731a32010-04-29 01:04:067696}
7697
[email protected]23e482282013-06-14 16:08:027698TEST_P(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:067699 const GroupNameTest tests[] = {
7700 {
7701 "socks4://socks_proxy:1080",
7702 "http://www.google.com/socks4_direct",
7703 "socks4/www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:187704 false,
[email protected]2d731a32010-04-29 01:04:067705 },
7706 {
7707 "socks5://socks_proxy:1080",
7708 "http://www.google.com/socks5_direct",
7709 "socks5/www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:187710 false,
[email protected]2d731a32010-04-29 01:04:067711 },
7712
7713 // SSL Tests
7714 {
7715 "socks4://socks_proxy:1080",
7716 "https://www.google.com/socks4_ssl",
[email protected]0e88ad602010-05-04 23:47:027717 "socks4/ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:187718 true,
[email protected]2d731a32010-04-29 01:04:067719 },
7720 {
7721 "socks5://socks_proxy:1080",
7722 "https://www.google.com/socks5_ssl",
[email protected]0e88ad602010-05-04 23:47:027723 "socks5/ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:187724 true,
[email protected]2d731a32010-04-29 01:04:067725 },
[email protected]af3490e2010-10-16 21:02:297726
[email protected]9faeded92010-04-29 20:03:057727 {
7728 "socks4://socks_proxy:1080",
7729 "http://host.with.alternate/direct",
[email protected]0e88ad602010-05-04 23:47:027730 "socks4/ssl/host.with.alternate:443",
[email protected]e60e47a2010-07-14 03:37:187731 true,
[email protected]9faeded92010-04-29 20:03:057732 },
[email protected]04e5be32009-06-26 20:00:317733 };
7734
[email protected]d7599122014-05-24 03:37:237735 session_deps_.use_alternate_protocols = true;
[email protected]2ff8b312010-04-26 22:20:547736
viettrungluue4a8b882014-10-16 06:17:387737 for (size_t i = 0; i < arraysize(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:077738 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:027739 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:067740 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:437741 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]8b114dd72011-03-25 05:33:027742
[email protected]2d731a32010-04-29 01:04:067743 HttpNetworkSessionPeer peer(session);
[email protected]04e5be32009-06-26 20:00:317744
[email protected]e60e47a2010-07-14 03:37:187745 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:137746 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347747 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:137748 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347749 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:027750
[email protected]831e4a32013-11-14 02:14:447751 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
7752 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:027753 mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_conn_pool);
7754 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
dchenge3d1ddc2014-10-15 19:30:517755 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]04e5be32009-06-26 20:00:317756
[email protected]262eec82013-03-19 21:01:367757 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507758 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]04e5be32009-06-26 20:00:317759
[email protected]2d731a32010-04-29 01:04:067760 EXPECT_EQ(ERR_IO_PENDING,
7761 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:187762 if (tests[i].ssl)
7763 EXPECT_EQ(tests[i].expected_group_name,
7764 ssl_conn_pool->last_group_name_received());
7765 else
7766 EXPECT_EQ(tests[i].expected_group_name,
7767 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:317768 }
7769}
7770
[email protected]23e482282013-06-14 16:08:027771TEST_P(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:277772 HttpRequestInfo request;
7773 request.method = "GET";
7774 request.url = GURL("http://www.google.com/");
7775
[email protected]bb88e1d32013-05-03 23:11:077776 session_deps_.proxy_service.reset(
[email protected]81cdfcd2010-10-16 00:49:007777 ProxyService::CreateFixed("myproxy:70;foobar:80"));
[email protected]b59ff372009-07-15 22:04:327778
[email protected]69719062010-01-05 20:09:217779 // This simulates failure resolving all hostnames; that means we will fail
7780 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:077781 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:327782
[email protected]3fe8d2f82013-10-17 08:56:077783 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]9172a982009-06-06 00:30:257784 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417785 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]9172a982009-06-06 00:30:257786
[email protected]49639fa2011-12-20 23:22:417787 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:257788
[email protected]49639fa2011-12-20 23:22:417789 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9172a982009-06-06 00:30:257790 EXPECT_EQ(ERR_IO_PENDING, rv);
7791
[email protected]9172a982009-06-06 00:30:257792 rv = callback.WaitForResult();
[email protected]f7fccee2010-09-16 20:53:017793 EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
[email protected]9172a982009-06-06 00:30:257794}
7795
[email protected]685af592010-05-11 19:31:247796// Base test to make sure that when the load flags for a request specify to
7797// bypass the cache, the DNS cache is not used.
[email protected]23e482282013-06-14 16:08:027798void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
[email protected]bb88e1d32013-05-03 23:11:077799 int load_flags) {
[email protected]cb9bf6ca2011-01-28 13:15:277800 // Issue a request, asking to bypass the cache(s).
7801 HttpRequestInfo request;
7802 request.method = "GET";
7803 request.load_flags = load_flags;
7804 request.url = GURL("http://www.google.com/");
7805
[email protected]a2c2fb92009-07-18 07:31:047806 // Select a host resolver that does caching.
[email protected]bb88e1d32013-05-03 23:11:077807 session_deps_.host_resolver.reset(new MockCachingHostResolver);
[email protected]b59ff372009-07-15 22:04:327808
[email protected]3fe8d2f82013-10-17 08:56:077809 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7810 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417811 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3b9cca42009-06-16 01:08:287812
[email protected]6e78dfb2011-07-28 21:34:477813 // Warm up the host cache so it has an entry for "www.google.com".
[email protected]3b9cca42009-06-16 01:08:287814 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:297815 TestCompletionCallback callback;
[email protected]bb88e1d32013-05-03 23:11:077816 int rv = session_deps_.host_resolver->Resolve(
[email protected]5109c1952013-08-20 18:44:107817 HostResolver::RequestInfo(HostPortPair("www.google.com", 80)),
7818 DEFAULT_PRIORITY,
[email protected]b9823c02013-08-16 21:24:417819 &addrlist,
7820 callback.callback(),
7821 NULL,
7822 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:477823 EXPECT_EQ(ERR_IO_PENDING, rv);
7824 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:287825 EXPECT_EQ(OK, rv);
7826
7827 // Verify that it was added to host cache, by doing a subsequent async lookup
7828 // and confirming it completes synchronously.
[email protected]bb88e1d32013-05-03 23:11:077829 rv = session_deps_.host_resolver->Resolve(
[email protected]5109c1952013-08-20 18:44:107830 HostResolver::RequestInfo(HostPortPair("www.google.com", 80)),
7831 DEFAULT_PRIORITY,
[email protected]b9823c02013-08-16 21:24:417832 &addrlist,
7833 callback.callback(),
7834 NULL,
7835 BoundNetLog());
[email protected]b59ff372009-07-15 22:04:327836 ASSERT_EQ(OK, rv);
[email protected]3b9cca42009-06-16 01:08:287837
7838 // Inject a failure the next time that "www.google.com" is resolved. This way
7839 // we can tell if the next lookup hit the cache, or the "network".
7840 // (cache --> success, "network" --> failure).
[email protected]bb88e1d32013-05-03 23:11:077841 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.google.com");
[email protected]3b9cca42009-06-16 01:08:287842
7843 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
7844 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:067845 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
[email protected]31a2bfe2010-02-09 08:03:397846 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077847 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:287848
[email protected]3b9cca42009-06-16 01:08:287849 // Run the request.
[email protected]49639fa2011-12-20 23:22:417850 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3b9cca42009-06-16 01:08:287851 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:417852 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:287853
7854 // If we bypassed the cache, we would have gotten a failure while resolving
7855 // "www.google.com".
7856 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
7857}
7858
[email protected]685af592010-05-11 19:31:247859// There are multiple load flags that should trigger the host cache bypass.
7860// Test each in isolation:
[email protected]23e482282013-06-14 16:08:027861TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
[email protected]685af592010-05-11 19:31:247862 BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
7863}
7864
[email protected]23e482282013-06-14 16:08:027865TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
[email protected]685af592010-05-11 19:31:247866 BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
7867}
7868
[email protected]23e482282013-06-14 16:08:027869TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
[email protected]685af592010-05-11 19:31:247870 BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
7871}
7872
[email protected]0877e3d2009-10-17 22:29:577873// Make sure we can handle an error when writing the request.
[email protected]23e482282013-06-14 16:08:027874TEST_P(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:577875 HttpRequestInfo request;
7876 request.method = "GET";
7877 request.url = GURL("http://www.foo.com/");
7878 request.load_flags = 0;
7879
7880 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:067881 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:577882 };
[email protected]31a2bfe2010-02-09 08:03:397883 StaticSocketDataProvider data(NULL, 0,
7884 write_failure, arraysize(write_failure));
[email protected]bb88e1d32013-05-03 23:11:077885 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3fe8d2f82013-10-17 08:56:077886 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:577887
[email protected]49639fa2011-12-20 23:22:417888 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:577889
7890 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417891 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:577892
[email protected]49639fa2011-12-20 23:22:417893 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:577894 EXPECT_EQ(ERR_IO_PENDING, rv);
7895
7896 rv = callback.WaitForResult();
7897 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
7898}
7899
7900// Check that a connection closed after the start of the headers finishes ok.
[email protected]23e482282013-06-14 16:08:027901TEST_P(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:577902 HttpRequestInfo request;
7903 request.method = "GET";
7904 request.url = GURL("http://www.foo.com/");
7905 request.load_flags = 0;
7906
7907 MockRead data_reads[] = {
7908 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:067909 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:577910 };
7911
[email protected]31a2bfe2010-02-09 08:03:397912 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077913 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3fe8d2f82013-10-17 08:56:077914 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:577915
[email protected]49639fa2011-12-20 23:22:417916 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:577917
7918 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417919 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:577920
[email protected]49639fa2011-12-20 23:22:417921 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:577922 EXPECT_EQ(ERR_IO_PENDING, rv);
7923
7924 rv = callback.WaitForResult();
7925 EXPECT_EQ(OK, rv);
7926
7927 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507928 ASSERT_TRUE(response != NULL);
[email protected]0877e3d2009-10-17 22:29:577929
[email protected]90499482013-06-01 00:39:507930 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]0877e3d2009-10-17 22:29:577931 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
7932
7933 std::string response_data;
7934 rv = ReadTransaction(trans.get(), &response_data);
7935 EXPECT_EQ(OK, rv);
7936 EXPECT_EQ("", response_data);
7937}
7938
7939// Make sure that a dropped connection while draining the body for auth
7940// restart does the right thing.
[email protected]23e482282013-06-14 16:08:027941TEST_P(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:577942 HttpRequestInfo request;
7943 request.method = "GET";
7944 request.url = GURL("http://www.google.com/");
7945 request.load_flags = 0;
7946
7947 MockWrite data_writes1[] = {
7948 MockWrite("GET / HTTP/1.1\r\n"
7949 "Host: www.google.com\r\n"
7950 "Connection: keep-alive\r\n\r\n"),
7951 };
7952
7953 MockRead data_reads1[] = {
7954 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
7955 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7956 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7957 MockRead("Content-Length: 14\r\n\r\n"),
7958 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:067959 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:577960 };
7961
[email protected]31a2bfe2010-02-09 08:03:397962 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7963 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:077964 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:577965
7966 // After calling trans->RestartWithAuth(), this is the request we should
7967 // be issuing -- the final header line contains the credentials.
7968 MockWrite data_writes2[] = {
7969 MockWrite("GET / HTTP/1.1\r\n"
7970 "Host: www.google.com\r\n"
7971 "Connection: keep-alive\r\n"
7972 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
7973 };
7974
7975 // Lastly, the server responds with the actual content.
7976 MockRead data_reads2[] = {
7977 MockRead("HTTP/1.1 200 OK\r\n"),
7978 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7979 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067980 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:577981 };
7982
[email protected]31a2bfe2010-02-09 08:03:397983 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7984 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077985 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3fe8d2f82013-10-17 08:56:077986 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:577987
[email protected]49639fa2011-12-20 23:22:417988 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:577989
[email protected]262eec82013-03-19 21:01:367990 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507991 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:507992
[email protected]49639fa2011-12-20 23:22:417993 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:577994 EXPECT_EQ(ERR_IO_PENDING, rv);
7995
7996 rv = callback1.WaitForResult();
7997 EXPECT_EQ(OK, rv);
7998
7999 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508000 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048001 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:578002
[email protected]49639fa2011-12-20 23:22:418003 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:578004
[email protected]49639fa2011-12-20 23:22:418005 rv = trans->RestartWithAuth(
8006 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]0877e3d2009-10-17 22:29:578007 EXPECT_EQ(ERR_IO_PENDING, rv);
8008
8009 rv = callback2.WaitForResult();
8010 EXPECT_EQ(OK, rv);
8011
8012 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508013 ASSERT_TRUE(response != NULL);
[email protected]0877e3d2009-10-17 22:29:578014 EXPECT_TRUE(response->auth_challenge.get() == NULL);
8015 EXPECT_EQ(100, response->headers->GetContentLength());
8016}
8017
8018// Test HTTPS connections going through a proxy that sends extra data.
[email protected]23e482282013-06-14 16:08:028019TEST_P(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
[email protected]bb88e1d32013-05-03 23:11:078020 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]0877e3d2009-10-17 22:29:578021
8022 HttpRequestInfo request;
8023 request.method = "GET";
8024 request.url = GURL("https://www.google.com/");
8025 request.load_flags = 0;
8026
8027 MockRead proxy_reads[] = {
8028 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:068029 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:578030 };
8031
[email protected]31a2bfe2010-02-09 08:03:398032 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
[email protected]8ddf8322012-02-23 18:08:068033 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:578034
[email protected]bb88e1d32013-05-03 23:11:078035 session_deps_.socket_factory->AddSocketDataProvider(&data);
8036 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:578037
[email protected]49639fa2011-12-20 23:22:418038 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:578039
[email protected]bb88e1d32013-05-03 23:11:078040 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:578041
[email protected]3fe8d2f82013-10-17 08:56:078042 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578043 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418044 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:578045
[email protected]49639fa2011-12-20 23:22:418046 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578047 EXPECT_EQ(ERR_IO_PENDING, rv);
8048
8049 rv = callback.WaitForResult();
8050 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
8051}
8052
[email protected]23e482282013-06-14 16:08:028053TEST_P(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:468054 HttpRequestInfo request;
8055 request.method = "GET";
8056 request.url = GURL("http://www.google.com/");
8057 request.load_flags = 0;
8058
[email protected]3fe8d2f82013-10-17 08:56:078059 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:278060 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418061 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278062
[email protected]e22e1362009-11-23 21:31:128063 MockRead data_reads[] = {
8064 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068065 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:128066 };
[email protected]9492e4a2010-02-24 00:58:468067
8068 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078069 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:468070
[email protected]49639fa2011-12-20 23:22:418071 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:468072
[email protected]49639fa2011-12-20 23:22:418073 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9492e4a2010-02-24 00:58:468074 EXPECT_EQ(ERR_IO_PENDING, rv);
8075
8076 EXPECT_EQ(OK, callback.WaitForResult());
8077
8078 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508079 ASSERT_TRUE(response != NULL);
[email protected]9492e4a2010-02-24 00:58:468080
[email protected]90499482013-06-01 00:39:508081 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]9492e4a2010-02-24 00:58:468082 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
8083
8084 std::string response_data;
8085 rv = ReadTransaction(trans.get(), &response_data);
[email protected]5543cbb2012-04-20 16:35:238086 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
[email protected]e22e1362009-11-23 21:31:128087}
8088
[email protected]23e482282013-06-14 16:08:028089TEST_P(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:158090 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:528091 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
[email protected]95d88ffe2010-02-04 21:25:338092 const uint64 kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:218093 UploadFileElementReader::ScopedOverridingContentLengthForTests
8094 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:338095
[email protected]b2d26cfd2012-12-11 10:36:068096 ScopedVector<UploadElementReader> element_readers;
8097 element_readers.push_back(
[email protected]cadac622013-06-11 16:46:368098 new UploadFileElementReader(base::MessageLoopProxy::current().get(),
8099 temp_file_path,
8100 0,
8101 kuint64max,
8102 base::Time()));
mmenkecbc2b712014-10-09 20:29:078103 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:278104
8105 HttpRequestInfo request;
8106 request.method = "POST";
8107 request.url = GURL("http://www.google.com/upload");
8108 request.upload_data_stream = &upload_data_stream;
8109 request.load_flags = 0;
8110
[email protected]3fe8d2f82013-10-17 08:56:078111 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]329b68b2012-11-14 17:54:278112 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418113 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]95d88ffe2010-02-04 21:25:338114
8115 MockRead data_reads[] = {
8116 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
8117 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068118 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:338119 };
[email protected]31a2bfe2010-02-09 08:03:398120 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078121 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:338122
[email protected]49639fa2011-12-20 23:22:418123 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:338124
[email protected]49639fa2011-12-20 23:22:418125 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]95d88ffe2010-02-04 21:25:338126 EXPECT_EQ(ERR_IO_PENDING, rv);
8127
8128 rv = callback.WaitForResult();
8129 EXPECT_EQ(OK, rv);
8130
8131 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508132 ASSERT_TRUE(response != NULL);
[email protected]95d88ffe2010-02-04 21:25:338133
[email protected]90499482013-06-01 00:39:508134 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]95d88ffe2010-02-04 21:25:338135 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
8136
8137 std::string response_data;
8138 rv = ReadTransaction(trans.get(), &response_data);
8139 EXPECT_EQ(OK, rv);
8140 EXPECT_EQ("hello world", response_data);
8141
[email protected]dd3aa792013-07-16 19:10:238142 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:338143}
8144
[email protected]23e482282013-06-14 16:08:028145TEST_P(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:158146 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:528147 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:368148 std::string temp_file_content("Unreadable file.");
[email protected]e5c2a22e2014-03-06 20:42:308149 ASSERT_TRUE(base::WriteFile(temp_file, temp_file_content.c_str(),
[email protected]6624b4622010-03-29 19:58:368150 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:118151 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:368152
[email protected]b2d26cfd2012-12-11 10:36:068153 ScopedVector<UploadElementReader> element_readers;
8154 element_readers.push_back(
[email protected]cadac622013-06-11 16:46:368155 new UploadFileElementReader(base::MessageLoopProxy::current().get(),
8156 temp_file,
8157 0,
8158 kuint64max,
8159 base::Time()));
mmenkecbc2b712014-10-09 20:29:078160 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:278161
8162 HttpRequestInfo request;
8163 request.method = "POST";
8164 request.url = GURL("http://www.google.com/upload");
8165 request.upload_data_stream = &upload_data_stream;
8166 request.load_flags = 0;
8167
[email protected]999dd8c2013-11-12 06:45:548168 // If we try to upload an unreadable file, the transaction should fail.
[email protected]3fe8d2f82013-10-17 08:56:078169 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]329b68b2012-11-14 17:54:278170 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418171 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]6624b4622010-03-29 19:58:368172
[email protected]999dd8c2013-11-12 06:45:548173 StaticSocketDataProvider data(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078174 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:368175
[email protected]49639fa2011-12-20 23:22:418176 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:368177
[email protected]49639fa2011-12-20 23:22:418178 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]6624b4622010-03-29 19:58:368179 EXPECT_EQ(ERR_IO_PENDING, rv);
8180
8181 rv = callback.WaitForResult();
[email protected]999dd8c2013-11-12 06:45:548182 EXPECT_EQ(ERR_ACCESS_DENIED, rv);
[email protected]6624b4622010-03-29 19:58:368183
8184 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]999dd8c2013-11-12 06:45:548185 EXPECT_FALSE(response);
[email protected]6624b4622010-03-29 19:58:368186
[email protected]dd3aa792013-07-16 19:10:238187 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:368188}
8189
[email protected]02cad5d2013-10-02 08:14:038190TEST_P(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
8191 class FakeUploadElementReader : public UploadElementReader {
8192 public:
8193 FakeUploadElementReader() {}
dchengb03027d2014-10-21 12:00:208194 ~FakeUploadElementReader() override {}
[email protected]02cad5d2013-10-02 08:14:038195
8196 const CompletionCallback& callback() const { return callback_; }
8197
8198 // UploadElementReader overrides:
dchengb03027d2014-10-21 12:00:208199 int Init(const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:038200 callback_ = callback;
8201 return ERR_IO_PENDING;
8202 }
dchengb03027d2014-10-21 12:00:208203 uint64 GetContentLength() const override { return 0; }
8204 uint64 BytesRemaining() const override { return 0; }
8205 int Read(IOBuffer* buf,
8206 int buf_length,
8207 const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:038208 return ERR_FAILED;
8209 }
8210
8211 private:
8212 CompletionCallback callback_;
8213 };
8214
8215 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
8216 ScopedVector<UploadElementReader> element_readers;
8217 element_readers.push_back(fake_reader);
mmenkecbc2b712014-10-09 20:29:078218 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02cad5d2013-10-02 08:14:038219
8220 HttpRequestInfo request;
8221 request.method = "POST";
8222 request.url = GURL("http://www.google.com/upload");
8223 request.upload_data_stream = &upload_data_stream;
8224 request.load_flags = 0;
8225
[email protected]3fe8d2f82013-10-17 08:56:078226 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02cad5d2013-10-02 08:14:038227 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418228 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02cad5d2013-10-02 08:14:038229
8230 StaticSocketDataProvider data;
8231 session_deps_.socket_factory->AddSocketDataProvider(&data);
8232
8233 TestCompletionCallback callback;
8234 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8235 EXPECT_EQ(ERR_IO_PENDING, rv);
8236 base::MessageLoop::current()->RunUntilIdle();
8237
8238 // Transaction is pending on request body initialization.
8239 ASSERT_FALSE(fake_reader->callback().is_null());
8240
8241 // Return Init()'s result after the transaction gets destroyed.
8242 trans.reset();
8243 fake_reader->callback().Run(OK); // Should not crash.
8244}
8245
[email protected]aeefc9e82010-02-19 16:18:278246// Tests that changes to Auth realms are treated like auth rejections.
[email protected]23e482282013-06-14 16:08:028247TEST_P(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:278248
8249 HttpRequestInfo request;
8250 request.method = "GET";
8251 request.url = GURL("http://www.google.com/");
8252 request.load_flags = 0;
8253
8254 // First transaction will request a resource and receive a Basic challenge
8255 // with realm="first_realm".
8256 MockWrite data_writes1[] = {
8257 MockWrite("GET / HTTP/1.1\r\n"
8258 "Host: www.google.com\r\n"
8259 "Connection: keep-alive\r\n"
8260 "\r\n"),
8261 };
8262 MockRead data_reads1[] = {
8263 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8264 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
8265 "\r\n"),
8266 };
8267
8268 // After calling trans->RestartWithAuth(), provide an Authentication header
8269 // for first_realm. The server will reject and provide a challenge with
8270 // second_realm.
8271 MockWrite data_writes2[] = {
8272 MockWrite("GET / HTTP/1.1\r\n"
8273 "Host: www.google.com\r\n"
8274 "Connection: keep-alive\r\n"
8275 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
8276 "\r\n"),
8277 };
8278 MockRead data_reads2[] = {
8279 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8280 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
8281 "\r\n"),
8282 };
8283
8284 // This again fails, and goes back to first_realm. Make sure that the
8285 // entry is removed from cache.
8286 MockWrite data_writes3[] = {
8287 MockWrite("GET / HTTP/1.1\r\n"
8288 "Host: www.google.com\r\n"
8289 "Connection: keep-alive\r\n"
8290 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
8291 "\r\n"),
8292 };
8293 MockRead data_reads3[] = {
8294 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8295 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
8296 "\r\n"),
8297 };
8298
8299 // Try one last time (with the correct password) and get the resource.
8300 MockWrite data_writes4[] = {
8301 MockWrite("GET / HTTP/1.1\r\n"
8302 "Host: www.google.com\r\n"
8303 "Connection: keep-alive\r\n"
8304 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
8305 "\r\n"),
8306 };
8307 MockRead data_reads4[] = {
8308 MockRead("HTTP/1.1 200 OK\r\n"
8309 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:508310 "Content-Length: 5\r\n"
8311 "\r\n"
8312 "hello"),
[email protected]aeefc9e82010-02-19 16:18:278313 };
8314
8315 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8316 data_writes1, arraysize(data_writes1));
8317 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8318 data_writes2, arraysize(data_writes2));
8319 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
8320 data_writes3, arraysize(data_writes3));
8321 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
8322 data_writes4, arraysize(data_writes4));
[email protected]bb88e1d32013-05-03 23:11:078323 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8324 session_deps_.socket_factory->AddSocketDataProvider(&data2);
8325 session_deps_.socket_factory->AddSocketDataProvider(&data3);
8326 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:278327
[email protected]49639fa2011-12-20 23:22:418328 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:278329
[email protected]3fe8d2f82013-10-17 08:56:078330 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0b0bf032010-09-21 18:08:508331 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418332 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:508333
[email protected]aeefc9e82010-02-19 16:18:278334 // Issue the first request with Authorize headers. There should be a
8335 // password prompt for first_realm waiting to be filled in after the
8336 // transaction completes.
[email protected]49639fa2011-12-20 23:22:418337 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]aeefc9e82010-02-19 16:18:278338 EXPECT_EQ(ERR_IO_PENDING, rv);
8339 rv = callback1.WaitForResult();
8340 EXPECT_EQ(OK, rv);
8341 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508342 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048343 const AuthChallengeInfo* challenge = response->auth_challenge.get();
8344 ASSERT_FALSE(challenge == NULL);
8345 EXPECT_FALSE(challenge->is_proxy);
8346 EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
8347 EXPECT_EQ("first_realm", challenge->realm);
8348 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278349
8350 // Issue the second request with an incorrect password. There should be a
8351 // password prompt for second_realm waiting to be filled in after the
8352 // transaction completes.
[email protected]49639fa2011-12-20 23:22:418353 TestCompletionCallback callback2;
8354 rv = trans->RestartWithAuth(
8355 AuthCredentials(kFirst, kBaz), callback2.callback());
[email protected]aeefc9e82010-02-19 16:18:278356 EXPECT_EQ(ERR_IO_PENDING, rv);
8357 rv = callback2.WaitForResult();
8358 EXPECT_EQ(OK, rv);
8359 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508360 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048361 challenge = response->auth_challenge.get();
8362 ASSERT_FALSE(challenge == NULL);
8363 EXPECT_FALSE(challenge->is_proxy);
8364 EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
8365 EXPECT_EQ("second_realm", challenge->realm);
8366 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278367
8368 // Issue the third request with another incorrect password. There should be
8369 // a password prompt for first_realm waiting to be filled in. If the password
8370 // prompt is not present, it indicates that the HttpAuthCacheEntry for
8371 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:418372 TestCompletionCallback callback3;
8373 rv = trans->RestartWithAuth(
8374 AuthCredentials(kSecond, kFou), callback3.callback());
[email protected]aeefc9e82010-02-19 16:18:278375 EXPECT_EQ(ERR_IO_PENDING, rv);
8376 rv = callback3.WaitForResult();
8377 EXPECT_EQ(OK, rv);
8378 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508379 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048380 challenge = response->auth_challenge.get();
8381 ASSERT_FALSE(challenge == NULL);
8382 EXPECT_FALSE(challenge->is_proxy);
8383 EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
8384 EXPECT_EQ("first_realm", challenge->realm);
8385 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278386
8387 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:418388 TestCompletionCallback callback4;
8389 rv = trans->RestartWithAuth(
8390 AuthCredentials(kFirst, kBar), callback4.callback());
[email protected]aeefc9e82010-02-19 16:18:278391 EXPECT_EQ(ERR_IO_PENDING, rv);
8392 rv = callback4.WaitForResult();
8393 EXPECT_EQ(OK, rv);
8394 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508395 ASSERT_TRUE(response != NULL);
[email protected]aeefc9e82010-02-19 16:18:278396 EXPECT_TRUE(response->auth_challenge.get() == NULL);
8397}
8398
[email protected]23e482282013-06-14 16:08:028399TEST_P(HttpNetworkTransactionTest, HonorAlternateProtocolHeader) {
[email protected]d7599122014-05-24 03:37:238400 session_deps_.next_protos = SpdyNextProtos();
8401 session_deps_.use_alternate_protocols = true;
[email protected]a2cb8122010-03-10 17:22:428402
[email protected]8a0fc822013-06-27 20:52:438403 std::string alternate_protocol_http_header =
8404 GetAlternateProtocolHttpHeader();
8405
[email protected]564b4912010-03-09 16:30:428406 MockRead data_reads[] = {
8407 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438408 MockRead(alternate_protocol_http_header.c_str()),
[email protected]564b4912010-03-09 16:30:428409 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068410 MockRead(SYNCHRONOUS, OK),
[email protected]564b4912010-03-09 16:30:428411 };
8412
8413 HttpRequestInfo request;
8414 request.method = "GET";
8415 request.url = GURL("http://www.google.com/");
8416 request.load_flags = 0;
8417
8418 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
8419
[email protected]bb88e1d32013-05-03 23:11:078420 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]564b4912010-03-09 16:30:428421
[email protected]49639fa2011-12-20 23:22:418422 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:428423
[email protected]bb88e1d32013-05-03 23:11:078424 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:368425 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508426 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]564b4912010-03-09 16:30:428427
[email protected]49639fa2011-12-20 23:22:418428 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:428429 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]9e743cd2010-03-16 07:03:538430
[email protected]2fbaecf22010-07-22 22:20:358431 HostPortPair http_host_port_pair("www.google.com", 80);
[email protected]9801e3702014-03-07 09:33:558432 HttpServerProperties& http_server_properties =
[email protected]17291a022011-10-10 07:32:538433 *session->http_server_properties();
[email protected]564b4912010-03-09 16:30:428434 EXPECT_FALSE(
[email protected]17291a022011-10-10 07:32:538435 http_server_properties.HasAlternateProtocol(http_host_port_pair));
[email protected]564b4912010-03-09 16:30:428436
8437 EXPECT_EQ(OK, callback.WaitForResult());
8438
8439 const HttpResponseInfo* response = trans->GetResponseInfo();
8440 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508441 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:428442 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:538443 EXPECT_FALSE(response->was_fetched_via_spdy);
8444 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]564b4912010-03-09 16:30:428445
8446 std::string response_data;
8447 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8448 EXPECT_EQ("hello world", response_data);
8449
[email protected]17291a022011-10-10 07:32:538450 ASSERT_TRUE(http_server_properties.HasAlternateProtocol(http_host_port_pair));
[email protected]287d9412014-07-08 23:01:008451 const AlternateProtocolInfo alternate =
[email protected]17291a022011-10-10 07:32:538452 http_server_properties.GetAlternateProtocol(http_host_port_pair);
[email protected]287d9412014-07-08 23:01:008453 AlternateProtocolInfo expected_alternate(
8454 443, AlternateProtocolFromNextProto(GetParam()), 1);
[email protected]564b4912010-03-09 16:30:428455 EXPECT_TRUE(expected_alternate.Equals(alternate));
8456}
8457
[email protected]23e482282013-06-14 16:08:028458TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238459 MarkBrokenAlternateProtocolAndFallback) {
[email protected]d7599122014-05-24 03:37:238460 session_deps_.use_alternate_protocols = true;
[email protected]564b4912010-03-09 16:30:428461
8462 HttpRequestInfo request;
8463 request.method = "GET";
8464 request.url = GURL("http://www.google.com/");
8465 request.load_flags = 0;
8466
[email protected]d973e99a2012-02-17 21:02:368467 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:428468 StaticSocketDataProvider first_data;
8469 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078470 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]564b4912010-03-09 16:30:428471
8472 MockRead data_reads[] = {
8473 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8474 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068475 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:428476 };
8477 StaticSocketDataProvider second_data(
8478 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078479 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:428480
[email protected]bb88e1d32013-05-03 23:11:078481 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:428482
[email protected]30d4c022013-07-18 22:58:168483 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538484 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118485 // Port must be < 1024, or the header will be ignored (since initial port was
8486 // port 80 (another restricted port).
[email protected]17291a022011-10-10 07:32:538487 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118488 HostPortPair::FromURL(request.url),
8489 666 /* port is ignored by MockConnect anyway */,
[email protected]287d9412014-07-08 23:01:008490 AlternateProtocolFromNextProto(GetParam()), 1);
[email protected]564b4912010-03-09 16:30:428491
[email protected]262eec82013-03-19 21:01:368492 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508493 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418494 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:428495
[email protected]49639fa2011-12-20 23:22:418496 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:428497 EXPECT_EQ(ERR_IO_PENDING, rv);
8498 EXPECT_EQ(OK, callback.WaitForResult());
8499
8500 const HttpResponseInfo* response = trans->GetResponseInfo();
8501 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508502 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:428503 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8504
8505 std::string response_data;
8506 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8507 EXPECT_EQ("hello world", response_data);
8508
[email protected]17291a022011-10-10 07:32:538509 ASSERT_TRUE(http_server_properties->HasAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118510 HostPortPair::FromURL(request.url)));
[email protected]287d9412014-07-08 23:01:008511 const AlternateProtocolInfo alternate =
[email protected]17291a022011-10-10 07:32:538512 http_server_properties->GetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118513 HostPortPair::FromURL(request.url));
[email protected]17291a022011-10-10 07:32:538514 EXPECT_EQ(ALTERNATE_PROTOCOL_BROKEN, alternate.protocol);
[email protected]564b4912010-03-09 16:30:428515}
8516
[email protected]23e482282013-06-14 16:08:028517TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238518 AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:118519 // Ensure that we're not allowed to redirect traffic via an alternate
8520 // protocol to an unrestricted (port >= 1024) when the original traffic was
8521 // on a restricted port (port < 1024). Ensure that we can redirect in all
8522 // other cases.
[email protected]d7599122014-05-24 03:37:238523 session_deps_.use_alternate_protocols = true;
[email protected]3912662a32011-10-04 00:51:118524
8525 HttpRequestInfo restricted_port_request;
8526 restricted_port_request.method = "GET";
8527 restricted_port_request.url = GURL("http://www.google.com:1023/");
8528 restricted_port_request.load_flags = 0;
8529
[email protected]d973e99a2012-02-17 21:02:368530 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118531 StaticSocketDataProvider first_data;
8532 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078533 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118534
8535 MockRead data_reads[] = {
8536 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8537 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068538 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118539 };
8540 StaticSocketDataProvider second_data(
8541 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078542 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118543
[email protected]bb88e1d32013-05-03 23:11:078544 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118545
[email protected]30d4c022013-07-18 22:58:168546 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538547 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118548 const int kUnrestrictedAlternatePort = 1024;
[email protected]17291a022011-10-10 07:32:538549 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118550 HostPortPair::FromURL(restricted_port_request.url),
8551 kUnrestrictedAlternatePort,
[email protected]287d9412014-07-08 23:01:008552 AlternateProtocolFromNextProto(GetParam()), 1);
[email protected]3912662a32011-10-04 00:51:118553
[email protected]262eec82013-03-19 21:01:368554 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508555 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418556 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118557
[email protected]49639fa2011-12-20 23:22:418558 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:368559 &restricted_port_request,
8560 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118561 EXPECT_EQ(ERR_IO_PENDING, rv);
8562 // Invalid change to unrestricted port should fail.
8563 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.WaitForResult());
[email protected]c54c6962013-02-01 04:53:198564}
[email protected]3912662a32011-10-04 00:51:118565
[email protected]23e482282013-06-14 16:08:028566TEST_P(HttpNetworkTransactionTest,
[email protected]c54c6962013-02-01 04:53:198567 AlternateProtocolPortRestrictedPermitted) {
8568 // Ensure that we're allowed to redirect traffic via an alternate
8569 // protocol to an unrestricted (port >= 1024) when the original traffic was
8570 // on a restricted port (port < 1024) if we set
8571 // enable_user_alternate_protocol_ports.
8572
[email protected]d7599122014-05-24 03:37:238573 session_deps_.use_alternate_protocols = true;
[email protected]bb88e1d32013-05-03 23:11:078574 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:198575
8576 HttpRequestInfo restricted_port_request;
8577 restricted_port_request.method = "GET";
8578 restricted_port_request.url = GURL("http://www.google.com:1023/");
8579 restricted_port_request.load_flags = 0;
8580
8581 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
8582 StaticSocketDataProvider first_data;
8583 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078584 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:198585
8586 MockRead data_reads[] = {
8587 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8588 MockRead("hello world"),
8589 MockRead(ASYNC, OK),
8590 };
8591 StaticSocketDataProvider second_data(
8592 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078593 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]c54c6962013-02-01 04:53:198594
[email protected]bb88e1d32013-05-03 23:11:078595 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:198596
[email protected]30d4c022013-07-18 22:58:168597 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]c54c6962013-02-01 04:53:198598 session->http_server_properties();
8599 const int kUnrestrictedAlternatePort = 1024;
8600 http_server_properties->SetAlternateProtocol(
8601 HostPortPair::FromURL(restricted_port_request.url),
8602 kUnrestrictedAlternatePort,
[email protected]287d9412014-07-08 23:01:008603 AlternateProtocolFromNextProto(GetParam()), 1);
[email protected]c54c6962013-02-01 04:53:198604
[email protected]262eec82013-03-19 21:01:368605 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508606 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]c54c6962013-02-01 04:53:198607 TestCompletionCallback callback;
8608
8609 EXPECT_EQ(ERR_IO_PENDING, trans->Start(
[email protected]262eec82013-03-19 21:01:368610 &restricted_port_request,
8611 callback.callback(), BoundNetLog()));
[email protected]c54c6962013-02-01 04:53:198612 // Change to unrestricted port should succeed.
8613 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:118614}
8615
[email protected]23e482282013-06-14 16:08:028616TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238617 AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:118618 // Ensure that we're not allowed to redirect traffic via an alternate
8619 // protocol to an unrestricted (port >= 1024) when the original traffic was
8620 // on a restricted port (port < 1024). Ensure that we can redirect in all
8621 // other cases.
[email protected]d7599122014-05-24 03:37:238622 session_deps_.use_alternate_protocols = true;
[email protected]3912662a32011-10-04 00:51:118623
8624 HttpRequestInfo restricted_port_request;
8625 restricted_port_request.method = "GET";
8626 restricted_port_request.url = GURL("http://www.google.com:1023/");
8627 restricted_port_request.load_flags = 0;
8628
[email protected]d973e99a2012-02-17 21:02:368629 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118630 StaticSocketDataProvider first_data;
8631 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078632 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118633
8634 MockRead data_reads[] = {
8635 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8636 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068637 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118638 };
8639 StaticSocketDataProvider second_data(
8640 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078641 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118642
[email protected]bb88e1d32013-05-03 23:11:078643 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118644
[email protected]30d4c022013-07-18 22:58:168645 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538646 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118647 const int kRestrictedAlternatePort = 80;
[email protected]17291a022011-10-10 07:32:538648 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118649 HostPortPair::FromURL(restricted_port_request.url),
8650 kRestrictedAlternatePort,
[email protected]287d9412014-07-08 23:01:008651 AlternateProtocolFromNextProto(GetParam()), 1);
[email protected]3912662a32011-10-04 00:51:118652
[email protected]262eec82013-03-19 21:01:368653 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508654 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418655 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118656
[email protected]49639fa2011-12-20 23:22:418657 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:368658 &restricted_port_request,
8659 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118660 EXPECT_EQ(ERR_IO_PENDING, rv);
8661 // Valid change to restricted port should pass.
8662 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:118663}
8664
[email protected]23e482282013-06-14 16:08:028665TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238666 AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:118667 // Ensure that we're not allowed to redirect traffic via an alternate
8668 // protocol to an unrestricted (port >= 1024) when the original traffic was
8669 // on a restricted port (port < 1024). Ensure that we can redirect in all
8670 // other cases.
[email protected]d7599122014-05-24 03:37:238671 session_deps_.use_alternate_protocols = true;
[email protected]3912662a32011-10-04 00:51:118672
8673 HttpRequestInfo unrestricted_port_request;
8674 unrestricted_port_request.method = "GET";
8675 unrestricted_port_request.url = GURL("http://www.google.com:1024/");
8676 unrestricted_port_request.load_flags = 0;
8677
[email protected]d973e99a2012-02-17 21:02:368678 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118679 StaticSocketDataProvider first_data;
8680 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078681 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118682
8683 MockRead data_reads[] = {
8684 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8685 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068686 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118687 };
8688 StaticSocketDataProvider second_data(
8689 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078690 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118691
[email protected]bb88e1d32013-05-03 23:11:078692 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118693
[email protected]30d4c022013-07-18 22:58:168694 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538695 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118696 const int kRestrictedAlternatePort = 80;
[email protected]17291a022011-10-10 07:32:538697 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118698 HostPortPair::FromURL(unrestricted_port_request.url),
8699 kRestrictedAlternatePort,
[email protected]287d9412014-07-08 23:01:008700 AlternateProtocolFromNextProto(GetParam()), 1);
[email protected]3912662a32011-10-04 00:51:118701
[email protected]262eec82013-03-19 21:01:368702 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508703 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418704 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118705
[email protected]49639fa2011-12-20 23:22:418706 int rv = trans->Start(
8707 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118708 EXPECT_EQ(ERR_IO_PENDING, rv);
8709 // Valid change to restricted port should pass.
8710 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:118711}
8712
[email protected]23e482282013-06-14 16:08:028713TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238714 AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:118715 // Ensure that we're not allowed to redirect traffic via an alternate
8716 // protocol to an unrestricted (port >= 1024) when the original traffic was
8717 // on a restricted port (port < 1024). Ensure that we can redirect in all
8718 // other cases.
[email protected]d7599122014-05-24 03:37:238719 session_deps_.use_alternate_protocols = true;
[email protected]3912662a32011-10-04 00:51:118720
8721 HttpRequestInfo unrestricted_port_request;
8722 unrestricted_port_request.method = "GET";
8723 unrestricted_port_request.url = GURL("http://www.google.com:1024/");
8724 unrestricted_port_request.load_flags = 0;
8725
[email protected]d973e99a2012-02-17 21:02:368726 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118727 StaticSocketDataProvider first_data;
8728 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078729 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118730
8731 MockRead data_reads[] = {
8732 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8733 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068734 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118735 };
8736 StaticSocketDataProvider second_data(
8737 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078738 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118739
[email protected]bb88e1d32013-05-03 23:11:078740 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118741
[email protected]30d4c022013-07-18 22:58:168742 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538743 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118744 const int kUnrestrictedAlternatePort = 1024;
[email protected]17291a022011-10-10 07:32:538745 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118746 HostPortPair::FromURL(unrestricted_port_request.url),
8747 kUnrestrictedAlternatePort,
[email protected]287d9412014-07-08 23:01:008748 AlternateProtocolFromNextProto(GetParam()), 1);
[email protected]3912662a32011-10-04 00:51:118749
[email protected]262eec82013-03-19 21:01:368750 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508751 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418752 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118753
[email protected]49639fa2011-12-20 23:22:418754 int rv = trans->Start(
8755 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118756 EXPECT_EQ(ERR_IO_PENDING, rv);
8757 // Valid change to an unrestricted port should pass.
8758 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:118759}
8760
[email protected]d7599122014-05-24 03:37:238761TEST_P(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:028762 // Ensure that we're not allowed to redirect traffic via an alternate
8763 // protocol to an unsafe port, and that we resume the second
8764 // HttpStreamFactoryImpl::Job once the alternate protocol request fails.
[email protected]d7599122014-05-24 03:37:238765 session_deps_.use_alternate_protocols = true;
[email protected]eb6234e2012-01-19 01:50:028766
8767 HttpRequestInfo request;
8768 request.method = "GET";
8769 request.url = GURL("http://www.google.com/");
8770 request.load_flags = 0;
8771
8772 // The alternate protocol request will error out before we attempt to connect,
8773 // so only the standard HTTP request will try to connect.
8774 MockRead data_reads[] = {
8775 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8776 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068777 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:028778 };
8779 StaticSocketDataProvider data(
8780 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078781 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:028782
[email protected]bb88e1d32013-05-03 23:11:078783 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:028784
[email protected]30d4c022013-07-18 22:58:168785 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]eb6234e2012-01-19 01:50:028786 session->http_server_properties();
8787 const int kUnsafePort = 7;
8788 http_server_properties->SetAlternateProtocol(
8789 HostPortPair::FromURL(request.url),
8790 kUnsafePort,
[email protected]287d9412014-07-08 23:01:008791 AlternateProtocolFromNextProto(GetParam()), 1);
[email protected]eb6234e2012-01-19 01:50:028792
[email protected]262eec82013-03-19 21:01:368793 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508794 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]eb6234e2012-01-19 01:50:028795 TestCompletionCallback callback;
8796
8797 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8798 EXPECT_EQ(ERR_IO_PENDING, rv);
8799 // The HTTP request should succeed.
8800 EXPECT_EQ(OK, callback.WaitForResult());
8801
8802 // Disable alternate protocol before the asserts.
[email protected]d7599122014-05-24 03:37:238803 // HttpStreamFactory::set_use_alternate_protocols(false);
[email protected]eb6234e2012-01-19 01:50:028804
8805 const HttpResponseInfo* response = trans->GetResponseInfo();
8806 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508807 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]eb6234e2012-01-19 01:50:028808 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8809
8810 std::string response_data;
8811 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8812 EXPECT_EQ("hello world", response_data);
8813}
8814
[email protected]23e482282013-06-14 16:08:028815TEST_P(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]d7599122014-05-24 03:37:238816 session_deps_.use_alternate_protocols = true;
8817 session_deps_.next_protos = SpdyNextProtos();
[email protected]2ff8b312010-04-26 22:20:548818
8819 HttpRequestInfo request;
8820 request.method = "GET";
8821 request.url = GURL("http://www.google.com/");
8822 request.load_flags = 0;
8823
[email protected]8a0fc822013-06-27 20:52:438824 std::string alternate_protocol_http_header =
8825 GetAlternateProtocolHttpHeader();
8826
[email protected]2ff8b312010-04-26 22:20:548827 MockRead data_reads[] = {
8828 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438829 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2ff8b312010-04-26 22:20:548830 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:178831 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
8832 MockRead(ASYNC, OK)
[email protected]2ff8b312010-04-26 22:20:548833 };
8834
8835 StaticSocketDataProvider first_transaction(
8836 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078837 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:548838
[email protected]8ddf8322012-02-23 18:08:068839 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:028840 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:078841 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:548842
[email protected]cdf8f7e72013-05-23 10:56:468843 scoped_ptr<SpdyFrame> req(
8844 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]e7f75092010-07-01 22:39:138845 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
[email protected]2ff8b312010-04-26 22:20:548846
[email protected]23e482282013-06-14 16:08:028847 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
8848 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:548849 MockRead spdy_reads[] = {
[email protected]e7f75092010-07-01 22:39:138850 CreateMockRead(*resp),
8851 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:068852 MockRead(ASYNC, 0, 0),
[email protected]2ff8b312010-04-26 22:20:548853 };
8854
[email protected]dd54bd82012-07-19 23:44:578855 DelayedSocketData spdy_data(
8856 1, // wait for one write to finish before reading.
8857 spdy_reads, arraysize(spdy_reads),
8858 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078859 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:548860
[email protected]d973e99a2012-02-17 21:02:368861 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:558862 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
8863 NULL, 0, NULL, 0);
8864 hanging_non_alternate_protocol_socket.set_connect_data(
8865 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:078866 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:558867 &hanging_non_alternate_protocol_socket);
8868
[email protected]49639fa2011-12-20 23:22:418869 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:548870
[email protected]bb88e1d32013-05-03 23:11:078871 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:368872 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508873 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:548874
[email protected]49639fa2011-12-20 23:22:418875 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:548876 EXPECT_EQ(ERR_IO_PENDING, rv);
8877 EXPECT_EQ(OK, callback.WaitForResult());
8878
8879 const HttpResponseInfo* response = trans->GetResponseInfo();
8880 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508881 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:548882 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8883
8884 std::string response_data;
8885 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8886 EXPECT_EQ("hello world", response_data);
8887
[email protected]90499482013-06-01 00:39:508888 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:548889
[email protected]49639fa2011-12-20 23:22:418890 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:548891 EXPECT_EQ(ERR_IO_PENDING, rv);
8892 EXPECT_EQ(OK, callback.WaitForResult());
8893
8894 response = trans->GetResponseInfo();
8895 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508896 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:548897 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:538898 EXPECT_TRUE(response->was_fetched_via_spdy);
8899 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:548900
8901 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8902 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:548903}
8904
[email protected]23e482282013-06-14 16:08:028905TEST_P(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]d7599122014-05-24 03:37:238906 session_deps_.use_alternate_protocols = true;
8907 session_deps_.next_protos = SpdyNextProtos();
[email protected]2d6728692011-03-12 01:39:558908
8909 HttpRequestInfo request;
8910 request.method = "GET";
8911 request.url = GURL("http://www.google.com/");
8912 request.load_flags = 0;
8913
[email protected]8a0fc822013-06-27 20:52:438914 std::string alternate_protocol_http_header =
8915 GetAlternateProtocolHttpHeader();
8916
[email protected]2d6728692011-03-12 01:39:558917 MockRead data_reads[] = {
8918 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438919 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2d6728692011-03-12 01:39:558920 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:178921 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:068922 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:558923 };
8924
8925 StaticSocketDataProvider first_transaction(
8926 data_reads, arraysize(data_reads), NULL, 0);
8927 // Socket 1 is the HTTP transaction with the Alternate-Protocol header.
[email protected]bb88e1d32013-05-03 23:11:078928 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:558929
[email protected]d973e99a2012-02-17 21:02:368930 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:558931 StaticSocketDataProvider hanging_socket(
8932 NULL, 0, NULL, 0);
8933 hanging_socket.set_connect_data(never_finishing_connect);
8934 // Socket 2 and 3 are the hanging Alternate-Protocol and
8935 // non-Alternate-Protocol jobs from the 2nd transaction.
[email protected]bb88e1d32013-05-03 23:11:078936 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
8937 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
[email protected]2d6728692011-03-12 01:39:558938
[email protected]8ddf8322012-02-23 18:08:068939 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:028940 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:078941 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:558942
[email protected]cdf8f7e72013-05-23 10:56:468943 scoped_ptr<SpdyFrame> req1(
8944 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
8945 scoped_ptr<SpdyFrame> req2(
8946 spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
[email protected]2d6728692011-03-12 01:39:558947 MockWrite spdy_writes[] = {
8948 CreateMockWrite(*req1),
8949 CreateMockWrite(*req2),
8950 };
[email protected]23e482282013-06-14 16:08:028951 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
8952 scoped_ptr<SpdyFrame> data1(spdy_util_.ConstructSpdyBodyFrame(1, true));
8953 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
8954 scoped_ptr<SpdyFrame> data2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]2d6728692011-03-12 01:39:558955 MockRead spdy_reads[] = {
8956 CreateMockRead(*resp1),
8957 CreateMockRead(*data1),
8958 CreateMockRead(*resp2),
8959 CreateMockRead(*data2),
[email protected]8ddf8322012-02-23 18:08:068960 MockRead(ASYNC, 0, 0),
[email protected]2d6728692011-03-12 01:39:558961 };
8962
[email protected]dd54bd82012-07-19 23:44:578963 DelayedSocketData spdy_data(
8964 2, // wait for writes to finish before reading.
8965 spdy_reads, arraysize(spdy_reads),
8966 spdy_writes, arraysize(spdy_writes));
[email protected]2d6728692011-03-12 01:39:558967 // Socket 4 is the successful Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:078968 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:558969
8970 // Socket 5 is the unsuccessful non-Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:078971 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
[email protected]2d6728692011-03-12 01:39:558972
[email protected]bb88e1d32013-05-03 23:11:078973 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:418974 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:508975 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:558976
[email protected]49639fa2011-12-20 23:22:418977 int rv = trans1.Start(&request, callback1.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:558978 EXPECT_EQ(ERR_IO_PENDING, rv);
8979 EXPECT_EQ(OK, callback1.WaitForResult());
8980
8981 const HttpResponseInfo* response = trans1.GetResponseInfo();
8982 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508983 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:558984 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8985
8986 std::string response_data;
8987 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
8988 EXPECT_EQ("hello world", response_data);
8989
[email protected]49639fa2011-12-20 23:22:418990 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:508991 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:418992 rv = trans2.Start(&request, callback2.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:558993 EXPECT_EQ(ERR_IO_PENDING, rv);
8994
[email protected]49639fa2011-12-20 23:22:418995 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:508996 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:418997 rv = trans3.Start(&request, callback3.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:558998 EXPECT_EQ(ERR_IO_PENDING, rv);
8999
9000 EXPECT_EQ(OK, callback2.WaitForResult());
9001 EXPECT_EQ(OK, callback3.WaitForResult());
9002
9003 response = trans2.GetResponseInfo();
9004 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509005 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559006 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9007 EXPECT_TRUE(response->was_fetched_via_spdy);
9008 EXPECT_TRUE(response->was_npn_negotiated);
9009 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
9010 EXPECT_EQ("hello!", response_data);
9011
9012 response = trans3.GetResponseInfo();
9013 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509014 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559015 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9016 EXPECT_TRUE(response->was_fetched_via_spdy);
9017 EXPECT_TRUE(response->was_npn_negotiated);
9018 ASSERT_EQ(OK, ReadTransaction(&trans3, &response_data));
9019 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:559020}
9021
[email protected]23e482282013-06-14 16:08:029022TEST_P(HttpNetworkTransactionTest, StallAlternateProtocolForNpnSpdy) {
[email protected]d7599122014-05-24 03:37:239023 session_deps_.use_alternate_protocols = true;
9024 session_deps_.next_protos = SpdyNextProtos();
[email protected]2d6728692011-03-12 01:39:559025
9026 HttpRequestInfo request;
9027 request.method = "GET";
9028 request.url = GURL("http://www.google.com/");
9029 request.load_flags = 0;
9030
[email protected]8a0fc822013-06-27 20:52:439031 std::string alternate_protocol_http_header =
9032 GetAlternateProtocolHttpHeader();
9033
[email protected]2d6728692011-03-12 01:39:559034 MockRead data_reads[] = {
9035 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439036 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2d6728692011-03-12 01:39:559037 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:179038 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:069039 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:559040 };
9041
9042 StaticSocketDataProvider first_transaction(
9043 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079044 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:559045
[email protected]8ddf8322012-02-23 18:08:069046 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029047 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:079048 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:559049
[email protected]d973e99a2012-02-17 21:02:369050 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559051 StaticSocketDataProvider hanging_alternate_protocol_socket(
9052 NULL, 0, NULL, 0);
9053 hanging_alternate_protocol_socket.set_connect_data(
9054 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:079055 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:559056 &hanging_alternate_protocol_socket);
9057
9058 // 2nd request is just a copy of the first one, over HTTP again.
[email protected]bb88e1d32013-05-03 23:11:079059 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:559060
[email protected]49639fa2011-12-20 23:22:419061 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:559062
[email protected]bb88e1d32013-05-03 23:11:079063 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369064 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509065 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:559066
[email protected]49639fa2011-12-20 23:22:419067 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559068 EXPECT_EQ(ERR_IO_PENDING, rv);
9069 EXPECT_EQ(OK, callback.WaitForResult());
9070
9071 const HttpResponseInfo* response = trans->GetResponseInfo();
9072 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509073 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559074 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9075
9076 std::string response_data;
9077 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9078 EXPECT_EQ("hello world", response_data);
9079
[email protected]90499482013-06-01 00:39:509080 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:559081
[email protected]49639fa2011-12-20 23:22:419082 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559083 EXPECT_EQ(ERR_IO_PENDING, rv);
9084 EXPECT_EQ(OK, callback.WaitForResult());
9085
9086 response = trans->GetResponseInfo();
9087 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509088 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559089 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9090 EXPECT_FALSE(response->was_fetched_via_spdy);
9091 EXPECT_FALSE(response->was_npn_negotiated);
9092
9093 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9094 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:559095}
9096
[email protected]631f1322010-04-30 17:59:119097class CapturingProxyResolver : public ProxyResolver {
9098 public:
9099 CapturingProxyResolver() : ProxyResolver(false /* expects_pac_bytes */) {}
dchengb03027d2014-10-21 12:00:209100 ~CapturingProxyResolver() override {}
[email protected]631f1322010-04-30 17:59:119101
dchengb03027d2014-10-21 12:00:209102 int GetProxyForURL(const GURL& url,
9103 ProxyInfo* results,
9104 const CompletionCallback& callback,
9105 RequestHandle* request,
9106 const BoundNetLog& net_log) override {
[email protected]fae7669f2010-08-02 21:49:409107 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
9108 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:429109 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:119110 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:429111 return OK;
[email protected]631f1322010-04-30 17:59:119112 }
9113
dchengb03027d2014-10-21 12:00:209114 void CancelRequest(RequestHandle request) override { NOTREACHED(); }
[email protected]631f1322010-04-30 17:59:119115
dchengb03027d2014-10-21 12:00:209116 LoadState GetLoadState(RequestHandle request) const override {
[email protected]f2c971f2011-11-08 00:33:179117 NOTREACHED();
9118 return LOAD_STATE_IDLE;
9119 }
9120
dchengb03027d2014-10-21 12:00:209121 void CancelSetPacScript() override { NOTREACHED(); }
[email protected]1e605472010-12-16 21:41:409122
dchengb03027d2014-10-21 12:00:209123 int SetPacScript(const scoped_refptr<ProxyResolverScriptData>&,
9124 const CompletionCallback& /*callback*/) override {
[email protected]d911f1b2010-05-05 22:39:429125 return OK;
[email protected]631f1322010-04-30 17:59:119126 }
9127
[email protected]24476402010-07-20 20:55:179128 const std::vector<GURL>& resolved() const { return resolved_; }
9129
9130 private:
[email protected]631f1322010-04-30 17:59:119131 std::vector<GURL> resolved_;
9132
9133 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
9134};
9135
[email protected]23e482282013-06-14 16:08:029136TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239137 UseAlternateProtocolForTunneledNpnSpdy) {
[email protected]d7599122014-05-24 03:37:239138 session_deps_.use_alternate_protocols = true;
9139 session_deps_.next_protos = SpdyNextProtos();
[email protected]631f1322010-04-30 17:59:119140
9141 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:429142 proxy_config.set_auto_detect(true);
9143 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:119144
[email protected]631f1322010-04-30 17:59:119145 CapturingProxyResolver* capturing_proxy_resolver =
9146 new CapturingProxyResolver();
[email protected]bb88e1d32013-05-03 23:11:079147 session_deps_.proxy_service.reset(new ProxyService(
[email protected]66761b952010-06-25 21:30:389148 new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver,
9149 NULL));
[email protected]029c83b62013-01-24 05:28:209150 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079151 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:119152
9153 HttpRequestInfo request;
9154 request.method = "GET";
9155 request.url = GURL("http://www.google.com/");
9156 request.load_flags = 0;
9157
[email protected]8a0fc822013-06-27 20:52:439158 std::string alternate_protocol_http_header =
9159 GetAlternateProtocolHttpHeader();
9160
[email protected]631f1322010-04-30 17:59:119161 MockRead data_reads[] = {
9162 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439163 MockRead(alternate_protocol_http_header.c_str()),
[email protected]631f1322010-04-30 17:59:119164 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:179165 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:069166 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:119167 };
9168
9169 StaticSocketDataProvider first_transaction(
9170 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079171 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]631f1322010-04-30 17:59:119172
[email protected]8ddf8322012-02-23 18:08:069173 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029174 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:079175 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]631f1322010-04-30 17:59:119176
[email protected]cdf8f7e72013-05-23 10:56:469177 scoped_ptr<SpdyFrame> req(
9178 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]631f1322010-04-30 17:59:119179 MockWrite spdy_writes[] = {
9180 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
9181 "Host: www.google.com\r\n"
[email protected]d911f1b2010-05-05 22:39:429182 "Proxy-Connection: keep-alive\r\n\r\n"), // 0
[email protected]cdf8f7e72013-05-23 10:56:469183 CreateMockWrite(*req), // 3
[email protected]631f1322010-04-30 17:59:119184 };
9185
[email protected]d911f1b2010-05-05 22:39:429186 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
9187
[email protected]23e482282013-06-14 16:08:029188 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9189 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]631f1322010-04-30 17:59:119190 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:069191 MockRead(ASYNC, kCONNECTResponse, arraysize(kCONNECTResponse) - 1, 1), // 1
[email protected]e7f75092010-07-01 22:39:139192 CreateMockRead(*resp.get(), 4), // 2, 4
9193 CreateMockRead(*data.get(), 4), // 5
[email protected]8ddf8322012-02-23 18:08:069194 MockRead(ASYNC, 0, 0, 4), // 6
[email protected]631f1322010-04-30 17:59:119195 };
9196
[email protected]dd54bd82012-07-19 23:44:579197 OrderedSocketData spdy_data(
9198 spdy_reads, arraysize(spdy_reads),
9199 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079200 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:119201
[email protected]d973e99a2012-02-17 21:02:369202 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559203 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
9204 NULL, 0, NULL, 0);
9205 hanging_non_alternate_protocol_socket.set_connect_data(
9206 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:079207 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:559208 &hanging_non_alternate_protocol_socket);
9209
[email protected]49639fa2011-12-20 23:22:419210 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:119211
[email protected]bb88e1d32013-05-03 23:11:079212 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369213 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509214 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:119215
[email protected]49639fa2011-12-20 23:22:419216 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:119217 EXPECT_EQ(ERR_IO_PENDING, rv);
9218 EXPECT_EQ(OK, callback.WaitForResult());
9219
9220 const HttpResponseInfo* response = trans->GetResponseInfo();
9221 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509222 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]631f1322010-04-30 17:59:119223 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539224 EXPECT_FALSE(response->was_fetched_via_spdy);
9225 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:119226
9227 std::string response_data;
9228 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9229 EXPECT_EQ("hello world", response_data);
9230
[email protected]90499482013-06-01 00:39:509231 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:119232
[email protected]49639fa2011-12-20 23:22:419233 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:119234 EXPECT_EQ(ERR_IO_PENDING, rv);
9235 EXPECT_EQ(OK, callback.WaitForResult());
9236
9237 response = trans->GetResponseInfo();
9238 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509239 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]631f1322010-04-30 17:59:119240 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539241 EXPECT_TRUE(response->was_fetched_via_spdy);
9242 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:119243
9244 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9245 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:559246 ASSERT_EQ(3u, capturing_proxy_resolver->resolved().size());
[email protected]d911f1b2010-05-05 22:39:429247 EXPECT_EQ("http://www.google.com/",
[email protected]631f1322010-04-30 17:59:119248 capturing_proxy_resolver->resolved()[0].spec());
[email protected]d911f1b2010-05-05 22:39:429249 EXPECT_EQ("https://www.google.com/",
9250 capturing_proxy_resolver->resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:119251
[email protected]029c83b62013-01-24 05:28:209252 LoadTimingInfo load_timing_info;
9253 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
9254 TestLoadTimingNotReusedWithPac(load_timing_info,
9255 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:119256}
[email protected]631f1322010-04-30 17:59:119257
[email protected]23e482282013-06-14 16:08:029258TEST_P(HttpNetworkTransactionTest,
[email protected]2ff8b312010-04-26 22:20:549259 UseAlternateProtocolForNpnSpdyWithExistingSpdySession) {
[email protected]d7599122014-05-24 03:37:239260 session_deps_.use_alternate_protocols = true;
9261 session_deps_.next_protos = SpdyNextProtos();
[email protected]2ff8b312010-04-26 22:20:549262
9263 HttpRequestInfo request;
9264 request.method = "GET";
9265 request.url = GURL("http://www.google.com/");
9266 request.load_flags = 0;
9267
[email protected]8a0fc822013-06-27 20:52:439268 std::string alternate_protocol_http_header =
9269 GetAlternateProtocolHttpHeader();
9270
[email protected]2ff8b312010-04-26 22:20:549271 MockRead data_reads[] = {
9272 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439273 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2ff8b312010-04-26 22:20:549274 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069275 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:549276 };
9277
9278 StaticSocketDataProvider first_transaction(
9279 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079280 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:549281
[email protected]8ddf8322012-02-23 18:08:069282 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029283 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:079284 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:549285
[email protected]cdf8f7e72013-05-23 10:56:469286 scoped_ptr<SpdyFrame> req(
9287 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]e7f75092010-07-01 22:39:139288 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
[email protected]2ff8b312010-04-26 22:20:549289
[email protected]23e482282013-06-14 16:08:029290 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9291 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:549292 MockRead spdy_reads[] = {
[email protected]e7f75092010-07-01 22:39:139293 CreateMockRead(*resp),
9294 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:069295 MockRead(ASYNC, 0, 0),
[email protected]2ff8b312010-04-26 22:20:549296 };
9297
[email protected]dd54bd82012-07-19 23:44:579298 DelayedSocketData spdy_data(
9299 1, // wait for one write to finish before reading.
9300 spdy_reads, arraysize(spdy_reads),
9301 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079302 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:549303
[email protected]83039bb2011-12-09 18:43:559304 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:549305
[email protected]bb88e1d32013-05-03 23:11:079306 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:549307
[email protected]262eec82013-03-19 21:01:369308 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509309 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:549310
[email protected]49639fa2011-12-20 23:22:419311 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:549312 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:419313 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:549314
9315 const HttpResponseInfo* response = trans->GetResponseInfo();
9316 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509317 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:549318 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9319
9320 std::string response_data;
9321 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9322 EXPECT_EQ("hello world", response_data);
9323
9324 // Set up an initial SpdySession in the pool to reuse.
[email protected]02b0c342010-09-25 21:09:389325 HostPortPair host_port_pair("www.google.com", 443);
[email protected]e6d017652013-05-17 18:01:409326 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:539327 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:279328 base::WeakPtr<SpdySession> spdy_session =
[email protected]41d64e82013-07-03 22:44:269329 CreateSecureSpdySession(session, key, BoundNetLog());
[email protected]02b0c342010-09-25 21:09:389330
[email protected]90499482013-06-01 00:39:509331 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:549332
[email protected]49639fa2011-12-20 23:22:419333 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:549334 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:419335 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:549336
9337 response = trans->GetResponseInfo();
9338 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509339 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:549340 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539341 EXPECT_TRUE(response->was_fetched_via_spdy);
9342 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:549343
9344 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9345 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:429346}
9347
[email protected]044de0642010-06-17 10:42:159348// GenerateAuthToken is a mighty big test.
9349// It tests all permutation of GenerateAuthToken behavior:
9350// - Synchronous and Asynchronous completion.
9351// - OK or error on completion.
9352// - Direct connection, non-authenticating proxy, and authenticating proxy.
9353// - HTTP or HTTPS backend (to include proxy tunneling).
9354// - Non-authenticating and authenticating backend.
9355//
[email protected]fe3b7dc2012-02-03 19:52:099356// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:159357// problems generating an auth token for an authenticating proxy, we don't
9358// need to test all permutations of the backend server).
9359//
9360// The test proceeds by going over each of the configuration cases, and
9361// potentially running up to three rounds in each of the tests. The TestConfig
9362// specifies both the configuration for the test as well as the expectations
9363// for the results.
[email protected]23e482282013-06-14 16:08:029364TEST_P(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:509365 static const char kServer[] = "http://www.example.com";
9366 static const char kSecureServer[] = "https://www.example.com";
9367 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:159368 const int kAuthErr = ERR_INVALID_AUTH_CREDENTIALS;
9369
9370 enum AuthTiming {
9371 AUTH_NONE,
9372 AUTH_SYNC,
9373 AUTH_ASYNC,
9374 };
9375
9376 const MockWrite kGet(
9377 "GET / HTTP/1.1\r\n"
9378 "Host: www.example.com\r\n"
9379 "Connection: keep-alive\r\n\r\n");
9380 const MockWrite kGetProxy(
9381 "GET http://www.example.com/ HTTP/1.1\r\n"
9382 "Host: www.example.com\r\n"
9383 "Proxy-Connection: keep-alive\r\n\r\n");
9384 const MockWrite kGetAuth(
9385 "GET / HTTP/1.1\r\n"
9386 "Host: www.example.com\r\n"
9387 "Connection: keep-alive\r\n"
9388 "Authorization: auth_token\r\n\r\n");
9389 const MockWrite kGetProxyAuth(
9390 "GET http://www.example.com/ HTTP/1.1\r\n"
9391 "Host: www.example.com\r\n"
9392 "Proxy-Connection: keep-alive\r\n"
9393 "Proxy-Authorization: auth_token\r\n\r\n");
9394 const MockWrite kGetAuthThroughProxy(
9395 "GET http://www.example.com/ HTTP/1.1\r\n"
9396 "Host: www.example.com\r\n"
9397 "Proxy-Connection: keep-alive\r\n"
9398 "Authorization: auth_token\r\n\r\n");
9399 const MockWrite kGetAuthWithProxyAuth(
9400 "GET http://www.example.com/ HTTP/1.1\r\n"
9401 "Host: www.example.com\r\n"
9402 "Proxy-Connection: keep-alive\r\n"
9403 "Proxy-Authorization: auth_token\r\n"
9404 "Authorization: auth_token\r\n\r\n");
9405 const MockWrite kConnect(
9406 "CONNECT www.example.com:443 HTTP/1.1\r\n"
9407 "Host: www.example.com\r\n"
9408 "Proxy-Connection: keep-alive\r\n\r\n");
9409 const MockWrite kConnectProxyAuth(
9410 "CONNECT www.example.com:443 HTTP/1.1\r\n"
9411 "Host: www.example.com\r\n"
9412 "Proxy-Connection: keep-alive\r\n"
9413 "Proxy-Authorization: auth_token\r\n\r\n");
9414
9415 const MockRead kSuccess(
9416 "HTTP/1.1 200 OK\r\n"
9417 "Content-Type: text/html; charset=iso-8859-1\r\n"
9418 "Content-Length: 3\r\n\r\n"
9419 "Yes");
9420 const MockRead kFailure(
9421 "Should not be called.");
9422 const MockRead kServerChallenge(
9423 "HTTP/1.1 401 Unauthorized\r\n"
9424 "WWW-Authenticate: Mock realm=server\r\n"
9425 "Content-Type: text/html; charset=iso-8859-1\r\n"
9426 "Content-Length: 14\r\n\r\n"
9427 "Unauthorized\r\n");
9428 const MockRead kProxyChallenge(
9429 "HTTP/1.1 407 Unauthorized\r\n"
9430 "Proxy-Authenticate: Mock realm=proxy\r\n"
9431 "Proxy-Connection: close\r\n"
9432 "Content-Type: text/html; charset=iso-8859-1\r\n"
9433 "Content-Length: 14\r\n\r\n"
9434 "Unauthorized\r\n");
9435 const MockRead kProxyConnected(
9436 "HTTP/1.1 200 Connection Established\r\n\r\n");
9437
9438 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
9439 // no constructors, but the C++ compiler on Windows warns about
9440 // unspecified data in compound literals. So, moved to using constructors,
9441 // and TestRound's created with the default constructor should not be used.
9442 struct TestRound {
9443 TestRound()
9444 : expected_rv(ERR_UNEXPECTED),
9445 extra_write(NULL),
9446 extra_read(NULL) {
9447 }
9448 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
9449 int expected_rv_arg)
9450 : write(write_arg),
9451 read(read_arg),
9452 expected_rv(expected_rv_arg),
9453 extra_write(NULL),
9454 extra_read(NULL) {
9455 }
9456 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
9457 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:019458 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:159459 : write(write_arg),
9460 read(read_arg),
9461 expected_rv(expected_rv_arg),
9462 extra_write(extra_write_arg),
9463 extra_read(extra_read_arg) {
9464 }
9465 MockWrite write;
9466 MockRead read;
9467 int expected_rv;
9468 const MockWrite* extra_write;
9469 const MockRead* extra_read;
9470 };
9471
9472 static const int kNoSSL = 500;
9473
9474 struct TestConfig {
9475 const char* proxy_url;
9476 AuthTiming proxy_auth_timing;
9477 int proxy_auth_rv;
9478 const char* server_url;
9479 AuthTiming server_auth_timing;
9480 int server_auth_rv;
9481 int num_auth_rounds;
9482 int first_ssl_round;
9483 TestRound rounds[3];
9484 } test_configs[] = {
9485 // Non-authenticating HTTP server with a direct connection.
9486 { NULL, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
9487 { TestRound(kGet, kSuccess, OK)}},
9488 // Authenticating HTTP server with a direct connection.
9489 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
9490 { TestRound(kGet, kServerChallenge, OK),
9491 TestRound(kGetAuth, kSuccess, OK)}},
9492 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
9493 { TestRound(kGet, kServerChallenge, OK),
9494 TestRound(kGetAuth, kFailure, kAuthErr)}},
9495 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
9496 { TestRound(kGet, kServerChallenge, OK),
9497 TestRound(kGetAuth, kSuccess, OK)}},
9498 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
9499 { TestRound(kGet, kServerChallenge, OK),
9500 TestRound(kGetAuth, kFailure, kAuthErr)}},
9501 // Non-authenticating HTTP server through a non-authenticating proxy.
9502 { kProxy, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
9503 { TestRound(kGetProxy, kSuccess, OK)}},
9504 // Authenticating HTTP server through a non-authenticating proxy.
9505 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
9506 { TestRound(kGetProxy, kServerChallenge, OK),
9507 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
9508 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
9509 { TestRound(kGetProxy, kServerChallenge, OK),
9510 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
9511 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
9512 { TestRound(kGetProxy, kServerChallenge, OK),
9513 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
9514 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
9515 { TestRound(kGetProxy, kServerChallenge, OK),
9516 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
9517 // Non-authenticating HTTP server through an authenticating proxy.
9518 { kProxy, AUTH_SYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
9519 { TestRound(kGetProxy, kProxyChallenge, OK),
9520 TestRound(kGetProxyAuth, kSuccess, OK)}},
9521 { kProxy, AUTH_SYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
9522 { TestRound(kGetProxy, kProxyChallenge, OK),
9523 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
9524 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
9525 { TestRound(kGetProxy, kProxyChallenge, OK),
9526 TestRound(kGetProxyAuth, kSuccess, OK)}},
9527 { kProxy, AUTH_ASYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
9528 { TestRound(kGetProxy, kProxyChallenge, OK),
9529 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
9530 // Authenticating HTTP server through an authenticating proxy.
9531 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
9532 { TestRound(kGetProxy, kProxyChallenge, OK),
9533 TestRound(kGetProxyAuth, kServerChallenge, OK),
9534 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9535 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
9536 { TestRound(kGetProxy, kProxyChallenge, OK),
9537 TestRound(kGetProxyAuth, kServerChallenge, OK),
9538 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9539 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
9540 { TestRound(kGetProxy, kProxyChallenge, OK),
9541 TestRound(kGetProxyAuth, kServerChallenge, OK),
9542 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9543 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
9544 { TestRound(kGetProxy, kProxyChallenge, OK),
9545 TestRound(kGetProxyAuth, kServerChallenge, OK),
9546 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9547 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
9548 { TestRound(kGetProxy, kProxyChallenge, OK),
9549 TestRound(kGetProxyAuth, kServerChallenge, OK),
9550 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9551 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
9552 { TestRound(kGetProxy, kProxyChallenge, OK),
9553 TestRound(kGetProxyAuth, kServerChallenge, OK),
9554 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9555 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
9556 { TestRound(kGetProxy, kProxyChallenge, OK),
9557 TestRound(kGetProxyAuth, kServerChallenge, OK),
9558 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9559 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
9560 { TestRound(kGetProxy, kProxyChallenge, OK),
9561 TestRound(kGetProxyAuth, kServerChallenge, OK),
9562 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9563 // Non-authenticating HTTPS server with a direct connection.
9564 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
9565 { TestRound(kGet, kSuccess, OK)}},
9566 // Authenticating HTTPS server with a direct connection.
9567 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
9568 { TestRound(kGet, kServerChallenge, OK),
9569 TestRound(kGetAuth, kSuccess, OK)}},
9570 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
9571 { TestRound(kGet, kServerChallenge, OK),
9572 TestRound(kGetAuth, kFailure, kAuthErr)}},
9573 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
9574 { TestRound(kGet, kServerChallenge, OK),
9575 TestRound(kGetAuth, kSuccess, OK)}},
9576 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
9577 { TestRound(kGet, kServerChallenge, OK),
9578 TestRound(kGetAuth, kFailure, kAuthErr)}},
9579 // Non-authenticating HTTPS server with a non-authenticating proxy.
9580 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
9581 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
9582 // Authenticating HTTPS server through a non-authenticating proxy.
9583 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
9584 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9585 TestRound(kGetAuth, kSuccess, OK)}},
9586 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
9587 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9588 TestRound(kGetAuth, kFailure, kAuthErr)}},
9589 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
9590 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9591 TestRound(kGetAuth, kSuccess, OK)}},
9592 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
9593 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9594 TestRound(kGetAuth, kFailure, kAuthErr)}},
9595 // Non-Authenticating HTTPS server through an authenticating proxy.
9596 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
9597 { TestRound(kConnect, kProxyChallenge, OK),
9598 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
9599 { kProxy, AUTH_SYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
9600 { TestRound(kConnect, kProxyChallenge, OK),
9601 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
9602 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
9603 { TestRound(kConnect, kProxyChallenge, OK),
9604 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
9605 { kProxy, AUTH_ASYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
9606 { TestRound(kConnect, kProxyChallenge, OK),
9607 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
9608 // Authenticating HTTPS server through an authenticating proxy.
9609 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
9610 { TestRound(kConnect, kProxyChallenge, OK),
9611 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9612 &kGet, &kServerChallenge),
9613 TestRound(kGetAuth, kSuccess, OK)}},
9614 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
9615 { TestRound(kConnect, kProxyChallenge, OK),
9616 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9617 &kGet, &kServerChallenge),
9618 TestRound(kGetAuth, kFailure, kAuthErr)}},
9619 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
9620 { TestRound(kConnect, kProxyChallenge, OK),
9621 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9622 &kGet, &kServerChallenge),
9623 TestRound(kGetAuth, kSuccess, OK)}},
9624 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
9625 { TestRound(kConnect, kProxyChallenge, OK),
9626 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9627 &kGet, &kServerChallenge),
9628 TestRound(kGetAuth, kFailure, kAuthErr)}},
9629 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
9630 { TestRound(kConnect, kProxyChallenge, OK),
9631 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9632 &kGet, &kServerChallenge),
9633 TestRound(kGetAuth, kSuccess, OK)}},
9634 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
9635 { TestRound(kConnect, kProxyChallenge, OK),
9636 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9637 &kGet, &kServerChallenge),
9638 TestRound(kGetAuth, kFailure, kAuthErr)}},
9639 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
9640 { TestRound(kConnect, kProxyChallenge, OK),
9641 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9642 &kGet, &kServerChallenge),
9643 TestRound(kGetAuth, kSuccess, OK)}},
9644 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
9645 { TestRound(kConnect, kProxyChallenge, OK),
9646 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9647 &kGet, &kServerChallenge),
9648 TestRound(kGetAuth, kFailure, kAuthErr)}},
9649 };
9650
viettrungluue4a8b882014-10-16 06:17:389651 for (size_t i = 0; i < arraysize(test_configs); ++i) {
[email protected]2d01c262011-08-11 23:07:089652 HttpAuthHandlerMock::Factory* auth_factory(
9653 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:079654 session_deps_.http_auth_handler_factory.reset(auth_factory);
[email protected]044de0642010-06-17 10:42:159655 const TestConfig& test_config = test_configs[i];
[email protected]65d34382010-07-01 18:12:269656
9657 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:159658 if (test_config.proxy_auth_timing != AUTH_NONE) {
[email protected]2d01c262011-08-11 23:07:089659 for (int n = 0; n < 2; n++) {
9660 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
9661 std::string auth_challenge = "Mock realm=proxy";
9662 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:249663 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
9664 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:089665 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
9666 origin, BoundNetLog());
9667 auth_handler->SetGenerateExpectation(
9668 test_config.proxy_auth_timing == AUTH_ASYNC,
9669 test_config.proxy_auth_rv);
9670 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
9671 }
[email protected]044de0642010-06-17 10:42:159672 }
9673 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:009674 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:159675 std::string auth_challenge = "Mock realm=server";
9676 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:249677 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
9678 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:159679 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
9680 origin, BoundNetLog());
9681 auth_handler->SetGenerateExpectation(
9682 test_config.server_auth_timing == AUTH_ASYNC,
9683 test_config.server_auth_rv);
[email protected]2d01c262011-08-11 23:07:089684 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:159685 }
9686 if (test_config.proxy_url) {
[email protected]bb88e1d32013-05-03 23:11:079687 session_deps_.proxy_service.reset(
[email protected]6104ea5d2011-04-27 21:37:129688 ProxyService::CreateFixed(test_config.proxy_url));
[email protected]044de0642010-06-17 10:42:159689 } else {
[email protected]bb88e1d32013-05-03 23:11:079690 session_deps_.proxy_service.reset(ProxyService::CreateDirect());
[email protected]044de0642010-06-17 10:42:159691 }
9692
9693 HttpRequestInfo request;
9694 request.method = "GET";
9695 request.url = GURL(test_config.server_url);
9696 request.load_flags = 0;
9697
[email protected]bb88e1d32013-05-03 23:11:079698 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
dcheng48459ac22014-08-26 00:46:419699 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]044de0642010-06-17 10:42:159700
9701 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
9702 const TestRound& read_write_round = test_config.rounds[round];
9703
9704 // Set up expected reads and writes.
9705 MockRead reads[2];
9706 reads[0] = read_write_round.read;
9707 size_t length_reads = 1;
9708 if (read_write_round.extra_read) {
9709 reads[1] = *read_write_round.extra_read;
9710 length_reads = 2;
9711 }
9712
9713 MockWrite writes[2];
9714 writes[0] = read_write_round.write;
9715 size_t length_writes = 1;
9716 if (read_write_round.extra_write) {
9717 writes[1] = *read_write_round.extra_write;
9718 length_writes = 2;
9719 }
9720 StaticSocketDataProvider data_provider(
9721 reads, length_reads, writes, length_writes);
[email protected]bb88e1d32013-05-03 23:11:079722 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]044de0642010-06-17 10:42:159723
9724 // Add an SSL sequence if necessary.
[email protected]8ddf8322012-02-23 18:08:069725 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
[email protected]044de0642010-06-17 10:42:159726 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:079727 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:159728 &ssl_socket_data_provider);
9729
9730 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:419731 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:159732 int rv;
9733 if (round == 0) {
[email protected]49639fa2011-12-20 23:22:419734 rv = trans.Start(&request, callback.callback(), BoundNetLog());
[email protected]044de0642010-06-17 10:42:159735 } else {
[email protected]49639fa2011-12-20 23:22:419736 rv = trans.RestartWithAuth(
9737 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:159738 }
9739 if (rv == ERR_IO_PENDING)
9740 rv = callback.WaitForResult();
9741
9742 // Compare results with expected data.
9743 EXPECT_EQ(read_write_round.expected_rv, rv);
[email protected]0b0bf032010-09-21 18:08:509744 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]044de0642010-06-17 10:42:159745 if (read_write_round.expected_rv == OK) {
[email protected]fe2255a2011-09-20 19:37:509746 ASSERT_TRUE(response != NULL);
[email protected]044de0642010-06-17 10:42:159747 } else {
9748 EXPECT_TRUE(response == NULL);
9749 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
9750 continue;
9751 }
9752 if (round + 1 < test_config.num_auth_rounds) {
9753 EXPECT_FALSE(response->auth_challenge.get() == NULL);
9754 } else {
9755 EXPECT_TRUE(response->auth_challenge.get() == NULL);
9756 }
9757 }
[email protected]e5ae96a2010-04-14 20:12:459758 }
9759}
9760
[email protected]23e482282013-06-14 16:08:029761TEST_P(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:149762 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:149763 HttpAuthHandlerMock::Factory* auth_factory(
9764 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:079765 session_deps_.http_auth_handler_factory.reset(auth_factory);
9766 session_deps_.proxy_service.reset(ProxyService::CreateDirect());
9767 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
9768 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:149769
9770 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
9771 auth_handler->set_connection_based(true);
9772 std::string auth_challenge = "Mock realm=server";
9773 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:249774 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
9775 auth_challenge.end());
[email protected]c871bce92010-07-15 21:51:149776 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
9777 origin, BoundNetLog());
[email protected]2d01c262011-08-11 23:07:089778 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:149779
[email protected]c871bce92010-07-15 21:51:149780 int rv = OK;
9781 const HttpResponseInfo* response = NULL;
9782 HttpRequestInfo request;
9783 request.method = "GET";
9784 request.url = origin;
9785 request.load_flags = 0;
[email protected]cb9bf6ca2011-01-28 13:15:279786
[email protected]bb88e1d32013-05-03 23:11:079787 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:109788
9789 // Use a TCP Socket Pool with only one connection per group. This is used
9790 // to validate that the TCP socket is not released to the pool between
9791 // each round of multi-round authentication.
9792 HttpNetworkSessionPeer session_peer(session);
[email protected]ab739042011-04-07 15:22:289793 ClientSocketPoolHistograms transport_pool_histograms("SmallTCP");
9794 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:109795 50, // Max sockets for pool
9796 1, // Max sockets per group
[email protected]ab739042011-04-07 15:22:289797 &transport_pool_histograms,
[email protected]bb88e1d32013-05-03 23:11:079798 session_deps_.host_resolver.get(),
9799 session_deps_.socket_factory.get(),
9800 session_deps_.net_log);
[email protected]831e4a32013-11-14 02:14:449801 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
9802 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:029803 mock_pool_manager->SetTransportSocketPool(transport_pool);
dchenge3d1ddc2014-10-15 19:30:519804 session_peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]7ef4cbbb2011-02-06 11:19:109805
[email protected]262eec82013-03-19 21:01:369806 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509807 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419808 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:149809
9810 const MockWrite kGet(
9811 "GET / HTTP/1.1\r\n"
9812 "Host: www.example.com\r\n"
9813 "Connection: keep-alive\r\n\r\n");
9814 const MockWrite kGetAuth(
9815 "GET / HTTP/1.1\r\n"
9816 "Host: www.example.com\r\n"
9817 "Connection: keep-alive\r\n"
9818 "Authorization: auth_token\r\n\r\n");
9819
9820 const MockRead kServerChallenge(
9821 "HTTP/1.1 401 Unauthorized\r\n"
9822 "WWW-Authenticate: Mock realm=server\r\n"
9823 "Content-Type: text/html; charset=iso-8859-1\r\n"
9824 "Content-Length: 14\r\n\r\n"
9825 "Unauthorized\r\n");
9826 const MockRead kSuccess(
9827 "HTTP/1.1 200 OK\r\n"
9828 "Content-Type: text/html; charset=iso-8859-1\r\n"
9829 "Content-Length: 3\r\n\r\n"
9830 "Yes");
9831
9832 MockWrite writes[] = {
9833 // First round
9834 kGet,
9835 // Second round
9836 kGetAuth,
9837 // Third round
9838 kGetAuth,
[email protected]eca50e122010-09-11 14:03:309839 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:109840 kGetAuth,
9841 // Competing request
9842 kGet,
[email protected]c871bce92010-07-15 21:51:149843 };
9844 MockRead reads[] = {
9845 // First round
9846 kServerChallenge,
9847 // Second round
9848 kServerChallenge,
9849 // Third round
[email protected]eca50e122010-09-11 14:03:309850 kServerChallenge,
9851 // Fourth round
[email protected]c871bce92010-07-15 21:51:149852 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:109853 // Competing response
9854 kSuccess,
[email protected]c871bce92010-07-15 21:51:149855 };
9856 StaticSocketDataProvider data_provider(reads, arraysize(reads),
9857 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:079858 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:149859
[email protected]7ef4cbbb2011-02-06 11:19:109860 const char* const kSocketGroup = "www.example.com:80";
9861
9862 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:149863 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:419864 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]c871bce92010-07-15 21:51:149865 if (rv == ERR_IO_PENDING)
9866 rv = callback.WaitForResult();
9867 EXPECT_EQ(OK, rv);
9868 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509869 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:149870 EXPECT_FALSE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:289871 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:149872
[email protected]7ef4cbbb2011-02-06 11:19:109873 // In between rounds, another request comes in for the same domain.
9874 // It should not be able to grab the TCP socket that trans has already
9875 // claimed.
9876 scoped_ptr<HttpTransaction> trans_compete(
[email protected]90499482013-06-01 00:39:509877 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419878 TestCompletionCallback callback_compete;
9879 rv = trans_compete->Start(
9880 &request, callback_compete.callback(), BoundNetLog());
[email protected]7ef4cbbb2011-02-06 11:19:109881 EXPECT_EQ(ERR_IO_PENDING, rv);
9882 // callback_compete.WaitForResult at this point would stall forever,
9883 // since the HttpNetworkTransaction does not release the request back to
9884 // the pool until after authentication completes.
9885
9886 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:149887 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:419888 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:149889 if (rv == ERR_IO_PENDING)
9890 rv = callback.WaitForResult();
9891 EXPECT_EQ(OK, rv);
9892 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509893 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:149894 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:289895 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:149896
[email protected]7ef4cbbb2011-02-06 11:19:109897 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:149898 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:419899 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:149900 if (rv == ERR_IO_PENDING)
9901 rv = callback.WaitForResult();
9902 EXPECT_EQ(OK, rv);
9903 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509904 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:149905 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:289906 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]eca50e122010-09-11 14:03:309907
[email protected]7ef4cbbb2011-02-06 11:19:109908 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:309909 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:419910 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:309911 if (rv == ERR_IO_PENDING)
9912 rv = callback.WaitForResult();
9913 EXPECT_EQ(OK, rv);
9914 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509915 ASSERT_TRUE(response != NULL);
[email protected]eca50e122010-09-11 14:03:309916 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:289917 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:109918
9919 // Read the body since the fourth round was successful. This will also
9920 // release the socket back to the pool.
9921 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
[email protected]90499482013-06-01 00:39:509922 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:109923 if (rv == ERR_IO_PENDING)
9924 rv = callback.WaitForResult();
9925 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:509926 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:109927 EXPECT_EQ(0, rv);
9928 // There are still 0 idle sockets, since the trans_compete transaction
9929 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:289930 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:109931
9932 // The competing request can now finish. Wait for the headers and then
9933 // read the body.
9934 rv = callback_compete.WaitForResult();
9935 EXPECT_EQ(OK, rv);
[email protected]90499482013-06-01 00:39:509936 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:109937 if (rv == ERR_IO_PENDING)
9938 rv = callback.WaitForResult();
9939 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:509940 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:109941 EXPECT_EQ(0, rv);
9942
9943 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:289944 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:149945}
9946
[email protected]65041fa2010-05-21 06:56:539947// This tests the case that a request is issued via http instead of spdy after
9948// npn is negotiated.
[email protected]23e482282013-06-14 16:08:029949TEST_P(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]d7599122014-05-24 03:37:239950 session_deps_.use_alternate_protocols = true;
9951 NextProtoVector next_protos;
[email protected]0ce3af82013-07-22 16:17:169952 next_protos.push_back(kProtoHTTP11);
[email protected]d7599122014-05-24 03:37:239953 session_deps_.next_protos = next_protos;
9954
[email protected]65041fa2010-05-21 06:56:539955 HttpRequestInfo request;
9956 request.method = "GET";
9957 request.url = GURL("https://www.google.com/");
9958 request.load_flags = 0;
9959
9960 MockWrite data_writes[] = {
9961 MockWrite("GET / HTTP/1.1\r\n"
9962 "Host: www.google.com\r\n"
9963 "Connection: keep-alive\r\n\r\n"),
9964 };
9965
[email protected]8a0fc822013-06-27 20:52:439966 std::string alternate_protocol_http_header =
9967 GetAlternateProtocolHttpHeader();
9968
[email protected]65041fa2010-05-21 06:56:539969 MockRead data_reads[] = {
9970 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439971 MockRead(alternate_protocol_http_header.c_str()),
[email protected]65041fa2010-05-21 06:56:539972 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069973 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:539974 };
9975
[email protected]8ddf8322012-02-23 18:08:069976 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]65041fa2010-05-21 06:56:539977 ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
9978 ssl.next_proto = "http/1.1";
[email protected]8e3c78cb2012-03-31 03:58:469979 ssl.protocol_negotiated = kProtoHTTP11;
[email protected]65041fa2010-05-21 06:56:539980
[email protected]bb88e1d32013-05-03 23:11:079981 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:539982
9983 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9984 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079985 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:539986
[email protected]49639fa2011-12-20 23:22:419987 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:539988
[email protected]bb88e1d32013-05-03 23:11:079989 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369990 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509991 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]65041fa2010-05-21 06:56:539992
[email protected]49639fa2011-12-20 23:22:419993 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]65041fa2010-05-21 06:56:539994
9995 EXPECT_EQ(ERR_IO_PENDING, rv);
9996 EXPECT_EQ(OK, callback.WaitForResult());
9997
9998 const HttpResponseInfo* response = trans->GetResponseInfo();
9999 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010000 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]65041fa2010-05-21 06:56:5310001 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10002
10003 std::string response_data;
10004 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10005 EXPECT_EQ("hello world", response_data);
10006
10007 EXPECT_FALSE(response->was_fetched_via_spdy);
10008 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]65041fa2010-05-21 06:56:5310009}
[email protected]26ef6582010-06-24 02:30:4710010
[email protected]23e482282013-06-14 16:08:0210011TEST_P(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:4710012 // Simulate the SSL handshake completing with an NPN negotiation
10013 // followed by an immediate server closing of the socket.
10014 // Fix crash: http://crbug.com/46369
[email protected]d7599122014-05-24 03:37:2310015 session_deps_.use_alternate_protocols = true;
10016 session_deps_.next_protos = SpdyNextProtos();
[email protected]26ef6582010-06-24 02:30:4710017
10018 HttpRequestInfo request;
10019 request.method = "GET";
10020 request.url = GURL("https://www.google.com/");
10021 request.load_flags = 0;
10022
[email protected]8ddf8322012-02-23 18:08:0610023 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210024 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710025 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4710026
[email protected]cdf8f7e72013-05-23 10:56:4610027 scoped_ptr<SpdyFrame> req(
10028 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]e7f75092010-07-01 22:39:1310029 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
[email protected]26ef6582010-06-24 02:30:4710030
10031 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0610032 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4710033 };
10034
[email protected]dd54bd82012-07-19 23:44:5710035 DelayedSocketData spdy_data(
10036 0, // don't wait in this case, immediate hangup.
10037 spdy_reads, arraysize(spdy_reads),
10038 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710039 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4710040
[email protected]49639fa2011-12-20 23:22:4110041 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4710042
[email protected]bb88e1d32013-05-03 23:11:0710043 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610044 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010045 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]26ef6582010-06-24 02:30:4710046
[email protected]49639fa2011-12-20 23:22:4110047 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]26ef6582010-06-24 02:30:4710048 EXPECT_EQ(ERR_IO_PENDING, rv);
10049 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult());
[email protected]26ef6582010-06-24 02:30:4710050}
[email protected]65d34382010-07-01 18:12:2610051
[email protected]795cbf82013-07-22 09:37:2710052// A subclass of HttpAuthHandlerMock that records the request URL when
10053// it gets it. This is needed since the auth handler may get destroyed
10054// before we get a chance to query it.
10055class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
10056 public:
10057 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
10058
dchengb03027d2014-10-21 12:00:2010059 ~UrlRecordingHttpAuthHandlerMock() override {}
[email protected]795cbf82013-07-22 09:37:2710060
10061 protected:
dchengb03027d2014-10-21 12:00:2010062 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
10063 const HttpRequestInfo* request,
10064 const CompletionCallback& callback,
10065 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2710066 *url_ = request->url;
10067 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
10068 credentials, request, callback, auth_token);
10069 }
10070
10071 private:
10072 GURL* url_;
10073};
10074
[email protected]23e482282013-06-14 16:08:0210075TEST_P(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) {
[email protected]f45c1ee2010-08-03 00:54:3010076 // This test ensures that the URL passed into the proxy is upgraded
10077 // to https when doing an Alternate Protocol upgrade.
[email protected]d7599122014-05-24 03:37:2310078 session_deps_.use_alternate_protocols = true;
10079 session_deps_.next_protos = SpdyNextProtos();
[email protected]f45c1ee2010-08-03 00:54:3010080
[email protected]bb88e1d32013-05-03 23:11:0710081 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:2010082 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
10083 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710084 session_deps_.net_log = &net_log;
[email protected]795cbf82013-07-22 09:37:2710085 GURL request_url;
10086 {
10087 HttpAuthHandlerMock::Factory* auth_factory =
10088 new HttpAuthHandlerMock::Factory();
10089 UrlRecordingHttpAuthHandlerMock* auth_handler =
10090 new UrlRecordingHttpAuthHandlerMock(&request_url);
10091 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
10092 auth_factory->set_do_init_from_challenge(true);
10093 session_deps_.http_auth_handler_factory.reset(auth_factory);
10094 }
[email protected]f45c1ee2010-08-03 00:54:3010095
10096 HttpRequestInfo request;
10097 request.method = "GET";
10098 request.url = GURL("http://www.google.com");
10099 request.load_flags = 0;
10100
10101 // First round goes unauthenticated through the proxy.
10102 MockWrite data_writes_1[] = {
10103 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
10104 "Host: www.google.com\r\n"
10105 "Proxy-Connection: keep-alive\r\n"
10106 "\r\n"),
10107 };
10108 MockRead data_reads_1[] = {
[email protected]8ddf8322012-02-23 18:08:0610109 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]f45c1ee2010-08-03 00:54:3010110 MockRead("HTTP/1.1 200 OK\r\n"
[email protected]448d4ca52012-03-04 04:12:2310111 "Alternate-Protocol: 443:npn-spdy/2\r\n"
[email protected]f45c1ee2010-08-03 00:54:3010112 "Proxy-Connection: close\r\n"
10113 "\r\n"),
10114 };
10115 StaticSocketDataProvider data_1(data_reads_1, arraysize(data_reads_1),
10116 data_writes_1, arraysize(data_writes_1));
10117
10118 // Second round tries to tunnel to www.google.com due to the
10119 // Alternate-Protocol announcement in the first round. It fails due
10120 // to a proxy authentication challenge.
[email protected]394816e92010-08-03 07:38:5910121 // After the failure, a tunnel is established to www.google.com using
10122 // Proxy-Authorization headers. There is then a SPDY request round.
10123 //
[email protected]fe3b7dc2012-02-03 19:52:0910124 // NOTE: Despite the "Proxy-Connection: Close", these are done on the
10125 // same MockTCPClientSocket since the underlying HttpNetworkClientSocket
10126 // does a Disconnect and Connect on the same socket, rather than trying
10127 // to obtain a new one.
10128 //
[email protected]394816e92010-08-03 07:38:5910129 // NOTE: Originally, the proxy response to the second CONNECT request
10130 // simply returned another 407 so the unit test could skip the SSL connection
10131 // establishment and SPDY framing issues. Alas, the
10132 // retry-http-when-alternate-protocol fails logic kicks in, which was more
[email protected]f45c1ee2010-08-03 00:54:3010133 // complicated to set up expectations for than the SPDY session.
[email protected]394816e92010-08-03 07:38:5910134
[email protected]cdf8f7e72013-05-23 10:56:4610135 scoped_ptr<SpdyFrame> req(
10136 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]23e482282013-06-14 16:08:0210137 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10138 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]f45c1ee2010-08-03 00:54:3010139
[email protected]394816e92010-08-03 07:38:5910140 MockWrite data_writes_2[] = {
10141 // First connection attempt without Proxy-Authorization.
10142 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
10143 "Host: www.google.com\r\n"
10144 "Proxy-Connection: keep-alive\r\n"
10145 "\r\n"),
10146
10147 // Second connection attempt with Proxy-Authorization.
[email protected]f45c1ee2010-08-03 00:54:3010148 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
10149 "Host: www.google.com\r\n"
10150 "Proxy-Connection: keep-alive\r\n"
10151 "Proxy-Authorization: auth_token\r\n"
10152 "\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3010153
[email protected]394816e92010-08-03 07:38:5910154 // SPDY request
10155 CreateMockWrite(*req),
[email protected]f45c1ee2010-08-03 00:54:3010156 };
[email protected]394816e92010-08-03 07:38:5910157 const char kRejectConnectResponse[] = ("HTTP/1.1 407 Unauthorized\r\n"
10158 "Proxy-Authenticate: Mock\r\n"
10159 "Proxy-Connection: close\r\n"
10160 "\r\n");
10161 const char kAcceptConnectResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
10162 MockRead data_reads_2[] = {
10163 // First connection attempt fails
[email protected]8ddf8322012-02-23 18:08:0610164 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ, 1),
10165 MockRead(ASYNC, kRejectConnectResponse,
[email protected]394816e92010-08-03 07:38:5910166 arraysize(kRejectConnectResponse) - 1, 1),
10167
10168 // Second connection attempt passes
[email protected]8ddf8322012-02-23 18:08:0610169 MockRead(ASYNC, kAcceptConnectResponse,
[email protected]fe3b7dc2012-02-03 19:52:0910170 arraysize(kAcceptConnectResponse) -1, 4),
[email protected]394816e92010-08-03 07:38:5910171
10172 // SPDY response
[email protected]fe3b7dc2012-02-03 19:52:0910173 CreateMockRead(*resp.get(), 6),
10174 CreateMockRead(*data.get(), 6),
[email protected]8ddf8322012-02-23 18:08:0610175 MockRead(ASYNC, 0, 0, 6),
[email protected]394816e92010-08-03 07:38:5910176 };
[email protected]dd54bd82012-07-19 23:44:5710177 OrderedSocketData data_2(
10178 data_reads_2, arraysize(data_reads_2),
10179 data_writes_2, arraysize(data_writes_2));
[email protected]f45c1ee2010-08-03 00:54:3010180
[email protected]8ddf8322012-02-23 18:08:0610181 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210182 ssl.SetNextProto(GetParam());
[email protected]f45c1ee2010-08-03 00:54:3010183
[email protected]d973e99a2012-02-17 21:02:3610184 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5510185 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
10186 NULL, 0, NULL, 0);
10187 hanging_non_alternate_protocol_socket.set_connect_data(
10188 never_finishing_connect);
10189
[email protected]bb88e1d32013-05-03 23:11:0710190 session_deps_.socket_factory->AddSocketDataProvider(&data_1);
10191 session_deps_.socket_factory->AddSocketDataProvider(&data_2);
10192 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10193 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5510194 &hanging_non_alternate_protocol_socket);
[email protected]bb88e1d32013-05-03 23:11:0710195 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f45c1ee2010-08-03 00:54:3010196
10197 // First round should work and provide the Alternate-Protocol state.
[email protected]49639fa2011-12-20 23:22:4110198 TestCompletionCallback callback_1;
[email protected]262eec82013-03-19 21:01:3610199 scoped_ptr<HttpTransaction> trans_1(
[email protected]90499482013-06-01 00:39:5010200 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110201 int rv = trans_1->Start(&request, callback_1.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:3010202 EXPECT_EQ(ERR_IO_PENDING, rv);
10203 EXPECT_EQ(OK, callback_1.WaitForResult());
10204
10205 // Second round should attempt a tunnel connect and get an auth challenge.
[email protected]49639fa2011-12-20 23:22:4110206 TestCompletionCallback callback_2;
[email protected]262eec82013-03-19 21:01:3610207 scoped_ptr<HttpTransaction> trans_2(
[email protected]90499482013-06-01 00:39:5010208 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110209 rv = trans_2->Start(&request, callback_2.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:3010210 EXPECT_EQ(ERR_IO_PENDING, rv);
10211 EXPECT_EQ(OK, callback_2.WaitForResult());
10212 const HttpResponseInfo* response = trans_2->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010213 ASSERT_TRUE(response != NULL);
[email protected]f45c1ee2010-08-03 00:54:3010214 ASSERT_FALSE(response->auth_challenge.get() == NULL);
10215
10216 // Restart with auth. Tunnel should work and response received.
[email protected]49639fa2011-12-20 23:22:4110217 TestCompletionCallback callback_3;
10218 rv = trans_2->RestartWithAuth(
10219 AuthCredentials(kFoo, kBar), callback_3.callback());
[email protected]f45c1ee2010-08-03 00:54:3010220 EXPECT_EQ(ERR_IO_PENDING, rv);
10221 EXPECT_EQ(OK, callback_3.WaitForResult());
10222
10223 // After all that work, these two lines (or actually, just the scheme) are
10224 // what this test is all about. Make sure it happens correctly.
[email protected]f45c1ee2010-08-03 00:54:3010225 EXPECT_EQ("https", request_url.scheme());
10226 EXPECT_EQ("www.google.com", request_url.host());
10227
[email protected]029c83b62013-01-24 05:28:2010228 LoadTimingInfo load_timing_info;
10229 EXPECT_TRUE(trans_2->GetLoadTimingInfo(&load_timing_info));
10230 TestLoadTimingNotReusedWithPac(load_timing_info,
10231 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]8e6441ca2010-08-19 05:56:3810232}
10233
10234// Test that if we cancel the transaction as the connection is completing, that
10235// everything tears down correctly.
[email protected]23e482282013-06-14 16:08:0210236TEST_P(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3810237 // Setup everything about the connection to complete synchronously, so that
10238 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
10239 // for is the callback from the HttpStreamRequest.
10240 // Then cancel the transaction.
10241 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3610242 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3810243 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0610244 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
10245 MockRead(SYNCHRONOUS, "hello world"),
10246 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3810247 };
10248
[email protected]8e6441ca2010-08-19 05:56:3810249 HttpRequestInfo request;
10250 request.method = "GET";
10251 request.url = GURL("http://www.google.com/");
10252 request.load_flags = 0;
10253
[email protected]bb88e1d32013-05-03 23:11:0710254 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]3fe8d2f82013-10-17 08:56:0710255 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:2710256 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4110257 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:2710258
[email protected]8e6441ca2010-08-19 05:56:3810259 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10260 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710261 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3810262
[email protected]49639fa2011-12-20 23:22:4110263 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3810264
[email protected]333bdf62012-06-08 22:57:2910265 CapturingBoundNetLog log;
[email protected]49639fa2011-12-20 23:22:4110266 int rv = trans->Start(&request, callback.callback(), log.bound());
[email protected]8e6441ca2010-08-19 05:56:3810267 EXPECT_EQ(ERR_IO_PENDING, rv);
10268 trans.reset(); // Cancel the transaction here.
10269
[email protected]2da659e2013-05-23 20:51:3410270 base::MessageLoop::current()->RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3010271}
10272
[email protected]ecab6e052014-05-16 14:58:1210273// Test that if a transaction is cancelled after receiving the headers, the
10274// stream is drained properly and added back to the socket pool. The main
10275// purpose of this test is to make sure that an HttpStreamParser can be read
10276// from after the HttpNetworkTransaction and the objects it owns have been
10277// deleted.
10278// See http://crbug.com/368418
10279TEST_P(HttpNetworkTransactionTest, CancelAfterHeaders) {
10280 MockRead data_reads[] = {
10281 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
10282 MockRead(ASYNC, "Content-Length: 2\r\n"),
10283 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
10284 MockRead(ASYNC, "1"),
10285 // 2 async reads are necessary to trigger a ReadResponseBody call after the
10286 // HttpNetworkTransaction has been deleted.
10287 MockRead(ASYNC, "2"),
10288 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
10289 };
10290 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10291 session_deps_.socket_factory->AddSocketDataProvider(&data);
10292
10293 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10294
10295 {
10296 HttpRequestInfo request;
10297 request.method = "GET";
10298 request.url = GURL("http://www.google.com/");
10299 request.load_flags = 0;
10300
dcheng48459ac22014-08-26 00:46:4110301 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1210302 TestCompletionCallback callback;
10303
10304 int rv = trans.Start(&request, callback.callback(), BoundNetLog());
10305 EXPECT_EQ(ERR_IO_PENDING, rv);
10306 callback.WaitForResult();
10307
10308 const HttpResponseInfo* response = trans.GetResponseInfo();
10309 ASSERT_TRUE(response != NULL);
10310 EXPECT_TRUE(response->headers.get() != NULL);
10311 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10312
10313 // The transaction and HttpRequestInfo are deleted.
10314 }
10315
10316 // Let the HttpResponseBodyDrainer drain the socket.
10317 base::MessageLoop::current()->RunUntilIdle();
10318
10319 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4110320 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1210321}
10322
[email protected]76a505b2010-08-25 06:23:0010323// Test a basic GET request through a proxy.
[email protected]23e482282013-06-14 16:08:0210324TEST_P(HttpNetworkTransactionTest, ProxyGet) {
[email protected]bb88e1d32013-05-03 23:11:0710325 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:2010326 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
[email protected]333bdf62012-06-08 22:57:2910327 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710328 session_deps_.net_log = log.bound().net_log();
10329 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0010330
[email protected]76a505b2010-08-25 06:23:0010331 HttpRequestInfo request;
10332 request.method = "GET";
10333 request.url = GURL("http://www.google.com/");
10334
10335 MockWrite data_writes1[] = {
10336 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
10337 "Host: www.google.com\r\n"
10338 "Proxy-Connection: keep-alive\r\n\r\n"),
10339 };
10340
10341 MockRead data_reads1[] = {
10342 MockRead("HTTP/1.1 200 OK\r\n"),
10343 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10344 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610345 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0010346 };
10347
10348 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10349 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710350 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0010351
[email protected]49639fa2011-12-20 23:22:4110352 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0010353
[email protected]262eec82013-03-19 21:01:3610354 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010355 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]597a1ab2014-06-26 08:12:2710356 BeforeProxyHeadersSentHandler proxy_headers_handler;
10357 trans->SetBeforeProxyHeadersSentCallback(
10358 base::Bind(&BeforeProxyHeadersSentHandler::OnBeforeProxyHeadersSent,
10359 base::Unretained(&proxy_headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5010360
[email protected]49639fa2011-12-20 23:22:4110361 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0010362 EXPECT_EQ(ERR_IO_PENDING, rv);
10363
10364 rv = callback1.WaitForResult();
10365 EXPECT_EQ(OK, rv);
10366
10367 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010368 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:0010369
10370 EXPECT_TRUE(response->headers->IsKeepAlive());
10371 EXPECT_EQ(200, response->headers->response_code());
10372 EXPECT_EQ(100, response->headers->GetContentLength());
10373 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]d8fc4722014-06-13 13:17:1510374 EXPECT_TRUE(
10375 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
[email protected]597a1ab2014-06-26 08:12:2710376 EXPECT_TRUE(proxy_headers_handler.observed_before_proxy_headers_sent());
10377 EXPECT_EQ("myproxy:70", proxy_headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0010378 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2010379
10380 LoadTimingInfo load_timing_info;
10381 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10382 TestLoadTimingNotReusedWithPac(load_timing_info,
10383 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0010384}
10385
10386// Test a basic HTTPS GET request through a proxy.
[email protected]23e482282013-06-14 16:08:0210387TEST_P(HttpNetworkTransactionTest, ProxyTunnelGet) {
[email protected]bb88e1d32013-05-03 23:11:0710388 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:2010389 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
[email protected]333bdf62012-06-08 22:57:2910390 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710391 session_deps_.net_log = log.bound().net_log();
10392 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0010393
[email protected]76a505b2010-08-25 06:23:0010394 HttpRequestInfo request;
10395 request.method = "GET";
10396 request.url = GURL("https://www.google.com/");
10397
10398 // Since we have proxy, should try to establish tunnel.
10399 MockWrite data_writes1[] = {
10400 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
10401 "Host: www.google.com\r\n"
10402 "Proxy-Connection: keep-alive\r\n\r\n"),
10403
10404 MockWrite("GET / HTTP/1.1\r\n"
10405 "Host: www.google.com\r\n"
10406 "Connection: keep-alive\r\n\r\n"),
10407 };
10408
10409 MockRead data_reads1[] = {
10410 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
10411
10412 MockRead("HTTP/1.1 200 OK\r\n"),
10413 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10414 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610415 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0010416 };
10417
10418 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10419 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710420 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0610421 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710422 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0010423
[email protected]49639fa2011-12-20 23:22:4110424 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0010425
[email protected]262eec82013-03-19 21:01:3610426 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010427 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5010428
[email protected]49639fa2011-12-20 23:22:4110429 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0010430 EXPECT_EQ(ERR_IO_PENDING, rv);
10431
10432 rv = callback1.WaitForResult();
10433 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:5710434 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:4010435 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0010436 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010437 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0010438 NetLog::PHASE_NONE);
10439 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010440 entries, pos,
[email protected]76a505b2010-08-25 06:23:0010441 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
10442 NetLog::PHASE_NONE);
10443
10444 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010445 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:0010446
10447 EXPECT_TRUE(response->headers->IsKeepAlive());
10448 EXPECT_EQ(200, response->headers->response_code());
10449 EXPECT_EQ(100, response->headers->GetContentLength());
10450 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10451 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]d8fc4722014-06-13 13:17:1510452 EXPECT_TRUE(
10453 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
[email protected]029c83b62013-01-24 05:28:2010454
10455 LoadTimingInfo load_timing_info;
10456 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10457 TestLoadTimingNotReusedWithPac(load_timing_info,
10458 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0010459}
10460
10461// Test a basic HTTPS GET request through a proxy, but the server hangs up
10462// while establishing the tunnel.
[email protected]23e482282013-06-14 16:08:0210463TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
[email protected]bb88e1d32013-05-03 23:11:0710464 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]333bdf62012-06-08 22:57:2910465 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710466 session_deps_.net_log = log.bound().net_log();
10467 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0010468
[email protected]76a505b2010-08-25 06:23:0010469 HttpRequestInfo request;
10470 request.method = "GET";
10471 request.url = GURL("https://www.google.com/");
10472
10473 // Since we have proxy, should try to establish tunnel.
10474 MockWrite data_writes1[] = {
10475 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
10476 "Host: www.google.com\r\n"
10477 "Proxy-Connection: keep-alive\r\n\r\n"),
10478
10479 MockWrite("GET / HTTP/1.1\r\n"
10480 "Host: www.google.com\r\n"
10481 "Connection: keep-alive\r\n\r\n"),
10482 };
10483
10484 MockRead data_reads1[] = {
[email protected]8ddf8322012-02-23 18:08:0610485 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:0010486 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610487 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0010488 };
10489
10490 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10491 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710492 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0610493 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710494 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0010495
[email protected]49639fa2011-12-20 23:22:4110496 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0010497
[email protected]262eec82013-03-19 21:01:3610498 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010499 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5010500
[email protected]49639fa2011-12-20 23:22:4110501 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0010502 EXPECT_EQ(ERR_IO_PENDING, rv);
10503
10504 rv = callback1.WaitForResult();
10505 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
[email protected]f3da152d2012-06-02 01:00:5710506 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:4010507 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0010508 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010509 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0010510 NetLog::PHASE_NONE);
10511 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010512 entries, pos,
[email protected]76a505b2010-08-25 06:23:0010513 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
10514 NetLog::PHASE_NONE);
10515}
10516
[email protected]749eefa82010-09-13 22:14:0310517// Test for crbug.com/55424.
[email protected]23e482282013-06-14 16:08:0210518TEST_P(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
[email protected]cdf8f7e72013-05-23 10:56:4610519 scoped_ptr<SpdyFrame> req(
10520 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
[email protected]749eefa82010-09-13 22:14:0310521 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
10522
[email protected]23e482282013-06-14 16:08:0210523 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10524 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0310525 MockRead spdy_reads[] = {
10526 CreateMockRead(*resp),
10527 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:0610528 MockRead(ASYNC, 0, 0),
[email protected]749eefa82010-09-13 22:14:0310529 };
10530
[email protected]dd54bd82012-07-19 23:44:5710531 DelayedSocketData spdy_data(
10532 1, // wait for one write to finish before reading.
10533 spdy_reads, arraysize(spdy_reads),
10534 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710535 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0310536
[email protected]8ddf8322012-02-23 18:08:0610537 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210538 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710539 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0310540
[email protected]bb88e1d32013-05-03 23:11:0710541 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0310542
10543 // Set up an initial SpdySession in the pool to reuse.
[email protected]02b0c342010-09-25 21:09:3810544 HostPortPair host_port_pair("www.google.com", 443);
[email protected]e6d017652013-05-17 18:01:4010545 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5310546 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2710547 base::WeakPtr<SpdySession> spdy_session =
[email protected]41d64e82013-07-03 22:44:2610548 CreateInsecureSpdySession(session, key, BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0310549
10550 HttpRequestInfo request;
10551 request.method = "GET";
10552 request.url = GURL("https://www.google.com/");
10553 request.load_flags = 0;
10554
10555 // This is the important line that marks this as a preconnect.
10556 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
10557
[email protected]262eec82013-03-19 21:01:3610558 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010559 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]749eefa82010-09-13 22:14:0310560
[email protected]41d64e82013-07-03 22:44:2610561 TestCompletionCallback callback;
[email protected]49639fa2011-12-20 23:22:4110562 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0310563 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110564 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]749eefa82010-09-13 22:14:0310565}
10566
[email protected]73b8dd222010-11-11 19:55:2410567// Given a net error, cause that error to be returned from the first Write()
10568// call and verify that the HttpTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0210569void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0710570 int error, IoMode mode) {
[email protected]cb9bf6ca2011-01-28 13:15:2710571 net::HttpRequestInfo request_info;
10572 request_info.url = GURL("https://www.example.com/");
10573 request_info.method = "GET";
10574 request_info.load_flags = net::LOAD_NORMAL;
10575
[email protected]8ddf8322012-02-23 18:08:0610576 SSLSocketDataProvider ssl_data(mode, OK);
[email protected]73b8dd222010-11-11 19:55:2410577 net::MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:0610578 net::MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2410579 };
10580 net::StaticSocketDataProvider data(NULL, 0,
10581 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0710582 session_deps_.socket_factory->AddSocketDataProvider(&data);
10583 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2410584
[email protected]bb88e1d32013-05-03 23:11:0710585 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610586 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010587 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]73b8dd222010-11-11 19:55:2410588
[email protected]49639fa2011-12-20 23:22:4110589 TestCompletionCallback callback;
10590 int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
[email protected]73b8dd222010-11-11 19:55:2410591 if (rv == net::ERR_IO_PENDING)
10592 rv = callback.WaitForResult();
10593 ASSERT_EQ(error, rv);
10594}
10595
[email protected]23e482282013-06-14 16:08:0210596TEST_P(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2410597 // Just check a grab bag of cert errors.
10598 static const int kErrors[] = {
10599 ERR_CERT_COMMON_NAME_INVALID,
10600 ERR_CERT_AUTHORITY_INVALID,
10601 ERR_CERT_DATE_INVALID,
10602 };
10603 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0610604 CheckErrorIsPassedBack(kErrors[i], ASYNC);
10605 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2410606 }
10607}
10608
[email protected]bd0b6772011-01-11 19:59:3010609// Ensure that a client certificate is removed from the SSL client auth
10610// cache when:
10611// 1) No proxy is involved.
10612// 2) TLS False Start is disabled.
10613// 3) The initial TLS handshake requests a client certificate.
10614// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0210615TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310616 ClientAuthCertCache_Direct_NoFalseStart) {
[email protected]cb9bf6ca2011-01-28 13:15:2710617 net::HttpRequestInfo request_info;
10618 request_info.url = GURL("https://www.example.com/");
10619 request_info.method = "GET";
10620 request_info.load_flags = net::LOAD_NORMAL;
10621
[email protected]bd0b6772011-01-11 19:59:3010622 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4110623 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3010624
10625 // [ssl_]data1 contains the data for the first SSL handshake. When a
10626 // CertificateRequest is received for the first time, the handshake will
10627 // be aborted to allow the caller to provide a certificate.
[email protected]8ddf8322012-02-23 18:08:0610628 SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3010629 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710630 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
[email protected]bd0b6772011-01-11 19:59:3010631 net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710632 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3010633
10634 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
10635 // False Start is not being used, the result of the SSL handshake will be
10636 // returned as part of the SSLClientSocket::Connect() call. This test
10637 // matches the result of a server sending a handshake_failure alert,
10638 // rather than a Finished message, because it requires a client
10639 // certificate and none was supplied.
[email protected]8ddf8322012-02-23 18:08:0610640 SSLSocketDataProvider ssl_data2(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3010641 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710642 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
[email protected]bd0b6772011-01-11 19:59:3010643 net::StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710644 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3010645
10646 // [ssl_]data3 contains the data for the third SSL handshake. When a
10647 // connection to a server fails during an SSL handshake,
[email protected]80c75f682012-05-26 16:22:1710648 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
10649 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3010650 // of the HttpNetworkTransaction. Because this test failure is due to
10651 // requiring a client certificate, this fallback handshake should also
10652 // fail.
[email protected]8ddf8322012-02-23 18:08:0610653 SSLSocketDataProvider ssl_data3(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3010654 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710655 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
[email protected]bd0b6772011-01-11 19:59:3010656 net::StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710657 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3010658
[email protected]80c75f682012-05-26 16:22:1710659 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
10660 // connection to a server fails during an SSL handshake,
10661 // HttpNetworkTransaction will attempt to fallback to SSLv3 if the previous
10662 // connection was attempted with TLSv1. This is transparent to the caller
10663 // of the HttpNetworkTransaction. Because this test failure is due to
10664 // requiring a client certificate, this fallback handshake should also
10665 // fail.
10666 SSLSocketDataProvider ssl_data4(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
10667 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710668 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
[email protected]80c75f682012-05-26 16:22:1710669 net::StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710670 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1710671
[email protected]7799de12013-05-30 05:52:5110672 // Need one more if TLSv1.2 is enabled.
10673 SSLSocketDataProvider ssl_data5(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
10674 ssl_data5.cert_request_info = cert_request.get();
10675 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
10676 net::StaticSocketDataProvider data5(NULL, 0, NULL, 0);
10677 session_deps_.socket_factory->AddSocketDataProvider(&data5);
10678
[email protected]bb88e1d32013-05-03 23:11:0710679 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610680 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010681 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3010682
[email protected]bd0b6772011-01-11 19:59:3010683 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4110684 TestCompletionCallback callback;
10685 int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
[email protected]bd0b6772011-01-11 19:59:3010686 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10687
10688 // Complete the SSL handshake, which should abort due to requiring a
10689 // client certificate.
10690 rv = callback.WaitForResult();
10691 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
10692
10693 // Indicate that no certificate should be supplied. From the perspective
10694 // of SSLClientCertCache, NULL is just as meaningful as a real
10695 // certificate, so this is the same as supply a
10696 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4110697 rv = trans->RestartWithCertificate(NULL, callback.callback());
[email protected]bd0b6772011-01-11 19:59:3010698 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10699
10700 // Ensure the certificate was added to the client auth cache before
10701 // allowing the connection to continue restarting.
10702 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4110703 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
10704 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3010705 ASSERT_EQ(NULL, client_cert.get());
10706
10707 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1710708 // then consume ssl_data3 and ssl_data4, both of which should also fail.
10709 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3010710 rv = callback.WaitForResult();
10711 ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
10712
10713 // Ensure that the client certificate is removed from the cache on a
10714 // handshake failure.
[email protected]791879c2013-12-17 07:22:4110715 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
10716 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3010717}
10718
10719// Ensure that a client certificate is removed from the SSL client auth
10720// cache when:
10721// 1) No proxy is involved.
10722// 2) TLS False Start is enabled.
10723// 3) The initial TLS handshake requests a client certificate.
10724// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0210725TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310726 ClientAuthCertCache_Direct_FalseStart) {
[email protected]cb9bf6ca2011-01-28 13:15:2710727 net::HttpRequestInfo request_info;
10728 request_info.url = GURL("https://www.example.com/");
10729 request_info.method = "GET";
10730 request_info.load_flags = net::LOAD_NORMAL;
10731
[email protected]bd0b6772011-01-11 19:59:3010732 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4110733 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3010734
10735 // When TLS False Start is used, SSLClientSocket::Connect() calls will
10736 // return successfully after reading up to the peer's Certificate message.
10737 // This is to allow the caller to call SSLClientSocket::Write(), which can
10738 // enqueue application data to be sent in the same packet as the
10739 // ChangeCipherSpec and Finished messages.
10740 // The actual handshake will be finished when SSLClientSocket::Read() is
10741 // called, which expects to process the peer's ChangeCipherSpec and
10742 // Finished messages. If there was an error negotiating with the peer,
10743 // such as due to the peer requiring a client certificate when none was
10744 // supplied, the alert sent by the peer won't be processed until Read() is
10745 // called.
10746
10747 // Like the non-False Start case, when a client certificate is requested by
10748 // the peer, the handshake is aborted during the Connect() call.
10749 // [ssl_]data1 represents the initial SSL handshake with the peer.
[email protected]8ddf8322012-02-23 18:08:0610750 SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3010751 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710752 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
[email protected]bd0b6772011-01-11 19:59:3010753 net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710754 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3010755
10756 // When a client certificate is supplied, Connect() will not be aborted
10757 // when the peer requests the certificate. Instead, the handshake will
10758 // artificially succeed, allowing the caller to write the HTTP request to
10759 // the socket. The handshake messages are not processed until Read() is
10760 // called, which then detects that the handshake was aborted, due to the
10761 // peer sending a handshake_failure because it requires a client
10762 // certificate.
[email protected]8ddf8322012-02-23 18:08:0610763 SSLSocketDataProvider ssl_data2(ASYNC, net::OK);
[email protected]bd0b6772011-01-11 19:59:3010764 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710765 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
[email protected]bd0b6772011-01-11 19:59:3010766 net::MockRead data2_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0610767 net::MockRead(ASYNC /* async */, net::ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3010768 };
10769 net::StaticSocketDataProvider data2(
10770 data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710771 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3010772
10773 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1710774 // the data for the SSL handshake once the TLSv1.1 connection falls back to
10775 // TLSv1. It has the same behaviour as [ssl_]data2.
[email protected]8ddf8322012-02-23 18:08:0610776 SSLSocketDataProvider ssl_data3(ASYNC, net::OK);
[email protected]bd0b6772011-01-11 19:59:3010777 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710778 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
[email protected]bd0b6772011-01-11 19:59:3010779 net::StaticSocketDataProvider data3(
10780 data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710781 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3010782
[email protected]80c75f682012-05-26 16:22:1710783 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
10784 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
10785 SSLSocketDataProvider ssl_data4(ASYNC, net::OK);
10786 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710787 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
[email protected]80c75f682012-05-26 16:22:1710788 net::StaticSocketDataProvider data4(
10789 data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710790 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1710791
[email protected]7799de12013-05-30 05:52:5110792 // Need one more if TLSv1.2 is enabled.
10793 SSLSocketDataProvider ssl_data5(ASYNC, net::OK);
10794 ssl_data5.cert_request_info = cert_request.get();
10795 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
10796 net::StaticSocketDataProvider data5(
10797 data2_reads, arraysize(data2_reads), NULL, 0);
10798 session_deps_.socket_factory->AddSocketDataProvider(&data5);
10799
[email protected]bb88e1d32013-05-03 23:11:0710800 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610801 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010802 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3010803
[email protected]bd0b6772011-01-11 19:59:3010804 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4110805 TestCompletionCallback callback;
10806 int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
[email protected]bd0b6772011-01-11 19:59:3010807 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10808
10809 // Complete the SSL handshake, which should abort due to requiring a
10810 // client certificate.
10811 rv = callback.WaitForResult();
10812 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
10813
10814 // Indicate that no certificate should be supplied. From the perspective
10815 // of SSLClientCertCache, NULL is just as meaningful as a real
10816 // certificate, so this is the same as supply a
10817 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4110818 rv = trans->RestartWithCertificate(NULL, callback.callback());
[email protected]bd0b6772011-01-11 19:59:3010819 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10820
10821 // Ensure the certificate was added to the client auth cache before
10822 // allowing the connection to continue restarting.
10823 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4110824 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
10825 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3010826 ASSERT_EQ(NULL, client_cert.get());
10827
[email protected]bd0b6772011-01-11 19:59:3010828 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1710829 // then consume ssl_data3 and ssl_data4, both of which should also fail.
10830 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3010831 rv = callback.WaitForResult();
10832 ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
10833
10834 // Ensure that the client certificate is removed from the cache on a
10835 // handshake failure.
[email protected]791879c2013-12-17 07:22:4110836 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
10837 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3010838}
10839
[email protected]8c405132011-01-11 22:03:1810840// Ensure that a client certificate is removed from the SSL client auth
10841// cache when:
10842// 1) An HTTPS proxy is involved.
10843// 3) The HTTPS proxy requests a client certificate.
10844// 4) The client supplies an invalid/unacceptable certificate for the
10845// proxy.
10846// The test is repeated twice, first for connecting to an HTTPS endpoint,
10847// then for connecting to an HTTP endpoint.
[email protected]23e482282013-06-14 16:08:0210848TEST_P(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
[email protected]bb88e1d32013-05-03 23:11:0710849 session_deps_.proxy_service.reset(
[email protected]8c405132011-01-11 22:03:1810850 ProxyService::CreateFixed("https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:2910851 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710852 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1810853
10854 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4110855 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1810856
10857 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
10858 // [ssl_]data[1-3]. Rather than represending the endpoint
10859 // (www.example.com:443), they represent failures with the HTTPS proxy
10860 // (proxy:70).
[email protected]8ddf8322012-02-23 18:08:0610861 SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1810862 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710863 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
[email protected]8c405132011-01-11 22:03:1810864 net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710865 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1810866
[email protected]8ddf8322012-02-23 18:08:0610867 SSLSocketDataProvider ssl_data2(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1810868 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710869 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
[email protected]8c405132011-01-11 22:03:1810870 net::StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710871 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1810872
[email protected]80c75f682012-05-26 16:22:1710873 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
10874#if 0
[email protected]8ddf8322012-02-23 18:08:0610875 SSLSocketDataProvider ssl_data3(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1810876 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710877 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
[email protected]8c405132011-01-11 22:03:1810878 net::StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710879 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1710880#endif
[email protected]8c405132011-01-11 22:03:1810881
10882 net::HttpRequestInfo requests[2];
10883 requests[0].url = GURL("https://www.example.com/");
10884 requests[0].method = "GET";
10885 requests[0].load_flags = net::LOAD_NORMAL;
10886
10887 requests[1].url = GURL("http://www.example.com/");
10888 requests[1].method = "GET";
10889 requests[1].load_flags = net::LOAD_NORMAL;
10890
10891 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0710892 session_deps_.socket_factory->ResetNextMockIndexes();
10893 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c405132011-01-11 22:03:1810894 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5010895 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c405132011-01-11 22:03:1810896
10897 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4110898 TestCompletionCallback callback;
10899 int rv = trans->Start(
10900 &requests[i], callback.callback(), net::BoundNetLog());
[email protected]8c405132011-01-11 22:03:1810901 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10902
10903 // Complete the SSL handshake, which should abort due to requiring a
10904 // client certificate.
10905 rv = callback.WaitForResult();
10906 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
10907
10908 // Indicate that no certificate should be supplied. From the perspective
10909 // of SSLClientCertCache, NULL is just as meaningful as a real
10910 // certificate, so this is the same as supply a
10911 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4110912 rv = trans->RestartWithCertificate(NULL, callback.callback());
[email protected]8c405132011-01-11 22:03:1810913 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10914
10915 // Ensure the certificate was added to the client auth cache before
10916 // allowing the connection to continue restarting.
10917 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4110918 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
10919 HostPortPair("proxy", 70), &client_cert));
[email protected]8c405132011-01-11 22:03:1810920 ASSERT_EQ(NULL, client_cert.get());
10921 // Ensure the certificate was NOT cached for the endpoint. This only
10922 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4110923 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
10924 HostPortPair("www.example.com", 443), &client_cert));
[email protected]8c405132011-01-11 22:03:1810925
10926 // Restart the handshake. This will consume ssl_data2, which fails, and
10927 // then consume ssl_data3, which should also fail. The result code is
10928 // checked against what ssl_data3 should return.
10929 rv = callback.WaitForResult();
10930 ASSERT_EQ(net::ERR_PROXY_CONNECTION_FAILED, rv);
10931
10932 // Now that the new handshake has failed, ensure that the client
10933 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4110934 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
10935 HostPortPair("proxy", 70), &client_cert));
10936 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
10937 HostPortPair("www.example.com", 443), &client_cert));
[email protected]8c405132011-01-11 22:03:1810938 }
10939}
10940
[email protected]23e482282013-06-14 16:08:0210941// Unlike TEST/TEST_F, which are macros that expand to further macros,
10942// TEST_P is a macro that expands directly to code that stringizes the
10943// arguments. As a result, macros passed as parameters (such as prefix
10944// or test_case_name) will not be expanded by the preprocessor. To
10945// work around this, indirect the macro for TEST_P, so that the
10946// pre-processor will expand macros such as MAYBE_test_name before
10947// instantiating the test.
10948#define WRAPPED_TEST_P(test_case_name, test_name) \
10949 TEST_P(test_case_name, test_name)
10950
[email protected]45b170822012-05-04 21:18:1410951// Times out on Win7 dbg(2) bot. http://crbug.com/124776
10952#if defined(OS_WIN)
10953#define MAYBE_UseIPConnectionPooling DISABLED_UseIPConnectionPooling
10954#else
10955#define MAYBE_UseIPConnectionPooling UseIPConnectionPooling
10956#endif
[email protected]23e482282013-06-14 16:08:0210957WRAPPED_TEST_P(HttpNetworkTransactionTest, MAYBE_UseIPConnectionPooling) {
[email protected]d7599122014-05-24 03:37:2310958 session_deps_.use_alternate_protocols = true;
10959 session_deps_.next_protos = SpdyNextProtos();
[email protected]e3ceb682011-06-28 23:55:4610960
10961 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0710962 session_deps_.host_resolver.reset(new MockCachingHostResolver());
10963 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2610964 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
10965 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4610966
[email protected]8ddf8322012-02-23 18:08:0610967 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210968 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710969 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4610970
[email protected]cdf8f7e72013-05-23 10:56:4610971 scoped_ptr<SpdyFrame> host1_req(
10972 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
10973 scoped_ptr<SpdyFrame> host2_req(
10974 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4610975 MockWrite spdy_writes[] = {
10976 CreateMockWrite(*host1_req, 1),
10977 CreateMockWrite(*host2_req, 4),
10978 };
[email protected]23e482282013-06-14 16:08:0210979 scoped_ptr<SpdyFrame> host1_resp(
10980 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10981 scoped_ptr<SpdyFrame> host1_resp_body(
10982 spdy_util_.ConstructSpdyBodyFrame(1, true));
10983 scoped_ptr<SpdyFrame> host2_resp(
10984 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
10985 scoped_ptr<SpdyFrame> host2_resp_body(
10986 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4610987 MockRead spdy_reads[] = {
10988 CreateMockRead(*host1_resp, 2),
10989 CreateMockRead(*host1_resp_body, 3),
10990 CreateMockRead(*host2_resp, 5),
10991 CreateMockRead(*host2_resp_body, 6),
[email protected]8ddf8322012-02-23 18:08:0610992 MockRead(ASYNC, 0, 7),
[email protected]e3ceb682011-06-28 23:55:4610993 };
10994
[email protected]d2b5f092012-06-08 23:55:0210995 IPAddressNumber ip;
10996 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
10997 IPEndPoint peer_addr = IPEndPoint(ip, 443);
10998 MockConnect connect(ASYNC, OK, peer_addr);
[email protected]dd54bd82012-07-19 23:44:5710999 OrderedSocketData spdy_data(
11000 connect,
11001 spdy_reads, arraysize(spdy_reads),
11002 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711003 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4611004
[email protected]aa22b242011-11-16 18:58:2911005 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4611006 HttpRequestInfo request1;
11007 request1.method = "GET";
11008 request1.url = GURL("https://www.google.com/");
11009 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011010 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611011
[email protected]49639fa2011-12-20 23:22:4111012 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611013 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111014 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611015
11016 const HttpResponseInfo* response = trans1.GetResponseInfo();
11017 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011018 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611019 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11020
11021 std::string response_data;
11022 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
11023 EXPECT_EQ("hello!", response_data);
11024
11025 // Preload www.gmail.com into HostCache.
11026 HostPortPair host_port("www.gmail.com", 443);
[email protected]5109c1952013-08-20 18:44:1011027 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4611028 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1011029 rv = session_deps_.host_resolver->Resolve(resolve_info,
11030 DEFAULT_PRIORITY,
11031 &ignored,
11032 callback.callback(),
11033 NULL,
11034 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4711035 EXPECT_EQ(ERR_IO_PENDING, rv);
11036 rv = callback.WaitForResult();
11037 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4611038
11039 HttpRequestInfo request2;
11040 request2.method = "GET";
11041 request2.url = GURL("https://www.gmail.com/");
11042 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011043 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611044
[email protected]49639fa2011-12-20 23:22:4111045 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611046 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111047 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611048
11049 response = trans2.GetResponseInfo();
11050 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011051 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611052 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11053 EXPECT_TRUE(response->was_fetched_via_spdy);
11054 EXPECT_TRUE(response->was_npn_negotiated);
11055 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
11056 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4611057}
[email protected]45b170822012-05-04 21:18:1411058#undef MAYBE_UseIPConnectionPooling
[email protected]e3ceb682011-06-28 23:55:4611059
[email protected]23e482282013-06-14 16:08:0211060TEST_P(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d7599122014-05-24 03:37:2311061 session_deps_.use_alternate_protocols = true;
11062 session_deps_.next_protos = SpdyNextProtos();
[email protected]d2b5f092012-06-08 23:55:0211063
11064 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0711065 session_deps_.host_resolver.reset(new MockCachingHostResolver());
11066 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0211067 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
11068 pool_peer.DisableDomainAuthenticationVerification();
11069
11070 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211071 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711072 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]d2b5f092012-06-08 23:55:0211073
[email protected]cdf8f7e72013-05-23 10:56:4611074 scoped_ptr<SpdyFrame> host1_req(
11075 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
11076 scoped_ptr<SpdyFrame> host2_req(
11077 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0211078 MockWrite spdy_writes[] = {
11079 CreateMockWrite(*host1_req, 1),
11080 CreateMockWrite(*host2_req, 4),
11081 };
[email protected]23e482282013-06-14 16:08:0211082 scoped_ptr<SpdyFrame> host1_resp(
11083 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11084 scoped_ptr<SpdyFrame> host1_resp_body(
11085 spdy_util_.ConstructSpdyBodyFrame(1, true));
11086 scoped_ptr<SpdyFrame> host2_resp(
11087 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11088 scoped_ptr<SpdyFrame> host2_resp_body(
11089 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0211090 MockRead spdy_reads[] = {
11091 CreateMockRead(*host1_resp, 2),
11092 CreateMockRead(*host1_resp_body, 3),
11093 CreateMockRead(*host2_resp, 5),
11094 CreateMockRead(*host2_resp_body, 6),
11095 MockRead(ASYNC, 0, 7),
11096 };
11097
11098 IPAddressNumber ip;
11099 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
11100 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11101 MockConnect connect(ASYNC, OK, peer_addr);
[email protected]dd54bd82012-07-19 23:44:5711102 OrderedSocketData spdy_data(
11103 connect,
11104 spdy_reads, arraysize(spdy_reads),
11105 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711106 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0211107
11108 TestCompletionCallback callback;
11109 HttpRequestInfo request1;
11110 request1.method = "GET";
11111 request1.url = GURL("https://www.google.com/");
11112 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011113 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0211114
11115 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
11116 EXPECT_EQ(ERR_IO_PENDING, rv);
11117 EXPECT_EQ(OK, callback.WaitForResult());
11118
11119 const HttpResponseInfo* response = trans1.GetResponseInfo();
11120 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011121 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d2b5f092012-06-08 23:55:0211122 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11123
11124 std::string response_data;
11125 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
11126 EXPECT_EQ("hello!", response_data);
11127
11128 HttpRequestInfo request2;
11129 request2.method = "GET";
11130 request2.url = GURL("https://www.gmail.com/");
11131 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011132 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0211133
11134 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
11135 EXPECT_EQ(ERR_IO_PENDING, rv);
11136 EXPECT_EQ(OK, callback.WaitForResult());
11137
11138 response = trans2.GetResponseInfo();
11139 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011140 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d2b5f092012-06-08 23:55:0211141 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11142 EXPECT_TRUE(response->was_fetched_via_spdy);
11143 EXPECT_TRUE(response->was_npn_negotiated);
11144 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
11145 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0211146}
11147
[email protected]e3ceb682011-06-28 23:55:4611148class OneTimeCachingHostResolver : public net::HostResolver {
11149 public:
11150 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
11151 : host_port_(host_port) {}
dchengb03027d2014-10-21 12:00:2011152 ~OneTimeCachingHostResolver() override {}
[email protected]e3ceb682011-06-28 23:55:4611153
11154 RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); }
11155
11156 // HostResolver methods:
dchengb03027d2014-10-21 12:00:2011157 int Resolve(const RequestInfo& info,
11158 RequestPriority priority,
11159 AddressList* addresses,
11160 const CompletionCallback& callback,
11161 RequestHandle* out_req,
11162 const BoundNetLog& net_log) override {
[email protected]95a214c2011-08-04 21:50:4011163 return host_resolver_.Resolve(
[email protected]5109c1952013-08-20 18:44:1011164 info, priority, addresses, callback, out_req, net_log);
[email protected]95a214c2011-08-04 21:50:4011165 }
11166
dchengb03027d2014-10-21 12:00:2011167 int ResolveFromCache(const RequestInfo& info,
11168 AddressList* addresses,
11169 const BoundNetLog& net_log) override {
[email protected]95a214c2011-08-04 21:50:4011170 int rv = host_resolver_.ResolveFromCache(info, addresses, net_log);
11171 if (rv == OK && info.host_port_pair().Equals(host_port_))
[email protected]98e1cd012011-11-08 15:33:0911172 host_resolver_.GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4611173 return rv;
11174 }
11175
dchengb03027d2014-10-21 12:00:2011176 void CancelRequest(RequestHandle req) override {
[email protected]e3ceb682011-06-28 23:55:4611177 host_resolver_.CancelRequest(req);
11178 }
11179
[email protected]46da33be2011-07-19 21:58:0411180 MockCachingHostResolver* GetMockHostResolver() {
11181 return &host_resolver_;
11182 }
11183
[email protected]e3ceb682011-06-28 23:55:4611184 private:
11185 MockCachingHostResolver host_resolver_;
11186 const HostPortPair host_port_;
11187};
11188
[email protected]45b170822012-05-04 21:18:1411189// Times out on Win7 dbg(2) bot. http://crbug.com/124776
11190#if defined(OS_WIN)
[email protected]bb88e1d32013-05-03 23:11:0711191#define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \
11192 DISABLED_UseIPConnectionPoolingWithHostCacheExpiration
[email protected]45b170822012-05-04 21:18:1411193#else
[email protected]bb88e1d32013-05-03 23:11:0711194#define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \
11195 UseIPConnectionPoolingWithHostCacheExpiration
[email protected]45b170822012-05-04 21:18:1411196#endif
[email protected]23e482282013-06-14 16:08:0211197WRAPPED_TEST_P(HttpNetworkTransactionTest,
11198 MAYBE_UseIPConnectionPoolingWithHostCacheExpiration) {
[email protected]23e482282013-06-14 16:08:0211199// Times out on Win7 dbg(2) bot. http://crbug.com/124776 . (MAYBE_
11200// prefix doesn't work with parametrized tests).
11201#if defined(OS_WIN)
11202 return;
[email protected]88c7b4be2014-03-19 23:04:0111203#else
[email protected]d7599122014-05-24 03:37:2311204 session_deps_.use_alternate_protocols = true;
11205 session_deps_.next_protos = SpdyNextProtos();
[email protected]e3ceb682011-06-28 23:55:4611206
11207 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
[email protected]e3ceb682011-06-28 23:55:4611208 OneTimeCachingHostResolver host_resolver(HostPortPair("www.gmail.com", 443));
[email protected]c6bf8152012-12-02 07:43:3411209 HttpNetworkSession::Params params =
[email protected]bb88e1d32013-05-03 23:11:0711210 SpdySessionDependencies::CreateSessionParams(&session_deps_);
[email protected]e3ceb682011-06-28 23:55:4611211 params.host_resolver = &host_resolver;
[email protected]bb88e1d32013-05-03 23:11:0711212 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2611213 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
11214 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4611215
[email protected]8ddf8322012-02-23 18:08:0611216 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211217 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711218 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4611219
[email protected]cdf8f7e72013-05-23 10:56:4611220 scoped_ptr<SpdyFrame> host1_req(
11221 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
11222 scoped_ptr<SpdyFrame> host2_req(
11223 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4611224 MockWrite spdy_writes[] = {
11225 CreateMockWrite(*host1_req, 1),
11226 CreateMockWrite(*host2_req, 4),
11227 };
[email protected]23e482282013-06-14 16:08:0211228 scoped_ptr<SpdyFrame> host1_resp(
11229 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11230 scoped_ptr<SpdyFrame> host1_resp_body(
11231 spdy_util_.ConstructSpdyBodyFrame(1, true));
11232 scoped_ptr<SpdyFrame> host2_resp(
11233 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11234 scoped_ptr<SpdyFrame> host2_resp_body(
11235 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4611236 MockRead spdy_reads[] = {
11237 CreateMockRead(*host1_resp, 2),
11238 CreateMockRead(*host1_resp_body, 3),
11239 CreateMockRead(*host2_resp, 5),
11240 CreateMockRead(*host2_resp_body, 6),
[email protected]8ddf8322012-02-23 18:08:0611241 MockRead(ASYNC, 0, 7),
[email protected]e3ceb682011-06-28 23:55:4611242 };
11243
[email protected]d2b5f092012-06-08 23:55:0211244 IPAddressNumber ip;
11245 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
11246 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11247 MockConnect connect(ASYNC, OK, peer_addr);
[email protected]dd54bd82012-07-19 23:44:5711248 OrderedSocketData spdy_data(
11249 connect,
11250 spdy_reads, arraysize(spdy_reads),
11251 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711252 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4611253
[email protected]aa22b242011-11-16 18:58:2911254 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4611255 HttpRequestInfo request1;
11256 request1.method = "GET";
11257 request1.url = GURL("https://www.google.com/");
11258 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011259 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611260
[email protected]49639fa2011-12-20 23:22:4111261 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611262 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111263 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611264
11265 const HttpResponseInfo* response = trans1.GetResponseInfo();
11266 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011267 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611268 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11269
11270 std::string response_data;
11271 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
11272 EXPECT_EQ("hello!", response_data);
11273
11274 // Preload cache entries into HostCache.
[email protected]5109c1952013-08-20 18:44:1011275 HostResolver::RequestInfo resolve_info(HostPortPair("www.gmail.com", 443));
[email protected]e3ceb682011-06-28 23:55:4611276 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1011277 rv = host_resolver.Resolve(resolve_info,
11278 DEFAULT_PRIORITY,
11279 &ignored,
11280 callback.callback(),
11281 NULL,
11282 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4711283 EXPECT_EQ(ERR_IO_PENDING, rv);
11284 rv = callback.WaitForResult();
11285 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4611286
11287 HttpRequestInfo request2;
11288 request2.method = "GET";
11289 request2.url = GURL("https://www.gmail.com/");
11290 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011291 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611292
[email protected]49639fa2011-12-20 23:22:4111293 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611294 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111295 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611296
11297 response = trans2.GetResponseInfo();
11298 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011299 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611300 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11301 EXPECT_TRUE(response->was_fetched_via_spdy);
11302 EXPECT_TRUE(response->was_npn_negotiated);
11303 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
11304 EXPECT_EQ("hello!", response_data);
[email protected]88c7b4be2014-03-19 23:04:0111305#endif
[email protected]e3ceb682011-06-28 23:55:4611306}
[email protected]45b170822012-05-04 21:18:1411307#undef MAYBE_UseIPConnectionPoolingWithHostCacheExpiration
[email protected]e3ceb682011-06-28 23:55:4611308
[email protected]23e482282013-06-14 16:08:0211309TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
[email protected]8450d722012-07-02 19:14:0411310 const std::string https_url = "https://www.google.com/";
11311 const std::string http_url = "http://www.google.com:443/";
11312
11313 // SPDY GET for HTTPS URL
[email protected]cdf8f7e72013-05-23 10:56:4611314 scoped_ptr<SpdyFrame> req1(
11315 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0411316
11317 MockWrite writes1[] = {
11318 CreateMockWrite(*req1, 0),
11319 };
11320
[email protected]23e482282013-06-14 16:08:0211321 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11322 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8450d722012-07-02 19:14:0411323 MockRead reads1[] = {
11324 CreateMockRead(*resp1, 1),
11325 CreateMockRead(*body1, 2),
11326 MockRead(ASYNC, ERR_IO_PENDING, 3)
11327 };
11328
[email protected]dd54bd82012-07-19 23:44:5711329 DelayedSocketData data1(
11330 1, reads1, arraysize(reads1),
11331 writes1, arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0411332 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5711333 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0411334
11335 // HTTP GET for the HTTP URL
11336 MockWrite writes2[] = {
11337 MockWrite(ASYNC, 4,
11338 "GET / HTTP/1.1\r\n"
11339 "Host: www.google.com:443\r\n"
11340 "Connection: keep-alive\r\n\r\n"),
11341 };
11342
11343 MockRead reads2[] = {
11344 MockRead(ASYNC, 5, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
11345 MockRead(ASYNC, 6, "hello"),
11346 MockRead(ASYNC, 7, OK),
11347 };
11348
[email protected]dd54bd82012-07-19 23:44:5711349 DelayedSocketData data2(
11350 1, reads2, arraysize(reads2),
11351 writes2, arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0411352
[email protected]8450d722012-07-02 19:14:0411353 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211354 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711355 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11356 session_deps_.socket_factory->AddSocketDataProvider(&data1);
11357 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0411358
[email protected]bb88e1d32013-05-03 23:11:0711359 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0411360
11361 // Start the first transaction to set up the SpdySession
11362 HttpRequestInfo request1;
11363 request1.method = "GET";
11364 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0411365 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011366 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0411367 TestCompletionCallback callback1;
11368 EXPECT_EQ(ERR_IO_PENDING,
11369 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411370 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411371
11372 EXPECT_EQ(OK, callback1.WaitForResult());
11373 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11374
11375 // Now, start the HTTP request
11376 HttpRequestInfo request2;
11377 request2.method = "GET";
11378 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0411379 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011380 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0411381 TestCompletionCallback callback2;
11382 EXPECT_EQ(ERR_IO_PENDING,
11383 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411384 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411385
11386 EXPECT_EQ(OK, callback2.WaitForResult());
11387 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11388}
11389
[email protected]23e482282013-06-14 16:08:0211390TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
[email protected]8450d722012-07-02 19:14:0411391 const std::string https_url = "https://www.google.com/";
11392 const std::string http_url = "http://www.google.com:443/";
11393
11394 // SPDY GET for HTTPS URL (through CONNECT tunnel)
[email protected]9075f51c2013-08-15 17:53:5411395 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
11396 LOWEST));
[email protected]cdf8f7e72013-05-23 10:56:4611397 scoped_ptr<SpdyFrame> req1(
11398 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]23e482282013-06-14 16:08:0211399 scoped_ptr<SpdyFrame> wrapped_req1(
11400 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3911401
11402 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
[email protected]745aa9c2014-06-27 02:21:2911403 SpdyHeaderBlock req2_block;
11404 req2_block[spdy_util_.GetMethodKey()] = "GET";
11405 req2_block[spdy_util_.GetPathKey()] =
11406 spdy_util_.is_spdy2() ? http_url.c_str() : "/";
11407 req2_block[spdy_util_.GetHostKey()] = "www.google.com:443";
11408 req2_block[spdy_util_.GetSchemeKey()] = "http";
11409 spdy_util_.MaybeAddVersionHeader(&req2_block);
[email protected]601e03f12014-04-06 16:26:3911410 scoped_ptr<SpdyFrame> req2(
[email protected]745aa9c2014-06-27 02:21:2911411 spdy_util_.ConstructSpdySyn(3, req2_block, MEDIUM, false, true));
[email protected]8450d722012-07-02 19:14:0411412
11413 MockWrite writes1[] = {
11414 CreateMockWrite(*connect, 0),
11415 CreateMockWrite(*wrapped_req1, 2),
11416 CreateMockWrite(*req2, 5),
11417 };
11418
[email protected]23e482282013-06-14 16:08:0211419 scoped_ptr<SpdyFrame> conn_resp(
11420 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11421 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11422 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
11423 scoped_ptr<SpdyFrame> wrapped_resp1(
11424 spdy_util_.ConstructWrappedSpdyFrame(resp1, 1));
11425 scoped_ptr<SpdyFrame> wrapped_body1(
11426 spdy_util_.ConstructWrappedSpdyFrame(body1, 1));
11427 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11428 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]8450d722012-07-02 19:14:0411429 MockRead reads1[] = {
11430 CreateMockRead(*conn_resp, 1),
11431 CreateMockRead(*wrapped_resp1, 3),
11432 CreateMockRead(*wrapped_body1, 4),
11433 CreateMockRead(*resp2, 6),
11434 CreateMockRead(*body2, 7),
11435 MockRead(ASYNC, ERR_IO_PENDING, 8)
11436 };
11437
[email protected]dd54bd82012-07-19 23:44:5711438 DeterministicSocketData data1(reads1, arraysize(reads1),
11439 writes1, arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0411440 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5711441 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0411442
[email protected]bb88e1d32013-05-03 23:11:0711443 session_deps_.proxy_service.reset(
[email protected]f6c63db52013-02-02 00:35:2211444 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
11445 CapturingNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0711446 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0411447 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
[email protected]23e482282013-06-14 16:08:0211448 ssl1.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711449 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0411450 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
[email protected]23e482282013-06-14 16:08:0211451 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711452 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11453 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0411454
11455 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0711456 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]8450d722012-07-02 19:14:0411457
11458 // Start the first transaction to set up the SpdySession
11459 HttpRequestInfo request1;
11460 request1.method = "GET";
11461 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0411462 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011463 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0411464 TestCompletionCallback callback1;
11465 EXPECT_EQ(ERR_IO_PENDING,
11466 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411467 base::MessageLoop::current()->RunUntilIdle();
[email protected]dd54bd82012-07-19 23:44:5711468 data1.RunFor(4);
[email protected]8450d722012-07-02 19:14:0411469
11470 EXPECT_EQ(OK, callback1.WaitForResult());
11471 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11472
[email protected]f6c63db52013-02-02 00:35:2211473 LoadTimingInfo load_timing_info1;
11474 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
11475 TestLoadTimingNotReusedWithPac(load_timing_info1,
11476 CONNECT_TIMING_HAS_SSL_TIMES);
11477
[email protected]8450d722012-07-02 19:14:0411478 // Now, start the HTTP request
11479 HttpRequestInfo request2;
11480 request2.method = "GET";
11481 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0411482 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011483 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0411484 TestCompletionCallback callback2;
11485 EXPECT_EQ(ERR_IO_PENDING,
11486 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411487 base::MessageLoop::current()->RunUntilIdle();
[email protected]dd54bd82012-07-19 23:44:5711488 data1.RunFor(3);
[email protected]8450d722012-07-02 19:14:0411489
11490 EXPECT_EQ(OK, callback2.WaitForResult());
11491 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2211492
11493 LoadTimingInfo load_timing_info2;
11494 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
11495 // The established SPDY sessions is considered reused by the HTTP request.
11496 TestLoadTimingReusedWithPac(load_timing_info2);
11497 // HTTP requests over a SPDY session should have a different connection
11498 // socket_log_id than requests over a tunnel.
11499 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0411500}
11501
[email protected]23e482282013-06-14 16:08:0211502TEST_P(HttpNetworkTransactionTest, UseSpdySessionForHttpWhenForced) {
[email protected]d7599122014-05-24 03:37:2311503 session_deps_.force_spdy_always = true;
[email protected]8450d722012-07-02 19:14:0411504 const std::string https_url = "https://www.google.com/";
11505 const std::string http_url = "http://www.google.com:443/";
11506
11507 // SPDY GET for HTTPS URL
[email protected]cdf8f7e72013-05-23 10:56:4611508 scoped_ptr<SpdyFrame> req1(
11509 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0411510 // SPDY GET for the HTTP URL
[email protected]cdf8f7e72013-05-23 10:56:4611511 scoped_ptr<SpdyFrame> req2(
11512 spdy_util_.ConstructSpdyGet(http_url.c_str(), false, 3, MEDIUM));
[email protected]8450d722012-07-02 19:14:0411513
11514 MockWrite writes[] = {
11515 CreateMockWrite(*req1, 1),
11516 CreateMockWrite(*req2, 4),
11517 };
11518
[email protected]23e482282013-06-14 16:08:0211519 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11520 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
11521 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11522 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]8450d722012-07-02 19:14:0411523 MockRead reads[] = {
11524 CreateMockRead(*resp1, 2),
11525 CreateMockRead(*body1, 3),
11526 CreateMockRead(*resp2, 5),
11527 CreateMockRead(*body2, 6),
11528 MockRead(ASYNC, ERR_IO_PENDING, 7)
11529 };
11530
[email protected]dd54bd82012-07-19 23:44:5711531 OrderedSocketData data(reads, arraysize(reads),
11532 writes, arraysize(writes));
[email protected]8450d722012-07-02 19:14:0411533
[email protected]8450d722012-07-02 19:14:0411534 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211535 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711536 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11537 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8450d722012-07-02 19:14:0411538
[email protected]bb88e1d32013-05-03 23:11:0711539 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0411540
11541 // Start the first transaction to set up the SpdySession
11542 HttpRequestInfo request1;
11543 request1.method = "GET";
11544 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0411545 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011546 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0411547 TestCompletionCallback callback1;
11548 EXPECT_EQ(ERR_IO_PENDING,
11549 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411550 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411551
11552 EXPECT_EQ(OK, callback1.WaitForResult());
11553 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11554
11555 // Now, start the HTTP request
11556 HttpRequestInfo request2;
11557 request2.method = "GET";
11558 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0411559 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011560 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0411561 TestCompletionCallback callback2;
11562 EXPECT_EQ(ERR_IO_PENDING,
11563 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411564 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411565
11566 EXPECT_EQ(OK, callback2.WaitForResult());
11567 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11568}
11569
[email protected]2d88e7d2012-07-19 17:55:1711570// Test that in the case where we have a SPDY session to a SPDY proxy
11571// that we do not pool other origins that resolve to the same IP when
11572// the certificate does not match the new origin.
11573// http://crbug.com/134690
[email protected]23e482282013-06-14 16:08:0211574TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
[email protected]2d88e7d2012-07-19 17:55:1711575 const std::string url1 = "http://www.google.com/";
11576 const std::string url2 = "https://mail.google.com/";
11577 const std::string ip_addr = "1.2.3.4";
11578
11579 // SPDY GET for HTTP URL (through SPDY proxy)
[email protected]23e482282013-06-14 16:08:0211580 scoped_ptr<SpdyHeaderBlock> headers(
11581 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/"));
[email protected]745aa9c2014-06-27 02:21:2911582 scoped_ptr<SpdyFrame> req1(
11583 spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, false, true));
[email protected]2d88e7d2012-07-19 17:55:1711584
11585 MockWrite writes1[] = {
11586 CreateMockWrite(*req1, 0),
11587 };
11588
[email protected]23e482282013-06-14 16:08:0211589 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11590 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1711591 MockRead reads1[] = {
11592 CreateMockRead(*resp1, 1),
11593 CreateMockRead(*body1, 2),
11594 MockRead(ASYNC, OK, 3) // EOF
11595 };
11596
11597 scoped_ptr<DeterministicSocketData> data1(
11598 new DeterministicSocketData(reads1, arraysize(reads1),
11599 writes1, arraysize(writes1)));
11600 IPAddressNumber ip;
11601 ASSERT_TRUE(ParseIPLiteralToNumber(ip_addr, &ip));
11602 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11603 MockConnect connect_data1(ASYNC, OK, peer_addr);
11604 data1->set_connect_data(connect_data1);
11605
11606 // SPDY GET for HTTPS URL (direct)
[email protected]cdf8f7e72013-05-23 10:56:4611607 scoped_ptr<SpdyFrame> req2(
11608 spdy_util_.ConstructSpdyGet(url2.c_str(), false, 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1711609
11610 MockWrite writes2[] = {
11611 CreateMockWrite(*req2, 0),
11612 };
11613
[email protected]23e482282013-06-14 16:08:0211614 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11615 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1711616 MockRead reads2[] = {
11617 CreateMockRead(*resp2, 1),
11618 CreateMockRead(*body2, 2),
11619 MockRead(ASYNC, OK, 3) // EOF
11620 };
11621
11622 scoped_ptr<DeterministicSocketData> data2(
11623 new DeterministicSocketData(reads2, arraysize(reads2),
11624 writes2, arraysize(writes2)));
11625 MockConnect connect_data2(ASYNC, OK);
11626 data2->set_connect_data(connect_data2);
11627
11628 // Set up a proxy config that sends HTTP requests to a proxy, and
11629 // all others direct.
11630 ProxyConfig proxy_config;
11631 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
11632 CapturingProxyResolver* capturing_proxy_resolver =
11633 new CapturingProxyResolver();
[email protected]bb88e1d32013-05-03 23:11:0711634 session_deps_.proxy_service.reset(new ProxyService(
[email protected]2d88e7d2012-07-19 17:55:1711635 new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver,
11636 NULL));
11637
11638 // Load a valid cert. Note, that this does not need to
11639 // be valid for proxy because the MockSSLClientSocket does
11640 // not actually verify it. But SpdySession will use this
11641 // to see if it is valid for the new origin
[email protected]6cdfd7f2013-02-08 20:40:1511642 base::FilePath certs_dir = GetTestCertsDirectory();
[email protected]2d88e7d2012-07-19 17:55:1711643 scoped_refptr<X509Certificate> server_cert(
11644 ImportCertFromFile(certs_dir, "ok_cert.pem"));
dcheng48459ac22014-08-26 00:46:4111645 ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert.get());
[email protected]2d88e7d2012-07-19 17:55:1711646
11647 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
[email protected]23e482282013-06-14 16:08:0211648 ssl1.SetNextProto(GetParam());
[email protected]2d88e7d2012-07-19 17:55:1711649 ssl1.cert = server_cert;
[email protected]bb88e1d32013-05-03 23:11:0711650 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
11651 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11652 data1.get());
[email protected]2d88e7d2012-07-19 17:55:1711653
11654 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
[email protected]23e482282013-06-14 16:08:0211655 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711656 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11657 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11658 data2.get());
[email protected]2d88e7d2012-07-19 17:55:1711659
[email protected]bb88e1d32013-05-03 23:11:0711660 session_deps_.host_resolver.reset(new MockCachingHostResolver());
11661 session_deps_.host_resolver->rules()->AddRule("mail.google.com", ip_addr);
11662 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1711663
11664 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0711665 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]2d88e7d2012-07-19 17:55:1711666
11667 // Start the first transaction to set up the SpdySession
11668 HttpRequestInfo request1;
11669 request1.method = "GET";
11670 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1711671 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011672 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1711673 TestCompletionCallback callback1;
11674 ASSERT_EQ(ERR_IO_PENDING,
11675 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
11676 data1->RunFor(3);
11677
11678 ASSERT_TRUE(callback1.have_result());
11679 EXPECT_EQ(OK, callback1.WaitForResult());
11680 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11681
11682 // Now, start the HTTP request
11683 HttpRequestInfo request2;
11684 request2.method = "GET";
11685 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1711686 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011687 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1711688 TestCompletionCallback callback2;
11689 EXPECT_EQ(ERR_IO_PENDING,
11690 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411691 base::MessageLoop::current()->RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1711692 data2->RunFor(3);
11693
11694 ASSERT_TRUE(callback2.have_result());
11695 EXPECT_EQ(OK, callback2.WaitForResult());
11696 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11697}
11698
[email protected]85f97342013-04-17 06:12:2411699// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
11700// error) in SPDY session, removes the socket from pool and closes the SPDY
11701// session. Verify that new url's from the same HttpNetworkSession (and a new
11702// SpdySession) do work. http://crbug.com/224701
[email protected]23e482282013-06-14 16:08:0211703TEST_P(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
[email protected]85f97342013-04-17 06:12:2411704 const std::string https_url = "https://www.google.com/";
11705
11706 MockRead reads1[] = {
11707 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
11708 };
11709
11710 scoped_ptr<DeterministicSocketData> data1(
11711 new DeterministicSocketData(reads1, arraysize(reads1), NULL, 0));
11712 data1->SetStop(1);
11713
[email protected]cdf8f7e72013-05-23 10:56:4611714 scoped_ptr<SpdyFrame> req2(
11715 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2411716 MockWrite writes2[] = {
11717 CreateMockWrite(*req2, 0),
11718 };
11719
[email protected]23e482282013-06-14 16:08:0211720 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11721 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]85f97342013-04-17 06:12:2411722 MockRead reads2[] = {
11723 CreateMockRead(*resp2, 1),
11724 CreateMockRead(*body2, 2),
11725 MockRead(ASYNC, OK, 3) // EOF
11726 };
11727
11728 scoped_ptr<DeterministicSocketData> data2(
11729 new DeterministicSocketData(reads2, arraysize(reads2),
11730 writes2, arraysize(writes2)));
11731
[email protected]85f97342013-04-17 06:12:2411732 SSLSocketDataProvider ssl1(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211733 ssl1.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711734 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
11735 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11736 data1.get());
[email protected]85f97342013-04-17 06:12:2411737
11738 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211739 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711740 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11741 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11742 data2.get());
[email protected]85f97342013-04-17 06:12:2411743
11744 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0711745 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]85f97342013-04-17 06:12:2411746
11747 // Start the first transaction to set up the SpdySession and verify that
11748 // connection was closed.
11749 HttpRequestInfo request1;
11750 request1.method = "GET";
11751 request1.url = GURL(https_url);
11752 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011753 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2411754 TestCompletionCallback callback1;
11755 EXPECT_EQ(ERR_IO_PENDING,
11756 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411757 base::MessageLoop::current()->RunUntilIdle();
[email protected]85f97342013-04-17 06:12:2411758 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback1.WaitForResult());
11759
11760 // Now, start the second request and make sure it succeeds.
11761 HttpRequestInfo request2;
11762 request2.method = "GET";
11763 request2.url = GURL(https_url);
11764 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011765 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2411766 TestCompletionCallback callback2;
11767 EXPECT_EQ(ERR_IO_PENDING,
11768 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411769 base::MessageLoop::current()->RunUntilIdle();
[email protected]85f97342013-04-17 06:12:2411770 data2->RunFor(3);
11771
11772 ASSERT_TRUE(callback2.have_result());
11773 EXPECT_EQ(OK, callback2.WaitForResult());
11774 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11775}
11776
[email protected]23e482282013-06-14 16:08:0211777TEST_P(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]d7599122014-05-24 03:37:2311778 session_deps_.next_protos = SpdyNextProtos();
[email protected]483fa202013-05-14 01:07:0311779 ClientSocketPoolManager::set_max_sockets_per_group(
11780 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
11781 ClientSocketPoolManager::set_max_sockets_per_pool(
11782 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
11783
11784 // Use two different hosts with different IPs so they don't get pooled.
11785 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
11786 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
11787 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11788
11789 SSLSocketDataProvider ssl1(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211790 ssl1.SetNextProto(GetParam());
[email protected]483fa202013-05-14 01:07:0311791 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211792 ssl2.SetNextProto(GetParam());
[email protected]483fa202013-05-14 01:07:0311793 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
11794 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
11795
[email protected]cdf8f7e72013-05-23 10:56:4611796 scoped_ptr<SpdyFrame> host1_req(spdy_util_.ConstructSpdyGet(
[email protected]483fa202013-05-14 01:07:0311797 "https://www.a.com", false, 1, DEFAULT_PRIORITY));
11798 MockWrite spdy1_writes[] = {
11799 CreateMockWrite(*host1_req, 1),
11800 };
[email protected]23e482282013-06-14 16:08:0211801 scoped_ptr<SpdyFrame> host1_resp(
11802 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11803 scoped_ptr<SpdyFrame> host1_resp_body(
11804 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0311805 MockRead spdy1_reads[] = {
11806 CreateMockRead(*host1_resp, 2),
11807 CreateMockRead(*host1_resp_body, 3),
11808 MockRead(ASYNC, ERR_IO_PENDING, 4),
11809 };
11810
11811 scoped_ptr<OrderedSocketData> spdy1_data(
11812 new OrderedSocketData(
11813 spdy1_reads, arraysize(spdy1_reads),
11814 spdy1_writes, arraysize(spdy1_writes)));
11815 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
11816
[email protected]cdf8f7e72013-05-23 10:56:4611817 scoped_ptr<SpdyFrame> host2_req(spdy_util_.ConstructSpdyGet(
[email protected]483fa202013-05-14 01:07:0311818 "https://www.b.com", false, 1, DEFAULT_PRIORITY));
11819 MockWrite spdy2_writes[] = {
11820 CreateMockWrite(*host2_req, 1),
11821 };
[email protected]23e482282013-06-14 16:08:0211822 scoped_ptr<SpdyFrame> host2_resp(
11823 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11824 scoped_ptr<SpdyFrame> host2_resp_body(
11825 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0311826 MockRead spdy2_reads[] = {
11827 CreateMockRead(*host2_resp, 2),
11828 CreateMockRead(*host2_resp_body, 3),
11829 MockRead(ASYNC, ERR_IO_PENDING, 4),
11830 };
11831
11832 scoped_ptr<OrderedSocketData> spdy2_data(
11833 new OrderedSocketData(
11834 spdy2_reads, arraysize(spdy2_reads),
11835 spdy2_writes, arraysize(spdy2_writes)));
11836 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
11837
11838 MockWrite http_write[] = {
11839 MockWrite("GET / HTTP/1.1\r\n"
11840 "Host: www.a.com\r\n"
11841 "Connection: keep-alive\r\n\r\n"),
11842 };
11843
11844 MockRead http_read[] = {
11845 MockRead("HTTP/1.1 200 OK\r\n"),
11846 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11847 MockRead("Content-Length: 6\r\n\r\n"),
11848 MockRead("hello!"),
11849 };
11850 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
11851 http_write, arraysize(http_write));
11852 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
11853
11854 HostPortPair host_port_pair_a("www.a.com", 443);
[email protected]e6d017652013-05-17 18:01:4011855 SpdySessionKey spdy_session_key_a(
[email protected]314b03992014-04-01 01:28:5311856 host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0311857 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611858 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0311859
11860 TestCompletionCallback callback;
11861 HttpRequestInfo request1;
11862 request1.method = "GET";
11863 request1.url = GURL("https://www.a.com/");
11864 request1.load_flags = 0;
11865 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5011866 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0311867
11868 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
11869 EXPECT_EQ(ERR_IO_PENDING, rv);
11870 EXPECT_EQ(OK, callback.WaitForResult());
11871
11872 const HttpResponseInfo* response = trans->GetResponseInfo();
11873 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011874 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0311875 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11876 EXPECT_TRUE(response->was_fetched_via_spdy);
11877 EXPECT_TRUE(response->was_npn_negotiated);
11878
11879 std::string response_data;
11880 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11881 EXPECT_EQ("hello!", response_data);
11882 trans.reset();
11883 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2611884 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0311885
11886 HostPortPair host_port_pair_b("www.b.com", 443);
[email protected]e6d017652013-05-17 18:01:4011887 SpdySessionKey spdy_session_key_b(
[email protected]314b03992014-04-01 01:28:5311888 host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0311889 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611890 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0311891 HttpRequestInfo request2;
11892 request2.method = "GET";
11893 request2.url = GURL("https://www.b.com/");
11894 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011895 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0311896
11897 rv = trans->Start(&request2, callback.callback(), BoundNetLog());
11898 EXPECT_EQ(ERR_IO_PENDING, rv);
11899 EXPECT_EQ(OK, callback.WaitForResult());
11900
11901 response = trans->GetResponseInfo();
11902 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011903 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0311904 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11905 EXPECT_TRUE(response->was_fetched_via_spdy);
11906 EXPECT_TRUE(response->was_npn_negotiated);
11907 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11908 EXPECT_EQ("hello!", response_data);
11909 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611910 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0311911 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2611912 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0311913
11914 HostPortPair host_port_pair_a1("www.a.com", 80);
[email protected]e6d017652013-05-17 18:01:4011915 SpdySessionKey spdy_session_key_a1(
[email protected]314b03992014-04-01 01:28:5311916 host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0311917 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611918 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0311919 HttpRequestInfo request3;
11920 request3.method = "GET";
11921 request3.url = GURL("http://www.a.com/");
11922 request3.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011923 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0311924
11925 rv = trans->Start(&request3, callback.callback(), BoundNetLog());
11926 EXPECT_EQ(ERR_IO_PENDING, rv);
11927 EXPECT_EQ(OK, callback.WaitForResult());
11928
11929 response = trans->GetResponseInfo();
11930 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011931 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0311932 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11933 EXPECT_FALSE(response->was_fetched_via_spdy);
11934 EXPECT_FALSE(response->was_npn_negotiated);
11935 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11936 EXPECT_EQ("hello!", response_data);
11937 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611938 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0311939 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611940 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0311941}
11942
[email protected]79e1fd62013-06-20 06:50:0411943TEST_P(HttpNetworkTransactionTest, HttpSyncConnectError) {
11944 HttpRequestInfo request;
11945 request.method = "GET";
11946 request.url = GURL("http://www.google.com/");
11947 request.load_flags = 0;
11948
[email protected]3fe8d2f82013-10-17 08:56:0711949 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0411950 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4111951 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0411952
11953 MockConnect mock_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
11954 StaticSocketDataProvider data;
11955 data.set_connect_data(mock_connect);
11956 session_deps_.socket_factory->AddSocketDataProvider(&data);
11957
11958 TestCompletionCallback callback;
11959
11960 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11961 EXPECT_EQ(ERR_IO_PENDING, rv);
11962
11963 rv = callback.WaitForResult();
11964 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
11965
11966 EXPECT_EQ(NULL, trans->GetResponseInfo());
11967
11968 // We don't care whether this succeeds or fails, but it shouldn't crash.
11969 HttpRequestHeaders request_headers;
11970 trans->GetFullRequestHeaders(&request_headers);
11971}
11972
11973TEST_P(HttpNetworkTransactionTest, HttpAsyncConnectError) {
11974 HttpRequestInfo request;
11975 request.method = "GET";
11976 request.url = GURL("http://www.google.com/");
11977 request.load_flags = 0;
11978
[email protected]3fe8d2f82013-10-17 08:56:0711979 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0411980 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4111981 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0411982
11983 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11984 StaticSocketDataProvider data;
11985 data.set_connect_data(mock_connect);
11986 session_deps_.socket_factory->AddSocketDataProvider(&data);
11987
11988 TestCompletionCallback callback;
11989
11990 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11991 EXPECT_EQ(ERR_IO_PENDING, rv);
11992
11993 rv = callback.WaitForResult();
11994 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
11995
11996 EXPECT_EQ(NULL, trans->GetResponseInfo());
11997
11998 // We don't care whether this succeeds or fails, but it shouldn't crash.
11999 HttpRequestHeaders request_headers;
12000 trans->GetFullRequestHeaders(&request_headers);
12001}
12002
12003TEST_P(HttpNetworkTransactionTest, HttpSyncWriteError) {
12004 HttpRequestInfo request;
12005 request.method = "GET";
12006 request.url = GURL("http://www.google.com/");
12007 request.load_flags = 0;
12008
[email protected]3fe8d2f82013-10-17 08:56:0712009 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412010 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112011 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412012
12013 MockWrite data_writes[] = {
12014 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
12015 };
12016 MockRead data_reads[] = {
12017 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
12018 };
12019
12020 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12021 data_writes, arraysize(data_writes));
12022 session_deps_.socket_factory->AddSocketDataProvider(&data);
12023
12024 TestCompletionCallback callback;
12025
12026 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12027 EXPECT_EQ(ERR_IO_PENDING, rv);
12028
12029 rv = callback.WaitForResult();
12030 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12031
12032 EXPECT_EQ(NULL, trans->GetResponseInfo());
12033
12034 HttpRequestHeaders request_headers;
12035 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12036 EXPECT_TRUE(request_headers.HasHeader("Host"));
12037}
12038
12039TEST_P(HttpNetworkTransactionTest, HttpAsyncWriteError) {
12040 HttpRequestInfo request;
12041 request.method = "GET";
12042 request.url = GURL("http://www.google.com/");
12043 request.load_flags = 0;
12044
[email protected]3fe8d2f82013-10-17 08:56:0712045 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412046 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112047 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412048
12049 MockWrite data_writes[] = {
12050 MockWrite(ASYNC, ERR_CONNECTION_RESET),
12051 };
12052 MockRead data_reads[] = {
12053 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
12054 };
12055
12056 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12057 data_writes, arraysize(data_writes));
12058 session_deps_.socket_factory->AddSocketDataProvider(&data);
12059
12060 TestCompletionCallback callback;
12061
12062 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12063 EXPECT_EQ(ERR_IO_PENDING, rv);
12064
12065 rv = callback.WaitForResult();
12066 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12067
12068 EXPECT_EQ(NULL, trans->GetResponseInfo());
12069
12070 HttpRequestHeaders request_headers;
12071 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12072 EXPECT_TRUE(request_headers.HasHeader("Host"));
12073}
12074
12075TEST_P(HttpNetworkTransactionTest, HttpSyncReadError) {
12076 HttpRequestInfo request;
12077 request.method = "GET";
12078 request.url = GURL("http://www.google.com/");
12079 request.load_flags = 0;
12080
[email protected]3fe8d2f82013-10-17 08:56:0712081 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412082 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112083 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412084
12085 MockWrite data_writes[] = {
12086 MockWrite("GET / HTTP/1.1\r\n"
12087 "Host: www.google.com\r\n"
12088 "Connection: keep-alive\r\n\r\n"),
12089 };
12090 MockRead data_reads[] = {
12091 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
12092 };
12093
12094 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12095 data_writes, arraysize(data_writes));
12096 session_deps_.socket_factory->AddSocketDataProvider(&data);
12097
12098 TestCompletionCallback callback;
12099
12100 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12101 EXPECT_EQ(ERR_IO_PENDING, rv);
12102
12103 rv = callback.WaitForResult();
12104 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12105
12106 EXPECT_EQ(NULL, trans->GetResponseInfo());
12107
12108 HttpRequestHeaders request_headers;
12109 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12110 EXPECT_TRUE(request_headers.HasHeader("Host"));
12111}
12112
12113TEST_P(HttpNetworkTransactionTest, HttpAsyncReadError) {
12114 HttpRequestInfo request;
12115 request.method = "GET";
12116 request.url = GURL("http://www.google.com/");
12117 request.load_flags = 0;
12118
[email protected]3fe8d2f82013-10-17 08:56:0712119 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412120 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112121 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412122
12123 MockWrite data_writes[] = {
12124 MockWrite("GET / HTTP/1.1\r\n"
12125 "Host: www.google.com\r\n"
12126 "Connection: keep-alive\r\n\r\n"),
12127 };
12128 MockRead data_reads[] = {
12129 MockRead(ASYNC, ERR_CONNECTION_RESET),
12130 };
12131
12132 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12133 data_writes, arraysize(data_writes));
12134 session_deps_.socket_factory->AddSocketDataProvider(&data);
12135
12136 TestCompletionCallback callback;
12137
12138 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12139 EXPECT_EQ(ERR_IO_PENDING, rv);
12140
12141 rv = callback.WaitForResult();
12142 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12143
12144 EXPECT_EQ(NULL, trans->GetResponseInfo());
12145
12146 HttpRequestHeaders request_headers;
12147 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12148 EXPECT_TRUE(request_headers.HasHeader("Host"));
12149}
12150
12151TEST_P(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
12152 HttpRequestInfo request;
12153 request.method = "GET";
12154 request.url = GURL("http://www.google.com/");
12155 request.load_flags = 0;
12156 request.extra_headers.SetHeader("X-Foo", "bar");
12157
[email protected]3fe8d2f82013-10-17 08:56:0712158 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412159 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112160 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412161
12162 MockWrite data_writes[] = {
12163 MockWrite("GET / HTTP/1.1\r\n"
12164 "Host: www.google.com\r\n"
12165 "Connection: keep-alive\r\n"
12166 "X-Foo: bar\r\n\r\n"),
12167 };
12168 MockRead data_reads[] = {
12169 MockRead("HTTP/1.1 200 OK\r\n"
12170 "Content-Length: 5\r\n\r\n"
12171 "hello"),
12172 MockRead(ASYNC, ERR_UNEXPECTED),
12173 };
12174
12175 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12176 data_writes, arraysize(data_writes));
12177 session_deps_.socket_factory->AddSocketDataProvider(&data);
12178
12179 TestCompletionCallback callback;
12180
12181 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12182 EXPECT_EQ(ERR_IO_PENDING, rv);
12183
12184 rv = callback.WaitForResult();
12185 EXPECT_EQ(OK, rv);
12186
12187 HttpRequestHeaders request_headers;
12188 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12189 std::string foo;
12190 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
12191 EXPECT_EQ("bar", foo);
12192}
12193
[email protected]bf828982013-08-14 18:01:4712194namespace {
12195
[email protected]e86839fd2013-08-14 18:29:0312196// Fake HttpStreamBase that simply records calls to SetPriority().
12197class FakeStream : public HttpStreamBase,
12198 public base::SupportsWeakPtr<FakeStream> {
12199 public:
12200 explicit FakeStream(RequestPriority priority) : priority_(priority) {}
dchengb03027d2014-10-21 12:00:2012201 ~FakeStream() override {}
[email protected]e86839fd2013-08-14 18:29:0312202
12203 RequestPriority priority() const { return priority_; }
12204
dchengb03027d2014-10-21 12:00:2012205 int InitializeStream(const HttpRequestInfo* request_info,
12206 RequestPriority priority,
12207 const BoundNetLog& net_log,
12208 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0312209 return ERR_IO_PENDING;
12210 }
12211
dchengb03027d2014-10-21 12:00:2012212 int SendRequest(const HttpRequestHeaders& request_headers,
12213 HttpResponseInfo* response,
12214 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0312215 ADD_FAILURE();
12216 return ERR_UNEXPECTED;
12217 }
12218
dchengb03027d2014-10-21 12:00:2012219 int ReadResponseHeaders(const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0312220 ADD_FAILURE();
12221 return ERR_UNEXPECTED;
12222 }
12223
dchengb03027d2014-10-21 12:00:2012224 int ReadResponseBody(IOBuffer* buf,
12225 int buf_len,
12226 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0312227 ADD_FAILURE();
12228 return ERR_UNEXPECTED;
12229 }
12230
dchengb03027d2014-10-21 12:00:2012231 void Close(bool not_reusable) override {}
[email protected]e86839fd2013-08-14 18:29:0312232
dchengb03027d2014-10-21 12:00:2012233 bool IsResponseBodyComplete() const override {
[email protected]e86839fd2013-08-14 18:29:0312234 ADD_FAILURE();
12235 return false;
12236 }
12237
dchengb03027d2014-10-21 12:00:2012238 bool CanFindEndOfResponse() const override { return false; }
[email protected]e86839fd2013-08-14 18:29:0312239
dchengb03027d2014-10-21 12:00:2012240 bool IsConnectionReused() const override {
[email protected]e86839fd2013-08-14 18:29:0312241 ADD_FAILURE();
12242 return false;
12243 }
12244
dchengb03027d2014-10-21 12:00:2012245 void SetConnectionReused() override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0312246
dchengb03027d2014-10-21 12:00:2012247 bool IsConnectionReusable() const override {
[email protected]e86839fd2013-08-14 18:29:0312248 ADD_FAILURE();
12249 return false;
12250 }
12251
dchengb03027d2014-10-21 12:00:2012252 int64 GetTotalReceivedBytes() const override {
[email protected]bc92bc972013-12-13 08:32:5912253 ADD_FAILURE();
12254 return 0;
12255 }
12256
dchengb03027d2014-10-21 12:00:2012257 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
[email protected]e86839fd2013-08-14 18:29:0312258 ADD_FAILURE();
12259 return false;
12260 }
12261
dchengb03027d2014-10-21 12:00:2012262 void GetSSLInfo(SSLInfo* ssl_info) override { ADD_FAILURE(); }
12263
12264 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
[email protected]e86839fd2013-08-14 18:29:0312265 ADD_FAILURE();
12266 }
12267
dchengb03027d2014-10-21 12:00:2012268 bool IsSpdyHttpStream() const override {
[email protected]e86839fd2013-08-14 18:29:0312269 ADD_FAILURE();
12270 return false;
12271 }
12272
dchengb03027d2014-10-21 12:00:2012273 void Drain(HttpNetworkSession* session) override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0312274
dchengb03027d2014-10-21 12:00:2012275 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]e86839fd2013-08-14 18:29:0312276
12277 private:
12278 RequestPriority priority_;
12279
12280 DISALLOW_COPY_AND_ASSIGN(FakeStream);
12281};
12282
12283// Fake HttpStreamRequest that simply records calls to SetPriority()
12284// and vends FakeStreams with its current priority.
[email protected]bf828982013-08-14 18:01:4712285class FakeStreamRequest : public HttpStreamRequest,
12286 public base::SupportsWeakPtr<FakeStreamRequest> {
12287 public:
[email protected]e86839fd2013-08-14 18:29:0312288 FakeStreamRequest(RequestPriority priority,
12289 HttpStreamRequest::Delegate* delegate)
12290 : priority_(priority),
[email protected]831e4a32013-11-14 02:14:4412291 delegate_(delegate),
12292 websocket_stream_create_helper_(NULL) {}
12293
12294 FakeStreamRequest(RequestPriority priority,
12295 HttpStreamRequest::Delegate* delegate,
12296 WebSocketHandshakeStreamBase::CreateHelper* create_helper)
12297 : priority_(priority),
12298 delegate_(delegate),
12299 websocket_stream_create_helper_(create_helper) {}
[email protected]e86839fd2013-08-14 18:29:0312300
dchengb03027d2014-10-21 12:00:2012301 ~FakeStreamRequest() override {}
[email protected]bf828982013-08-14 18:01:4712302
12303 RequestPriority priority() const { return priority_; }
12304
[email protected]831e4a32013-11-14 02:14:4412305 const WebSocketHandshakeStreamBase::CreateHelper*
12306 websocket_stream_create_helper() const {
12307 return websocket_stream_create_helper_;
12308 }
12309
[email protected]e86839fd2013-08-14 18:29:0312310 // Create a new FakeStream and pass it to the request's
12311 // delegate. Returns a weak pointer to the FakeStream.
12312 base::WeakPtr<FakeStream> FinishStreamRequest() {
12313 FakeStream* fake_stream = new FakeStream(priority_);
12314 // Do this before calling OnStreamReady() as OnStreamReady() may
12315 // immediately delete |fake_stream|.
12316 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
12317 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), fake_stream);
12318 return weak_stream;
12319 }
12320
dchengb03027d2014-10-21 12:00:2012321 int RestartTunnelWithProxyAuth(const AuthCredentials& credentials) override {
[email protected]bf828982013-08-14 18:01:4712322 ADD_FAILURE();
12323 return ERR_UNEXPECTED;
12324 }
12325
dchengb03027d2014-10-21 12:00:2012326 LoadState GetLoadState() const override {
[email protected]bf828982013-08-14 18:01:4712327 ADD_FAILURE();
12328 return LoadState();
12329 }
12330
dchengb03027d2014-10-21 12:00:2012331 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]bf828982013-08-14 18:01:4712332
dchengb03027d2014-10-21 12:00:2012333 bool was_npn_negotiated() const override { return false; }
[email protected]bf828982013-08-14 18:01:4712334
dchengb03027d2014-10-21 12:00:2012335 NextProto protocol_negotiated() const override { return kProtoUnknown; }
[email protected]bf828982013-08-14 18:01:4712336
dchengb03027d2014-10-21 12:00:2012337 bool using_spdy() const override { return false; }
[email protected]bf828982013-08-14 18:01:4712338
12339 private:
12340 RequestPriority priority_;
[email protected]e86839fd2013-08-14 18:29:0312341 HttpStreamRequest::Delegate* const delegate_;
[email protected]831e4a32013-11-14 02:14:4412342 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
[email protected]bf828982013-08-14 18:01:4712343
12344 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
12345};
12346
12347// Fake HttpStreamFactory that vends FakeStreamRequests.
12348class FakeStreamFactory : public HttpStreamFactory {
12349 public:
12350 FakeStreamFactory() {}
dchengb03027d2014-10-21 12:00:2012351 ~FakeStreamFactory() override {}
[email protected]bf828982013-08-14 18:01:4712352
12353 // Returns a WeakPtr<> to the last HttpStreamRequest returned by
12354 // RequestStream() (which may be NULL if it was destroyed already).
12355 base::WeakPtr<FakeStreamRequest> last_stream_request() {
12356 return last_stream_request_;
12357 }
12358
dchengb03027d2014-10-21 12:00:2012359 HttpStreamRequest* RequestStream(const HttpRequestInfo& info,
12360 RequestPriority priority,
12361 const SSLConfig& server_ssl_config,
12362 const SSLConfig& proxy_ssl_config,
12363 HttpStreamRequest::Delegate* delegate,
12364 const BoundNetLog& net_log) override {
[email protected]e86839fd2013-08-14 18:29:0312365 FakeStreamRequest* fake_request = new FakeStreamRequest(priority, delegate);
[email protected]bf828982013-08-14 18:01:4712366 last_stream_request_ = fake_request->AsWeakPtr();
12367 return fake_request;
12368 }
12369
dchengb03027d2014-10-21 12:00:2012370 HttpStreamRequest* RequestWebSocketHandshakeStream(
[email protected]bf828982013-08-14 18:01:4712371 const HttpRequestInfo& info,
12372 RequestPriority priority,
12373 const SSLConfig& server_ssl_config,
12374 const SSLConfig& proxy_ssl_config,
12375 HttpStreamRequest::Delegate* delegate,
[email protected]467086b2013-11-12 08:19:4612376 WebSocketHandshakeStreamBase::CreateHelper* create_helper,
mostynbba063d6032014-10-09 11:01:1312377 const BoundNetLog& net_log) override {
[email protected]831e4a32013-11-14 02:14:4412378 FakeStreamRequest* fake_request =
12379 new FakeStreamRequest(priority, delegate, create_helper);
12380 last_stream_request_ = fake_request->AsWeakPtr();
12381 return fake_request;
[email protected]bf828982013-08-14 18:01:4712382 }
12383
dchengb03027d2014-10-21 12:00:2012384 void PreconnectStreams(int num_streams,
12385 const HttpRequestInfo& info,
12386 RequestPriority priority,
12387 const SSLConfig& server_ssl_config,
12388 const SSLConfig& proxy_ssl_config) override {
[email protected]bf828982013-08-14 18:01:4712389 ADD_FAILURE();
12390 }
12391
dchengb03027d2014-10-21 12:00:2012392 const HostMappingRules* GetHostMappingRules() const override {
[email protected]bf828982013-08-14 18:01:4712393 ADD_FAILURE();
12394 return NULL;
12395 }
12396
12397 private:
12398 base::WeakPtr<FakeStreamRequest> last_stream_request_;
12399
12400 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
12401};
12402
[email protected]831e4a32013-11-14 02:14:4412403// TODO(yhirano): Split this class out into a net/websockets file, if it is
12404// worth doing.
12405class FakeWebSocketStreamCreateHelper :
12406 public WebSocketHandshakeStreamBase::CreateHelper {
12407 public:
dchengb03027d2014-10-21 12:00:2012408 WebSocketHandshakeStreamBase* CreateBasicStream(
[email protected]7e841a52013-11-22 09:04:2112409 scoped_ptr<ClientSocketHandle> connection,
mostynbba063d6032014-10-09 11:01:1312410 bool using_proxy) override {
[email protected]831e4a32013-11-14 02:14:4412411 NOTREACHED();
12412 return NULL;
12413 }
12414
dchengb03027d2014-10-21 12:00:2012415 WebSocketHandshakeStreamBase* CreateSpdyStream(
[email protected]831e4a32013-11-14 02:14:4412416 const base::WeakPtr<SpdySession>& session,
mostynbba063d6032014-10-09 11:01:1312417 bool use_relative_url) override {
[email protected]831e4a32013-11-14 02:14:4412418 NOTREACHED();
12419 return NULL;
12420 };
12421
dchengb03027d2014-10-21 12:00:2012422 ~FakeWebSocketStreamCreateHelper() override {}
[email protected]831e4a32013-11-14 02:14:4412423
12424 virtual scoped_ptr<WebSocketStream> Upgrade() {
12425 NOTREACHED();
12426 return scoped_ptr<WebSocketStream>();
12427 }
12428};
12429
[email protected]bf828982013-08-14 18:01:4712430} // namespace
12431
12432// Make sure that HttpNetworkTransaction passes on its priority to its
12433// stream request on start.
12434TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
12435 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12436 HttpNetworkSessionPeer peer(session);
12437 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4412438 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4712439
dcheng48459ac22014-08-26 00:46:4112440 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4712441
12442 ASSERT_TRUE(fake_factory->last_stream_request() == NULL);
12443
12444 HttpRequestInfo request;
12445 TestCompletionCallback callback;
12446 EXPECT_EQ(ERR_IO_PENDING,
12447 trans.Start(&request, callback.callback(), BoundNetLog()));
12448
12449 base::WeakPtr<FakeStreamRequest> fake_request =
12450 fake_factory->last_stream_request();
12451 ASSERT_TRUE(fake_request != NULL);
12452 EXPECT_EQ(LOW, fake_request->priority());
12453}
12454
12455// Make sure that HttpNetworkTransaction passes on its priority
12456// updates to its stream request.
12457TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriority) {
12458 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12459 HttpNetworkSessionPeer peer(session);
12460 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4412461 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4712462
dcheng48459ac22014-08-26 00:46:4112463 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4712464
12465 HttpRequestInfo request;
12466 TestCompletionCallback callback;
12467 EXPECT_EQ(ERR_IO_PENDING,
12468 trans.Start(&request, callback.callback(), BoundNetLog()));
12469
12470 base::WeakPtr<FakeStreamRequest> fake_request =
12471 fake_factory->last_stream_request();
12472 ASSERT_TRUE(fake_request != NULL);
12473 EXPECT_EQ(LOW, fake_request->priority());
12474
12475 trans.SetPriority(LOWEST);
12476 ASSERT_TRUE(fake_request != NULL);
12477 EXPECT_EQ(LOWEST, fake_request->priority());
12478}
12479
[email protected]e86839fd2013-08-14 18:29:0312480// Make sure that HttpNetworkTransaction passes on its priority
12481// updates to its stream.
12482TEST_P(HttpNetworkTransactionTest, SetStreamPriority) {
12483 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12484 HttpNetworkSessionPeer peer(session);
12485 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4412486 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]e86839fd2013-08-14 18:29:0312487
dcheng48459ac22014-08-26 00:46:4112488 HttpNetworkTransaction trans(LOW, session.get());
[email protected]e86839fd2013-08-14 18:29:0312489
12490 HttpRequestInfo request;
12491 TestCompletionCallback callback;
12492 EXPECT_EQ(ERR_IO_PENDING,
12493 trans.Start(&request, callback.callback(), BoundNetLog()));
12494
12495 base::WeakPtr<FakeStreamRequest> fake_request =
12496 fake_factory->last_stream_request();
12497 ASSERT_TRUE(fake_request != NULL);
12498 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
12499 ASSERT_TRUE(fake_stream != NULL);
12500 EXPECT_EQ(LOW, fake_stream->priority());
12501
12502 trans.SetPriority(LOWEST);
12503 EXPECT_EQ(LOWEST, fake_stream->priority());
12504}
12505
[email protected]831e4a32013-11-14 02:14:4412506TEST_P(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
12507 // The same logic needs to be tested for both ws: and wss: schemes, but this
12508 // test is already parameterised on NextProto, so it uses a loop to verify
12509 // that the different schemes work.
12510 std::string test_cases[] = {"ws://www.google.com/", "wss://www.google.com/"};
12511 for (size_t i = 0; i < arraysize(test_cases); ++i) {
12512 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12513 HttpNetworkSessionPeer peer(session);
12514 FakeStreamFactory* fake_factory = new FakeStreamFactory();
12515 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
[email protected]0191b51c2013-11-18 10:55:2312516 peer.SetHttpStreamFactoryForWebSocket(
[email protected]831e4a32013-11-14 02:14:4412517 scoped_ptr<HttpStreamFactory>(fake_factory));
12518
dcheng48459ac22014-08-26 00:46:4112519 HttpNetworkTransaction trans(LOW, session.get());
[email protected]831e4a32013-11-14 02:14:4412520 trans.SetWebSocketHandshakeStreamCreateHelper(
12521 &websocket_stream_create_helper);
12522
12523 HttpRequestInfo request;
12524 TestCompletionCallback callback;
12525 request.method = "GET";
12526 request.url = GURL(test_cases[i]);
12527
12528 EXPECT_EQ(ERR_IO_PENDING,
12529 trans.Start(&request, callback.callback(), BoundNetLog()));
12530
12531 base::WeakPtr<FakeStreamRequest> fake_request =
12532 fake_factory->last_stream_request();
12533 ASSERT_TRUE(fake_request != NULL);
12534 EXPECT_EQ(&websocket_stream_create_helper,
12535 fake_request->websocket_stream_create_helper());
12536 }
12537}
12538
[email protected]043b68c82013-08-22 23:41:5212539// Tests that when a used socket is returned to the SSL socket pool, it's closed
12540// if the transport socket pool is stalled on the global socket limit.
12541TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
12542 ClientSocketPoolManager::set_max_sockets_per_group(
12543 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12544 ClientSocketPoolManager::set_max_sockets_per_pool(
12545 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12546
12547 // Set up SSL request.
12548
12549 HttpRequestInfo ssl_request;
12550 ssl_request.method = "GET";
12551 ssl_request.url = GURL("https://www.google.com/");
12552
12553 MockWrite ssl_writes[] = {
12554 MockWrite("GET / HTTP/1.1\r\n"
12555 "Host: www.google.com\r\n"
12556 "Connection: keep-alive\r\n\r\n"),
12557 };
12558 MockRead ssl_reads[] = {
12559 MockRead("HTTP/1.1 200 OK\r\n"),
12560 MockRead("Content-Length: 11\r\n\r\n"),
12561 MockRead("hello world"),
12562 MockRead(SYNCHRONOUS, OK),
12563 };
12564 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
12565 ssl_writes, arraysize(ssl_writes));
12566 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
12567
12568 SSLSocketDataProvider ssl(ASYNC, OK);
12569 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12570
12571 // Set up HTTP request.
12572
12573 HttpRequestInfo http_request;
12574 http_request.method = "GET";
12575 http_request.url = GURL("http://www.google.com/");
12576
12577 MockWrite http_writes[] = {
12578 MockWrite("GET / HTTP/1.1\r\n"
12579 "Host: www.google.com\r\n"
12580 "Connection: keep-alive\r\n\r\n"),
12581 };
12582 MockRead http_reads[] = {
12583 MockRead("HTTP/1.1 200 OK\r\n"),
12584 MockRead("Content-Length: 7\r\n\r\n"),
12585 MockRead("falafel"),
12586 MockRead(SYNCHRONOUS, OK),
12587 };
12588 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
12589 http_writes, arraysize(http_writes));
12590 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12591
12592 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12593
12594 // Start the SSL request.
12595 TestCompletionCallback ssl_callback;
12596 scoped_ptr<HttpTransaction> ssl_trans(
12597 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12598 ASSERT_EQ(ERR_IO_PENDING,
12599 ssl_trans->Start(&ssl_request, ssl_callback.callback(),
12600 BoundNetLog()));
12601
12602 // Start the HTTP request. Pool should stall.
12603 TestCompletionCallback http_callback;
12604 scoped_ptr<HttpTransaction> http_trans(
12605 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12606 ASSERT_EQ(ERR_IO_PENDING,
12607 http_trans->Start(&http_request, http_callback.callback(),
12608 BoundNetLog()));
dcheng48459ac22014-08-26 00:46:4112609 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5212610
12611 // Wait for response from SSL request.
12612 ASSERT_EQ(OK, ssl_callback.WaitForResult());
12613 std::string response_data;
12614 ASSERT_EQ(OK, ReadTransaction(ssl_trans.get(), &response_data));
12615 EXPECT_EQ("hello world", response_data);
12616
12617 // The SSL socket should automatically be closed, so the HTTP request can
12618 // start.
dcheng48459ac22014-08-26 00:46:4112619 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
12620 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5212621
12622 // The HTTP request can now complete.
12623 ASSERT_EQ(OK, http_callback.WaitForResult());
12624 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
12625 EXPECT_EQ("falafel", response_data);
12626
dcheng48459ac22014-08-26 00:46:4112627 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5212628}
12629
12630// Tests that when a SSL connection is established but there's no corresponding
12631// request that needs it, the new socket is closed if the transport socket pool
12632// is stalled on the global socket limit.
12633TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
12634 ClientSocketPoolManager::set_max_sockets_per_group(
12635 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12636 ClientSocketPoolManager::set_max_sockets_per_pool(
12637 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12638
12639 // Set up an ssl request.
12640
12641 HttpRequestInfo ssl_request;
12642 ssl_request.method = "GET";
12643 ssl_request.url = GURL("https://www.foopy.com/");
12644
12645 // No data will be sent on the SSL socket.
12646 StaticSocketDataProvider ssl_data;
12647 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
12648
12649 SSLSocketDataProvider ssl(ASYNC, OK);
12650 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12651
12652 // Set up HTTP request.
12653
12654 HttpRequestInfo http_request;
12655 http_request.method = "GET";
12656 http_request.url = GURL("http://www.google.com/");
12657
12658 MockWrite http_writes[] = {
12659 MockWrite("GET / HTTP/1.1\r\n"
12660 "Host: www.google.com\r\n"
12661 "Connection: keep-alive\r\n\r\n"),
12662 };
12663 MockRead http_reads[] = {
12664 MockRead("HTTP/1.1 200 OK\r\n"),
12665 MockRead("Content-Length: 7\r\n\r\n"),
12666 MockRead("falafel"),
12667 MockRead(SYNCHRONOUS, OK),
12668 };
12669 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
12670 http_writes, arraysize(http_writes));
12671 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12672
12673 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12674
12675 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
12676 // cancelled when a normal transaction is cancelled.
12677 net::HttpStreamFactory* http_stream_factory = session->http_stream_factory();
12678 net::SSLConfig ssl_config;
12679 session->ssl_config_service()->GetSSLConfig(&ssl_config);
12680 http_stream_factory->PreconnectStreams(1, ssl_request, DEFAULT_PRIORITY,
12681 ssl_config, ssl_config);
dcheng48459ac22014-08-26 00:46:4112682 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5212683
12684 // Start the HTTP request. Pool should stall.
12685 TestCompletionCallback http_callback;
12686 scoped_ptr<HttpTransaction> http_trans(
12687 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12688 ASSERT_EQ(ERR_IO_PENDING,
12689 http_trans->Start(&http_request, http_callback.callback(),
12690 BoundNetLog()));
dcheng48459ac22014-08-26 00:46:4112691 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5212692
12693 // The SSL connection will automatically be closed once the connection is
12694 // established, to let the HTTP request start.
12695 ASSERT_EQ(OK, http_callback.WaitForResult());
12696 std::string response_data;
12697 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
12698 EXPECT_EQ("falafel", response_data);
12699
dcheng48459ac22014-08-26 00:46:4112700 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5212701}
12702
[email protected]02d74a02014-04-23 18:10:5412703TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
12704 ScopedVector<UploadElementReader> element_readers;
12705 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0712706 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5412707
12708 HttpRequestInfo request;
12709 request.method = "POST";
12710 request.url = GURL("http://www.foo.com/");
12711 request.upload_data_stream = &upload_data_stream;
12712 request.load_flags = 0;
12713
12714 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12715 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112716 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5412717 // Send headers successfully, but get an error while sending the body.
12718 MockWrite data_writes[] = {
12719 MockWrite("POST / HTTP/1.1\r\n"
12720 "Host: www.foo.com\r\n"
12721 "Connection: keep-alive\r\n"
12722 "Content-Length: 3\r\n\r\n"),
12723 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
12724 };
12725
12726 MockRead data_reads[] = {
12727 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
12728 MockRead("hello world"),
12729 MockRead(SYNCHRONOUS, OK),
12730 };
12731 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
12732 arraysize(data_writes));
12733 session_deps_.socket_factory->AddSocketDataProvider(&data);
12734
12735 TestCompletionCallback callback;
12736
12737 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12738 EXPECT_EQ(ERR_IO_PENDING, rv);
12739
12740 rv = callback.WaitForResult();
12741 EXPECT_EQ(OK, rv);
12742
12743 const HttpResponseInfo* response = trans->GetResponseInfo();
12744 ASSERT_TRUE(response != NULL);
12745
12746 EXPECT_TRUE(response->headers.get() != NULL);
12747 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
12748
12749 std::string response_data;
12750 rv = ReadTransaction(trans.get(), &response_data);
12751 EXPECT_EQ(OK, rv);
12752 EXPECT_EQ("hello world", response_data);
12753}
12754
12755// This test makes sure the retry logic doesn't trigger when reading an error
12756// response from a server that rejected a POST with a CONNECTION_RESET.
12757TEST_P(HttpNetworkTransactionTest,
12758 PostReadsErrorResponseAfterResetOnReusedSocket) {
12759 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12760 MockWrite data_writes[] = {
12761 MockWrite("GET / HTTP/1.1\r\n"
12762 "Host: www.foo.com\r\n"
12763 "Connection: keep-alive\r\n\r\n"),
12764 MockWrite("POST / HTTP/1.1\r\n"
12765 "Host: www.foo.com\r\n"
12766 "Connection: keep-alive\r\n"
12767 "Content-Length: 3\r\n\r\n"),
12768 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
12769 };
12770
12771 MockRead data_reads[] = {
12772 MockRead("HTTP/1.1 200 Peachy\r\n"
12773 "Content-Length: 14\r\n\r\n"),
12774 MockRead("first response"),
12775 MockRead("HTTP/1.1 400 Not OK\r\n"
12776 "Content-Length: 15\r\n\r\n"),
12777 MockRead("second response"),
12778 MockRead(SYNCHRONOUS, OK),
12779 };
12780 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
12781 arraysize(data_writes));
12782 session_deps_.socket_factory->AddSocketDataProvider(&data);
12783
12784 TestCompletionCallback callback;
12785 HttpRequestInfo request1;
12786 request1.method = "GET";
12787 request1.url = GURL("http://www.foo.com/");
12788 request1.load_flags = 0;
12789
12790 scoped_ptr<HttpTransaction> trans1(
dcheng48459ac22014-08-26 00:46:4112791 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5412792 int rv = trans1->Start(&request1, callback.callback(), BoundNetLog());
12793 EXPECT_EQ(ERR_IO_PENDING, rv);
12794
12795 rv = callback.WaitForResult();
12796 EXPECT_EQ(OK, rv);
12797
12798 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
12799 ASSERT_TRUE(response1 != NULL);
12800
12801 EXPECT_TRUE(response1->headers.get() != NULL);
12802 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
12803
12804 std::string response_data1;
12805 rv = ReadTransaction(trans1.get(), &response_data1);
12806 EXPECT_EQ(OK, rv);
12807 EXPECT_EQ("first response", response_data1);
12808 // Delete the transaction to release the socket back into the socket pool.
12809 trans1.reset();
12810
12811 ScopedVector<UploadElementReader> element_readers;
12812 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0712813 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5412814
12815 HttpRequestInfo request2;
12816 request2.method = "POST";
12817 request2.url = GURL("http://www.foo.com/");
12818 request2.upload_data_stream = &upload_data_stream;
12819 request2.load_flags = 0;
12820
12821 scoped_ptr<HttpTransaction> trans2(
dcheng48459ac22014-08-26 00:46:4112822 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5412823 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
12824 EXPECT_EQ(ERR_IO_PENDING, rv);
12825
12826 rv = callback.WaitForResult();
12827 EXPECT_EQ(OK, rv);
12828
12829 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
12830 ASSERT_TRUE(response2 != NULL);
12831
12832 EXPECT_TRUE(response2->headers.get() != NULL);
12833 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
12834
12835 std::string response_data2;
12836 rv = ReadTransaction(trans2.get(), &response_data2);
12837 EXPECT_EQ(OK, rv);
12838 EXPECT_EQ("second response", response_data2);
12839}
12840
12841TEST_P(HttpNetworkTransactionTest,
12842 PostReadsErrorResponseAfterResetPartialBodySent) {
12843 ScopedVector<UploadElementReader> element_readers;
12844 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0712845 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5412846
12847 HttpRequestInfo request;
12848 request.method = "POST";
12849 request.url = GURL("http://www.foo.com/");
12850 request.upload_data_stream = &upload_data_stream;
12851 request.load_flags = 0;
12852
12853 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12854 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112855 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5412856 // Send headers successfully, but get an error while sending the body.
12857 MockWrite data_writes[] = {
12858 MockWrite("POST / HTTP/1.1\r\n"
12859 "Host: www.foo.com\r\n"
12860 "Connection: keep-alive\r\n"
12861 "Content-Length: 3\r\n\r\n"
12862 "fo"),
12863 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
12864 };
12865
12866 MockRead data_reads[] = {
12867 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
12868 MockRead("hello world"),
12869 MockRead(SYNCHRONOUS, OK),
12870 };
12871 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
12872 arraysize(data_writes));
12873 session_deps_.socket_factory->AddSocketDataProvider(&data);
12874
12875 TestCompletionCallback callback;
12876
12877 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12878 EXPECT_EQ(ERR_IO_PENDING, rv);
12879
12880 rv = callback.WaitForResult();
12881 EXPECT_EQ(OK, rv);
12882
12883 const HttpResponseInfo* response = trans->GetResponseInfo();
12884 ASSERT_TRUE(response != NULL);
12885
12886 EXPECT_TRUE(response->headers.get() != NULL);
12887 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
12888
12889 std::string response_data;
12890 rv = ReadTransaction(trans.get(), &response_data);
12891 EXPECT_EQ(OK, rv);
12892 EXPECT_EQ("hello world", response_data);
12893}
12894
12895// This tests the more common case than the previous test, where headers and
12896// body are not merged into a single request.
12897TEST_P(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
12898 ScopedVector<UploadElementReader> element_readers;
12899 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0712900 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5412901
12902 HttpRequestInfo request;
12903 request.method = "POST";
12904 request.url = GURL("http://www.foo.com/");
12905 request.upload_data_stream = &upload_data_stream;
12906 request.load_flags = 0;
12907
12908 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12909 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112910 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5412911 // Send headers successfully, but get an error while sending the body.
12912 MockWrite data_writes[] = {
12913 MockWrite("POST / HTTP/1.1\r\n"
12914 "Host: www.foo.com\r\n"
12915 "Connection: keep-alive\r\n"
12916 "Transfer-Encoding: chunked\r\n\r\n"),
12917 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
12918 };
12919
12920 MockRead data_reads[] = {
12921 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
12922 MockRead("hello world"),
12923 MockRead(SYNCHRONOUS, OK),
12924 };
12925 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
12926 arraysize(data_writes));
12927 session_deps_.socket_factory->AddSocketDataProvider(&data);
12928
12929 TestCompletionCallback callback;
12930
12931 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12932 EXPECT_EQ(ERR_IO_PENDING, rv);
12933 // Make sure the headers are sent before adding a chunk. This ensures that
12934 // they can't be merged with the body in a single send. Not currently
12935 // necessary since a chunked body is never merged with headers, but this makes
12936 // the test more future proof.
12937 base::RunLoop().RunUntilIdle();
12938
mmenkecbc2b712014-10-09 20:29:0712939 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5412940
12941 rv = callback.WaitForResult();
12942 EXPECT_EQ(OK, rv);
12943
12944 const HttpResponseInfo* response = trans->GetResponseInfo();
12945 ASSERT_TRUE(response != NULL);
12946
12947 EXPECT_TRUE(response->headers.get() != NULL);
12948 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
12949
12950 std::string response_data;
12951 rv = ReadTransaction(trans.get(), &response_data);
12952 EXPECT_EQ(OK, rv);
12953 EXPECT_EQ("hello world", response_data);
12954}
12955
12956TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
12957 ScopedVector<UploadElementReader> element_readers;
12958 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0712959 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5412960
12961 HttpRequestInfo request;
12962 request.method = "POST";
12963 request.url = GURL("http://www.foo.com/");
12964 request.upload_data_stream = &upload_data_stream;
12965 request.load_flags = 0;
12966
12967 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12968 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112969 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5412970
12971 MockWrite data_writes[] = {
12972 MockWrite("POST / HTTP/1.1\r\n"
12973 "Host: www.foo.com\r\n"
12974 "Connection: keep-alive\r\n"
12975 "Content-Length: 3\r\n\r\n"),
12976 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
12977 };
12978
12979 MockRead data_reads[] = {
12980 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
12981 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
12982 MockRead("hello world"),
12983 MockRead(SYNCHRONOUS, OK),
12984 };
12985 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
12986 arraysize(data_writes));
12987 session_deps_.socket_factory->AddSocketDataProvider(&data);
12988
12989 TestCompletionCallback callback;
12990
12991 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12992 EXPECT_EQ(ERR_IO_PENDING, rv);
12993
12994 rv = callback.WaitForResult();
12995 EXPECT_EQ(OK, rv);
12996
12997 const HttpResponseInfo* response = trans->GetResponseInfo();
12998 ASSERT_TRUE(response != NULL);
12999
13000 EXPECT_TRUE(response->headers.get() != NULL);
13001 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
13002
13003 std::string response_data;
13004 rv = ReadTransaction(trans.get(), &response_data);
13005 EXPECT_EQ(OK, rv);
13006 EXPECT_EQ("hello world", response_data);
13007}
13008
13009TEST_P(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
13010 ScopedVector<UploadElementReader> element_readers;
13011 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713012 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413013
13014 HttpRequestInfo request;
13015 request.method = "POST";
13016 request.url = GURL("http://www.foo.com/");
13017 request.upload_data_stream = &upload_data_stream;
13018 request.load_flags = 0;
13019
13020 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13021 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113022 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413023 // Send headers successfully, but get an error while sending the body.
13024 MockWrite data_writes[] = {
13025 MockWrite("POST / HTTP/1.1\r\n"
13026 "Host: www.foo.com\r\n"
13027 "Connection: keep-alive\r\n"
13028 "Content-Length: 3\r\n\r\n"),
13029 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13030 };
13031
13032 MockRead data_reads[] = {
13033 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
13034 MockRead("hello world"),
13035 MockRead(SYNCHRONOUS, OK),
13036 };
13037 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13038 arraysize(data_writes));
13039 session_deps_.socket_factory->AddSocketDataProvider(&data);
13040
13041 TestCompletionCallback callback;
13042
13043 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13044 EXPECT_EQ(ERR_IO_PENDING, rv);
13045
13046 rv = callback.WaitForResult();
13047 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13048
13049 const HttpResponseInfo* response = trans->GetResponseInfo();
13050 EXPECT_TRUE(response == NULL);
13051}
13052
13053TEST_P(HttpNetworkTransactionTest,
13054 PostIgnoresNonErrorResponseAfterResetAnd100) {
13055 ScopedVector<UploadElementReader> element_readers;
13056 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713057 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413058
13059 HttpRequestInfo request;
13060 request.method = "POST";
13061 request.url = GURL("http://www.foo.com/");
13062 request.upload_data_stream = &upload_data_stream;
13063 request.load_flags = 0;
13064
13065 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13066 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113067 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413068 // Send headers successfully, but get an error while sending the body.
13069 MockWrite data_writes[] = {
13070 MockWrite("POST / HTTP/1.1\r\n"
13071 "Host: www.foo.com\r\n"
13072 "Connection: keep-alive\r\n"
13073 "Content-Length: 3\r\n\r\n"),
13074 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13075 };
13076
13077 MockRead data_reads[] = {
13078 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
13079 MockRead("HTTP/1.0 302 Redirect\r\n"),
13080 MockRead("Location: http://somewhere-else.com/\r\n"),
13081 MockRead("Content-Length: 0\r\n\r\n"),
13082 MockRead(SYNCHRONOUS, OK),
13083 };
13084 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13085 arraysize(data_writes));
13086 session_deps_.socket_factory->AddSocketDataProvider(&data);
13087
13088 TestCompletionCallback callback;
13089
13090 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13091 EXPECT_EQ(ERR_IO_PENDING, rv);
13092
13093 rv = callback.WaitForResult();
13094 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13095
13096 const HttpResponseInfo* response = trans->GetResponseInfo();
13097 EXPECT_TRUE(response == NULL);
13098}
13099
13100TEST_P(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
13101 ScopedVector<UploadElementReader> element_readers;
13102 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713103 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413104
13105 HttpRequestInfo request;
13106 request.method = "POST";
13107 request.url = GURL("http://www.foo.com/");
13108 request.upload_data_stream = &upload_data_stream;
13109 request.load_flags = 0;
13110
13111 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13112 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113113 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413114 // Send headers successfully, but get an error while sending the body.
13115 MockWrite data_writes[] = {
13116 MockWrite("POST / HTTP/1.1\r\n"
13117 "Host: www.foo.com\r\n"
13118 "Connection: keep-alive\r\n"
13119 "Content-Length: 3\r\n\r\n"),
13120 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13121 };
13122
13123 MockRead data_reads[] = {
13124 MockRead("HTTP 0.9 rocks!"),
13125 MockRead(SYNCHRONOUS, OK),
13126 };
13127 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13128 arraysize(data_writes));
13129 session_deps_.socket_factory->AddSocketDataProvider(&data);
13130
13131 TestCompletionCallback callback;
13132
13133 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13134 EXPECT_EQ(ERR_IO_PENDING, rv);
13135
13136 rv = callback.WaitForResult();
13137 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13138
13139 const HttpResponseInfo* response = trans->GetResponseInfo();
13140 EXPECT_TRUE(response == NULL);
13141}
13142
13143TEST_P(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
13144 ScopedVector<UploadElementReader> element_readers;
13145 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713146 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413147
13148 HttpRequestInfo request;
13149 request.method = "POST";
13150 request.url = GURL("http://www.foo.com/");
13151 request.upload_data_stream = &upload_data_stream;
13152 request.load_flags = 0;
13153
13154 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13155 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113156 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413157 // Send headers successfully, but get an error while sending the body.
13158 MockWrite data_writes[] = {
13159 MockWrite("POST / HTTP/1.1\r\n"
13160 "Host: www.foo.com\r\n"
13161 "Connection: keep-alive\r\n"
13162 "Content-Length: 3\r\n\r\n"),
13163 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13164 };
13165
13166 MockRead data_reads[] = {
13167 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
13168 MockRead(SYNCHRONOUS, OK),
13169 };
13170 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13171 arraysize(data_writes));
13172 session_deps_.socket_factory->AddSocketDataProvider(&data);
13173
13174 TestCompletionCallback callback;
13175
13176 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13177 EXPECT_EQ(ERR_IO_PENDING, rv);
13178
13179 rv = callback.WaitForResult();
13180 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13181
13182 const HttpResponseInfo* response = trans->GetResponseInfo();
13183 EXPECT_TRUE(response == NULL);
13184}
13185
[email protected]89ceba9a2009-03-21 03:46:0613186} // namespace net