blob: 19dfeb7e7063f848e0ccb206afdbc796663dbc93 [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
bnc33b8cef42014-11-19 17:30:38271 const char* GetAlternateProtocolFromParam() {
272 return
273 AlternateProtocolToString(AlternateProtocolFromNextProto(GetParam()));
274 }
275
[email protected]8a0fc822013-06-27 20:52:43276 // This is the expected return from a current server advertising SPDY.
277 std::string GetAlternateProtocolHttpHeader() {
bnc33b8cef42014-11-19 17:30:38278 return std::string("Alternate-Protocol: 443:") +
279 GetAlternateProtocolFromParam() + "\r\n\r\n";
[email protected]8a0fc822013-06-27 20:52:43280 }
281
[email protected]202965992011-12-07 23:04:51282 // Either |write_failure| specifies a write failure or |read_failure|
283 // specifies a read failure when using a reused socket. In either case, the
284 // failure should cause the network transaction to resend the request, and the
285 // other argument should be NULL.
286 void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
287 const MockRead* read_failure);
initial.commit586acc5fe2008-07-26 22:42:52288
[email protected]a34f61ee2014-03-18 20:59:49289 // Either |write_failure| specifies a write failure or |read_failure|
290 // specifies a read failure when using a reused socket. In either case, the
291 // failure should cause the network transaction to resend the request, and the
292 // other argument should be NULL.
293 void PreconnectErrorResendRequestTest(const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:10294 const MockRead* read_failure,
295 bool use_spdy);
[email protected]a34f61ee2014-03-18 20:59:49296
[email protected]5a60c8b2011-10-19 20:14:29297 SimpleGetHelperResult SimpleGetHelperForData(StaticSocketDataProvider* data[],
298 size_t data_count) {
[email protected]ff007e162009-05-23 09:13:15299 SimpleGetHelperResult out;
initial.commit586acc5fe2008-07-26 22:42:52300
[email protected]ff007e162009-05-23 09:13:15301 HttpRequestInfo request;
302 request.method = "GET";
303 request.url = GURL("http://www.google.com/");
304 request.load_flags = 0;
initial.commit586acc5fe2008-07-26 22:42:52305
[email protected]58e32bb2013-01-21 18:23:25306 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:07307 session_deps_.net_log = log.bound().net_log();
[email protected]3fe8d2f82013-10-17 08:56:07308 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:27309 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:41310 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:27311
[email protected]5a60c8b2011-10-19 20:14:29312 for (size_t i = 0; i < data_count; ++i) {
[email protected]bb88e1d32013-05-03 23:11:07313 session_deps_.socket_factory->AddSocketDataProvider(data[i]);
[email protected]5a60c8b2011-10-19 20:14:29314 }
initial.commit586acc5fe2008-07-26 22:42:52315
[email protected]49639fa2011-12-20 23:22:41316 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52317
[email protected]c47c0372014-03-12 23:07:02318 EXPECT_TRUE(log.bound().IsLogging());
[email protected]49639fa2011-12-20 23:22:41319 int rv = trans->Start(&request, callback.callback(), log.bound());
[email protected]ff007e162009-05-23 09:13:15320 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:52321
[email protected]ff007e162009-05-23 09:13:15322 out.rv = callback.WaitForResult();
[email protected]58e32bb2013-01-21 18:23:25323
324 // Even in the failure cases that use this function, connections are always
325 // successfully established before the error.
326 EXPECT_TRUE(trans->GetLoadTimingInfo(&out.load_timing_info));
327 TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
328
[email protected]ff007e162009-05-23 09:13:15329 if (out.rv != OK)
330 return out;
331
332 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50333 // Can't use ASSERT_* inside helper functions like this, so
334 // return an error.
[email protected]90499482013-06-01 00:39:50335 if (response == NULL || response->headers.get() == NULL) {
[email protected]fe2255a2011-09-20 19:37:50336 out.rv = ERR_UNEXPECTED;
337 return out;
338 }
[email protected]ff007e162009-05-23 09:13:15339 out.status_line = response->headers->GetStatusLine();
340
[email protected]80a09a82012-11-16 17:40:06341 EXPECT_EQ("127.0.0.1", response->socket_address.host());
342 EXPECT_EQ(80, response->socket_address.port());
[email protected]6d81b482011-02-22 19:47:19343
[email protected]ff007e162009-05-23 09:13:15344 rv = ReadTransaction(trans.get(), &out.response_data);
345 EXPECT_EQ(OK, rv);
[email protected]b2fcd0e2010-12-01 15:19:40346
[email protected]f3da152d2012-06-02 01:00:57347 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:40348 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:39349 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:40350 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
[email protected]169d0012010-05-10 23:20:12351 NetLog::PHASE_NONE);
[email protected]dbb83db2010-05-11 18:13:39352 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:40353 entries, pos,
[email protected]dbb83db2010-05-11 18:13:39354 NetLog::TYPE_HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
355 NetLog::PHASE_NONE);
[email protected]ff007e162009-05-23 09:13:15356
[email protected]f3da152d2012-06-02 01:00:57357 std::string line;
358 EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
359 EXPECT_EQ("GET / HTTP/1.1\r\n", line);
360
[email protected]79e1fd62013-06-20 06:50:04361 HttpRequestHeaders request_headers;
362 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
363 std::string value;
364 EXPECT_TRUE(request_headers.GetHeader("Host", &value));
365 EXPECT_EQ("www.google.com", value);
366 EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
367 EXPECT_EQ("keep-alive", value);
368
369 std::string response_headers;
370 EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
371 EXPECT_EQ("['Host: www.google.com','Connection: keep-alive']",
372 response_headers);
[email protected]3deb9a52010-11-11 00:24:40373
[email protected]b8015c42013-12-24 15:18:19374 out.totalReceivedBytes = trans->GetTotalReceivedBytes();
[email protected]aecfbf22008-10-16 02:02:47375 return out;
[email protected]ff007e162009-05-23 09:13:15376 }
initial.commit586acc5fe2008-07-26 22:42:52377
[email protected]5a60c8b2011-10-19 20:14:29378 SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[],
379 size_t reads_count) {
380 StaticSocketDataProvider reads(data_reads, reads_count, NULL, 0);
381 StaticSocketDataProvider* data[] = { &reads };
382 return SimpleGetHelperForData(data, 1);
383 }
384
[email protected]b8015c42013-12-24 15:18:19385 int64 ReadsSize(MockRead data_reads[], size_t reads_count) {
386 int64 size = 0;
387 for (size_t i = 0; i < reads_count; ++i)
388 size += data_reads[i].data_len;
389 return size;
390 }
391
[email protected]ff007e162009-05-23 09:13:15392 void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
393 int expected_status);
initial.commit586acc5fe2008-07-26 22:42:52394
[email protected]ff007e162009-05-23 09:13:15395 void ConnectStatusHelper(const MockRead& status);
[email protected]bb88e1d32013-05-03 23:11:07396
397 void BypassHostCacheOnRefreshHelper(int load_flags);
398
399 void CheckErrorIsPassedBack(int error, IoMode mode);
400
[email protected]4bd46222013-05-14 19:32:23401 SpdyTestUtil spdy_util_;
[email protected]bb88e1d32013-05-03 23:11:07402 SpdySessionDependencies session_deps_;
[email protected]483fa202013-05-14 01:07:03403
404 // Original socket limits. Some tests set these. Safest to always restore
405 // them once each test has been run.
406 int old_max_group_sockets_;
407 int old_max_pool_sockets_;
[email protected]ff007e162009-05-23 09:13:15408};
[email protected]231d5a32008-09-13 00:45:27409
[email protected]23e482282013-06-14 16:08:02410INSTANTIATE_TEST_CASE_P(
411 NextProto,
412 HttpNetworkTransactionTest,
bnc33b8cef42014-11-19 17:30:38413 testing::Values(kProtoSPDY31, kProtoSPDY4_14, kProtoSPDY4_15));
[email protected]23e482282013-06-14 16:08:02414
[email protected]448d4ca52012-03-04 04:12:23415namespace {
416
[email protected]1826a402014-01-08 15:40:48417class BeforeNetworkStartHandler {
418 public:
419 explicit BeforeNetworkStartHandler(bool defer)
420 : defer_on_before_network_start_(defer),
421 observed_before_network_start_(false) {}
422
423 void OnBeforeNetworkStart(bool* defer) {
424 *defer = defer_on_before_network_start_;
425 observed_before_network_start_ = true;
426 }
427
428 bool observed_before_network_start() const {
429 return observed_before_network_start_;
430 }
431
432 private:
433 const bool defer_on_before_network_start_;
434 bool observed_before_network_start_;
435
436 DISALLOW_COPY_AND_ASSIGN(BeforeNetworkStartHandler);
437};
438
[email protected]597a1ab2014-06-26 08:12:27439class BeforeProxyHeadersSentHandler {
440 public:
441 BeforeProxyHeadersSentHandler()
442 : observed_before_proxy_headers_sent_(false) {}
443
[email protected]1252d42f2014-07-01 21:20:20444 void OnBeforeProxyHeadersSent(const ProxyInfo& proxy_info,
445 HttpRequestHeaders* request_headers) {
[email protected]597a1ab2014-06-26 08:12:27446 observed_before_proxy_headers_sent_ = true;
447 observed_proxy_server_uri_ = proxy_info.proxy_server().ToURI();
448 }
449
450 bool observed_before_proxy_headers_sent() const {
451 return observed_before_proxy_headers_sent_;
452 }
453
454 std::string observed_proxy_server_uri() const {
455 return observed_proxy_server_uri_;
456 }
457
458 private:
459 bool observed_before_proxy_headers_sent_;
460 std::string observed_proxy_server_uri_;
461
462 DISALLOW_COPY_AND_ASSIGN(BeforeProxyHeadersSentHandler);
463};
464
[email protected]15a5ccf82008-10-23 19:57:43465// Fill |str| with a long header list that consumes >= |size| bytes.
466void FillLargeHeadersString(std::string* str, int size) {
[email protected]4ddaf2502008-10-23 18:26:19467 const char* row =
468 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
469 const int sizeof_row = strlen(row);
470 const int num_rows = static_cast<int>(
471 ceil(static_cast<float>(size) / sizeof_row));
472 const int sizeof_data = num_rows * sizeof_row;
473 DCHECK(sizeof_data >= size);
[email protected]15a5ccf82008-10-23 19:57:43474 str->reserve(sizeof_data);
[email protected]372d34a2008-11-05 21:30:51475
[email protected]4ddaf2502008-10-23 18:26:19476 for (int i = 0; i < num_rows; ++i)
[email protected]15a5ccf82008-10-23 19:57:43477 str->append(row, sizeof_row);
[email protected]4ddaf2502008-10-23 18:26:19478}
479
[email protected]385a4672009-03-11 22:21:29480// Alternative functions that eliminate randomness and dependency on the local
481// host name so that the generated NTLM messages are reproducible.
[email protected]fe2bc6a2009-03-23 16:52:20482void MockGenerateRandom1(uint8* output, size_t n) {
[email protected]385a4672009-03-11 22:21:29483 static const uint8 bytes[] = {
484 0x55, 0x29, 0x66, 0x26, 0x6b, 0x9c, 0x73, 0x54
485 };
486 static size_t current_byte = 0;
487 for (size_t i = 0; i < n; ++i) {
488 output[i] = bytes[current_byte++];
489 current_byte %= arraysize(bytes);
490 }
491}
492
[email protected]fe2bc6a2009-03-23 16:52:20493void MockGenerateRandom2(uint8* output, size_t n) {
[email protected]385a4672009-03-11 22:21:29494 static const uint8 bytes[] = {
495 0x96, 0x79, 0x85, 0xe7, 0x49, 0x93, 0x70, 0xa1,
496 0x4e, 0xe7, 0x87, 0x45, 0x31, 0x5b, 0xd3, 0x1f
497 };
498 static size_t current_byte = 0;
499 for (size_t i = 0; i < n; ++i) {
500 output[i] = bytes[current_byte++];
501 current_byte %= arraysize(bytes);
502 }
503}
504
[email protected]fe2bc6a2009-03-23 16:52:20505std::string MockGetHostName() {
506 return "WTC-WIN7";
[email protected]385a4672009-03-11 22:21:29507}
508
[email protected]e60e47a2010-07-14 03:37:18509template<typename ParentPool>
510class CaptureGroupNameSocketPool : public ParentPool {
[email protected]04e5be32009-06-26 20:00:31511 public:
[email protected]9e1bdd32011-02-03 21:48:34512 CaptureGroupNameSocketPool(HostResolver* host_resolver,
513 CertVerifier* cert_verifier);
[email protected]e60e47a2010-07-14 03:37:18514
[email protected]d80a4322009-08-14 07:07:49515 const std::string last_group_name_received() const {
516 return last_group_name_;
517 }
518
dmichaeld6e570d2014-12-18 22:30:57519 int RequestSocket(const std::string& group_name,
520 const void* socket_params,
521 RequestPriority priority,
522 ClientSocketHandle* handle,
523 const CompletionCallback& callback,
524 const BoundNetLog& net_log) override {
[email protected]04e5be32009-06-26 20:00:31525 last_group_name_ = group_name;
526 return ERR_IO_PENDING;
527 }
dmichaeld6e570d2014-12-18 22:30:57528 void CancelRequest(const std::string& group_name,
529 ClientSocketHandle* handle) override {}
530 void ReleaseSocket(const std::string& group_name,
531 scoped_ptr<StreamSocket> socket,
532 int id) override {}
533 void CloseIdleSockets() override {}
534 int IdleSocketCount() const override { return 0; }
535 int IdleSocketCountInGroup(const std::string& group_name) const override {
[email protected]04e5be32009-06-26 20:00:31536 return 0;
537 }
dmichaeld6e570d2014-12-18 22:30:57538 LoadState GetLoadState(const std::string& group_name,
539 const ClientSocketHandle* handle) const override {
[email protected]04e5be32009-06-26 20:00:31540 return LOAD_STATE_IDLE;
541 }
dmichaeld6e570d2014-12-18 22:30:57542 base::TimeDelta ConnectionTimeout() const override {
[email protected]a796bcec2010-03-22 17:17:26543 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,
eranm6571b2b2014-12-03 15:53:23584 NULL,
[email protected]007b3f82013-04-09 08:46:45585 std::string(),
586 NULL,
587 NULL,
588 NULL,
589 NULL,
590 NULL,
[email protected]8e458552014-08-05 00:02:15591 false,
592 NULL) {
593}
[email protected]2227c692010-05-04 15:36:11594
[email protected]231d5a32008-09-13 00:45:27595//-----------------------------------------------------------------------------
596
[email protected]79cb5c12011-09-12 13:12:04597// Helper functions for validating that AuthChallengeInfo's are correctly
598// configured for common cases.
599bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
600 if (!auth_challenge)
601 return false;
602 EXPECT_FALSE(auth_challenge->is_proxy);
603 EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString());
604 EXPECT_EQ("MyRealm1", auth_challenge->realm);
605 EXPECT_EQ("basic", auth_challenge->scheme);
606 return true;
607}
608
609bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
610 if (!auth_challenge)
611 return false;
612 EXPECT_TRUE(auth_challenge->is_proxy);
613 EXPECT_EQ("myproxy:70", auth_challenge->challenger.ToString());
614 EXPECT_EQ("MyRealm1", auth_challenge->realm);
615 EXPECT_EQ("basic", auth_challenge->scheme);
616 return true;
617}
618
619bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
620 if (!auth_challenge)
621 return false;
622 EXPECT_FALSE(auth_challenge->is_proxy);
623 EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString());
624 EXPECT_EQ("digestive", auth_challenge->realm);
625 EXPECT_EQ("digest", auth_challenge->scheme);
626 return true;
627}
628
629bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
630 if (!auth_challenge)
631 return false;
632 EXPECT_FALSE(auth_challenge->is_proxy);
633 EXPECT_EQ("172.22.68.17:80", auth_challenge->challenger.ToString());
634 EXPECT_EQ(std::string(), auth_challenge->realm);
635 EXPECT_EQ("ntlm", auth_challenge->scheme);
636 return true;
637}
638
[email protected]448d4ca52012-03-04 04:12:23639} // namespace
640
[email protected]23e482282013-06-14 16:08:02641TEST_P(HttpNetworkTransactionTest, Basic) {
[email protected]3fe8d2f82013-10-17 08:56:07642 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:40643 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:41644 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]231d5a32008-09-13 00:45:27645}
646
[email protected]23e482282013-06-14 16:08:02647TEST_P(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27648 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35649 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
650 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06651 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27652 };
[email protected]31a2bfe2010-02-09 08:03:39653 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
654 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42655 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27656 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
657 EXPECT_EQ("hello world", out.response_data);
[email protected]b8015c42013-12-24 15:18:19658 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
659 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27660}
661
662// Response with no status line.
[email protected]23e482282013-06-14 16:08:02663TEST_P(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27664 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35665 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06666 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27667 };
[email protected]31a2bfe2010-02-09 08:03:39668 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
669 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42670 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27671 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
672 EXPECT_EQ("hello world", out.response_data);
[email protected]b8015c42013-12-24 15:18:19673 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
674 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27675}
676
677// Allow up to 4 bytes of junk to precede status line.
[email protected]23e482282013-06-14 16:08:02678TEST_P(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27679 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35680 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06681 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27682 };
[email protected]31a2bfe2010-02-09 08:03:39683 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
684 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42685 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27686 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
687 EXPECT_EQ("DATA", out.response_data);
[email protected]b8015c42013-12-24 15:18:19688 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
689 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27690}
691
692// Allow up to 4 bytes of junk to precede status line.
[email protected]23e482282013-06-14 16:08:02693TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27694 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35695 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06696 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27697 };
[email protected]31a2bfe2010-02-09 08:03:39698 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
699 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42700 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27701 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
702 EXPECT_EQ("DATA", out.response_data);
[email protected]b8015c42013-12-24 15:18:19703 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
704 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27705}
706
707// Beyond 4 bytes of slop and it should fail to find a status line.
[email protected]23e482282013-06-14 16:08:02708TEST_P(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27709 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35710 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06711 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27712 };
[email protected]31a2bfe2010-02-09 08:03:39713 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
714 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42715 EXPECT_EQ(OK, out.rv);
[email protected]3d2a59b2008-09-26 19:44:25716 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
717 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
[email protected]b8015c42013-12-24 15:18:19718 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
719 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27720}
721
722// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
[email protected]23e482282013-06-14 16:08:02723TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27724 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35725 MockRead("\n"),
726 MockRead("\n"),
727 MockRead("Q"),
728 MockRead("J"),
729 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06730 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27731 };
[email protected]31a2bfe2010-02-09 08:03:39732 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
733 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42734 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27735 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
736 EXPECT_EQ("DATA", out.response_data);
[email protected]b8015c42013-12-24 15:18:19737 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
738 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27739}
740
741// Close the connection before enough bytes to have a status line.
[email protected]23e482282013-06-14 16:08:02742TEST_P(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:27743 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35744 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:06745 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27746 };
[email protected]31a2bfe2010-02-09 08:03:39747 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
748 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42749 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27750 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
751 EXPECT_EQ("HTT", out.response_data);
[email protected]b8015c42013-12-24 15:18:19752 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
753 EXPECT_EQ(reads_size, out.totalReceivedBytes);
initial.commit586acc5fe2008-07-26 22:42:52754}
755
[email protected]f9d44aa2008-09-23 23:57:17756// Simulate a 204 response, lacking a Content-Length header, sent over a
757// persistent connection. The response should still terminate since a 204
758// cannot have a response body.
[email protected]23e482282013-06-14 16:08:02759TEST_P(HttpNetworkTransactionTest, StopsReading204) {
[email protected]b8015c42013-12-24 15:18:19760 char junk[] = "junk";
[email protected]f9d44aa2008-09-23 23:57:17761 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35762 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
[email protected]b8015c42013-12-24 15:18:19763 MockRead(junk), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:06764 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:17765 };
[email protected]31a2bfe2010-02-09 08:03:39766 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
767 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42768 EXPECT_EQ(OK, out.rv);
[email protected]f9d44aa2008-09-23 23:57:17769 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
770 EXPECT_EQ("", out.response_data);
[email protected]b8015c42013-12-24 15:18:19771 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
772 int64 response_size = reads_size - strlen(junk);
773 EXPECT_EQ(response_size, out.totalReceivedBytes);
[email protected]f9d44aa2008-09-23 23:57:17774}
775
[email protected]0877e3d2009-10-17 22:29:57776// A simple request using chunked encoding with some extra data after.
[email protected]23e482282013-06-14 16:08:02777TEST_P(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]b8015c42013-12-24 15:18:19778 std::string final_chunk = "0\r\n\r\n";
779 std::string extra_data = "HTTP/1.1 200 OK\r\n";
780 std::string last_read = final_chunk + extra_data;
[email protected]0877e3d2009-10-17 22:29:57781 MockRead data_reads[] = {
782 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
783 MockRead("5\r\nHello\r\n"),
784 MockRead("1\r\n"),
785 MockRead(" \r\n"),
786 MockRead("5\r\nworld\r\n"),
[email protected]b8015c42013-12-24 15:18:19787 MockRead(last_read.data()),
[email protected]8ddf8322012-02-23 18:08:06788 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:57789 };
[email protected]31a2bfe2010-02-09 08:03:39790 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
791 arraysize(data_reads));
[email protected]0877e3d2009-10-17 22:29:57792 EXPECT_EQ(OK, out.rv);
793 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
794 EXPECT_EQ("Hello world", out.response_data);
[email protected]b8015c42013-12-24 15:18:19795 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
796 int64 response_size = reads_size - extra_data.size();
797 EXPECT_EQ(response_size, out.totalReceivedBytes);
[email protected]0877e3d2009-10-17 22:29:57798}
799
[email protected]9fe44f52010-09-23 18:36:00800// Next tests deal with http://crbug.com/56344.
801
[email protected]23e482282013-06-14 16:08:02802TEST_P(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00803 MultipleContentLengthHeadersNoTransferEncoding) {
804 MockRead data_reads[] = {
805 MockRead("HTTP/1.1 200 OK\r\n"),
806 MockRead("Content-Length: 10\r\n"),
807 MockRead("Content-Length: 5\r\n\r\n"),
808 };
809 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
810 arraysize(data_reads));
811 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
812}
813
[email protected]23e482282013-06-14 16:08:02814TEST_P(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04815 DuplicateContentLengthHeadersNoTransferEncoding) {
816 MockRead data_reads[] = {
817 MockRead("HTTP/1.1 200 OK\r\n"),
818 MockRead("Content-Length: 5\r\n"),
819 MockRead("Content-Length: 5\r\n\r\n"),
820 MockRead("Hello"),
821 };
822 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
823 arraysize(data_reads));
824 EXPECT_EQ(OK, out.rv);
825 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
826 EXPECT_EQ("Hello", out.response_data);
827}
828
[email protected]23e482282013-06-14 16:08:02829TEST_P(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04830 ComplexContentLengthHeadersNoTransferEncoding) {
831 // More than 2 dupes.
832 {
833 MockRead data_reads[] = {
834 MockRead("HTTP/1.1 200 OK\r\n"),
835 MockRead("Content-Length: 5\r\n"),
836 MockRead("Content-Length: 5\r\n"),
837 MockRead("Content-Length: 5\r\n\r\n"),
838 MockRead("Hello"),
839 };
840 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
841 arraysize(data_reads));
842 EXPECT_EQ(OK, out.rv);
843 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
844 EXPECT_EQ("Hello", out.response_data);
845 }
846 // HTTP/1.0
847 {
848 MockRead data_reads[] = {
849 MockRead("HTTP/1.0 200 OK\r\n"),
850 MockRead("Content-Length: 5\r\n"),
851 MockRead("Content-Length: 5\r\n"),
852 MockRead("Content-Length: 5\r\n\r\n"),
853 MockRead("Hello"),
854 };
855 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
856 arraysize(data_reads));
857 EXPECT_EQ(OK, out.rv);
858 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
859 EXPECT_EQ("Hello", out.response_data);
860 }
861 // 2 dupes and one mismatched.
862 {
863 MockRead data_reads[] = {
864 MockRead("HTTP/1.1 200 OK\r\n"),
865 MockRead("Content-Length: 10\r\n"),
866 MockRead("Content-Length: 10\r\n"),
867 MockRead("Content-Length: 5\r\n\r\n"),
868 };
869 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
870 arraysize(data_reads));
871 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
872 }
873}
874
[email protected]23e482282013-06-14 16:08:02875TEST_P(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00876 MultipleContentLengthHeadersTransferEncoding) {
877 MockRead data_reads[] = {
878 MockRead("HTTP/1.1 200 OK\r\n"),
879 MockRead("Content-Length: 666\r\n"),
880 MockRead("Content-Length: 1337\r\n"),
881 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
882 MockRead("5\r\nHello\r\n"),
883 MockRead("1\r\n"),
884 MockRead(" \r\n"),
885 MockRead("5\r\nworld\r\n"),
886 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:06887 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:00888 };
889 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
890 arraysize(data_reads));
891 EXPECT_EQ(OK, out.rv);
892 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
893 EXPECT_EQ("Hello world", out.response_data);
894}
895
[email protected]1628fe92011-10-04 23:04:55896// Next tests deal with http://crbug.com/98895.
897
898// Checks that a single Content-Disposition header results in no error.
[email protected]23e482282013-06-14 16:08:02899TEST_P(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:55900 MockRead data_reads[] = {
901 MockRead("HTTP/1.1 200 OK\r\n"),
902 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
903 MockRead("Content-Length: 5\r\n\r\n"),
904 MockRead("Hello"),
905 };
906 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
907 arraysize(data_reads));
908 EXPECT_EQ(OK, out.rv);
909 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
910 EXPECT_EQ("Hello", out.response_data);
911}
912
[email protected]54a9c6e52012-03-21 20:10:59913// Checks that two identical Content-Disposition headers result in no error.
[email protected]23e482282013-06-14 16:08:02914TEST_P(HttpNetworkTransactionTest,
[email protected]54a9c6e52012-03-21 20:10:59915 TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:55916 MockRead data_reads[] = {
917 MockRead("HTTP/1.1 200 OK\r\n"),
918 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
919 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
920 MockRead("Content-Length: 5\r\n\r\n"),
921 MockRead("Hello"),
922 };
923 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
924 arraysize(data_reads));
[email protected]54a9c6e52012-03-21 20:10:59925 EXPECT_EQ(OK, out.rv);
926 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
927 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:55928}
929
930// Checks that two distinct Content-Disposition headers result in an error.
[email protected]23e482282013-06-14 16:08:02931TEST_P(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:55932 MockRead data_reads[] = {
933 MockRead("HTTP/1.1 200 OK\r\n"),
934 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
935 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
936 MockRead("Content-Length: 5\r\n\r\n"),
937 MockRead("Hello"),
938 };
939 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
940 arraysize(data_reads));
941 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION, out.rv);
942}
943
[email protected]54a9c6e52012-03-21 20:10:59944// Checks that two identical Location headers result in no error.
945// Also tests Location header behavior.
[email protected]23e482282013-06-14 16:08:02946TEST_P(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:55947 MockRead data_reads[] = {
948 MockRead("HTTP/1.1 302 Redirect\r\n"),
949 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:59950 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:55951 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:06952 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:55953 };
954
955 HttpRequestInfo request;
956 request.method = "GET";
957 request.url = GURL("http://redirect.com/");
958 request.load_flags = 0;
959
[email protected]3fe8d2f82013-10-17 08:56:07960 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1628fe92011-10-04 23:04:55961 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:41962 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]1628fe92011-10-04 23:04:55963
964 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:07965 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:55966
[email protected]49639fa2011-12-20 23:22:41967 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:55968
[email protected]49639fa2011-12-20 23:22:41969 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1628fe92011-10-04 23:04:55970 EXPECT_EQ(ERR_IO_PENDING, rv);
971
972 EXPECT_EQ(OK, callback.WaitForResult());
973
974 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]90499482013-06-01 00:39:50975 ASSERT_TRUE(response != NULL && response->headers.get() != NULL);
[email protected]1628fe92011-10-04 23:04:55976 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
977 std::string url;
978 EXPECT_TRUE(response->headers->IsRedirect(&url));
979 EXPECT_EQ("http://good.com/", url);
[email protected]d8fc4722014-06-13 13:17:15980 EXPECT_TRUE(response->proxy_server.IsEmpty());
[email protected]1628fe92011-10-04 23:04:55981}
982
[email protected]1628fe92011-10-04 23:04:55983// Checks that two distinct Location headers result in an error.
[email protected]23e482282013-06-14 16:08:02984TEST_P(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:55985 MockRead data_reads[] = {
986 MockRead("HTTP/1.1 302 Redirect\r\n"),
987 MockRead("Location: http://good.com/\r\n"),
988 MockRead("Location: http://evil.com/\r\n"),
989 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:06990 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:55991 };
992 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
993 arraysize(data_reads));
994 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION, out.rv);
995}
996
[email protected]ef0faf2e72009-03-05 23:27:23997// Do a request using the HEAD method. Verify that we don't try to read the
998// message body (since HEAD has none).
[email protected]23e482282013-06-14 16:08:02999TEST_P(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:421000 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:231001 request.method = "HEAD";
1002 request.url = GURL("http://www.google.com/");
1003 request.load_flags = 0;
1004
[email protected]3fe8d2f82013-10-17 08:56:071005 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271006 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411007 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]597a1ab2014-06-26 08:12:271008 BeforeProxyHeadersSentHandler proxy_headers_handler;
1009 trans->SetBeforeProxyHeadersSentCallback(
1010 base::Bind(&BeforeProxyHeadersSentHandler::OnBeforeProxyHeadersSent,
1011 base::Unretained(&proxy_headers_handler)));
[email protected]cb9bf6ca2011-01-28 13:15:271012
[email protected]ef0faf2e72009-03-05 23:27:231013 MockWrite data_writes1[] = {
1014 MockWrite("HEAD / HTTP/1.1\r\n"
1015 "Host: www.google.com\r\n"
1016 "Connection: keep-alive\r\n"
1017 "Content-Length: 0\r\n\r\n"),
1018 };
1019 MockRead data_reads1[] = {
1020 MockRead("HTTP/1.1 404 Not Found\r\n"),
1021 MockRead("Server: Blah\r\n"),
1022 MockRead("Content-Length: 1234\r\n\r\n"),
1023
1024 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:061025 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]ef0faf2e72009-03-05 23:27:231026 };
1027
[email protected]31a2bfe2010-02-09 08:03:391028 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1029 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:071030 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:231031
[email protected]49639fa2011-12-20 23:22:411032 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:231033
[email protected]49639fa2011-12-20 23:22:411034 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421035 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]ef0faf2e72009-03-05 23:27:231036
1037 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421038 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:231039
[email protected]1c773ea12009-04-28 19:58:421040 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501041 ASSERT_TRUE(response != NULL);
[email protected]ef0faf2e72009-03-05 23:27:231042
1043 // Check that the headers got parsed.
[email protected]90499482013-06-01 00:39:501044 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]ef0faf2e72009-03-05 23:27:231045 EXPECT_EQ(1234, response->headers->GetContentLength());
1046 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
[email protected]d8fc4722014-06-13 13:17:151047 EXPECT_TRUE(response->proxy_server.IsEmpty());
[email protected]597a1ab2014-06-26 08:12:271048 EXPECT_FALSE(proxy_headers_handler.observed_before_proxy_headers_sent());
[email protected]ef0faf2e72009-03-05 23:27:231049
1050 std::string server_header;
1051 void* iter = NULL;
1052 bool has_server_header = response->headers->EnumerateHeader(
1053 &iter, "Server", &server_header);
1054 EXPECT_TRUE(has_server_header);
1055 EXPECT_EQ("Blah", server_header);
1056
1057 // Reading should give EOF right away, since there is no message body
1058 // (despite non-zero content-length).
1059 std::string response_data;
1060 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421061 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:231062 EXPECT_EQ("", response_data);
1063}
1064
[email protected]23e482282013-06-14 16:08:021065TEST_P(HttpNetworkTransactionTest, ReuseConnection) {
[email protected]bb88e1d32013-05-03 23:11:071066 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:521067
1068 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351069 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1070 MockRead("hello"),
1071 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1072 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061073 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521074 };
[email protected]31a2bfe2010-02-09 08:03:391075 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071076 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521077
[email protected]0b0bf032010-09-21 18:08:501078 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521079 "hello", "world"
1080 };
1081
1082 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:421083 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521084 request.method = "GET";
1085 request.url = GURL("http://www.google.com/");
1086 request.load_flags = 0;
1087
[email protected]262eec82013-03-19 21:01:361088 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501089 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271090
[email protected]49639fa2011-12-20 23:22:411091 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521092
[email protected]49639fa2011-12-20 23:22:411093 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421094 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521095
1096 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421097 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521098
[email protected]1c773ea12009-04-28 19:58:421099 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501100 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521101
[email protected]90499482013-06-01 00:39:501102 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251103 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]d8fc4722014-06-13 13:17:151104 EXPECT_TRUE(response->proxy_server.IsEmpty());
initial.commit586acc5fe2008-07-26 22:42:521105
1106 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571107 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421108 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251109 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521110 }
1111}
1112
[email protected]23e482282013-06-14 16:08:021113TEST_P(HttpNetworkTransactionTest, Ignores100) {
[email protected]b2d26cfd2012-12-11 10:36:061114 ScopedVector<UploadElementReader> element_readers;
1115 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:071116 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:271117
[email protected]1c773ea12009-04-28 19:58:421118 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521119 request.method = "POST";
1120 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271121 request.upload_data_stream = &upload_data_stream;
initial.commit586acc5fe2008-07-26 22:42:521122 request.load_flags = 0;
1123
[email protected]3fe8d2f82013-10-17 08:56:071124 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271125 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411126 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271127
initial.commit586acc5fe2008-07-26 22:42:521128 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351129 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1130 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1131 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061132 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521133 };
[email protected]31a2bfe2010-02-09 08:03:391134 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071135 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521136
[email protected]49639fa2011-12-20 23:22:411137 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521138
[email protected]49639fa2011-12-20 23:22:411139 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421140 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521141
1142 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421143 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521144
[email protected]1c773ea12009-04-28 19:58:421145 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501146 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521147
[email protected]90499482013-06-01 00:39:501148 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251149 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521150
1151 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571152 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421153 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251154 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521155}
1156
[email protected]3a2d3662009-03-27 03:49:141157// This test is almost the same as Ignores100 above, but the response contains
1158// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571159// HTTP/1.1 and the two status headers are read in one read.
[email protected]23e482282013-06-14 16:08:021160TEST_P(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421161 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141162 request.method = "GET";
1163 request.url = GURL("http://www.foo.com/");
1164 request.load_flags = 0;
1165
[email protected]3fe8d2f82013-10-17 08:56:071166 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271167 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411168 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271169
[email protected]3a2d3662009-03-27 03:49:141170 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571171 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1172 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141173 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061174 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141175 };
[email protected]31a2bfe2010-02-09 08:03:391176 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071177 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141178
[email protected]49639fa2011-12-20 23:22:411179 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141180
[email protected]49639fa2011-12-20 23:22:411181 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421182 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3a2d3662009-03-27 03:49:141183
1184 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421185 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:141186
[email protected]1c773ea12009-04-28 19:58:421187 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501188 ASSERT_TRUE(response != NULL);
[email protected]3a2d3662009-03-27 03:49:141189
[email protected]90499482013-06-01 00:39:501190 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3a2d3662009-03-27 03:49:141191 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1192
1193 std::string response_data;
1194 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421195 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:141196 EXPECT_EQ("hello world", response_data);
1197}
1198
[email protected]23e482282013-06-14 16:08:021199TEST_P(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
[email protected]ee9410e72010-01-07 01:42:381200 HttpRequestInfo request;
1201 request.method = "POST";
1202 request.url = GURL("http://www.foo.com/");
1203 request.load_flags = 0;
1204
[email protected]3fe8d2f82013-10-17 08:56:071205 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271206 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411207 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271208
[email protected]ee9410e72010-01-07 01:42:381209 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061210 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1211 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381212 };
[email protected]31a2bfe2010-02-09 08:03:391213 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071214 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381215
[email protected]49639fa2011-12-20 23:22:411216 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381217
[email protected]49639fa2011-12-20 23:22:411218 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]ee9410e72010-01-07 01:42:381219 EXPECT_EQ(ERR_IO_PENDING, rv);
1220
1221 rv = callback.WaitForResult();
1222 EXPECT_EQ(OK, rv);
1223
1224 std::string response_data;
1225 rv = ReadTransaction(trans.get(), &response_data);
1226 EXPECT_EQ(OK, rv);
1227 EXPECT_EQ("", response_data);
1228}
1229
[email protected]23e482282013-06-14 16:08:021230TEST_P(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381231 HttpRequestInfo request;
1232 request.method = "POST";
1233 request.url = GURL("http://www.foo.com/");
1234 request.load_flags = 0;
1235
[email protected]3fe8d2f82013-10-17 08:56:071236 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271237 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411238 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271239
[email protected]ee9410e72010-01-07 01:42:381240 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061241 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381242 };
[email protected]31a2bfe2010-02-09 08:03:391243 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071244 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381245
[email protected]49639fa2011-12-20 23:22:411246 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381247
[email protected]49639fa2011-12-20 23:22:411248 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]ee9410e72010-01-07 01:42:381249 EXPECT_EQ(ERR_IO_PENDING, rv);
1250
1251 rv = callback.WaitForResult();
1252 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
1253}
1254
[email protected]23e482282013-06-14 16:08:021255void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511256 const MockWrite* write_failure,
1257 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421258 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521259 request.method = "GET";
1260 request.url = GURL("http://www.foo.com/");
1261 request.load_flags = 0;
1262
[email protected]58e32bb2013-01-21 18:23:251263 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071264 session_deps_.net_log = &net_log;
1265 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271266
[email protected]202965992011-12-07 23:04:511267 // Written data for successfully sending both requests.
1268 MockWrite data1_writes[] = {
1269 MockWrite("GET / HTTP/1.1\r\n"
1270 "Host: www.foo.com\r\n"
1271 "Connection: keep-alive\r\n\r\n"),
1272 MockWrite("GET / HTTP/1.1\r\n"
1273 "Host: www.foo.com\r\n"
1274 "Connection: keep-alive\r\n\r\n")
1275 };
1276
1277 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521278 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351279 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1280 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061281 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521282 };
[email protected]202965992011-12-07 23:04:511283
1284 if (write_failure) {
[email protected]a34f61ee2014-03-18 20:59:491285 ASSERT_FALSE(read_failure);
[email protected]202965992011-12-07 23:04:511286 data1_writes[1] = *write_failure;
1287 } else {
1288 ASSERT_TRUE(read_failure);
1289 data1_reads[2] = *read_failure;
1290 }
1291
1292 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
1293 data1_writes, arraysize(data1_writes));
[email protected]bb88e1d32013-05-03 23:11:071294 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521295
1296 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351297 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1298 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061299 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521300 };
[email protected]31a2bfe2010-02-09 08:03:391301 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071302 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521303
1304 const char* kExpectedResponseData[] = {
1305 "hello", "world"
1306 };
1307
[email protected]58e32bb2013-01-21 18:23:251308 uint32 first_socket_log_id = NetLog::Source::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521309 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411310 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521311
[email protected]262eec82013-03-19 21:01:361312 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501313 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
initial.commit586acc5fe2008-07-26 22:42:521314
[email protected]49639fa2011-12-20 23:22:411315 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421316 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521317
1318 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421319 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521320
[email protected]58e32bb2013-01-21 18:23:251321 LoadTimingInfo load_timing_info;
1322 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1323 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1324 if (i == 0) {
1325 first_socket_log_id = load_timing_info.socket_log_id;
1326 } else {
1327 // The second request should be using a new socket.
1328 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1329 }
1330
[email protected]1c773ea12009-04-28 19:58:421331 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501332 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521333
[email protected]90499482013-06-01 00:39:501334 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251335 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521336
1337 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571338 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421339 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251340 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521341 }
1342}
[email protected]3d2a59b2008-09-26 19:44:251343
[email protected]a34f61ee2014-03-18 20:59:491344void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1345 const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:101346 const MockRead* read_failure,
1347 bool use_spdy) {
[email protected]a34f61ee2014-03-18 20:59:491348 HttpRequestInfo request;
1349 request.method = "GET";
[email protected]09356c652014-03-25 15:36:101350 request.url = GURL("https://www.foo.com/");
[email protected]a34f61ee2014-03-18 20:59:491351 request.load_flags = 0;
1352
1353 CapturingNetLog net_log;
1354 session_deps_.net_log = &net_log;
1355 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1356
[email protected]09356c652014-03-25 15:36:101357 SSLSocketDataProvider ssl1(ASYNC, OK);
1358 SSLSocketDataProvider ssl2(ASYNC, OK);
1359 if (use_spdy) {
1360 ssl1.SetNextProto(GetParam());
1361 ssl2.SetNextProto(GetParam());
1362 }
1363 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1364 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]a34f61ee2014-03-18 20:59:491365
[email protected]09356c652014-03-25 15:36:101366 // SPDY versions of the request and response.
1367 scoped_ptr<SpdyFrame> spdy_request(spdy_util_.ConstructSpdyGet(
1368 request.url.spec().c_str(), false, 1, DEFAULT_PRIORITY));
1369 scoped_ptr<SpdyFrame> spdy_response(
1370 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
1371 scoped_ptr<SpdyFrame> spdy_data(
1372 spdy_util_.ConstructSpdyBodyFrame(1, "hello", 5, true));
[email protected]a34f61ee2014-03-18 20:59:491373
[email protected]09356c652014-03-25 15:36:101374 // HTTP/1.1 versions of the request and response.
1375 const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1376 "Host: www.foo.com\r\n"
1377 "Connection: keep-alive\r\n\r\n";
1378 const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1379 const char kHttpData[] = "hello";
1380
1381 std::vector<MockRead> data1_reads;
1382 std::vector<MockWrite> data1_writes;
[email protected]a34f61ee2014-03-18 20:59:491383 if (write_failure) {
1384 ASSERT_FALSE(read_failure);
[email protected]09356c652014-03-25 15:36:101385 data1_writes.push_back(*write_failure);
1386 data1_reads.push_back(MockRead(ASYNC, OK));
[email protected]a34f61ee2014-03-18 20:59:491387 } else {
1388 ASSERT_TRUE(read_failure);
[email protected]09356c652014-03-25 15:36:101389 if (use_spdy) {
1390 data1_writes.push_back(CreateMockWrite(*spdy_request));
1391 } else {
1392 data1_writes.push_back(MockWrite(kHttpRequest));
1393 }
1394 data1_reads.push_back(*read_failure);
[email protected]a34f61ee2014-03-18 20:59:491395 }
1396
[email protected]09356c652014-03-25 15:36:101397 StaticSocketDataProvider data1(&data1_reads[0], data1_reads.size(),
1398 &data1_writes[0], data1_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491399 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1400
[email protected]09356c652014-03-25 15:36:101401 std::vector<MockRead> data2_reads;
1402 std::vector<MockWrite> data2_writes;
1403
1404 if (use_spdy) {
1405 data2_writes.push_back(CreateMockWrite(*spdy_request, 0, ASYNC));
1406
1407 data2_reads.push_back(CreateMockRead(*spdy_response, 1, ASYNC));
1408 data2_reads.push_back(CreateMockRead(*spdy_data, 2, ASYNC));
1409 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1410 } else {
1411 data2_writes.push_back(
1412 MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1413
1414 data2_reads.push_back(
1415 MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1416 data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1417 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1418 }
1419 OrderedSocketData data2(&data2_reads[0], data2_reads.size(),
1420 &data2_writes[0], data2_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491421 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1422
1423 // Preconnect a socket.
1424 net::SSLConfig ssl_config;
1425 session->ssl_config_service()->GetSSLConfig(&ssl_config);
[email protected]d7599122014-05-24 03:37:231426 session->GetNextProtos(&ssl_config.next_protos);
[email protected]a34f61ee2014-03-18 20:59:491427 session->http_stream_factory()->PreconnectStreams(
1428 1, request, DEFAULT_PRIORITY, ssl_config, ssl_config);
1429 // Wait for the preconnect to complete.
1430 // TODO(davidben): Some way to wait for an idle socket count might be handy.
1431 base::RunLoop().RunUntilIdle();
[email protected]09356c652014-03-25 15:36:101432 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]a34f61ee2014-03-18 20:59:491433
1434 // Make the request.
1435 TestCompletionCallback callback;
1436
1437 scoped_ptr<HttpTransaction> trans(
1438 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1439
1440 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1441 EXPECT_EQ(ERR_IO_PENDING, rv);
1442
1443 rv = callback.WaitForResult();
1444 EXPECT_EQ(OK, rv);
1445
1446 LoadTimingInfo load_timing_info;
1447 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
[email protected]09356c652014-03-25 15:36:101448 TestLoadTimingNotReused(
1449 load_timing_info,
1450 CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]a34f61ee2014-03-18 20:59:491451
1452 const HttpResponseInfo* response = trans->GetResponseInfo();
1453 ASSERT_TRUE(response != NULL);
1454
1455 EXPECT_TRUE(response->headers.get() != NULL);
1456 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1457
1458 std::string response_data;
1459 rv = ReadTransaction(trans.get(), &response_data);
1460 EXPECT_EQ(OK, rv);
[email protected]09356c652014-03-25 15:36:101461 EXPECT_EQ(kHttpData, response_data);
[email protected]a34f61ee2014-03-18 20:59:491462}
1463
[email protected]23e482282013-06-14 16:08:021464TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:231465 KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061466 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]202965992011-12-07 23:04:511467 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1468}
1469
[email protected]23e482282013-06-14 16:08:021470TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061471 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]202965992011-12-07 23:04:511472 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251473}
1474
[email protected]23e482282013-06-14 16:08:021475TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061476 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]202965992011-12-07 23:04:511477 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251478}
1479
[email protected]d58ceea82014-06-04 10:55:541480// Make sure that on a 408 response (Request Timeout), the request is retried,
1481// if the socket was a reused keep alive socket.
1482TEST_P(HttpNetworkTransactionTest, KeepAlive408) {
1483 MockRead read_failure(SYNCHRONOUS,
1484 "HTTP/1.1 408 Request Timeout\r\n"
1485 "Connection: Keep-Alive\r\n"
1486 "Content-Length: 6\r\n\r\n"
1487 "Pickle");
1488 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1489}
1490
[email protected]a34f61ee2014-03-18 20:59:491491TEST_P(HttpNetworkTransactionTest,
1492 PreconnectErrorNotConnectedOnWrite) {
1493 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]09356c652014-03-25 15:36:101494 PreconnectErrorResendRequestTest(&write_failure, NULL, false);
[email protected]a34f61ee2014-03-18 20:59:491495}
1496
1497TEST_P(HttpNetworkTransactionTest, PreconnectErrorReset) {
1498 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]09356c652014-03-25 15:36:101499 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
[email protected]a34f61ee2014-03-18 20:59:491500}
1501
1502TEST_P(HttpNetworkTransactionTest, PreconnectErrorEOF) {
1503 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]09356c652014-03-25 15:36:101504 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1505}
1506
1507TEST_P(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
1508 MockRead read_failure(ASYNC, OK); // EOF
1509 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1510}
1511
[email protected]d58ceea82014-06-04 10:55:541512// Make sure that on a 408 response (Request Timeout), the request is retried,
1513// if the socket was a preconnected (UNUSED_IDLE) socket.
1514TEST_P(HttpNetworkTransactionTest, RetryOnIdle408) {
1515 MockRead read_failure(SYNCHRONOUS,
1516 "HTTP/1.1 408 Request Timeout\r\n"
1517 "Connection: Keep-Alive\r\n"
1518 "Content-Length: 6\r\n\r\n"
1519 "Pickle");
1520 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1521 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1522}
1523
[email protected]09356c652014-03-25 15:36:101524TEST_P(HttpNetworkTransactionTest,
1525 SpdyPreconnectErrorNotConnectedOnWrite) {
1526 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1527 PreconnectErrorResendRequestTest(&write_failure, NULL, true);
1528}
1529
1530TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
1531 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1532 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1533}
1534
1535TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
1536 MockRead read_failure(SYNCHRONOUS, OK); // EOF
1537 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1538}
1539
1540TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
1541 MockRead read_failure(ASYNC, OK); // EOF
1542 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
[email protected]a34f61ee2014-03-18 20:59:491543}
1544
[email protected]23e482282013-06-14 16:08:021545TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:421546 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:251547 request.method = "GET";
1548 request.url = GURL("http://www.google.com/");
1549 request.load_flags = 0;
1550
[email protected]3fe8d2f82013-10-17 08:56:071551 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271552 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411553 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271554
[email protected]3d2a59b2008-09-26 19:44:251555 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061556 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:351557 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1558 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061559 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251560 };
[email protected]31a2bfe2010-02-09 08:03:391561 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071562 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:251563
[email protected]49639fa2011-12-20 23:22:411564 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:251565
[email protected]49639fa2011-12-20 23:22:411566 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421567 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3d2a59b2008-09-26 19:44:251568
1569 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421570 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]3d2a59b2008-09-26 19:44:251571
[email protected]1c773ea12009-04-28 19:58:421572 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]3d2a59b2008-09-26 19:44:251573 EXPECT_TRUE(response == NULL);
[email protected]3d2a59b2008-09-26 19:44:251574}
1575
1576// What do various browsers do when the server closes a non-keepalive
1577// connection without sending any response header or body?
1578//
1579// IE7: error page
1580// Safari 3.1.2 (Windows): error page
1581// Firefox 3.0.1: blank page
1582// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:421583// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1584// Us: error page (EMPTY_RESPONSE)
[email protected]23e482282013-06-14 16:08:021585TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:251586 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061587 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:351588 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1589 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061590 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251591 };
[email protected]31a2bfe2010-02-09 08:03:391592 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1593 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:421594 EXPECT_EQ(ERR_EMPTY_RESPONSE, out.rv);
[email protected]3d2a59b2008-09-26 19:44:251595}
[email protected]038e9a32008-10-08 22:40:161596
[email protected]1826a402014-01-08 15:40:481597// Test that network access can be deferred and resumed.
1598TEST_P(HttpNetworkTransactionTest, ThrottleBeforeNetworkStart) {
1599 HttpRequestInfo request;
1600 request.method = "GET";
1601 request.url = GURL("http://www.google.com/");
1602 request.load_flags = 0;
1603
1604 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1605 scoped_ptr<HttpTransaction> trans(
1606 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1607
1608 // Defer on OnBeforeNetworkStart.
1609 BeforeNetworkStartHandler net_start_handler(true); // defer
1610 trans->SetBeforeNetworkStartCallback(
1611 base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
1612 base::Unretained(&net_start_handler)));
1613
1614 MockRead data_reads[] = {
1615 MockRead("HTTP/1.0 200 OK\r\n"),
1616 MockRead("Content-Length: 5\r\n\r\n"),
1617 MockRead("hello"),
1618 MockRead(SYNCHRONOUS, 0),
1619 };
1620 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1621 session_deps_.socket_factory->AddSocketDataProvider(&data);
1622
1623 TestCompletionCallback callback;
1624
1625 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1626 EXPECT_EQ(ERR_IO_PENDING, rv);
1627 base::MessageLoop::current()->RunUntilIdle();
1628
1629 // Should have deferred for network start.
1630 EXPECT_TRUE(net_start_handler.observed_before_network_start());
1631 EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
1632 EXPECT_TRUE(trans->GetResponseInfo() == NULL);
1633
1634 trans->ResumeNetworkStart();
1635 rv = callback.WaitForResult();
1636 EXPECT_EQ(OK, rv);
1637 EXPECT_TRUE(trans->GetResponseInfo() != NULL);
1638
1639 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
1640 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
1641 if (rv == ERR_IO_PENDING)
1642 rv = callback.WaitForResult();
1643 EXPECT_EQ(5, rv);
1644 trans.reset();
1645}
1646
1647// Test that network use can be deferred and canceled.
1648TEST_P(HttpNetworkTransactionTest, ThrottleAndCancelBeforeNetworkStart) {
1649 HttpRequestInfo request;
1650 request.method = "GET";
1651 request.url = GURL("http://www.google.com/");
1652 request.load_flags = 0;
1653
1654 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1655 scoped_ptr<HttpTransaction> trans(
1656 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1657
1658 // Defer on OnBeforeNetworkStart.
1659 BeforeNetworkStartHandler net_start_handler(true); // defer
1660 trans->SetBeforeNetworkStartCallback(
1661 base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
1662 base::Unretained(&net_start_handler)));
1663
1664 TestCompletionCallback callback;
1665
1666 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1667 EXPECT_EQ(ERR_IO_PENDING, rv);
1668 base::MessageLoop::current()->RunUntilIdle();
1669
1670 // Should have deferred for network start.
1671 EXPECT_TRUE(net_start_handler.observed_before_network_start());
1672 EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
1673 EXPECT_TRUE(trans->GetResponseInfo() == NULL);
1674}
1675
[email protected]7a5378b2012-11-04 03:25:171676// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
1677// tests. There was a bug causing HttpNetworkTransaction to hang in the
1678// destructor in such situations.
1679// See http://crbug.com/154712 and http://crbug.com/156609.
[email protected]23e482282013-06-14 16:08:021680TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:171681 HttpRequestInfo request;
1682 request.method = "GET";
1683 request.url = GURL("http://www.google.com/");
1684 request.load_flags = 0;
1685
[email protected]bb88e1d32013-05-03 23:11:071686 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:361687 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501688 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171689
1690 MockRead data_reads[] = {
1691 MockRead("HTTP/1.0 200 OK\r\n"),
1692 MockRead("Connection: keep-alive\r\n"),
1693 MockRead("Content-Length: 100\r\n\r\n"),
1694 MockRead("hello"),
1695 MockRead(SYNCHRONOUS, 0),
1696 };
1697 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071698 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171699
1700 TestCompletionCallback callback;
1701
1702 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1703 EXPECT_EQ(ERR_IO_PENDING, rv);
1704
1705 rv = callback.WaitForResult();
1706 EXPECT_EQ(OK, rv);
1707
1708 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501709 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171710 if (rv == ERR_IO_PENDING)
1711 rv = callback.WaitForResult();
1712 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:501713 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171714 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1715
1716 trans.reset();
[email protected]2da659e2013-05-23 20:51:341717 base::MessageLoop::current()->RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171718 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1719}
1720
[email protected]23e482282013-06-14 16:08:021721TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:171722 HttpRequestInfo request;
1723 request.method = "GET";
1724 request.url = GURL("http://www.google.com/");
1725 request.load_flags = 0;
1726
[email protected]bb88e1d32013-05-03 23:11:071727 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:361728 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501729 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171730
1731 MockRead data_reads[] = {
1732 MockRead("HTTP/1.0 200 OK\r\n"),
1733 MockRead("Connection: keep-alive\r\n"),
1734 MockRead("Content-Length: 100\r\n\r\n"),
1735 MockRead(SYNCHRONOUS, 0),
1736 };
1737 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071738 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171739
1740 TestCompletionCallback callback;
1741
1742 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1743 EXPECT_EQ(ERR_IO_PENDING, rv);
1744
1745 rv = callback.WaitForResult();
1746 EXPECT_EQ(OK, rv);
1747
1748 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501749 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171750 if (rv == ERR_IO_PENDING)
1751 rv = callback.WaitForResult();
1752 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1753
1754 trans.reset();
[email protected]2da659e2013-05-23 20:51:341755 base::MessageLoop::current()->RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171756 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1757}
1758
[email protected]0b0bf032010-09-21 18:08:501759// Test that we correctly reuse a keep-alive connection after not explicitly
1760// reading the body.
[email protected]23e482282013-06-14 16:08:021761TEST_P(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:131762 HttpRequestInfo request;
1763 request.method = "GET";
1764 request.url = GURL("http://www.foo.com/");
1765 request.load_flags = 0;
1766
[email protected]58e32bb2013-01-21 18:23:251767 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071768 session_deps_.net_log = &net_log;
1769 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271770
[email protected]0b0bf032010-09-21 18:08:501771 // Note that because all these reads happen in the same
1772 // StaticSocketDataProvider, it shows that the same socket is being reused for
1773 // all transactions.
[email protected]fc31d6a42010-06-24 18:05:131774 MockRead data1_reads[] = {
[email protected]0b0bf032010-09-21 18:08:501775 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
1776 MockRead("HTTP/1.1 205 Reset Content\r\n\r\n"),
[email protected]fc31d6a42010-06-24 18:05:131777 MockRead("HTTP/1.1 304 Not Modified\r\n\r\n"),
[email protected]0b0bf032010-09-21 18:08:501778 MockRead("HTTP/1.1 302 Found\r\n"
1779 "Content-Length: 0\r\n\r\n"),
1780 MockRead("HTTP/1.1 302 Found\r\n"
1781 "Content-Length: 5\r\n\r\n"
1782 "hello"),
1783 MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1784 "Content-Length: 0\r\n\r\n"),
1785 MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1786 "Content-Length: 5\r\n\r\n"
1787 "hello"),
[email protected]fc31d6a42010-06-24 18:05:131788 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1789 MockRead("hello"),
1790 };
1791 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071792 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]fc31d6a42010-06-24 18:05:131793
1794 MockRead data2_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061795 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]fc31d6a42010-06-24 18:05:131796 };
1797 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071798 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]fc31d6a42010-06-24 18:05:131799
[email protected]0b0bf032010-09-21 18:08:501800 const int kNumUnreadBodies = arraysize(data1_reads) - 2;
1801 std::string response_lines[kNumUnreadBodies];
1802
[email protected]58e32bb2013-01-21 18:23:251803 uint32 first_socket_log_id = NetLog::Source::kInvalidId;
[email protected]0b0bf032010-09-21 18:08:501804 for (size_t i = 0; i < arraysize(data1_reads) - 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411805 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:131806
[email protected]262eec82013-03-19 21:01:361807 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501808 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]fc31d6a42010-06-24 18:05:131809
[email protected]49639fa2011-12-20 23:22:411810 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]fc31d6a42010-06-24 18:05:131811 EXPECT_EQ(ERR_IO_PENDING, rv);
1812
1813 rv = callback.WaitForResult();
1814 EXPECT_EQ(OK, rv);
1815
[email protected]58e32bb2013-01-21 18:23:251816 LoadTimingInfo load_timing_info;
1817 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1818 if (i == 0) {
1819 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1820 first_socket_log_id = load_timing_info.socket_log_id;
1821 } else {
1822 TestLoadTimingReused(load_timing_info);
1823 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
1824 }
1825
[email protected]fc31d6a42010-06-24 18:05:131826 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]0b0bf032010-09-21 18:08:501827 ASSERT_TRUE(response != NULL);
[email protected]fc31d6a42010-06-24 18:05:131828
[email protected]90499482013-06-01 00:39:501829 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]0b0bf032010-09-21 18:08:501830 response_lines[i] = response->headers->GetStatusLine();
1831
1832 // We intentionally don't read the response bodies.
[email protected]fc31d6a42010-06-24 18:05:131833 }
[email protected]0b0bf032010-09-21 18:08:501834
1835 const char* const kStatusLines[] = {
1836 "HTTP/1.1 204 No Content",
1837 "HTTP/1.1 205 Reset Content",
1838 "HTTP/1.1 304 Not Modified",
1839 "HTTP/1.1 302 Found",
1840 "HTTP/1.1 302 Found",
1841 "HTTP/1.1 301 Moved Permanently",
1842 "HTTP/1.1 301 Moved Permanently",
1843 };
1844
1845 COMPILE_ASSERT(kNumUnreadBodies == arraysize(kStatusLines),
1846 forgot_to_update_kStatusLines);
1847
1848 for (int i = 0; i < kNumUnreadBodies; ++i)
1849 EXPECT_EQ(kStatusLines[i], response_lines[i]);
1850
[email protected]49639fa2011-12-20 23:22:411851 TestCompletionCallback callback;
[email protected]262eec82013-03-19 21:01:361852 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501853 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:411854 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0b0bf032010-09-21 18:08:501855 EXPECT_EQ(ERR_IO_PENDING, rv);
1856 rv = callback.WaitForResult();
1857 EXPECT_EQ(OK, rv);
1858 const HttpResponseInfo* response = trans->GetResponseInfo();
1859 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:501860 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]0b0bf032010-09-21 18:08:501861 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1862 std::string response_data;
1863 rv = ReadTransaction(trans.get(), &response_data);
1864 EXPECT_EQ(OK, rv);
1865 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:131866}
1867
[email protected]038e9a32008-10-08 22:40:161868// Test the request-challenge-retry sequence for basic auth.
1869// (basic auth is the easiest to mock, because it has no randomness).
[email protected]23e482282013-06-14 16:08:021870TEST_P(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:421871 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:161872 request.method = "GET";
1873 request.url = GURL("http://www.google.com/");
1874 request.load_flags = 0;
1875
[email protected]58e32bb2013-01-21 18:23:251876 CapturingNetLog log;
[email protected]bb88e1d32013-05-03 23:11:071877 session_deps_.net_log = &log;
[email protected]3fe8d2f82013-10-17 08:56:071878 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271879 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411880 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271881
[email protected]f9ee6b52008-11-08 06:46:231882 MockWrite data_writes1[] = {
1883 MockWrite("GET / HTTP/1.1\r\n"
1884 "Host: www.google.com\r\n"
1885 "Connection: keep-alive\r\n\r\n"),
1886 };
1887
[email protected]038e9a32008-10-08 22:40:161888 MockRead data_reads1[] = {
1889 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
1890 // Give a couple authenticate options (only the middle one is actually
1891 // supported).
[email protected]22927ad2009-09-21 19:56:191892 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:161893 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1894 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
1895 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1896 // Large content-length -- won't matter, as connection will be reset.
1897 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061898 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:161899 };
1900
1901 // After calling trans->RestartWithAuth(), this is the request we should
1902 // be issuing -- the final header line contains the credentials.
1903 MockWrite data_writes2[] = {
1904 MockWrite("GET / HTTP/1.1\r\n"
1905 "Host: www.google.com\r\n"
1906 "Connection: keep-alive\r\n"
1907 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1908 };
1909
1910 // Lastly, the server responds with the actual content.
1911 MockRead data_reads2[] = {
1912 MockRead("HTTP/1.0 200 OK\r\n"),
1913 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1914 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061915 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:161916 };
1917
[email protected]31a2bfe2010-02-09 08:03:391918 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1919 data_writes1, arraysize(data_writes1));
1920 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1921 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:071922 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1923 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:161924
[email protected]49639fa2011-12-20 23:22:411925 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:161926
[email protected]49639fa2011-12-20 23:22:411927 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421928 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:161929
1930 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421931 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:161932
[email protected]58e32bb2013-01-21 18:23:251933 LoadTimingInfo load_timing_info1;
1934 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
1935 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
1936
[email protected]b8015c42013-12-24 15:18:191937 int64 reads_size1 = ReadsSize(data_reads1, arraysize(data_reads1));
1938 EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
1939
[email protected]1c773ea12009-04-28 19:58:421940 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501941 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:041942 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:161943
[email protected]49639fa2011-12-20 23:22:411944 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:161945
[email protected]49639fa2011-12-20 23:22:411946 rv = trans->RestartWithAuth(
1947 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:421948 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:161949
1950 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421951 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:161952
[email protected]58e32bb2013-01-21 18:23:251953 LoadTimingInfo load_timing_info2;
1954 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
1955 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
1956 // The load timing after restart should have a new socket ID, and times after
1957 // those of the first load timing.
1958 EXPECT_LE(load_timing_info1.receive_headers_end,
1959 load_timing_info2.connect_timing.connect_start);
1960 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
1961
[email protected]b8015c42013-12-24 15:18:191962 int64 reads_size2 = ReadsSize(data_reads2, arraysize(data_reads2));
1963 EXPECT_EQ(reads_size1 + reads_size2, trans->GetTotalReceivedBytes());
1964
[email protected]038e9a32008-10-08 22:40:161965 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501966 ASSERT_TRUE(response != NULL);
[email protected]038e9a32008-10-08 22:40:161967 EXPECT_TRUE(response->auth_challenge.get() == NULL);
1968 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:161969}
1970
[email protected]23e482282013-06-14 16:08:021971TEST_P(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:461972 HttpRequestInfo request;
1973 request.method = "GET";
1974 request.url = GURL("http://www.google.com/");
1975 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
1976
[email protected]3fe8d2f82013-10-17 08:56:071977 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271978 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411979 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271980
[email protected]861fcd52009-08-26 02:33:461981 MockWrite data_writes[] = {
1982 MockWrite("GET / HTTP/1.1\r\n"
1983 "Host: www.google.com\r\n"
1984 "Connection: keep-alive\r\n\r\n"),
1985 };
1986
1987 MockRead data_reads[] = {
1988 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
1989 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1990 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1991 // Large content-length -- won't matter, as connection will be reset.
1992 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061993 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:461994 };
1995
[email protected]31a2bfe2010-02-09 08:03:391996 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
1997 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:071998 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:411999 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:462000
[email protected]49639fa2011-12-20 23:22:412001 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]861fcd52009-08-26 02:33:462002 EXPECT_EQ(ERR_IO_PENDING, rv);
2003
2004 rv = callback.WaitForResult();
2005 EXPECT_EQ(0, rv);
2006
[email protected]b8015c42013-12-24 15:18:192007 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
2008 EXPECT_EQ(reads_size, trans->GetTotalReceivedBytes());
2009
[email protected]861fcd52009-08-26 02:33:462010 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502011 ASSERT_TRUE(response != NULL);
[email protected]861fcd52009-08-26 02:33:462012 EXPECT_TRUE(response->auth_challenge.get() == NULL);
2013}
2014
[email protected]2d2697f92009-02-18 21:00:322015// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2016// connection.
[email protected]23e482282013-06-14 16:08:022017TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
[email protected]1c773ea12009-04-28 19:58:422018 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322019 request.method = "GET";
2020 request.url = GURL("http://www.google.com/");
2021 request.load_flags = 0;
2022
[email protected]58e32bb2013-01-21 18:23:252023 CapturingNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072024 session_deps_.net_log = &log;
2025 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272026
[email protected]2d2697f92009-02-18 21:00:322027 MockWrite data_writes1[] = {
2028 MockWrite("GET / HTTP/1.1\r\n"
2029 "Host: www.google.com\r\n"
2030 "Connection: keep-alive\r\n\r\n"),
2031
2032 // After calling trans->RestartWithAuth(), this is the request we should
2033 // be issuing -- the final header line contains the credentials.
2034 MockWrite("GET / HTTP/1.1\r\n"
2035 "Host: www.google.com\r\n"
2036 "Connection: keep-alive\r\n"
2037 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2038 };
2039
2040 MockRead data_reads1[] = {
2041 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2042 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2043 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2044 MockRead("Content-Length: 14\r\n\r\n"),
2045 MockRead("Unauthorized\r\n"),
2046
2047 // Lastly, the server responds with the actual content.
2048 MockRead("HTTP/1.1 200 OK\r\n"),
2049 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502050 MockRead("Content-Length: 5\r\n\r\n"),
2051 MockRead("Hello"),
[email protected]2d2697f92009-02-18 21:00:322052 };
2053
[email protected]2d0a4f92011-05-05 16:38:462054 // If there is a regression where we disconnect a Keep-Alive
2055 // connection during an auth roundtrip, we'll end up reading this.
2056 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062057 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462058 };
2059
[email protected]31a2bfe2010-02-09 08:03:392060 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2061 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462062 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2063 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072064 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2065 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322066
[email protected]49639fa2011-12-20 23:22:412067 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322068
[email protected]262eec82013-03-19 21:01:362069 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502070 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412071 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422072 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322073
2074 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422075 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322076
[email protected]58e32bb2013-01-21 18:23:252077 LoadTimingInfo load_timing_info1;
2078 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
2079 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2080
[email protected]1c773ea12009-04-28 19:58:422081 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502082 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042083 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322084
[email protected]49639fa2011-12-20 23:22:412085 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322086
[email protected]49639fa2011-12-20 23:22:412087 rv = trans->RestartWithAuth(
2088 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422089 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322090
2091 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422092 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322093
[email protected]58e32bb2013-01-21 18:23:252094 LoadTimingInfo load_timing_info2;
2095 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
2096 TestLoadTimingReused(load_timing_info2);
2097 // The load timing after restart should have the same socket ID, and times
2098 // those of the first load timing.
2099 EXPECT_LE(load_timing_info1.receive_headers_end,
2100 load_timing_info2.send_start);
2101 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2102
[email protected]2d2697f92009-02-18 21:00:322103 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502104 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322105 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502106 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]b8015c42013-12-24 15:18:192107
2108 std::string response_data;
2109 rv = ReadTransaction(trans.get(), &response_data);
2110 EXPECT_EQ(OK, rv);
2111 int64 reads_size1 = ReadsSize(data_reads1, arraysize(data_reads1));
2112 EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
[email protected]2d2697f92009-02-18 21:00:322113}
2114
2115// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2116// connection and with no response body to drain.
[email protected]23e482282013-06-14 16:08:022117TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:422118 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322119 request.method = "GET";
2120 request.url = GURL("http://www.google.com/");
2121 request.load_flags = 0;
2122
[email protected]bb88e1d32013-05-03 23:11:072123 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272124
[email protected]2d2697f92009-02-18 21:00:322125 MockWrite data_writes1[] = {
2126 MockWrite("GET / HTTP/1.1\r\n"
2127 "Host: www.google.com\r\n"
2128 "Connection: keep-alive\r\n\r\n"),
2129
2130 // After calling trans->RestartWithAuth(), this is the request we should
2131 // be issuing -- the final header line contains the credentials.
2132 MockWrite("GET / HTTP/1.1\r\n"
2133 "Host: www.google.com\r\n"
2134 "Connection: keep-alive\r\n"
2135 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2136 };
2137
[email protected]2d2697f92009-02-18 21:00:322138 MockRead data_reads1[] = {
2139 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2140 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:312141 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:322142
2143 // Lastly, the server responds with the actual content.
2144 MockRead("HTTP/1.1 200 OK\r\n"),
2145 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502146 MockRead("Content-Length: 5\r\n\r\n"),
2147 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322148 };
2149
[email protected]2d0a4f92011-05-05 16:38:462150 // An incorrect reconnect would cause this to be read.
2151 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062152 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462153 };
2154
[email protected]31a2bfe2010-02-09 08:03:392155 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2156 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462157 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2158 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072159 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2160 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322161
[email protected]49639fa2011-12-20 23:22:412162 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322163
[email protected]262eec82013-03-19 21:01:362164 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502165 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412166 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422167 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322168
2169 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422170 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322171
[email protected]1c773ea12009-04-28 19:58:422172 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502173 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042174 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322175
[email protected]49639fa2011-12-20 23:22:412176 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322177
[email protected]49639fa2011-12-20 23:22:412178 rv = trans->RestartWithAuth(
2179 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422180 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322181
2182 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422183 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322184
2185 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502186 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322187 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502188 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322189}
2190
2191// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2192// connection and with a large response body to drain.
[email protected]23e482282013-06-14 16:08:022193TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:422194 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322195 request.method = "GET";
2196 request.url = GURL("http://www.google.com/");
2197 request.load_flags = 0;
2198
[email protected]bb88e1d32013-05-03 23:11:072199 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272200
[email protected]2d2697f92009-02-18 21:00:322201 MockWrite data_writes1[] = {
2202 MockWrite("GET / HTTP/1.1\r\n"
2203 "Host: www.google.com\r\n"
2204 "Connection: keep-alive\r\n\r\n"),
2205
2206 // After calling trans->RestartWithAuth(), this is the request we should
2207 // be issuing -- the final header line contains the credentials.
2208 MockWrite("GET / HTTP/1.1\r\n"
2209 "Host: www.google.com\r\n"
2210 "Connection: keep-alive\r\n"
2211 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2212 };
2213
2214 // Respond with 5 kb of response body.
2215 std::string large_body_string("Unauthorized");
2216 large_body_string.append(5 * 1024, ' ');
2217 large_body_string.append("\r\n");
2218
2219 MockRead data_reads1[] = {
2220 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2221 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2222 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2223 // 5134 = 12 + 5 * 1024 + 2
2224 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062225 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:322226
2227 // Lastly, the server responds with the actual content.
2228 MockRead("HTTP/1.1 200 OK\r\n"),
2229 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502230 MockRead("Content-Length: 5\r\n\r\n"),
2231 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322232 };
2233
[email protected]2d0a4f92011-05-05 16:38:462234 // An incorrect reconnect would cause this to be read.
2235 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062236 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462237 };
2238
[email protected]31a2bfe2010-02-09 08:03:392239 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2240 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462241 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2242 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072243 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2244 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322245
[email protected]49639fa2011-12-20 23:22:412246 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322247
[email protected]262eec82013-03-19 21:01:362248 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502249 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412250 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422251 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322252
2253 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422254 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322255
[email protected]1c773ea12009-04-28 19:58:422256 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502257 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042258 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322259
[email protected]49639fa2011-12-20 23:22:412260 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322261
[email protected]49639fa2011-12-20 23:22:412262 rv = trans->RestartWithAuth(
2263 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422264 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322265
2266 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422267 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322268
2269 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502270 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322271 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502272 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322273}
2274
2275// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:312276// connection, but the server gets impatient and closes the connection.
[email protected]23e482282013-06-14 16:08:022277TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:312278 HttpRequestInfo request;
2279 request.method = "GET";
2280 request.url = GURL("http://www.google.com/");
2281 request.load_flags = 0;
2282
[email protected]bb88e1d32013-05-03 23:11:072283 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272284
[email protected]11203f012009-11-12 23:02:312285 MockWrite data_writes1[] = {
2286 MockWrite("GET / HTTP/1.1\r\n"
2287 "Host: www.google.com\r\n"
2288 "Connection: keep-alive\r\n\r\n"),
2289 // This simulates the seemingly successful write to a closed connection
2290 // if the bug is not fixed.
2291 MockWrite("GET / HTTP/1.1\r\n"
2292 "Host: www.google.com\r\n"
2293 "Connection: keep-alive\r\n"
2294 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2295 };
2296
2297 MockRead data_reads1[] = {
2298 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2299 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2300 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2301 MockRead("Content-Length: 14\r\n\r\n"),
2302 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:062303 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:312304 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:062305 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:312306 };
2307
2308 // After calling trans->RestartWithAuth(), this is the request we should
2309 // be issuing -- the final header line contains the credentials.
2310 MockWrite data_writes2[] = {
2311 MockWrite("GET / HTTP/1.1\r\n"
2312 "Host: www.google.com\r\n"
2313 "Connection: keep-alive\r\n"
2314 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2315 };
2316
2317 // Lastly, the server responds with the actual content.
2318 MockRead data_reads2[] = {
2319 MockRead("HTTP/1.1 200 OK\r\n"),
2320 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502321 MockRead("Content-Length: 5\r\n\r\n"),
2322 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:312323 };
2324
[email protected]31a2bfe2010-02-09 08:03:392325 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2326 data_writes1, arraysize(data_writes1));
2327 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2328 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072329 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2330 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:312331
[email protected]49639fa2011-12-20 23:22:412332 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:312333
[email protected]262eec82013-03-19 21:01:362334 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502335 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412336 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]11203f012009-11-12 23:02:312337 EXPECT_EQ(ERR_IO_PENDING, rv);
2338
2339 rv = callback1.WaitForResult();
2340 EXPECT_EQ(OK, rv);
2341
2342 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502343 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042344 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:312345
[email protected]49639fa2011-12-20 23:22:412346 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:312347
[email protected]49639fa2011-12-20 23:22:412348 rv = trans->RestartWithAuth(
2349 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]11203f012009-11-12 23:02:312350 EXPECT_EQ(ERR_IO_PENDING, rv);
2351
2352 rv = callback2.WaitForResult();
2353 EXPECT_EQ(OK, rv);
2354
2355 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502356 ASSERT_TRUE(response != NULL);
[email protected]11203f012009-11-12 23:02:312357 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502358 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:312359}
2360
[email protected]394816e92010-08-03 07:38:592361// Test the request-challenge-retry sequence for basic auth, over a connection
2362// that requires a restart when setting up an SSL tunnel.
[email protected]23e482282013-06-14 16:08:022363TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAlive) {
[email protected]394816e92010-08-03 07:38:592364 HttpRequestInfo request;
2365 request.method = "GET";
2366 request.url = GURL("https://www.google.com/");
2367 // when the no authentication data flag is set.
2368 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
2369
[email protected]cb9bf6ca2011-01-28 13:15:272370 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072371 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:202372 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
[email protected]333bdf62012-06-08 22:57:292373 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072374 session_deps_.net_log = log.bound().net_log();
2375 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272376
[email protected]394816e92010-08-03 07:38:592377 // Since we have proxy, should try to establish tunnel.
2378 MockWrite data_writes1[] = {
2379 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2380 "Host: www.google.com\r\n"
2381 "Proxy-Connection: keep-alive\r\n\r\n"),
2382
2383 // After calling trans->RestartWithAuth(), this is the request we should
2384 // be issuing -- the final header line contains the credentials.
2385 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2386 "Host: www.google.com\r\n"
2387 "Proxy-Connection: keep-alive\r\n"
2388 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2389
2390 MockWrite("GET / HTTP/1.1\r\n"
2391 "Host: www.google.com\r\n"
2392 "Connection: keep-alive\r\n\r\n"),
2393 };
2394
2395 // The proxy responds to the connect with a 407, using a persistent
2396 // connection.
2397 MockRead data_reads1[] = {
2398 // No credentials.
2399 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2400 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2401 MockRead("Proxy-Connection: close\r\n\r\n"),
2402
2403 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2404
2405 MockRead("HTTP/1.1 200 OK\r\n"),
2406 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502407 MockRead("Content-Length: 5\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062408 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:592409 };
2410
2411 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2412 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072413 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:062414 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072415 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:592416
[email protected]49639fa2011-12-20 23:22:412417 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:592418
[email protected]262eec82013-03-19 21:01:362419 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502420 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:502421
[email protected]49639fa2011-12-20 23:22:412422 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]394816e92010-08-03 07:38:592423 EXPECT_EQ(ERR_IO_PENDING, rv);
2424
2425 rv = callback1.WaitForResult();
2426 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:572427 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:402428 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:592429 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402430 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]394816e92010-08-03 07:38:592431 NetLog::PHASE_NONE);
2432 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402433 entries, pos,
[email protected]394816e92010-08-03 07:38:592434 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2435 NetLog::PHASE_NONE);
2436
2437 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502438 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502439 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]394816e92010-08-03 07:38:592440 EXPECT_EQ(407, response->headers->response_code());
2441 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042442 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:592443
[email protected]029c83b62013-01-24 05:28:202444 LoadTimingInfo load_timing_info;
2445 // CONNECT requests and responses are handled at the connect job level, so
2446 // the transaction does not yet have a connection.
2447 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
2448
[email protected]49639fa2011-12-20 23:22:412449 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:592450
[email protected]49639fa2011-12-20 23:22:412451 rv = trans->RestartWithAuth(
2452 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]394816e92010-08-03 07:38:592453 EXPECT_EQ(ERR_IO_PENDING, rv);
2454
2455 rv = callback2.WaitForResult();
2456 EXPECT_EQ(OK, rv);
2457
2458 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502459 ASSERT_TRUE(response != NULL);
[email protected]394816e92010-08-03 07:38:592460
2461 EXPECT_TRUE(response->headers->IsKeepAlive());
2462 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:502463 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:592464 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2465
2466 // The password prompt info should not be set.
2467 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502468
[email protected]029c83b62013-01-24 05:28:202469 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2470 TestLoadTimingNotReusedWithPac(load_timing_info,
2471 CONNECT_TIMING_HAS_SSL_TIMES);
2472
[email protected]0b0bf032010-09-21 18:08:502473 trans.reset();
[email protected]102e27c2011-02-23 01:01:312474 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:592475}
2476
[email protected]11203f012009-11-12 23:02:312477// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]2d2697f92009-02-18 21:00:322478// proxy connection, when setting up an SSL tunnel.
[email protected]23e482282013-06-14 16:08:022479TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAlive) {
[email protected]cb9bf6ca2011-01-28 13:15:272480 HttpRequestInfo request;
2481 request.method = "GET";
2482 request.url = GURL("https://www.google.com/");
2483 // Ensure that proxy authentication is attempted even
2484 // when the no authentication data flag is set.
2485 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
2486
[email protected]2d2697f92009-02-18 21:00:322487 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072488 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]333bdf62012-06-08 22:57:292489 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072490 session_deps_.net_log = log.bound().net_log();
2491 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:322492
[email protected]262eec82013-03-19 21:01:362493 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502494 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d2697f92009-02-18 21:00:322495
[email protected]2d2697f92009-02-18 21:00:322496 // Since we have proxy, should try to establish tunnel.
2497 MockWrite data_writes1[] = {
2498 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:452499 "Host: www.google.com\r\n"
2500 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322501
2502 // After calling trans->RestartWithAuth(), this is the request we should
2503 // be issuing -- the final header line contains the credentials.
2504 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2505 "Host: www.google.com\r\n"
[email protected]e44de5d2009-06-05 20:12:452506 "Proxy-Connection: keep-alive\r\n"
[email protected]2d2697f92009-02-18 21:00:322507 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
2508 };
2509
2510 // The proxy responds to the connect with a 407, using a persistent
2511 // connection.
2512 MockRead data_reads1[] = {
2513 // No credentials.
2514 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2515 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2516 MockRead("Content-Length: 10\r\n\r\n"),
2517 MockRead("0123456789"),
2518
2519 // Wrong credentials (wrong password).
2520 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2521 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2522 MockRead("Content-Length: 10\r\n\r\n"),
2523 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:062524 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]2d2697f92009-02-18 21:00:322525 };
2526
[email protected]31a2bfe2010-02-09 08:03:392527 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2528 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072529 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d2697f92009-02-18 21:00:322530
[email protected]49639fa2011-12-20 23:22:412531 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322532
[email protected]49639fa2011-12-20 23:22:412533 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]1c773ea12009-04-28 19:58:422534 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322535
2536 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422537 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:572538 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:402539 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:392540 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402541 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]dbb83db2010-05-11 18:13:392542 NetLog::PHASE_NONE);
2543 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402544 entries, pos,
[email protected]dbb83db2010-05-11 18:13:392545 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2546 NetLog::PHASE_NONE);
[email protected]2d2697f92009-02-18 21:00:322547
[email protected]1c773ea12009-04-28 19:58:422548 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502549 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502550 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]2d2697f92009-02-18 21:00:322551 EXPECT_TRUE(response->headers->IsKeepAlive());
2552 EXPECT_EQ(407, response->headers->response_code());
2553 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422554 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042555 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322556
[email protected]49639fa2011-12-20 23:22:412557 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322558
2559 // Wrong password (should be "bar").
[email protected]49639fa2011-12-20 23:22:412560 rv = trans->RestartWithAuth(
2561 AuthCredentials(kFoo, kBaz), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422562 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322563
2564 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422565 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322566
2567 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502568 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502569 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]2d2697f92009-02-18 21:00:322570 EXPECT_TRUE(response->headers->IsKeepAlive());
2571 EXPECT_EQ(407, response->headers->response_code());
2572 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422573 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042574 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]e772db3f2010-07-12 18:11:132575
[email protected]e60e47a2010-07-14 03:37:182576 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
2577 // out of scope.
[email protected]102e27c2011-02-23 01:01:312578 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:322579}
2580
[email protected]a8e9b162009-03-12 00:06:442581// Test that we don't read the response body when we fail to establish a tunnel,
2582// even if the user cancels the proxy's auth attempt.
[email protected]23e482282013-06-14 16:08:022583TEST_P(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:272584 HttpRequestInfo request;
2585 request.method = "GET";
2586 request.url = GURL("https://www.google.com/");
2587 request.load_flags = 0;
2588
[email protected]a8e9b162009-03-12 00:06:442589 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072590 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]a8e9b162009-03-12 00:06:442591
[email protected]bb88e1d32013-05-03 23:11:072592 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:442593
[email protected]262eec82013-03-19 21:01:362594 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502595 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]a8e9b162009-03-12 00:06:442596
[email protected]a8e9b162009-03-12 00:06:442597 // Since we have proxy, should try to establish tunnel.
2598 MockWrite data_writes[] = {
2599 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:452600 "Host: www.google.com\r\n"
2601 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:442602 };
2603
2604 // The proxy responds to the connect with a 407.
2605 MockRead data_reads[] = {
2606 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2607 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2608 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062609 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]a8e9b162009-03-12 00:06:442610 };
2611
[email protected]31a2bfe2010-02-09 08:03:392612 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2613 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072614 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:442615
[email protected]49639fa2011-12-20 23:22:412616 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:442617
[email protected]49639fa2011-12-20 23:22:412618 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422619 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a8e9b162009-03-12 00:06:442620
2621 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422622 EXPECT_EQ(OK, rv);
[email protected]a8e9b162009-03-12 00:06:442623
[email protected]1c773ea12009-04-28 19:58:422624 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502625 ASSERT_TRUE(response != NULL);
[email protected]a8e9b162009-03-12 00:06:442626
2627 EXPECT_TRUE(response->headers->IsKeepAlive());
2628 EXPECT_EQ(407, response->headers->response_code());
2629 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422630 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:442631
2632 std::string response_data;
2633 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:422634 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]e60e47a2010-07-14 03:37:182635
2636 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:312637 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:442638}
2639
[email protected]8fdbcd22010-05-05 02:54:522640// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
2641// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
[email protected]23e482282013-06-14 16:08:022642TEST_P(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:522643 HttpRequestInfo request;
2644 request.method = "GET";
2645 request.url = GURL("http://www.google.com/");
2646 request.load_flags = 0;
2647
[email protected]cb9bf6ca2011-01-28 13:15:272648 // We are using a DIRECT connection (i.e. no proxy) for this session.
[email protected]3fe8d2f82013-10-17 08:56:072649 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272650 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:412651 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:272652
[email protected]8fdbcd22010-05-05 02:54:522653 MockWrite data_writes1[] = {
2654 MockWrite("GET / HTTP/1.1\r\n"
2655 "Host: www.google.com\r\n"
2656 "Connection: keep-alive\r\n\r\n"),
2657 };
2658
2659 MockRead data_reads1[] = {
2660 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
2661 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2662 // Large content-length -- won't matter, as connection will be reset.
2663 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062664 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:522665 };
2666
2667 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2668 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072669 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:522670
[email protected]49639fa2011-12-20 23:22:412671 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:522672
[email protected]49639fa2011-12-20 23:22:412673 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]8fdbcd22010-05-05 02:54:522674 EXPECT_EQ(ERR_IO_PENDING, rv);
2675
2676 rv = callback.WaitForResult();
2677 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
2678}
2679
[email protected]7a67a8152010-11-05 18:31:102680// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
2681// through a non-authenticating proxy. The request should fail with
2682// ERR_UNEXPECTED_PROXY_AUTH.
2683// Note that it is impossible to detect if an HTTP server returns a 407 through
2684// a non-authenticating proxy - there is nothing to indicate whether the
2685// response came from the proxy or the server, so it is treated as if the proxy
2686// issued the challenge.
[email protected]23e482282013-06-14 16:08:022687TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:232688 HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:272689 HttpRequestInfo request;
2690 request.method = "GET";
2691 request.url = GURL("https://www.google.com/");
2692
[email protected]bb88e1d32013-05-03 23:11:072693 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]333bdf62012-06-08 22:57:292694 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072695 session_deps_.net_log = log.bound().net_log();
2696 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:102697
[email protected]7a67a8152010-11-05 18:31:102698 // Since we have proxy, should try to establish tunnel.
2699 MockWrite data_writes1[] = {
2700 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2701 "Host: www.google.com\r\n"
2702 "Proxy-Connection: keep-alive\r\n\r\n"),
2703
2704 MockWrite("GET / HTTP/1.1\r\n"
2705 "Host: www.google.com\r\n"
2706 "Connection: keep-alive\r\n\r\n"),
2707 };
2708
2709 MockRead data_reads1[] = {
2710 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2711
2712 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
2713 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2714 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:062715 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:102716 };
2717
2718 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2719 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072720 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:062721 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072722 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:102723
[email protected]49639fa2011-12-20 23:22:412724 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:102725
[email protected]262eec82013-03-19 21:01:362726 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502727 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a67a8152010-11-05 18:31:102728
[email protected]49639fa2011-12-20 23:22:412729 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7a67a8152010-11-05 18:31:102730 EXPECT_EQ(ERR_IO_PENDING, rv);
2731
2732 rv = callback1.WaitForResult();
2733 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
[email protected]f3da152d2012-06-02 01:00:572734 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:402735 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:102736 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402737 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]7a67a8152010-11-05 18:31:102738 NetLog::PHASE_NONE);
2739 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402740 entries, pos,
[email protected]7a67a8152010-11-05 18:31:102741 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2742 NetLog::PHASE_NONE);
2743}
[email protected]2df19bb2010-08-25 20:13:462744
[email protected]029c83b62013-01-24 05:28:202745// Test the load timing for HTTPS requests with an HTTP proxy.
[email protected]23e482282013-06-14 16:08:022746TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:202747 HttpRequestInfo request1;
2748 request1.method = "GET";
2749 request1.url = GURL("https://www.google.com/1");
2750
2751 HttpRequestInfo request2;
2752 request2.method = "GET";
2753 request2.url = GURL("https://www.google.com/2");
2754
2755 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072756 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:202757 ProxyService::CreateFixed("PROXY myproxy:70"));
2758 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072759 session_deps_.net_log = log.bound().net_log();
2760 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:202761
2762 // Since we have proxy, should try to establish tunnel.
2763 MockWrite data_writes1[] = {
2764 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2765 "Host: www.google.com\r\n"
2766 "Proxy-Connection: keep-alive\r\n\r\n"),
2767
2768 MockWrite("GET /1 HTTP/1.1\r\n"
2769 "Host: www.google.com\r\n"
2770 "Connection: keep-alive\r\n\r\n"),
2771
2772 MockWrite("GET /2 HTTP/1.1\r\n"
2773 "Host: www.google.com\r\n"
2774 "Connection: keep-alive\r\n\r\n"),
2775 };
2776
2777 // The proxy responds to the connect with a 407, using a persistent
2778 // connection.
2779 MockRead data_reads1[] = {
2780 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2781
2782 MockRead("HTTP/1.1 200 OK\r\n"),
2783 MockRead("Content-Length: 1\r\n\r\n"),
2784 MockRead(SYNCHRONOUS, "1"),
2785
2786 MockRead("HTTP/1.1 200 OK\r\n"),
2787 MockRead("Content-Length: 2\r\n\r\n"),
2788 MockRead(SYNCHRONOUS, "22"),
2789 };
2790
2791 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2792 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072793 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:202794 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072795 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:202796
2797 TestCompletionCallback callback1;
[email protected]262eec82013-03-19 21:01:362798 scoped_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:502799 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:202800
2801 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
2802 EXPECT_EQ(ERR_IO_PENDING, rv);
2803
2804 rv = callback1.WaitForResult();
2805 EXPECT_EQ(OK, rv);
2806
2807 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2808 ASSERT_TRUE(response1 != NULL);
[email protected]90499482013-06-01 00:39:502809 ASSERT_TRUE(response1->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:202810 EXPECT_EQ(1, response1->headers->GetContentLength());
2811
2812 LoadTimingInfo load_timing_info1;
2813 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
2814 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
2815
2816 trans1.reset();
2817
2818 TestCompletionCallback callback2;
[email protected]262eec82013-03-19 21:01:362819 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:502820 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:202821
2822 rv = trans2->Start(&request2, callback2.callback(), log.bound());
2823 EXPECT_EQ(ERR_IO_PENDING, rv);
2824
2825 rv = callback2.WaitForResult();
2826 EXPECT_EQ(OK, rv);
2827
2828 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2829 ASSERT_TRUE(response2 != NULL);
[email protected]90499482013-06-01 00:39:502830 ASSERT_TRUE(response2->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:202831 EXPECT_EQ(2, response2->headers->GetContentLength());
2832
2833 LoadTimingInfo load_timing_info2;
2834 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
2835 TestLoadTimingReused(load_timing_info2);
2836
2837 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2838
2839 trans2.reset();
2840 session->CloseAllConnections();
2841}
2842
2843// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
[email protected]23e482282013-06-14 16:08:022844TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:202845 HttpRequestInfo request1;
2846 request1.method = "GET";
2847 request1.url = GURL("https://www.google.com/1");
2848
2849 HttpRequestInfo request2;
2850 request2.method = "GET";
2851 request2.url = GURL("https://www.google.com/2");
2852
2853 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072854 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:202855 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
2856 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072857 session_deps_.net_log = log.bound().net_log();
2858 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:202859
2860 // Since we have proxy, should try to establish tunnel.
2861 MockWrite data_writes1[] = {
2862 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2863 "Host: www.google.com\r\n"
2864 "Proxy-Connection: keep-alive\r\n\r\n"),
2865
2866 MockWrite("GET /1 HTTP/1.1\r\n"
2867 "Host: www.google.com\r\n"
2868 "Connection: keep-alive\r\n\r\n"),
2869
2870 MockWrite("GET /2 HTTP/1.1\r\n"
2871 "Host: www.google.com\r\n"
2872 "Connection: keep-alive\r\n\r\n"),
2873 };
2874
2875 // The proxy responds to the connect with a 407, using a persistent
2876 // connection.
2877 MockRead data_reads1[] = {
2878 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2879
2880 MockRead("HTTP/1.1 200 OK\r\n"),
2881 MockRead("Content-Length: 1\r\n\r\n"),
2882 MockRead(SYNCHRONOUS, "1"),
2883
2884 MockRead("HTTP/1.1 200 OK\r\n"),
2885 MockRead("Content-Length: 2\r\n\r\n"),
2886 MockRead(SYNCHRONOUS, "22"),
2887 };
2888
2889 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2890 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072891 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:202892 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072893 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:202894
2895 TestCompletionCallback callback1;
[email protected]262eec82013-03-19 21:01:362896 scoped_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:502897 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:202898
2899 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
2900 EXPECT_EQ(ERR_IO_PENDING, rv);
2901
2902 rv = callback1.WaitForResult();
2903 EXPECT_EQ(OK, rv);
2904
2905 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2906 ASSERT_TRUE(response1 != NULL);
[email protected]90499482013-06-01 00:39:502907 ASSERT_TRUE(response1->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:202908 EXPECT_EQ(1, response1->headers->GetContentLength());
2909
2910 LoadTimingInfo load_timing_info1;
2911 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
2912 TestLoadTimingNotReusedWithPac(load_timing_info1,
2913 CONNECT_TIMING_HAS_SSL_TIMES);
2914
2915 trans1.reset();
2916
2917 TestCompletionCallback callback2;
[email protected]262eec82013-03-19 21:01:362918 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:502919 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:202920
2921 rv = trans2->Start(&request2, callback2.callback(), log.bound());
2922 EXPECT_EQ(ERR_IO_PENDING, rv);
2923
2924 rv = callback2.WaitForResult();
2925 EXPECT_EQ(OK, rv);
2926
2927 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2928 ASSERT_TRUE(response2 != NULL);
[email protected]90499482013-06-01 00:39:502929 ASSERT_TRUE(response2->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:202930 EXPECT_EQ(2, response2->headers->GetContentLength());
2931
2932 LoadTimingInfo load_timing_info2;
2933 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
2934 TestLoadTimingReusedWithPac(load_timing_info2);
2935
2936 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2937
2938 trans2.reset();
2939 session->CloseAllConnections();
2940}
2941
[email protected]2df19bb2010-08-25 20:13:462942// Test a simple get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:022943TEST_P(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:272944 HttpRequestInfo request;
2945 request.method = "GET";
2946 request.url = GURL("http://www.google.com/");
2947
[email protected]2df19bb2010-08-25 20:13:462948 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:072949 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:112950 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:292951 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072952 session_deps_.net_log = log.bound().net_log();
2953 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:462954
[email protected]2df19bb2010-08-25 20:13:462955 // Since we have proxy, should use full url
2956 MockWrite data_writes1[] = {
2957 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
2958 "Host: www.google.com\r\n"
2959 "Proxy-Connection: keep-alive\r\n\r\n"),
2960 };
2961
2962 MockRead data_reads1[] = {
2963 MockRead("HTTP/1.1 200 OK\r\n"),
2964 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2965 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062966 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:462967 };
2968
2969 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2970 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072971 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:062972 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072973 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:462974
[email protected]49639fa2011-12-20 23:22:412975 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:462976
[email protected]262eec82013-03-19 21:01:362977 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502978 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:502979
[email protected]49639fa2011-12-20 23:22:412980 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:462981 EXPECT_EQ(ERR_IO_PENDING, rv);
2982
2983 rv = callback1.WaitForResult();
2984 EXPECT_EQ(OK, rv);
2985
[email protected]58e32bb2013-01-21 18:23:252986 LoadTimingInfo load_timing_info;
2987 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2988 TestLoadTimingNotReused(load_timing_info,
2989 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
2990
[email protected]2df19bb2010-08-25 20:13:462991 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502992 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:462993
2994 EXPECT_TRUE(response->headers->IsKeepAlive());
2995 EXPECT_EQ(200, response->headers->response_code());
2996 EXPECT_EQ(100, response->headers->GetContentLength());
2997 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2998
2999 // The password prompt info should not be set.
3000 EXPECT_TRUE(response->auth_challenge.get() == NULL);
3001}
3002
[email protected]7642b5ae2010-09-01 20:55:173003// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023004TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:273005 HttpRequestInfo request;
3006 request.method = "GET";
3007 request.url = GURL("http://www.google.com/");
3008 request.load_flags = 0;
3009
[email protected]7642b5ae2010-09-01 20:55:173010 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073011 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113012 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:293013 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073014 session_deps_.net_log = log.bound().net_log();
3015 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:173016
[email protected]7642b5ae2010-09-01 20:55:173017 // fetch http://www.google.com/ via SPDY
[email protected]cdf8f7e72013-05-23 10:56:463018 scoped_ptr<SpdyFrame> req(
3019 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]7642b5ae2010-09-01 20:55:173020 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
3021
[email protected]23e482282013-06-14 16:08:023022 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3023 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:173024 MockRead spdy_reads[] = {
3025 CreateMockRead(*resp),
3026 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:063027 MockRead(ASYNC, 0, 0),
[email protected]7642b5ae2010-09-01 20:55:173028 };
3029
[email protected]dd54bd82012-07-19 23:44:573030 DelayedSocketData spdy_data(
3031 1, // wait for one write to finish before reading.
3032 spdy_reads, arraysize(spdy_reads),
3033 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073034 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:173035
[email protected]8ddf8322012-02-23 18:08:063036 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023037 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073038 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:173039
[email protected]49639fa2011-12-20 23:22:413040 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:173041
[email protected]262eec82013-03-19 21:01:363042 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503043 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503044
[email protected]49639fa2011-12-20 23:22:413045 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7642b5ae2010-09-01 20:55:173046 EXPECT_EQ(ERR_IO_PENDING, rv);
3047
3048 rv = callback1.WaitForResult();
3049 EXPECT_EQ(OK, rv);
3050
[email protected]58e32bb2013-01-21 18:23:253051 LoadTimingInfo load_timing_info;
3052 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3053 TestLoadTimingNotReused(load_timing_info,
3054 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3055
[email protected]7642b5ae2010-09-01 20:55:173056 const HttpResponseInfo* response = trans->GetResponseInfo();
3057 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503058 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]7642b5ae2010-09-01 20:55:173059 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3060
3061 std::string response_data;
3062 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:233063 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:173064}
3065
[email protected]1c173852014-06-19 12:51:503066// Verifies that a session which races and wins against the owning transaction
3067// (completing prior to host resolution), doesn't fail the transaction.
3068// Regression test for crbug.com/334413.
3069TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
3070 HttpRequestInfo request;
3071 request.method = "GET";
3072 request.url = GURL("http://www.google.com/");
3073 request.load_flags = 0;
3074
3075 // Configure SPDY proxy server "proxy:70".
3076 session_deps_.proxy_service.reset(
3077 ProxyService::CreateFixed("https://proxy:70"));
3078 CapturingBoundNetLog log;
3079 session_deps_.net_log = log.bound().net_log();
3080 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3081
3082 // Fetch http://www.google.com/ through the SPDY proxy.
3083 scoped_ptr<SpdyFrame> req(
3084 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
3085 MockWrite spdy_writes[] = {CreateMockWrite(*req)};
3086
3087 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3088 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
3089 MockRead spdy_reads[] = {
3090 CreateMockRead(*resp), CreateMockRead(*data), MockRead(ASYNC, 0, 0),
3091 };
3092
3093 DelayedSocketData spdy_data(
3094 1, // wait for one write to finish before reading.
3095 spdy_reads,
3096 arraysize(spdy_reads),
3097 spdy_writes,
3098 arraysize(spdy_writes));
3099 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
3100
3101 SSLSocketDataProvider ssl(ASYNC, OK);
3102 ssl.SetNextProto(GetParam());
3103 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3104
3105 TestCompletionCallback callback1;
3106
3107 scoped_ptr<HttpTransaction> trans(
3108 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3109
3110 // Stall the hostname resolution begun by the transaction.
3111 session_deps_.host_resolver->set_synchronous_mode(false);
3112 session_deps_.host_resolver->set_ondemand_mode(true);
3113
3114 int rv = trans->Start(&request, callback1.callback(), log.bound());
3115 EXPECT_EQ(ERR_IO_PENDING, rv);
3116
3117 // Race a session to the proxy, which completes first.
3118 session_deps_.host_resolver->set_ondemand_mode(false);
3119 SpdySessionKey key(
3120 HostPortPair("proxy", 70), ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
3121 base::WeakPtr<SpdySession> spdy_session =
3122 CreateSecureSpdySession(session, key, log.bound());
3123
3124 // Unstall the resolution begun by the transaction.
3125 session_deps_.host_resolver->set_ondemand_mode(true);
3126 session_deps_.host_resolver->ResolveAllPending();
3127
3128 EXPECT_FALSE(callback1.have_result());
3129 rv = callback1.WaitForResult();
3130 EXPECT_EQ(OK, rv);
3131
3132 const HttpResponseInfo* response = trans->GetResponseInfo();
3133 ASSERT_TRUE(response != NULL);
3134 ASSERT_TRUE(response->headers.get() != NULL);
3135 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3136
3137 std::string response_data;
3138 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
3139 EXPECT_EQ(kUploadData, response_data);
3140}
3141
[email protected]dc7bd1c52010-11-12 00:01:133142// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023143TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:273144 HttpRequestInfo request;
3145 request.method = "GET";
3146 request.url = GURL("http://www.google.com/");
3147 request.load_flags = 0;
3148
[email protected]79cb5c12011-09-12 13:12:043149 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073150 session_deps_.proxy_service.reset(
[email protected]79cb5c12011-09-12 13:12:043151 ProxyService::CreateFixed("https://myproxy:70"));
[email protected]333bdf62012-06-08 22:57:293152 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073153 session_deps_.net_log = log.bound().net_log();
3154 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:133155
[email protected]dc7bd1c52010-11-12 00:01:133156 // The first request will be a bare GET, the second request will be a
3157 // GET with a Proxy-Authorization header.
[email protected]ff98d7f02012-03-22 21:44:193158 scoped_ptr<SpdyFrame> req_get(
[email protected]cdf8f7e72013-05-23 10:56:463159 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]dc7bd1c52010-11-12 00:01:133160 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:463161 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:133162 };
[email protected]ff98d7f02012-03-22 21:44:193163 scoped_ptr<SpdyFrame> req_get_authorization(
[email protected]cdf8f7e72013-05-23 10:56:463164 spdy_util_.ConstructSpdyGet(kExtraAuthorizationHeaders,
3165 arraysize(kExtraAuthorizationHeaders) / 2,
3166 false,
3167 3,
3168 LOWEST,
3169 false));
[email protected]dc7bd1c52010-11-12 00:01:133170 MockWrite spdy_writes[] = {
3171 CreateMockWrite(*req_get, 1),
3172 CreateMockWrite(*req_get_authorization, 4),
3173 };
3174
3175 // The first response is a 407 proxy authentication challenge, and the second
3176 // response will be a 200 response since the second request includes a valid
3177 // Authorization header.
3178 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:463179 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:133180 };
[email protected]ff98d7f02012-03-22 21:44:193181 scoped_ptr<SpdyFrame> resp_authentication(
[email protected]23e482282013-06-14 16:08:023182 spdy_util_.ConstructSpdySynReplyError(
[email protected]dc7bd1c52010-11-12 00:01:133183 "407 Proxy Authentication Required",
3184 kExtraAuthenticationHeaders, arraysize(kExtraAuthenticationHeaders)/2,
3185 1));
[email protected]ff98d7f02012-03-22 21:44:193186 scoped_ptr<SpdyFrame> body_authentication(
[email protected]23e482282013-06-14 16:08:023187 spdy_util_.ConstructSpdyBodyFrame(1, true));
3188 scoped_ptr<SpdyFrame> resp_data(
3189 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
3190 scoped_ptr<SpdyFrame> body_data(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:133191 MockRead spdy_reads[] = {
3192 CreateMockRead(*resp_authentication, 2),
3193 CreateMockRead(*body_authentication, 3),
3194 CreateMockRead(*resp_data, 5),
3195 CreateMockRead(*body_data, 6),
[email protected]8ddf8322012-02-23 18:08:063196 MockRead(ASYNC, 0, 7),
[email protected]dc7bd1c52010-11-12 00:01:133197 };
3198
[email protected]dd54bd82012-07-19 23:44:573199 OrderedSocketData data(
3200 spdy_reads, arraysize(spdy_reads),
3201 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073202 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:133203
[email protected]8ddf8322012-02-23 18:08:063204 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023205 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073206 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:133207
[email protected]49639fa2011-12-20 23:22:413208 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:133209
[email protected]262eec82013-03-19 21:01:363210 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503211 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]dc7bd1c52010-11-12 00:01:133212
[email protected]49639fa2011-12-20 23:22:413213 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]dc7bd1c52010-11-12 00:01:133214 EXPECT_EQ(ERR_IO_PENDING, rv);
3215
3216 rv = callback1.WaitForResult();
3217 EXPECT_EQ(OK, rv);
3218
3219 const HttpResponseInfo* const response = trans->GetResponseInfo();
3220
3221 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503222 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]dc7bd1c52010-11-12 00:01:133223 EXPECT_EQ(407, response->headers->response_code());
3224 EXPECT_TRUE(response->was_fetched_via_spdy);
[email protected]79cb5c12011-09-12 13:12:043225 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:133226
[email protected]49639fa2011-12-20 23:22:413227 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:133228
[email protected]49639fa2011-12-20 23:22:413229 rv = trans->RestartWithAuth(
3230 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]dc7bd1c52010-11-12 00:01:133231 EXPECT_EQ(ERR_IO_PENDING, rv);
3232
3233 rv = callback2.WaitForResult();
3234 EXPECT_EQ(OK, rv);
3235
3236 const HttpResponseInfo* const response_restart = trans->GetResponseInfo();
3237
3238 ASSERT_TRUE(response_restart != NULL);
[email protected]90499482013-06-01 00:39:503239 ASSERT_TRUE(response_restart->headers.get() != NULL);
[email protected]dc7bd1c52010-11-12 00:01:133240 EXPECT_EQ(200, response_restart->headers->response_code());
3241 // The password prompt info should not be set.
3242 EXPECT_TRUE(response_restart->auth_challenge.get() == NULL);
3243}
3244
[email protected]d9da5fe2010-10-13 22:37:163245// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
[email protected]23e482282013-06-14 16:08:023246TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:273247 HttpRequestInfo request;
3248 request.method = "GET";
3249 request.url = GURL("https://www.google.com/");
3250 request.load_flags = 0;
3251
[email protected]d9da5fe2010-10-13 22:37:163252 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073253 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113254 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:293255 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073256 session_deps_.net_log = log.bound().net_log();
3257 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:163258
[email protected]262eec82013-03-19 21:01:363259 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503260 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:163261
[email protected]d9da5fe2010-10-13 22:37:163262 // CONNECT to www.google.com:443 via SPDY
lgarrona91df87f2014-12-05 00:51:343263 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(
3264 NULL, 0, 1, LOWEST, HostPortPair("www.google.com", 443)));
[email protected]d9da5fe2010-10-13 22:37:163265 // fetch https://www.google.com/ via HTTP
3266
3267 const char get[] = "GET / HTTP/1.1\r\n"
3268 "Host: www.google.com\r\n"
3269 "Connection: keep-alive\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:193270 scoped_ptr<SpdyFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:023271 spdy_util_.ConstructSpdyBodyFrame(1, get, strlen(get), false));
3272 scoped_ptr<SpdyFrame> conn_resp(
3273 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:163274 const char resp[] = "HTTP/1.1 200 OK\r\n"
3275 "Content-Length: 10\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:193276 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:023277 spdy_util_.ConstructSpdyBodyFrame(1, resp, strlen(resp), false));
[email protected]ff98d7f02012-03-22 21:44:193278 scoped_ptr<SpdyFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:023279 spdy_util_.ConstructSpdyBodyFrame(1, "1234567890", 10, false));
[email protected]ff98d7f02012-03-22 21:44:193280 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203281 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
[email protected]8d2f7012012-02-16 00:08:043282
3283 MockWrite spdy_writes[] = {
3284 CreateMockWrite(*connect, 1),
3285 CreateMockWrite(*wrapped_get, 3),
[email protected]cdf8f7e72013-05-23 10:56:463286 CreateMockWrite(*window_update, 5),
[email protected]8d2f7012012-02-16 00:08:043287 };
3288
[email protected]d9da5fe2010-10-13 22:37:163289 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:063290 CreateMockRead(*conn_resp, 2, ASYNC),
3291 CreateMockRead(*wrapped_get_resp, 4, ASYNC),
3292 CreateMockRead(*wrapped_body, 6, ASYNC),
3293 CreateMockRead(*wrapped_body, 7, ASYNC),
3294 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:163295 };
3296
[email protected]dd54bd82012-07-19 23:44:573297 OrderedSocketData spdy_data(
3298 spdy_reads, arraysize(spdy_reads),
3299 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073300 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163301
[email protected]8ddf8322012-02-23 18:08:063302 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023303 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073304 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063305 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]d9da5fe2010-10-13 22:37:163306 ssl2.was_npn_negotiated = false;
[email protected]8e3c78cb2012-03-31 03:58:463307 ssl2.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:073308 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163309
[email protected]49639fa2011-12-20 23:22:413310 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163311
[email protected]49639fa2011-12-20 23:22:413312 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163313 EXPECT_EQ(ERR_IO_PENDING, rv);
3314
3315 rv = callback1.WaitForResult();
3316 EXPECT_EQ(OK, rv);
3317
[email protected]58e32bb2013-01-21 18:23:253318 LoadTimingInfo load_timing_info;
3319 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3320 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3321
[email protected]d9da5fe2010-10-13 22:37:163322 const HttpResponseInfo* response = trans->GetResponseInfo();
3323 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503324 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d9da5fe2010-10-13 22:37:163325 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3326
3327 std::string response_data;
3328 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
3329 EXPECT_EQ("1234567890", response_data);
3330}
3331
3332// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
[email protected]23e482282013-06-14 16:08:023333TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
[email protected]cb9bf6ca2011-01-28 13:15:273334 HttpRequestInfo request;
3335 request.method = "GET";
3336 request.url = GURL("https://www.google.com/");
3337 request.load_flags = 0;
3338
[email protected]d9da5fe2010-10-13 22:37:163339 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073340 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113341 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:293342 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073343 session_deps_.net_log = log.bound().net_log();
3344 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:163345
[email protected]262eec82013-03-19 21:01:363346 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503347 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:163348
[email protected]d9da5fe2010-10-13 22:37:163349 // CONNECT to www.google.com:443 via SPDY
lgarrona91df87f2014-12-05 00:51:343350 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(
3351 NULL, 0, 1, LOWEST, HostPortPair("www.google.com", 443)));
[email protected]d9da5fe2010-10-13 22:37:163352 // fetch https://www.google.com/ via SPDY
3353 const char* const kMyUrl = "https://www.google.com/";
[email protected]cdf8f7e72013-05-23 10:56:463354 scoped_ptr<SpdyFrame> get(
3355 spdy_util_.ConstructSpdyGet(kMyUrl, false, 1, LOWEST));
[email protected]23e482282013-06-14 16:08:023356 scoped_ptr<SpdyFrame> wrapped_get(
3357 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
3358 scoped_ptr<SpdyFrame> conn_resp(
3359 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3360 scoped_ptr<SpdyFrame> get_resp(
3361 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]ff98d7f02012-03-22 21:44:193362 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:023363 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
3364 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
3365 scoped_ptr<SpdyFrame> wrapped_body(
3366 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
[email protected]ff98d7f02012-03-22 21:44:193367 scoped_ptr<SpdyFrame> window_update_get_resp(
[email protected]c10b20852013-05-15 21:29:203368 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
[email protected]ff98d7f02012-03-22 21:44:193369 scoped_ptr<SpdyFrame> window_update_body(
[email protected]c10b20852013-05-15 21:29:203370 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body->size()));
[email protected]8d2f7012012-02-16 00:08:043371
3372 MockWrite spdy_writes[] = {
3373 CreateMockWrite(*connect, 1),
3374 CreateMockWrite(*wrapped_get, 3),
3375 CreateMockWrite(*window_update_get_resp, 5),
3376 CreateMockWrite(*window_update_body, 7),
3377 };
3378
[email protected]d9da5fe2010-10-13 22:37:163379 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:063380 CreateMockRead(*conn_resp, 2, ASYNC),
3381 CreateMockRead(*wrapped_get_resp, 4, ASYNC),
3382 CreateMockRead(*wrapped_body, 6, ASYNC),
3383 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:163384 };
3385
[email protected]dd54bd82012-07-19 23:44:573386 OrderedSocketData spdy_data(
3387 spdy_reads, arraysize(spdy_reads),
3388 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073389 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163390
[email protected]8ddf8322012-02-23 18:08:063391 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023392 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073393 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063394 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023395 ssl2.SetNextProto(GetParam());
3396 ssl2.protocol_negotiated = GetParam();
[email protected]bb88e1d32013-05-03 23:11:073397 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163398
[email protected]49639fa2011-12-20 23:22:413399 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163400
[email protected]49639fa2011-12-20 23:22:413401 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163402 EXPECT_EQ(ERR_IO_PENDING, rv);
3403
3404 rv = callback1.WaitForResult();
3405 EXPECT_EQ(OK, rv);
3406
[email protected]58e32bb2013-01-21 18:23:253407 LoadTimingInfo load_timing_info;
3408 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3409 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3410
[email protected]d9da5fe2010-10-13 22:37:163411 const HttpResponseInfo* response = trans->GetResponseInfo();
3412 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503413 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d9da5fe2010-10-13 22:37:163414 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3415
3416 std::string response_data;
3417 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:233418 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:163419}
3420
3421// Test a SPDY CONNECT failure through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023422TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:273423 HttpRequestInfo request;
3424 request.method = "GET";
3425 request.url = GURL("https://www.google.com/");
3426 request.load_flags = 0;
3427
[email protected]d9da5fe2010-10-13 22:37:163428 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073429 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113430 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:293431 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073432 session_deps_.net_log = log.bound().net_log();
3433 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:163434
[email protected]262eec82013-03-19 21:01:363435 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503436 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:163437
[email protected]d9da5fe2010-10-13 22:37:163438 // CONNECT to www.google.com:443 via SPDY
lgarrona91df87f2014-12-05 00:51:343439 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(
3440 NULL, 0, 1, LOWEST, HostPortPair("www.google.com", 443)));
[email protected]c10b20852013-05-15 21:29:203441 scoped_ptr<SpdyFrame> get(
3442 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:163443
3444 MockWrite spdy_writes[] = {
3445 CreateMockWrite(*connect, 1),
3446 CreateMockWrite(*get, 3),
3447 };
3448
[email protected]23e482282013-06-14 16:08:023449 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdySynReplyError(1));
3450 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:163451 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:063452 CreateMockRead(*resp, 2, ASYNC),
3453 MockRead(ASYNC, 0, 4),
[email protected]d9da5fe2010-10-13 22:37:163454 };
3455
[email protected]dd54bd82012-07-19 23:44:573456 OrderedSocketData spdy_data(
3457 spdy_reads, arraysize(spdy_reads),
3458 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073459 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163460
[email protected]8ddf8322012-02-23 18:08:063461 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023462 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073463 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063464 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023465 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073466 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163467
[email protected]49639fa2011-12-20 23:22:413468 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163469
[email protected]49639fa2011-12-20 23:22:413470 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163471 EXPECT_EQ(ERR_IO_PENDING, rv);
3472
3473 rv = callback1.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:173474 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]d9da5fe2010-10-13 22:37:163475
[email protected]4eddbc732012-08-09 05:40:173476 // TODO(ttuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:163477}
3478
[email protected]f6c63db52013-02-02 00:35:223479// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
3480// HTTPS Proxy to different servers.
[email protected]23e482282013-06-14 16:08:023481TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:223482 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
3483 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073484 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:223485 "https://proxy:70"));
3486 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073487 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:223488 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:073489 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:223490
3491 HttpRequestInfo request1;
3492 request1.method = "GET";
3493 request1.url = GURL("https://www.google.com/");
3494 request1.load_flags = 0;
3495
3496 HttpRequestInfo request2;
3497 request2.method = "GET";
3498 request2.url = GURL("https://news.google.com/");
3499 request2.load_flags = 0;
3500
3501 // CONNECT to www.google.com:443 via SPDY.
lgarrona91df87f2014-12-05 00:51:343502 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(
3503 NULL, 0, 1, LOWEST, HostPortPair("www.google.com", 443)));
[email protected]23e482282013-06-14 16:08:023504 scoped_ptr<SpdyFrame> conn_resp1(
3505 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:223506
3507 // Fetch https://www.google.com/ via HTTP.
3508 const char get1[] = "GET / HTTP/1.1\r\n"
3509 "Host: www.google.com\r\n"
3510 "Connection: keep-alive\r\n\r\n";
3511 scoped_ptr<SpdyFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:023512 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:223513 const char resp1[] = "HTTP/1.1 200 OK\r\n"
3514 "Content-Length: 1\r\n\r\n";
3515 scoped_ptr<SpdyFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:023516 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
3517 scoped_ptr<SpdyFrame> wrapped_body1(
3518 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
[email protected]f6c63db52013-02-02 00:35:223519 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203520 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:223521
3522 // CONNECT to news.google.com:443 via SPDY.
[email protected]745aa9c2014-06-27 02:21:293523 SpdyHeaderBlock connect2_block;
3524 connect2_block[spdy_util_.GetMethodKey()] = "CONNECT";
3525 connect2_block[spdy_util_.GetPathKey()] = "news.google.com:443";
3526 connect2_block[spdy_util_.GetHostKey()] = "news.google.com";
3527 spdy_util_.MaybeAddVersionHeader(&connect2_block);
[email protected]f6c63db52013-02-02 00:35:223528 scoped_ptr<SpdyFrame> connect2(
[email protected]745aa9c2014-06-27 02:21:293529 spdy_util_.ConstructSpdySyn(3, connect2_block, LOWEST, false, false));
[email protected]601e03f12014-04-06 16:26:393530
[email protected]23e482282013-06-14 16:08:023531 scoped_ptr<SpdyFrame> conn_resp2(
3532 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:223533
3534 // Fetch https://news.google.com/ via HTTP.
3535 const char get2[] = "GET / HTTP/1.1\r\n"
3536 "Host: news.google.com\r\n"
3537 "Connection: keep-alive\r\n\r\n";
3538 scoped_ptr<SpdyFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:023539 spdy_util_.ConstructSpdyBodyFrame(3, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:223540 const char resp2[] = "HTTP/1.1 200 OK\r\n"
3541 "Content-Length: 2\r\n\r\n";
3542 scoped_ptr<SpdyFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:023543 spdy_util_.ConstructSpdyBodyFrame(3, resp2, strlen(resp2), false));
[email protected]f6c63db52013-02-02 00:35:223544 scoped_ptr<SpdyFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:023545 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:223546
3547 MockWrite spdy_writes[] = {
3548 CreateMockWrite(*connect1, 0),
3549 CreateMockWrite(*wrapped_get1, 2),
3550 CreateMockWrite(*connect2, 5),
3551 CreateMockWrite(*wrapped_get2, 7),
3552 };
3553
3554 MockRead spdy_reads[] = {
3555 CreateMockRead(*conn_resp1, 1, ASYNC),
3556 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
3557 CreateMockRead(*wrapped_body1, 4, ASYNC),
3558 CreateMockRead(*conn_resp2, 6, ASYNC),
3559 CreateMockRead(*wrapped_get_resp2, 8, ASYNC),
3560 CreateMockRead(*wrapped_body2, 9, ASYNC),
3561 MockRead(ASYNC, 0, 10),
3562 };
3563
3564 DeterministicSocketData spdy_data(
3565 spdy_reads, arraysize(spdy_reads),
3566 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073567 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:223568
3569 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023570 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073571 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:223572 SSLSocketDataProvider ssl2(ASYNC, OK);
3573 ssl2.was_npn_negotiated = false;
3574 ssl2.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:073575 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:223576 SSLSocketDataProvider ssl3(ASYNC, OK);
3577 ssl3.was_npn_negotiated = false;
3578 ssl3.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:073579 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:223580
3581 TestCompletionCallback callback;
3582
[email protected]262eec82013-03-19 21:01:363583 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503584 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223585 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
3586 EXPECT_EQ(ERR_IO_PENDING, rv);
3587 // The first connect and request, each of their responses, and the body.
3588 spdy_data.RunFor(5);
3589
3590 rv = callback.WaitForResult();
3591 EXPECT_EQ(OK, rv);
3592
3593 LoadTimingInfo load_timing_info;
3594 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3595 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3596
3597 const HttpResponseInfo* response = trans->GetResponseInfo();
3598 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503599 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:223600 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3601
3602 std::string response_data;
3603 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
[email protected]90499482013-06-01 00:39:503604 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223605
[email protected]262eec82013-03-19 21:01:363606 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503607 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223608 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
3609 EXPECT_EQ(ERR_IO_PENDING, rv);
3610
3611 // The second connect and request, each of their responses, and the body.
3612 spdy_data.RunFor(5);
3613 rv = callback.WaitForResult();
3614 EXPECT_EQ(OK, rv);
3615
3616 LoadTimingInfo load_timing_info2;
3617 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3618 // Even though the SPDY connection is reused, a new tunnelled connection has
3619 // to be created, so the socket's load timing looks like a fresh connection.
3620 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
3621
3622 // The requests should have different IDs, since they each are using their own
3623 // separate stream.
3624 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
3625
[email protected]90499482013-06-01 00:39:503626 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223627}
3628
3629// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
3630// HTTPS Proxy to the same server.
[email protected]23e482282013-06-14 16:08:023631TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:223632 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
3633 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073634 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:223635 "https://proxy:70"));
3636 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073637 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:223638 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:073639 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:223640
3641 HttpRequestInfo request1;
3642 request1.method = "GET";
3643 request1.url = GURL("https://www.google.com/");
3644 request1.load_flags = 0;
3645
3646 HttpRequestInfo request2;
3647 request2.method = "GET";
3648 request2.url = GURL("https://www.google.com/2");
3649 request2.load_flags = 0;
3650
3651 // CONNECT to www.google.com:443 via SPDY.
lgarrona91df87f2014-12-05 00:51:343652 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(
3653 NULL, 0, 1, LOWEST, HostPortPair("www.google.com", 443)));
[email protected]23e482282013-06-14 16:08:023654 scoped_ptr<SpdyFrame> conn_resp1(
3655 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:223656
3657 // Fetch https://www.google.com/ via HTTP.
3658 const char get1[] = "GET / HTTP/1.1\r\n"
3659 "Host: www.google.com\r\n"
3660 "Connection: keep-alive\r\n\r\n";
3661 scoped_ptr<SpdyFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:023662 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:223663 const char resp1[] = "HTTP/1.1 200 OK\r\n"
3664 "Content-Length: 1\r\n\r\n";
3665 scoped_ptr<SpdyFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:023666 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
3667 scoped_ptr<SpdyFrame> wrapped_body1(
3668 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
[email protected]f6c63db52013-02-02 00:35:223669 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203670 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:223671
3672 // Fetch https://www.google.com/2 via HTTP.
3673 const char get2[] = "GET /2 HTTP/1.1\r\n"
3674 "Host: www.google.com\r\n"
3675 "Connection: keep-alive\r\n\r\n";
3676 scoped_ptr<SpdyFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:023677 spdy_util_.ConstructSpdyBodyFrame(1, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:223678 const char resp2[] = "HTTP/1.1 200 OK\r\n"
3679 "Content-Length: 2\r\n\r\n";
3680 scoped_ptr<SpdyFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:023681 spdy_util_.ConstructSpdyBodyFrame(1, resp2, strlen(resp2), false));
[email protected]f6c63db52013-02-02 00:35:223682 scoped_ptr<SpdyFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:023683 spdy_util_.ConstructSpdyBodyFrame(1, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:223684
3685 MockWrite spdy_writes[] = {
3686 CreateMockWrite(*connect1, 0),
3687 CreateMockWrite(*wrapped_get1, 2),
3688 CreateMockWrite(*wrapped_get2, 5),
3689 };
3690
3691 MockRead spdy_reads[] = {
3692 CreateMockRead(*conn_resp1, 1, ASYNC),
3693 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
3694 CreateMockRead(*wrapped_body1, 4, ASYNC),
3695 CreateMockRead(*wrapped_get_resp2, 6, ASYNC),
3696 CreateMockRead(*wrapped_body2, 7, ASYNC),
3697 MockRead(ASYNC, 0, 8),
3698 };
3699
3700 DeterministicSocketData spdy_data(
3701 spdy_reads, arraysize(spdy_reads),
3702 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073703 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:223704
3705 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023706 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073707 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:223708 SSLSocketDataProvider ssl2(ASYNC, OK);
3709 ssl2.was_npn_negotiated = false;
3710 ssl2.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:073711 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:223712
3713 TestCompletionCallback callback;
3714
[email protected]262eec82013-03-19 21:01:363715 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503716 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223717 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
3718 EXPECT_EQ(ERR_IO_PENDING, rv);
3719 // The first connect and request, each of their responses, and the body.
3720 spdy_data.RunFor(5);
3721
3722 rv = callback.WaitForResult();
3723 EXPECT_EQ(OK, rv);
3724
3725 LoadTimingInfo load_timing_info;
3726 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3727 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3728
3729 const HttpResponseInfo* response = trans->GetResponseInfo();
3730 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503731 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:223732 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3733
3734 std::string response_data;
3735 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
[email protected]90499482013-06-01 00:39:503736 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223737 trans.reset();
3738
[email protected]262eec82013-03-19 21:01:363739 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503740 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223741 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
3742 EXPECT_EQ(ERR_IO_PENDING, rv);
3743
3744 // The second request, response, and body. There should not be a second
3745 // connect.
3746 spdy_data.RunFor(3);
3747 rv = callback.WaitForResult();
3748 EXPECT_EQ(OK, rv);
3749
3750 LoadTimingInfo load_timing_info2;
3751 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3752 TestLoadTimingReused(load_timing_info2);
3753
3754 // The requests should have the same ID.
3755 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
3756
[email protected]90499482013-06-01 00:39:503757 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223758}
3759
3760// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
3761// Proxy to different servers.
[email protected]23e482282013-06-14 16:08:023762TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:223763 HttpsProxySpdyLoadTimingTwoHttpRequests) {
3764 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073765 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:223766 "https://proxy:70"));
3767 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073768 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:223769 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:073770 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:223771
3772 HttpRequestInfo request1;
3773 request1.method = "GET";
3774 request1.url = GURL("http://www.google.com/");
3775 request1.load_flags = 0;
3776
3777 HttpRequestInfo request2;
3778 request2.method = "GET";
3779 request2.url = GURL("http://news.google.com/");
3780 request2.load_flags = 0;
3781
3782 // http://www.google.com/
[email protected]23e482282013-06-14 16:08:023783 scoped_ptr<SpdyHeaderBlock> headers(
3784 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/"));
[email protected]745aa9c2014-06-27 02:21:293785 scoped_ptr<SpdyFrame> get1(
3786 spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, false, true));
[email protected]23e482282013-06-14 16:08:023787 scoped_ptr<SpdyFrame> get_resp1(
3788 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3789 scoped_ptr<SpdyFrame> body1(
3790 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, true));
[email protected]f6c63db52013-02-02 00:35:223791
3792 // http://news.google.com/
[email protected]23e482282013-06-14 16:08:023793 scoped_ptr<SpdyHeaderBlock> headers2(
3794 spdy_util_.ConstructGetHeaderBlockForProxy("http://news.google.com/"));
[email protected]745aa9c2014-06-27 02:21:293795 scoped_ptr<SpdyFrame> get2(
3796 spdy_util_.ConstructSpdySyn(3, *headers2, LOWEST, false, true));
[email protected]23e482282013-06-14 16:08:023797 scoped_ptr<SpdyFrame> get_resp2(
3798 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
3799 scoped_ptr<SpdyFrame> body2(
3800 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, true));
[email protected]f6c63db52013-02-02 00:35:223801
3802 MockWrite spdy_writes[] = {
3803 CreateMockWrite(*get1, 0),
3804 CreateMockWrite(*get2, 3),
3805 };
3806
3807 MockRead spdy_reads[] = {
3808 CreateMockRead(*get_resp1, 1, ASYNC),
3809 CreateMockRead(*body1, 2, ASYNC),
3810 CreateMockRead(*get_resp2, 4, ASYNC),
3811 CreateMockRead(*body2, 5, ASYNC),
3812 MockRead(ASYNC, 0, 6),
3813 };
3814
3815 DeterministicSocketData spdy_data(
3816 spdy_reads, arraysize(spdy_reads),
3817 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073818 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:223819
3820 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023821 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073822 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:223823
3824 TestCompletionCallback callback;
3825
[email protected]262eec82013-03-19 21:01:363826 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503827 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223828 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
3829 EXPECT_EQ(ERR_IO_PENDING, rv);
3830 spdy_data.RunFor(2);
3831
3832 rv = callback.WaitForResult();
3833 EXPECT_EQ(OK, rv);
3834
3835 LoadTimingInfo load_timing_info;
3836 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3837 TestLoadTimingNotReused(load_timing_info,
3838 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3839
3840 const HttpResponseInfo* response = trans->GetResponseInfo();
3841 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503842 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:223843 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3844
3845 std::string response_data;
3846 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
[email protected]90499482013-06-01 00:39:503847 EXPECT_EQ(ERR_IO_PENDING, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223848 spdy_data.RunFor(1);
3849 EXPECT_EQ(1, callback.WaitForResult());
3850 // Delete the first request, so the second one can reuse the socket.
3851 trans.reset();
3852
[email protected]262eec82013-03-19 21:01:363853 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503854 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223855 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
3856 EXPECT_EQ(ERR_IO_PENDING, rv);
3857
3858 spdy_data.RunFor(2);
3859 rv = callback.WaitForResult();
3860 EXPECT_EQ(OK, rv);
3861
3862 LoadTimingInfo load_timing_info2;
3863 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3864 TestLoadTimingReused(load_timing_info2);
3865
3866 // The requests should have the same ID.
3867 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
3868
[email protected]90499482013-06-01 00:39:503869 EXPECT_EQ(ERR_IO_PENDING, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223870 spdy_data.RunFor(1);
3871 EXPECT_EQ(2, callback.WaitForResult());
3872}
3873
[email protected]2df19bb2010-08-25 20:13:463874// Test the challenge-response-retry sequence through an HTTPS Proxy
[email protected]23e482282013-06-14 16:08:023875TEST_P(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:463876 HttpRequestInfo request;
3877 request.method = "GET";
3878 request.url = GURL("http://www.google.com/");
3879 // when the no authentication data flag is set.
3880 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
3881
[email protected]79cb5c12011-09-12 13:12:043882 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073883 session_deps_.proxy_service.reset(
[email protected]79cb5c12011-09-12 13:12:043884 ProxyService::CreateFixed("https://myproxy:70"));
[email protected]333bdf62012-06-08 22:57:293885 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073886 session_deps_.net_log = log.bound().net_log();
3887 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273888
[email protected]2df19bb2010-08-25 20:13:463889 // Since we have proxy, should use full url
3890 MockWrite data_writes1[] = {
3891 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
3892 "Host: www.google.com\r\n"
3893 "Proxy-Connection: keep-alive\r\n\r\n"),
3894
3895 // After calling trans->RestartWithAuth(), this is the request we should
3896 // be issuing -- the final header line contains the credentials.
3897 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
3898 "Host: www.google.com\r\n"
3899 "Proxy-Connection: keep-alive\r\n"
3900 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3901 };
3902
3903 // The proxy responds to the GET with a 407, using a persistent
3904 // connection.
3905 MockRead data_reads1[] = {
3906 // No credentials.
3907 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3908 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3909 MockRead("Proxy-Connection: keep-alive\r\n"),
3910 MockRead("Content-Length: 0\r\n\r\n"),
3911
3912 MockRead("HTTP/1.1 200 OK\r\n"),
3913 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3914 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063915 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:463916 };
3917
3918 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3919 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073920 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063921 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073922 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:463923
[email protected]49639fa2011-12-20 23:22:413924 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:463925
[email protected]262eec82013-03-19 21:01:363926 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503927 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503928
[email protected]49639fa2011-12-20 23:22:413929 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:463930 EXPECT_EQ(ERR_IO_PENDING, rv);
3931
3932 rv = callback1.WaitForResult();
3933 EXPECT_EQ(OK, rv);
3934
[email protected]58e32bb2013-01-21 18:23:253935 LoadTimingInfo load_timing_info;
3936 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3937 TestLoadTimingNotReused(load_timing_info,
3938 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3939
[email protected]2df19bb2010-08-25 20:13:463940 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503941 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503942 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]2df19bb2010-08-25 20:13:463943 EXPECT_EQ(407, response->headers->response_code());
3944 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043945 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:463946
[email protected]49639fa2011-12-20 23:22:413947 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:463948
[email protected]49639fa2011-12-20 23:22:413949 rv = trans->RestartWithAuth(
3950 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]2df19bb2010-08-25 20:13:463951 EXPECT_EQ(ERR_IO_PENDING, rv);
3952
3953 rv = callback2.WaitForResult();
3954 EXPECT_EQ(OK, rv);
3955
[email protected]58e32bb2013-01-21 18:23:253956 load_timing_info = LoadTimingInfo();
3957 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3958 // Retrying with HTTP AUTH is considered to be reusing a socket.
3959 TestLoadTimingReused(load_timing_info);
3960
[email protected]2df19bb2010-08-25 20:13:463961 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503962 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:463963
3964 EXPECT_TRUE(response->headers->IsKeepAlive());
3965 EXPECT_EQ(200, response->headers->response_code());
3966 EXPECT_EQ(100, response->headers->GetContentLength());
3967 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3968
3969 // The password prompt info should not be set.
3970 EXPECT_TRUE(response->auth_challenge.get() == NULL);
3971}
3972
[email protected]23e482282013-06-14 16:08:023973void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:083974 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:423975 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:083976 request.method = "GET";
3977 request.url = GURL("https://www.google.com/");
3978 request.load_flags = 0;
3979
[email protected]cb9bf6ca2011-01-28 13:15:273980 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073981 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]bb88e1d32013-05-03 23:11:073982 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273983
[email protected]c744cf22009-02-27 07:28:083984 // Since we have proxy, should try to establish tunnel.
3985 MockWrite data_writes[] = {
3986 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:453987 "Host: www.google.com\r\n"
3988 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:083989 };
3990
3991 MockRead data_reads[] = {
3992 status,
3993 MockRead("Content-Length: 10\r\n\r\n"),
3994 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:063995 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]c744cf22009-02-27 07:28:083996 };
3997
[email protected]31a2bfe2010-02-09 08:03:393998 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
3999 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:074000 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:084001
[email protected]49639fa2011-12-20 23:22:414002 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:084003
[email protected]262eec82013-03-19 21:01:364004 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504005 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504006
[email protected]49639fa2011-12-20 23:22:414007 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424008 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]c744cf22009-02-27 07:28:084009
4010 rv = callback.WaitForResult();
4011 EXPECT_EQ(expected_status, rv);
4012}
4013
[email protected]23e482282013-06-14 16:08:024014void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:234015 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:084016 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:424017 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:084018}
4019
[email protected]23e482282013-06-14 16:08:024020TEST_P(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:084021 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
4022}
4023
[email protected]23e482282013-06-14 16:08:024024TEST_P(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:084025 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
4026}
4027
[email protected]23e482282013-06-14 16:08:024028TEST_P(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:084029 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
4030}
4031
[email protected]23e482282013-06-14 16:08:024032TEST_P(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:084033 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
4034}
4035
[email protected]23e482282013-06-14 16:08:024036TEST_P(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:084037 ConnectStatusHelper(
4038 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
4039}
4040
[email protected]23e482282013-06-14 16:08:024041TEST_P(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:084042 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
4043}
4044
[email protected]23e482282013-06-14 16:08:024045TEST_P(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:084046 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
4047}
4048
[email protected]23e482282013-06-14 16:08:024049TEST_P(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:084050 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
4051}
4052
[email protected]23e482282013-06-14 16:08:024053TEST_P(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:084054 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
4055}
4056
[email protected]23e482282013-06-14 16:08:024057TEST_P(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:084058 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
4059}
4060
[email protected]23e482282013-06-14 16:08:024061TEST_P(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:084062 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
4063}
4064
[email protected]23e482282013-06-14 16:08:024065TEST_P(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:084066 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
4067}
4068
[email protected]23e482282013-06-14 16:08:024069TEST_P(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:084070 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
4071}
4072
[email protected]23e482282013-06-14 16:08:024073TEST_P(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:084074 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
4075}
4076
[email protected]23e482282013-06-14 16:08:024077TEST_P(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:084078 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
4079}
4080
[email protected]23e482282013-06-14 16:08:024081TEST_P(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:084082 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
4083}
4084
[email protected]0a17aab32014-04-24 03:32:374085TEST_P(HttpNetworkTransactionTest, ConnectStatus308) {
4086 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
4087}
4088
[email protected]23e482282013-06-14 16:08:024089TEST_P(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:084090 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
4091}
4092
[email protected]23e482282013-06-14 16:08:024093TEST_P(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:084094 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
4095}
4096
[email protected]23e482282013-06-14 16:08:024097TEST_P(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:084098 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
4099}
4100
[email protected]23e482282013-06-14 16:08:024101TEST_P(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:084102 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
4103}
4104
[email protected]23e482282013-06-14 16:08:024105TEST_P(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:084106 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
4107}
4108
[email protected]23e482282013-06-14 16:08:024109TEST_P(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:084110 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
4111}
4112
[email protected]23e482282013-06-14 16:08:024113TEST_P(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:084114 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
4115}
4116
[email protected]23e482282013-06-14 16:08:024117TEST_P(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:084118 ConnectStatusHelperWithExpectedStatus(
4119 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:544120 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:084121}
4122
[email protected]23e482282013-06-14 16:08:024123TEST_P(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:084124 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
4125}
4126
[email protected]23e482282013-06-14 16:08:024127TEST_P(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:084128 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
4129}
4130
[email protected]23e482282013-06-14 16:08:024131TEST_P(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:084132 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
4133}
4134
[email protected]23e482282013-06-14 16:08:024135TEST_P(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:084136 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
4137}
4138
[email protected]23e482282013-06-14 16:08:024139TEST_P(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:084140 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
4141}
4142
[email protected]23e482282013-06-14 16:08:024143TEST_P(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:084144 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
4145}
4146
[email protected]23e482282013-06-14 16:08:024147TEST_P(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:084148 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
4149}
4150
[email protected]23e482282013-06-14 16:08:024151TEST_P(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:084152 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
4153}
4154
[email protected]23e482282013-06-14 16:08:024155TEST_P(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:084156 ConnectStatusHelper(
4157 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
4158}
4159
[email protected]23e482282013-06-14 16:08:024160TEST_P(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:084161 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
4162}
4163
[email protected]23e482282013-06-14 16:08:024164TEST_P(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:084165 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
4166}
4167
[email protected]23e482282013-06-14 16:08:024168TEST_P(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:084169 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
4170}
4171
[email protected]23e482282013-06-14 16:08:024172TEST_P(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:084173 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
4174}
4175
[email protected]23e482282013-06-14 16:08:024176TEST_P(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:084177 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
4178}
4179
[email protected]23e482282013-06-14 16:08:024180TEST_P(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:084181 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
4182}
4183
[email protected]23e482282013-06-14 16:08:024184TEST_P(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:084185 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
4186}
4187
[email protected]038e9a32008-10-08 22:40:164188// Test the flow when both the proxy server AND origin server require
4189// authentication. Again, this uses basic auth for both since that is
4190// the simplest to mock.
[email protected]23e482282013-06-14 16:08:024191TEST_P(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:274192 HttpRequestInfo request;
4193 request.method = "GET";
4194 request.url = GURL("http://www.google.com/");
4195 request.load_flags = 0;
4196
[email protected]038e9a32008-10-08 22:40:164197 // Configure against proxy server "myproxy:70".
[email protected]3fe8d2f82013-10-17 08:56:074198 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
4199 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4200
4201 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:414202 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]038e9a32008-10-08 22:40:164203
[email protected]f9ee6b52008-11-08 06:46:234204 MockWrite data_writes1[] = {
4205 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
4206 "Host: www.google.com\r\n"
4207 "Proxy-Connection: keep-alive\r\n\r\n"),
4208 };
4209
[email protected]038e9a32008-10-08 22:40:164210 MockRead data_reads1[] = {
4211 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
4212 // Give a couple authenticate options (only the middle one is actually
4213 // supported).
[email protected]22927ad2009-09-21 19:56:194214 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:164215 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4216 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
4217 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4218 // Large content-length -- won't matter, as connection will be reset.
4219 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064220 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:164221 };
4222
4223 // After calling trans->RestartWithAuth() the first time, this is the
4224 // request we should be issuing -- the final header line contains the
4225 // proxy's credentials.
4226 MockWrite data_writes2[] = {
4227 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
4228 "Host: www.google.com\r\n"
4229 "Proxy-Connection: keep-alive\r\n"
4230 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
4231 };
4232
4233 // Now the proxy server lets the request pass through to origin server.
4234 // The origin server responds with a 401.
4235 MockRead data_reads2[] = {
4236 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4237 // Note: We are using the same realm-name as the proxy server. This is
4238 // completely valid, as realms are unique across hosts.
4239 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4240 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4241 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064242 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:164243 };
4244
4245 // After calling trans->RestartWithAuth() the second time, we should send
4246 // the credentials for both the proxy and origin server.
4247 MockWrite data_writes3[] = {
4248 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
4249 "Host: www.google.com\r\n"
4250 "Proxy-Connection: keep-alive\r\n"
4251 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
4252 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
4253 };
4254
4255 // Lastly we get the desired content.
4256 MockRead data_reads3[] = {
4257 MockRead("HTTP/1.0 200 OK\r\n"),
4258 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4259 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064260 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:164261 };
4262
[email protected]31a2bfe2010-02-09 08:03:394263 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4264 data_writes1, arraysize(data_writes1));
4265 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4266 data_writes2, arraysize(data_writes2));
4267 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4268 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:074269 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4270 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4271 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:164272
[email protected]49639fa2011-12-20 23:22:414273 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:164274
[email protected]49639fa2011-12-20 23:22:414275 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424276 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:164277
4278 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424279 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:164280
[email protected]1c773ea12009-04-28 19:58:424281 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504282 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044283 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:164284
[email protected]49639fa2011-12-20 23:22:414285 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:164286
[email protected]49639fa2011-12-20 23:22:414287 rv = trans->RestartWithAuth(
4288 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:424289 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:164290
4291 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424292 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:164293
4294 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504295 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044296 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:164297
[email protected]49639fa2011-12-20 23:22:414298 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:164299
[email protected]49639fa2011-12-20 23:22:414300 rv = trans->RestartWithAuth(
4301 AuthCredentials(kFoo2, kBar2), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424302 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:164303
4304 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424305 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:164306
4307 response = trans->GetResponseInfo();
4308 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4309 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:164310}
[email protected]4ddaf2502008-10-23 18:26:194311
[email protected]ea9dc9a2009-09-05 00:43:324312// For the NTLM implementation using SSPI, we skip the NTLM tests since we
4313// can't hook into its internals to cause it to generate predictable NTLM
4314// authorization headers.
4315#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:294316// The NTLM authentication unit tests were generated by capturing the HTTP
4317// requests and responses using Fiddler 2 and inspecting the generated random
4318// bytes in the debugger.
4319
4320// Enter the correct password and authenticate successfully.
[email protected]23e482282013-06-14 16:08:024321TEST_P(HttpNetworkTransactionTest, NTLMAuth1) {
[email protected]1c773ea12009-04-28 19:58:424322 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:244323 request.method = "GET";
4324 request.url = GURL("http://172.22.68.17/kids/login.aspx");
[email protected]2217aa22013-10-11 03:03:544325
4326 // Ensure load is not disrupted by flags which suppress behaviour specific
4327 // to other auth schemes.
4328 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:244329
[email protected]cb9bf6ca2011-01-28 13:15:274330 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
4331 MockGetHostName);
[email protected]bb88e1d32013-05-03 23:11:074332 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274333
[email protected]3f918782009-02-28 01:29:244334 MockWrite data_writes1[] = {
4335 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4336 "Host: 172.22.68.17\r\n"
4337 "Connection: keep-alive\r\n\r\n"),
4338 };
4339
4340 MockRead data_reads1[] = {
4341 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:044342 // Negotiate and NTLM are often requested together. However, we only want
4343 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
4344 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:244345 MockRead("WWW-Authenticate: NTLM\r\n"),
4346 MockRead("Connection: close\r\n"),
4347 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364348 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:244349 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064350 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]3f918782009-02-28 01:29:244351 };
4352
4353 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:224354 // After restarting with a null identity, this is the
[email protected]3f918782009-02-28 01:29:244355 // request we should be issuing -- the final header line contains a Type
4356 // 1 message.
4357 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4358 "Host: 172.22.68.17\r\n"
4359 "Connection: keep-alive\r\n"
4360 "Authorization: NTLM "
4361 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4362
4363 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4364 // (the credentials for the origin server). The second request continues
4365 // on the same connection.
4366 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4367 "Host: 172.22.68.17\r\n"
4368 "Connection: keep-alive\r\n"
[email protected]385a4672009-03-11 22:21:294369 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4370 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4371 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
4372 "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
4373 "ahlhx5I=\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:244374 };
4375
4376 MockRead data_reads2[] = {
4377 // The origin server responds with a Type 2 message.
4378 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4379 MockRead("WWW-Authenticate: NTLM "
[email protected]385a4672009-03-11 22:21:294380 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
[email protected]3f918782009-02-28 01:29:244381 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4382 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4383 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4384 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4385 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4386 "BtAAAAAAA=\r\n"),
4387 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364388 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:244389 MockRead("You are not authorized to view this page\r\n"),
4390
4391 // Lastly we get the desired content.
4392 MockRead("HTTP/1.1 200 OK\r\n"),
4393 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
4394 MockRead("Content-Length: 13\r\n\r\n"),
4395 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:064396 MockRead(SYNCHRONOUS, OK),
[email protected]3f918782009-02-28 01:29:244397 };
4398
[email protected]31a2bfe2010-02-09 08:03:394399 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4400 data_writes1, arraysize(data_writes1));
4401 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4402 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:074403 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4404 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:244405
[email protected]49639fa2011-12-20 23:22:414406 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:244407
[email protected]262eec82013-03-19 21:01:364408 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504409 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504410
[email protected]49639fa2011-12-20 23:22:414411 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424412 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:244413
4414 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424415 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:244416
[email protected]0757e7702009-03-27 04:00:224417 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4418
[email protected]1c773ea12009-04-28 19:58:424419 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:044420 ASSERT_FALSE(response == NULL);
4421 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:244422
[email protected]49639fa2011-12-20 23:22:414423 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:254424
[email protected]f3cf9802011-10-28 18:44:584425 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:414426 callback2.callback());
[email protected]10af5fe72011-01-31 16:17:254427 EXPECT_EQ(ERR_IO_PENDING, rv);
4428
4429 rv = callback2.WaitForResult();
4430 EXPECT_EQ(OK, rv);
4431
4432 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4433
4434 response = trans->GetResponseInfo();
4435 ASSERT_TRUE(response != NULL);
[email protected]10af5fe72011-01-31 16:17:254436 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4437
[email protected]49639fa2011-12-20 23:22:414438 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:244439
[email protected]49639fa2011-12-20 23:22:414440 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424441 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:244442
[email protected]0757e7702009-03-27 04:00:224443 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424444 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:244445
4446 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504447 ASSERT_TRUE(response != NULL);
[email protected]3f918782009-02-28 01:29:244448 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4449 EXPECT_EQ(13, response->headers->GetContentLength());
4450}
4451
[email protected]385a4672009-03-11 22:21:294452// Enter a wrong password, and then the correct one.
[email protected]23e482282013-06-14 16:08:024453TEST_P(HttpNetworkTransactionTest, NTLMAuth2) {
[email protected]1c773ea12009-04-28 19:58:424454 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:294455 request.method = "GET";
4456 request.url = GURL("http://172.22.68.17/kids/login.aspx");
4457 request.load_flags = 0;
4458
[email protected]cb9bf6ca2011-01-28 13:15:274459 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
4460 MockGetHostName);
[email protected]bb88e1d32013-05-03 23:11:074461 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274462
[email protected]385a4672009-03-11 22:21:294463 MockWrite data_writes1[] = {
4464 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4465 "Host: 172.22.68.17\r\n"
4466 "Connection: keep-alive\r\n\r\n"),
4467 };
4468
4469 MockRead data_reads1[] = {
4470 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:044471 // Negotiate and NTLM are often requested together. However, we only want
4472 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
4473 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:294474 MockRead("WWW-Authenticate: NTLM\r\n"),
4475 MockRead("Connection: close\r\n"),
4476 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364477 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294478 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064479 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:294480 };
4481
4482 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:224483 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:294484 // request we should be issuing -- the final header line contains a Type
4485 // 1 message.
4486 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4487 "Host: 172.22.68.17\r\n"
4488 "Connection: keep-alive\r\n"
4489 "Authorization: NTLM "
4490 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4491
4492 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4493 // (the credentials for the origin server). The second request continues
4494 // on the same connection.
4495 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4496 "Host: 172.22.68.17\r\n"
4497 "Connection: keep-alive\r\n"
4498 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4499 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4500 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
4501 "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
4502 "4Ww7b7E=\r\n\r\n"),
4503 };
4504
4505 MockRead data_reads2[] = {
4506 // The origin server responds with a Type 2 message.
4507 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4508 MockRead("WWW-Authenticate: NTLM "
4509 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
4510 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4511 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4512 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4513 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4514 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4515 "BtAAAAAAA=\r\n"),
4516 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364517 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294518 MockRead("You are not authorized to view this page\r\n"),
4519
4520 // Wrong password.
4521 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]385a4672009-03-11 22:21:294522 MockRead("WWW-Authenticate: NTLM\r\n"),
4523 MockRead("Connection: close\r\n"),
4524 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364525 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294526 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064527 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:294528 };
4529
4530 MockWrite data_writes3[] = {
[email protected]0757e7702009-03-27 04:00:224531 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:294532 // request we should be issuing -- the final header line contains a Type
4533 // 1 message.
4534 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4535 "Host: 172.22.68.17\r\n"
4536 "Connection: keep-alive\r\n"
4537 "Authorization: NTLM "
4538 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4539
4540 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4541 // (the credentials for the origin server). The second request continues
4542 // on the same connection.
4543 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4544 "Host: 172.22.68.17\r\n"
4545 "Connection: keep-alive\r\n"
4546 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4547 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4548 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
4549 "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
4550 "+4MUm7c=\r\n\r\n"),
4551 };
4552
4553 MockRead data_reads3[] = {
4554 // The origin server responds with a Type 2 message.
4555 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4556 MockRead("WWW-Authenticate: NTLM "
4557 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
4558 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4559 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4560 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4561 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4562 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4563 "BtAAAAAAA=\r\n"),
4564 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364565 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294566 MockRead("You are not authorized to view this page\r\n"),
4567
4568 // Lastly we get the desired content.
4569 MockRead("HTTP/1.1 200 OK\r\n"),
4570 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
4571 MockRead("Content-Length: 13\r\n\r\n"),
4572 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:064573 MockRead(SYNCHRONOUS, OK),
[email protected]385a4672009-03-11 22:21:294574 };
4575
[email protected]31a2bfe2010-02-09 08:03:394576 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4577 data_writes1, arraysize(data_writes1));
4578 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4579 data_writes2, arraysize(data_writes2));
4580 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4581 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:074582 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4583 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4584 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:294585
[email protected]49639fa2011-12-20 23:22:414586 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:294587
[email protected]262eec82013-03-19 21:01:364588 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504589 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504590
[email protected]49639fa2011-12-20 23:22:414591 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424592 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:294593
4594 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424595 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:294596
[email protected]0757e7702009-03-27 04:00:224597 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:294598
[email protected]1c773ea12009-04-28 19:58:424599 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504600 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044601 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:294602
[email protected]49639fa2011-12-20 23:22:414603 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:294604
[email protected]0757e7702009-03-27 04:00:224605 // Enter the wrong password.
[email protected]f3cf9802011-10-28 18:44:584606 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword),
[email protected]49639fa2011-12-20 23:22:414607 callback2.callback());
[email protected]1c773ea12009-04-28 19:58:424608 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:294609
[email protected]10af5fe72011-01-31 16:17:254610 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424611 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:294612
[email protected]0757e7702009-03-27 04:00:224613 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:414614 TestCompletionCallback callback3;
4615 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424616 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]10af5fe72011-01-31 16:17:254617 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424618 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:224619 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4620
4621 response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:044622 ASSERT_FALSE(response == NULL);
4623 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:224624
[email protected]49639fa2011-12-20 23:22:414625 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:224626
4627 // Now enter the right password.
[email protected]f3cf9802011-10-28 18:44:584628 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:414629 callback4.callback());
[email protected]10af5fe72011-01-31 16:17:254630 EXPECT_EQ(ERR_IO_PENDING, rv);
4631
4632 rv = callback4.WaitForResult();
4633 EXPECT_EQ(OK, rv);
4634
4635 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4636
[email protected]49639fa2011-12-20 23:22:414637 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:254638
4639 // One more roundtrip
[email protected]49639fa2011-12-20 23:22:414640 rv = trans->RestartWithAuth(AuthCredentials(), callback5.callback());
[email protected]1c773ea12009-04-28 19:58:424641 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:224642
4643 rv = callback5.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424644 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:224645
[email protected]385a4672009-03-11 22:21:294646 response = trans->GetResponseInfo();
4647 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4648 EXPECT_EQ(13, response->headers->GetContentLength());
4649}
[email protected]ea9dc9a2009-09-05 00:43:324650#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:294651
[email protected]4ddaf2502008-10-23 18:26:194652// Test reading a server response which has only headers, and no body.
4653// After some maximum number of bytes is consumed, the transaction should
4654// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
[email protected]23e482282013-06-14 16:08:024655TEST_P(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:424656 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:194657 request.method = "GET";
4658 request.url = GURL("http://www.google.com/");
4659 request.load_flags = 0;
4660
[email protected]3fe8d2f82013-10-17 08:56:074661 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274662 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:414663 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:274664
[email protected]b75b7b2f2009-10-06 00:54:534665 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:434666 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:534667 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:194668
4669 MockRead data_reads[] = {
4670 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:064671 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:194672 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:064673 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:194674 };
[email protected]31a2bfe2010-02-09 08:03:394675 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:074676 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:194677
[email protected]49639fa2011-12-20 23:22:414678 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:194679
[email protected]49639fa2011-12-20 23:22:414680 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424681 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]4ddaf2502008-10-23 18:26:194682
4683 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424684 EXPECT_EQ(ERR_RESPONSE_HEADERS_TOO_BIG, rv);
[email protected]4ddaf2502008-10-23 18:26:194685
[email protected]1c773ea12009-04-28 19:58:424686 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]4ddaf2502008-10-23 18:26:194687 EXPECT_TRUE(response == NULL);
4688}
[email protected]f4e426b2008-11-05 00:24:494689
4690// Make sure that we don't try to reuse a TCPClientSocket when failing to
4691// establish tunnel.
4692// http://code.google.com/p/chromium/issues/detail?id=3772
[email protected]23e482282013-06-14 16:08:024693TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:234694 DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:274695 HttpRequestInfo request;
4696 request.method = "GET";
4697 request.url = GURL("https://www.google.com/");
4698 request.load_flags = 0;
4699
[email protected]f4e426b2008-11-05 00:24:494700 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:074701 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]db8f44c2008-12-13 04:52:014702
[email protected]bb88e1d32013-05-03 23:11:074703 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:494704
[email protected]262eec82013-03-19 21:01:364705 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504706 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f4e426b2008-11-05 00:24:494707
[email protected]f4e426b2008-11-05 00:24:494708 // Since we have proxy, should try to establish tunnel.
4709 MockWrite data_writes1[] = {
4710 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:454711 "Host: www.google.com\r\n"
4712 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:494713 };
4714
[email protected]77848d12008-11-14 00:00:224715 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:494716 // connection. Usually a proxy would return 501 (not implemented),
4717 // or 200 (tunnel established).
4718 MockRead data_reads1[] = {
4719 MockRead("HTTP/1.1 404 Not Found\r\n"),
4720 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064721 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]f4e426b2008-11-05 00:24:494722 };
4723
[email protected]31a2bfe2010-02-09 08:03:394724 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4725 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074726 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:494727
[email protected]49639fa2011-12-20 23:22:414728 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:494729
[email protected]49639fa2011-12-20 23:22:414730 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424731 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f4e426b2008-11-05 00:24:494732
4733 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424734 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]f4e426b2008-11-05 00:24:494735
[email protected]1c773ea12009-04-28 19:58:424736 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]c744cf22009-02-27 07:28:084737 EXPECT_TRUE(response == NULL);
[email protected]f4e426b2008-11-05 00:24:494738
[email protected]b4404c02009-04-10 16:38:524739 // Empty the current queue. This is necessary because idle sockets are
4740 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344741 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:524742
[email protected]f4e426b2008-11-05 00:24:494743 // We now check to make sure the TCPClientSocket was not added back to
4744 // the pool.
[email protected]90499482013-06-01 00:39:504745 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:494746 trans.reset();
[email protected]2da659e2013-05-23 20:51:344747 base::MessageLoop::current()->RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:494748 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:504749 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:494750}
[email protected]372d34a2008-11-05 21:30:514751
[email protected]1b157c02009-04-21 01:55:404752// Make sure that we recycle a socket after reading all of the response body.
[email protected]23e482282013-06-14 16:08:024753TEST_P(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:424754 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:404755 request.method = "GET";
4756 request.url = GURL("http://www.google.com/");
4757 request.load_flags = 0;
4758
[email protected]bb88e1d32013-05-03 23:11:074759 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274760
[email protected]262eec82013-03-19 21:01:364761 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504762 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:274763
[email protected]1b157c02009-04-21 01:55:404764 MockRead data_reads[] = {
4765 // A part of the response body is received with the response headers.
4766 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
4767 // The rest of the response body is received in two parts.
4768 MockRead("lo"),
4769 MockRead(" world"),
4770 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:064771 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:404772 };
4773
[email protected]31a2bfe2010-02-09 08:03:394774 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:074775 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:404776
[email protected]49639fa2011-12-20 23:22:414777 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:404778
[email protected]49639fa2011-12-20 23:22:414779 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424780 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]1b157c02009-04-21 01:55:404781
4782 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424783 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:404784
[email protected]1c773ea12009-04-28 19:58:424785 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504786 ASSERT_TRUE(response != NULL);
[email protected]1b157c02009-04-21 01:55:404787
[email protected]90499482013-06-01 00:39:504788 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]1b157c02009-04-21 01:55:404789 std::string status_line = response->headers->GetStatusLine();
4790 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
4791
[email protected]90499482013-06-01 00:39:504792 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:404793
4794 std::string response_data;
4795 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:424796 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:404797 EXPECT_EQ("hello world", response_data);
4798
4799 // Empty the current queue. This is necessary because idle sockets are
4800 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344801 base::MessageLoop::current()->RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:404802
4803 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504804 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:404805}
4806
[email protected]76a505b2010-08-25 06:23:004807// Make sure that we recycle a SSL socket after reading all of the response
4808// body.
[email protected]23e482282013-06-14 16:08:024809TEST_P(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:004810 HttpRequestInfo request;
4811 request.method = "GET";
4812 request.url = GURL("https://www.google.com/");
4813 request.load_flags = 0;
4814
4815 MockWrite data_writes[] = {
4816 MockWrite("GET / HTTP/1.1\r\n"
4817 "Host: www.google.com\r\n"
4818 "Connection: keep-alive\r\n\r\n"),
4819 };
4820
4821 MockRead data_reads[] = {
4822 MockRead("HTTP/1.1 200 OK\r\n"),
4823 MockRead("Content-Length: 11\r\n\r\n"),
4824 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:064825 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:004826 };
4827
[email protected]8ddf8322012-02-23 18:08:064828 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074829 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:004830
4831 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
4832 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:074833 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:004834
[email protected]49639fa2011-12-20 23:22:414835 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:004836
[email protected]bb88e1d32013-05-03 23:11:074837 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:364838 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504839 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:004840
[email protected]49639fa2011-12-20 23:22:414841 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:004842
4843 EXPECT_EQ(ERR_IO_PENDING, rv);
4844 EXPECT_EQ(OK, callback.WaitForResult());
4845
4846 const HttpResponseInfo* response = trans->GetResponseInfo();
4847 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504848 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:004849 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4850
[email protected]90499482013-06-01 00:39:504851 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004852
4853 std::string response_data;
4854 rv = ReadTransaction(trans.get(), &response_data);
4855 EXPECT_EQ(OK, rv);
4856 EXPECT_EQ("hello world", response_data);
4857
4858 // Empty the current queue. This is necessary because idle sockets are
4859 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344860 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:004861
4862 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504863 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004864}
4865
4866// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
4867// from the pool and make sure that we recover okay.
[email protected]23e482282013-06-14 16:08:024868TEST_P(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:004869 HttpRequestInfo request;
4870 request.method = "GET";
4871 request.url = GURL("https://www.google.com/");
4872 request.load_flags = 0;
4873
4874 MockWrite data_writes[] = {
4875 MockWrite("GET / HTTP/1.1\r\n"
4876 "Host: www.google.com\r\n"
4877 "Connection: keep-alive\r\n\r\n"),
4878 MockWrite("GET / HTTP/1.1\r\n"
4879 "Host: www.google.com\r\n"
4880 "Connection: keep-alive\r\n\r\n"),
4881 };
4882
4883 MockRead data_reads[] = {
4884 MockRead("HTTP/1.1 200 OK\r\n"),
4885 MockRead("Content-Length: 11\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064886 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:004887 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:064888 MockRead(ASYNC, 0, 0) // EOF
[email protected]76a505b2010-08-25 06:23:004889 };
4890
[email protected]8ddf8322012-02-23 18:08:064891 SSLSocketDataProvider ssl(ASYNC, OK);
4892 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074893 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4894 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:004895
4896 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
4897 data_writes, arraysize(data_writes));
4898 StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
4899 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:074900 session_deps_.socket_factory->AddSocketDataProvider(&data);
4901 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:004902
[email protected]49639fa2011-12-20 23:22:414903 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:004904
[email protected]bb88e1d32013-05-03 23:11:074905 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:364906 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504907 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:004908
[email protected]49639fa2011-12-20 23:22:414909 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:004910
4911 EXPECT_EQ(ERR_IO_PENDING, rv);
4912 EXPECT_EQ(OK, callback.WaitForResult());
4913
4914 const HttpResponseInfo* response = trans->GetResponseInfo();
4915 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504916 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:004917 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4918
[email protected]90499482013-06-01 00:39:504919 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004920
4921 std::string response_data;
4922 rv = ReadTransaction(trans.get(), &response_data);
4923 EXPECT_EQ(OK, rv);
4924 EXPECT_EQ("hello world", response_data);
4925
4926 // Empty the current queue. This is necessary because idle sockets are
4927 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344928 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:004929
4930 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504931 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004932
4933 // Now start the second transaction, which should reuse the previous socket.
4934
[email protected]90499482013-06-01 00:39:504935 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:004936
[email protected]49639fa2011-12-20 23:22:414937 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:004938
4939 EXPECT_EQ(ERR_IO_PENDING, rv);
4940 EXPECT_EQ(OK, callback.WaitForResult());
4941
4942 response = trans->GetResponseInfo();
4943 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504944 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:004945 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4946
[email protected]90499482013-06-01 00:39:504947 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004948
4949 rv = ReadTransaction(trans.get(), &response_data);
4950 EXPECT_EQ(OK, rv);
4951 EXPECT_EQ("hello world", response_data);
4952
4953 // Empty the current queue. This is necessary because idle sockets are
4954 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344955 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:004956
4957 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504958 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004959}
4960
[email protected]b4404c02009-04-10 16:38:524961// Make sure that we recycle a socket after a zero-length response.
4962// http://crbug.com/9880
[email protected]23e482282013-06-14 16:08:024963TEST_P(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:424964 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:524965 request.method = "GET";
4966 request.url = GURL("http://www.google.com/csi?v=3&s=web&action=&"
4967 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
4968 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
4969 "rt=prt.2642,ol.2649,xjs.2951");
4970 request.load_flags = 0;
4971
[email protected]bb88e1d32013-05-03 23:11:074972 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274973
[email protected]262eec82013-03-19 21:01:364974 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504975 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:274976
[email protected]b4404c02009-04-10 16:38:524977 MockRead data_reads[] = {
4978 MockRead("HTTP/1.1 204 No Content\r\n"
4979 "Content-Length: 0\r\n"
4980 "Content-Type: text/html\r\n\r\n"),
4981 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:064982 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:524983 };
4984
[email protected]31a2bfe2010-02-09 08:03:394985 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:074986 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:524987
[email protected]49639fa2011-12-20 23:22:414988 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:524989
[email protected]49639fa2011-12-20 23:22:414990 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424991 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]b4404c02009-04-10 16:38:524992
4993 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424994 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:524995
[email protected]1c773ea12009-04-28 19:58:424996 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504997 ASSERT_TRUE(response != NULL);
[email protected]b4404c02009-04-10 16:38:524998
[email protected]90499482013-06-01 00:39:504999 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]b4404c02009-04-10 16:38:525000 std::string status_line = response->headers->GetStatusLine();
5001 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
5002
[email protected]90499482013-06-01 00:39:505003 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:525004
5005 std::string response_data;
5006 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:425007 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:525008 EXPECT_EQ("", response_data);
5009
5010 // Empty the current queue. This is necessary because idle sockets are
5011 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345012 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:525013
5014 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505015 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:525016}
5017
[email protected]23e482282013-06-14 16:08:025018TEST_P(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
[email protected]b2d26cfd2012-12-11 10:36:065019 ScopedVector<UploadElementReader> element_readers;
5020 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:075021 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:275022
[email protected]1c773ea12009-04-28 19:58:425023 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:515024 // Transaction 1: a GET request that succeeds. The socket is recycled
5025 // after use.
5026 request[0].method = "GET";
5027 request[0].url = GURL("http://www.google.com/");
5028 request[0].load_flags = 0;
5029 // Transaction 2: a POST request. Reuses the socket kept alive from
5030 // transaction 1. The first attempts fails when writing the POST data.
5031 // This causes the transaction to retry with a new socket. The second
5032 // attempt succeeds.
5033 request[1].method = "POST";
5034 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:275035 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:515036 request[1].load_flags = 0;
5037
[email protected]bb88e1d32013-05-03 23:11:075038 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:515039
5040 // The first socket is used for transaction 1 and the first attempt of
5041 // transaction 2.
5042
5043 // The response of transaction 1.
5044 MockRead data_reads1[] = {
5045 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
5046 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:065047 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:515048 };
5049 // The mock write results of transaction 1 and the first attempt of
5050 // transaction 2.
5051 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:065052 MockWrite(SYNCHRONOUS, 64), // GET
5053 MockWrite(SYNCHRONOUS, 93), // POST
5054 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:515055 };
[email protected]31a2bfe2010-02-09 08:03:395056 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5057 data_writes1, arraysize(data_writes1));
[email protected]372d34a2008-11-05 21:30:515058
5059 // The second socket is used for the second attempt of transaction 2.
5060
5061 // The response of transaction 2.
5062 MockRead data_reads2[] = {
5063 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
5064 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:065065 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:515066 };
5067 // The mock write results of the second attempt of transaction 2.
5068 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:065069 MockWrite(SYNCHRONOUS, 93), // POST
5070 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:515071 };
[email protected]31a2bfe2010-02-09 08:03:395072 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5073 data_writes2, arraysize(data_writes2));
[email protected]372d34a2008-11-05 21:30:515074
[email protected]bb88e1d32013-05-03 23:11:075075 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5076 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:515077
5078 const char* kExpectedResponseData[] = {
5079 "hello world", "welcome"
5080 };
5081
5082 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:425083 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505084 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]372d34a2008-11-05 21:30:515085
[email protected]49639fa2011-12-20 23:22:415086 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:515087
[email protected]49639fa2011-12-20 23:22:415088 int rv = trans->Start(&request[i], callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425089 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]372d34a2008-11-05 21:30:515090
5091 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425092 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:515093
[email protected]1c773ea12009-04-28 19:58:425094 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505095 ASSERT_TRUE(response != NULL);
[email protected]372d34a2008-11-05 21:30:515096
[email protected]90499482013-06-01 00:39:505097 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]372d34a2008-11-05 21:30:515098 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5099
5100 std::string response_data;
5101 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:425102 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:515103 EXPECT_EQ(kExpectedResponseData[i], response_data);
5104 }
5105}
[email protected]f9ee6b52008-11-08 06:46:235106
5107// Test the request-challenge-retry sequence for basic auth when there is
5108// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:165109// it fails the identity from the URL is used to answer the challenge.
[email protected]23e482282013-06-14 16:08:025110TEST_P(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:425111 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235112 request.method = "GET";
[email protected]a97cca42009-08-14 01:00:295113 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:415114 request.load_flags = LOAD_NORMAL;
[email protected]a97cca42009-08-14 01:00:295115
[email protected]3fe8d2f82013-10-17 08:56:075116 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275117 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415118 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275119
[email protected]a97cca42009-08-14 01:00:295120 // The password contains an escaped character -- for this test to pass it
5121 // will need to be unescaped by HttpNetworkTransaction.
5122 EXPECT_EQ("b%40r", request.url.password());
5123
[email protected]f9ee6b52008-11-08 06:46:235124 MockWrite data_writes1[] = {
5125 MockWrite("GET / HTTP/1.1\r\n"
5126 "Host: www.google.com\r\n"
5127 "Connection: keep-alive\r\n\r\n"),
5128 };
5129
5130 MockRead data_reads1[] = {
5131 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5132 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5133 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065134 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235135 };
5136
[email protected]2262e3a2012-05-22 16:08:165137 // After the challenge above, the transaction will be restarted using the
5138 // identity from the url (foo, b@r) to answer the challenge.
5139 MockWrite data_writes2[] = {
5140 MockWrite("GET / HTTP/1.1\r\n"
5141 "Host: www.google.com\r\n"
5142 "Connection: keep-alive\r\n"
5143 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
5144 };
5145
5146 MockRead data_reads2[] = {
5147 MockRead("HTTP/1.0 200 OK\r\n"),
5148 MockRead("Content-Length: 100\r\n\r\n"),
5149 MockRead(SYNCHRONOUS, OK),
5150 };
5151
[email protected]31a2bfe2010-02-09 08:03:395152 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5153 data_writes1, arraysize(data_writes1));
[email protected]2262e3a2012-05-22 16:08:165154 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5155 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075156 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5157 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235158
[email protected]49639fa2011-12-20 23:22:415159 TestCompletionCallback callback1;
[email protected]49639fa2011-12-20 23:22:415160 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425161 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235162 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425163 EXPECT_EQ(OK, rv);
[email protected]2262e3a2012-05-22 16:08:165164 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5165
5166 TestCompletionCallback callback2;
5167 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
5168 EXPECT_EQ(ERR_IO_PENDING, rv);
5169 rv = callback2.WaitForResult();
5170 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225171 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5172
[email protected]2262e3a2012-05-22 16:08:165173 const HttpResponseInfo* response = trans->GetResponseInfo();
5174 ASSERT_TRUE(response != NULL);
5175
5176 // There is no challenge info, since the identity in URL worked.
5177 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5178
5179 EXPECT_EQ(100, response->headers->GetContentLength());
5180
5181 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:345182 base::MessageLoop::current()->RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:165183}
5184
5185// Test the request-challenge-retry sequence for basic auth when there is an
5186// incorrect identity in the URL. The identity from the URL should be used only
5187// once.
[email protected]23e482282013-06-14 16:08:025188TEST_P(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:165189 HttpRequestInfo request;
5190 request.method = "GET";
5191 // Note: the URL has a username:password in it. The password "baz" is
5192 // wrong (should be "bar").
5193 request.url = GURL("http://foo:[email protected]/");
5194
5195 request.load_flags = LOAD_NORMAL;
5196
[email protected]3fe8d2f82013-10-17 08:56:075197 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2262e3a2012-05-22 16:08:165198 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415199 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2262e3a2012-05-22 16:08:165200
5201 MockWrite data_writes1[] = {
5202 MockWrite("GET / HTTP/1.1\r\n"
5203 "Host: www.google.com\r\n"
5204 "Connection: keep-alive\r\n\r\n"),
5205 };
5206
5207 MockRead data_reads1[] = {
5208 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5209 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5210 MockRead("Content-Length: 10\r\n\r\n"),
5211 MockRead(SYNCHRONOUS, ERR_FAILED),
5212 };
5213
5214 // After the challenge above, the transaction will be restarted using the
5215 // identity from the url (foo, baz) to answer the challenge.
5216 MockWrite data_writes2[] = {
5217 MockWrite("GET / HTTP/1.1\r\n"
5218 "Host: www.google.com\r\n"
5219 "Connection: keep-alive\r\n"
5220 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
5221 };
5222
5223 MockRead data_reads2[] = {
5224 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5225 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5226 MockRead("Content-Length: 10\r\n\r\n"),
5227 MockRead(SYNCHRONOUS, ERR_FAILED),
5228 };
5229
5230 // After the challenge above, the transaction will be restarted using the
5231 // identity supplied by the user (foo, bar) to answer the challenge.
5232 MockWrite data_writes3[] = {
5233 MockWrite("GET / HTTP/1.1\r\n"
5234 "Host: www.google.com\r\n"
5235 "Connection: keep-alive\r\n"
5236 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5237 };
5238
5239 MockRead data_reads3[] = {
5240 MockRead("HTTP/1.0 200 OK\r\n"),
5241 MockRead("Content-Length: 100\r\n\r\n"),
5242 MockRead(SYNCHRONOUS, OK),
5243 };
5244
5245 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5246 data_writes1, arraysize(data_writes1));
5247 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5248 data_writes2, arraysize(data_writes2));
5249 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5250 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075251 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5252 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5253 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:165254
5255 TestCompletionCallback callback1;
5256
5257 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5258 EXPECT_EQ(ERR_IO_PENDING, rv);
5259
5260 rv = callback1.WaitForResult();
5261 EXPECT_EQ(OK, rv);
5262
5263 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5264 TestCompletionCallback callback2;
5265 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
5266 EXPECT_EQ(ERR_IO_PENDING, rv);
5267 rv = callback2.WaitForResult();
5268 EXPECT_EQ(OK, rv);
5269 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5270
5271 const HttpResponseInfo* response = trans->GetResponseInfo();
5272 ASSERT_TRUE(response != NULL);
5273 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
5274
5275 TestCompletionCallback callback3;
5276 rv = trans->RestartWithAuth(
5277 AuthCredentials(kFoo, kBar), callback3.callback());
5278 EXPECT_EQ(ERR_IO_PENDING, rv);
5279 rv = callback3.WaitForResult();
5280 EXPECT_EQ(OK, rv);
5281 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5282
5283 response = trans->GetResponseInfo();
5284 ASSERT_TRUE(response != NULL);
5285
5286 // There is no challenge info, since the identity worked.
5287 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5288
5289 EXPECT_EQ(100, response->headers->GetContentLength());
5290
[email protected]ea9dc9a2009-09-05 00:43:325291 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:345292 base::MessageLoop::current()->RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:325293}
5294
[email protected]2217aa22013-10-11 03:03:545295
5296// Test the request-challenge-retry sequence for basic auth when there is a
5297// correct identity in the URL, but its use is being suppressed. The identity
5298// from the URL should never be used.
5299TEST_P(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
5300 HttpRequestInfo request;
5301 request.method = "GET";
5302 request.url = GURL("http://foo:[email protected]/");
5303 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
5304
[email protected]3fe8d2f82013-10-17 08:56:075305 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2217aa22013-10-11 03:03:545306 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415307 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2217aa22013-10-11 03:03:545308
5309 MockWrite data_writes1[] = {
5310 MockWrite("GET / HTTP/1.1\r\n"
5311 "Host: www.google.com\r\n"
5312 "Connection: keep-alive\r\n\r\n"),
5313 };
5314
5315 MockRead data_reads1[] = {
5316 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5317 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5318 MockRead("Content-Length: 10\r\n\r\n"),
5319 MockRead(SYNCHRONOUS, ERR_FAILED),
5320 };
5321
5322 // After the challenge above, the transaction will be restarted using the
5323 // identity supplied by the user, not the one in the URL, to answer the
5324 // challenge.
5325 MockWrite data_writes3[] = {
5326 MockWrite("GET / HTTP/1.1\r\n"
5327 "Host: www.google.com\r\n"
5328 "Connection: keep-alive\r\n"
5329 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5330 };
5331
5332 MockRead data_reads3[] = {
5333 MockRead("HTTP/1.0 200 OK\r\n"),
5334 MockRead("Content-Length: 100\r\n\r\n"),
5335 MockRead(SYNCHRONOUS, OK),
5336 };
5337
5338 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5339 data_writes1, arraysize(data_writes1));
5340 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5341 data_writes3, arraysize(data_writes3));
5342 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5343 session_deps_.socket_factory->AddSocketDataProvider(&data3);
5344
5345 TestCompletionCallback callback1;
5346 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5347 EXPECT_EQ(ERR_IO_PENDING, rv);
5348 rv = callback1.WaitForResult();
5349 EXPECT_EQ(OK, rv);
5350 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5351
5352 const HttpResponseInfo* response = trans->GetResponseInfo();
5353 ASSERT_TRUE(response != NULL);
5354 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
5355
5356 TestCompletionCallback callback3;
5357 rv = trans->RestartWithAuth(
5358 AuthCredentials(kFoo, kBar), callback3.callback());
5359 EXPECT_EQ(ERR_IO_PENDING, rv);
5360 rv = callback3.WaitForResult();
5361 EXPECT_EQ(OK, rv);
5362 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5363
5364 response = trans->GetResponseInfo();
5365 ASSERT_TRUE(response != NULL);
5366
5367 // There is no challenge info, since the identity worked.
5368 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5369 EXPECT_EQ(100, response->headers->GetContentLength());
5370
5371 // Empty the current queue.
5372 base::MessageLoop::current()->RunUntilIdle();
5373}
5374
[email protected]f9ee6b52008-11-08 06:46:235375// Test that previously tried username/passwords for a realm get re-used.
[email protected]23e482282013-06-14 16:08:025376TEST_P(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
[email protected]bb88e1d32013-05-03 23:11:075377 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:235378
5379 // Transaction 1: authenticate (foo, bar) on MyRealm1
5380 {
[email protected]1c773ea12009-04-28 19:58:425381 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235382 request.method = "GET";
5383 request.url = GURL("http://www.google.com/x/y/z");
5384 request.load_flags = 0;
5385
[email protected]262eec82013-03-19 21:01:365386 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505387 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275388
[email protected]f9ee6b52008-11-08 06:46:235389 MockWrite data_writes1[] = {
5390 MockWrite("GET /x/y/z HTTP/1.1\r\n"
5391 "Host: www.google.com\r\n"
5392 "Connection: keep-alive\r\n\r\n"),
5393 };
5394
5395 MockRead data_reads1[] = {
5396 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5397 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5398 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065399 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235400 };
5401
5402 // Resend with authorization (username=foo, password=bar)
5403 MockWrite data_writes2[] = {
5404 MockWrite("GET /x/y/z HTTP/1.1\r\n"
5405 "Host: www.google.com\r\n"
5406 "Connection: keep-alive\r\n"
5407 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5408 };
5409
5410 // Sever accepts the authorization.
5411 MockRead data_reads2[] = {
5412 MockRead("HTTP/1.0 200 OK\r\n"),
5413 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065414 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235415 };
5416
[email protected]31a2bfe2010-02-09 08:03:395417 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5418 data_writes1, arraysize(data_writes1));
5419 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5420 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075421 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5422 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235423
[email protected]49639fa2011-12-20 23:22:415424 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235425
[email protected]49639fa2011-12-20 23:22:415426 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425427 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235428
5429 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425430 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235431
[email protected]1c773ea12009-04-28 19:58:425432 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505433 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045434 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:235435
[email protected]49639fa2011-12-20 23:22:415436 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:235437
[email protected]49639fa2011-12-20 23:22:415438 rv = trans->RestartWithAuth(
5439 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425440 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235441
5442 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425443 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235444
5445 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505446 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235447 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5448 EXPECT_EQ(100, response->headers->GetContentLength());
5449 }
5450
5451 // ------------------------------------------------------------------------
5452
5453 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
5454 {
[email protected]1c773ea12009-04-28 19:58:425455 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235456 request.method = "GET";
5457 // Note that Transaction 1 was at /x/y/z, so this is in the same
5458 // protection space as MyRealm1.
5459 request.url = GURL("http://www.google.com/x/y/a/b");
5460 request.load_flags = 0;
5461
[email protected]262eec82013-03-19 21:01:365462 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505463 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275464
[email protected]f9ee6b52008-11-08 06:46:235465 MockWrite data_writes1[] = {
5466 MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
5467 "Host: www.google.com\r\n"
5468 "Connection: keep-alive\r\n"
5469 // Send preemptive authorization for MyRealm1
5470 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5471 };
5472
5473 // The server didn't like the preemptive authorization, and
5474 // challenges us for a different realm (MyRealm2).
5475 MockRead data_reads1[] = {
5476 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5477 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
5478 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065479 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235480 };
5481
5482 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
5483 MockWrite data_writes2[] = {
5484 MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
5485 "Host: www.google.com\r\n"
5486 "Connection: keep-alive\r\n"
5487 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
5488 };
5489
5490 // Sever accepts the authorization.
5491 MockRead data_reads2[] = {
5492 MockRead("HTTP/1.0 200 OK\r\n"),
5493 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065494 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235495 };
5496
[email protected]31a2bfe2010-02-09 08:03:395497 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5498 data_writes1, arraysize(data_writes1));
5499 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5500 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075501 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5502 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235503
[email protected]49639fa2011-12-20 23:22:415504 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235505
[email protected]49639fa2011-12-20 23:22:415506 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425507 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235508
5509 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425510 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235511
[email protected]1c773ea12009-04-28 19:58:425512 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505513 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045514 ASSERT_TRUE(response->auth_challenge.get());
5515 EXPECT_FALSE(response->auth_challenge->is_proxy);
5516 EXPECT_EQ("www.google.com:80",
5517 response->auth_challenge->challenger.ToString());
5518 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
5519 EXPECT_EQ("basic", response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:235520
[email protected]49639fa2011-12-20 23:22:415521 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:235522
[email protected]49639fa2011-12-20 23:22:415523 rv = trans->RestartWithAuth(
5524 AuthCredentials(kFoo2, kBar2), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425525 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235526
5527 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425528 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235529
5530 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505531 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235532 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5533 EXPECT_EQ(100, response->headers->GetContentLength());
5534 }
5535
5536 // ------------------------------------------------------------------------
5537
5538 // Transaction 3: Resend a request in MyRealm's protection space --
5539 // succeed with preemptive authorization.
5540 {
[email protected]1c773ea12009-04-28 19:58:425541 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235542 request.method = "GET";
5543 request.url = GURL("http://www.google.com/x/y/z2");
5544 request.load_flags = 0;
5545
[email protected]262eec82013-03-19 21:01:365546 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505547 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275548
[email protected]f9ee6b52008-11-08 06:46:235549 MockWrite data_writes1[] = {
5550 MockWrite("GET /x/y/z2 HTTP/1.1\r\n"
5551 "Host: www.google.com\r\n"
5552 "Connection: keep-alive\r\n"
5553 // The authorization for MyRealm1 gets sent preemptively
5554 // (since the url is in the same protection space)
5555 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5556 };
5557
5558 // Sever accepts the preemptive authorization
5559 MockRead data_reads1[] = {
5560 MockRead("HTTP/1.0 200 OK\r\n"),
5561 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065562 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235563 };
5564
[email protected]31a2bfe2010-02-09 08:03:395565 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5566 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075567 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:235568
[email protected]49639fa2011-12-20 23:22:415569 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235570
[email protected]49639fa2011-12-20 23:22:415571 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425572 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235573
5574 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425575 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235576
[email protected]1c773ea12009-04-28 19:58:425577 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505578 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235579
5580 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5581 EXPECT_EQ(100, response->headers->GetContentLength());
5582 }
5583
5584 // ------------------------------------------------------------------------
5585
5586 // Transaction 4: request another URL in MyRealm (however the
5587 // url is not known to belong to the protection space, so no pre-auth).
5588 {
[email protected]1c773ea12009-04-28 19:58:425589 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235590 request.method = "GET";
5591 request.url = GURL("http://www.google.com/x/1");
5592 request.load_flags = 0;
5593
[email protected]262eec82013-03-19 21:01:365594 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505595 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275596
[email protected]f9ee6b52008-11-08 06:46:235597 MockWrite data_writes1[] = {
5598 MockWrite("GET /x/1 HTTP/1.1\r\n"
5599 "Host: www.google.com\r\n"
5600 "Connection: keep-alive\r\n\r\n"),
5601 };
5602
5603 MockRead data_reads1[] = {
5604 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5605 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5606 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065607 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235608 };
5609
5610 // Resend with authorization from MyRealm's cache.
5611 MockWrite data_writes2[] = {
5612 MockWrite("GET /x/1 HTTP/1.1\r\n"
5613 "Host: www.google.com\r\n"
5614 "Connection: keep-alive\r\n"
5615 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5616 };
5617
5618 // Sever accepts the authorization.
5619 MockRead data_reads2[] = {
5620 MockRead("HTTP/1.0 200 OK\r\n"),
5621 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065622 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235623 };
5624
[email protected]31a2bfe2010-02-09 08:03:395625 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5626 data_writes1, arraysize(data_writes1));
5627 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5628 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075629 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5630 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235631
[email protected]49639fa2011-12-20 23:22:415632 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235633
[email protected]49639fa2011-12-20 23:22:415634 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425635 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235636
5637 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425638 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235639
[email protected]0757e7702009-03-27 04:00:225640 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:415641 TestCompletionCallback callback2;
5642 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425643 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:225644 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425645 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225646 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5647
[email protected]1c773ea12009-04-28 19:58:425648 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505649 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235650 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5651 EXPECT_EQ(100, response->headers->GetContentLength());
5652 }
5653
5654 // ------------------------------------------------------------------------
5655
5656 // Transaction 5: request a URL in MyRealm, but the server rejects the
5657 // cached identity. Should invalidate and re-prompt.
5658 {
[email protected]1c773ea12009-04-28 19:58:425659 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235660 request.method = "GET";
5661 request.url = GURL("http://www.google.com/p/q/t");
5662 request.load_flags = 0;
5663
[email protected]262eec82013-03-19 21:01:365664 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505665 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275666
[email protected]f9ee6b52008-11-08 06:46:235667 MockWrite data_writes1[] = {
5668 MockWrite("GET /p/q/t HTTP/1.1\r\n"
5669 "Host: www.google.com\r\n"
5670 "Connection: keep-alive\r\n\r\n"),
5671 };
5672
5673 MockRead data_reads1[] = {
5674 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5675 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5676 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065677 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235678 };
5679
5680 // Resend with authorization from cache for MyRealm.
5681 MockWrite data_writes2[] = {
5682 MockWrite("GET /p/q/t HTTP/1.1\r\n"
5683 "Host: www.google.com\r\n"
5684 "Connection: keep-alive\r\n"
5685 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5686 };
5687
5688 // Sever rejects the authorization.
5689 MockRead data_reads2[] = {
5690 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5691 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5692 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065693 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235694 };
5695
5696 // At this point we should prompt for new credentials for MyRealm.
5697 // Restart with username=foo3, password=foo4.
5698 MockWrite data_writes3[] = {
5699 MockWrite("GET /p/q/t HTTP/1.1\r\n"
5700 "Host: www.google.com\r\n"
5701 "Connection: keep-alive\r\n"
5702 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
5703 };
5704
5705 // Sever accepts the authorization.
5706 MockRead data_reads3[] = {
5707 MockRead("HTTP/1.0 200 OK\r\n"),
5708 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065709 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235710 };
5711
[email protected]31a2bfe2010-02-09 08:03:395712 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5713 data_writes1, arraysize(data_writes1));
5714 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5715 data_writes2, arraysize(data_writes2));
5716 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5717 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075718 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5719 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5720 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:235721
[email protected]49639fa2011-12-20 23:22:415722 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235723
[email protected]49639fa2011-12-20 23:22:415724 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425725 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235726
5727 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425728 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235729
[email protected]0757e7702009-03-27 04:00:225730 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:415731 TestCompletionCallback callback2;
5732 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425733 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:225734 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425735 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225736 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5737
[email protected]1c773ea12009-04-28 19:58:425738 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505739 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045740 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:235741
[email protected]49639fa2011-12-20 23:22:415742 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:235743
[email protected]49639fa2011-12-20 23:22:415744 rv = trans->RestartWithAuth(
5745 AuthCredentials(kFoo3, kBar3), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:425746 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235747
[email protected]0757e7702009-03-27 04:00:225748 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425749 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235750
5751 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505752 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235753 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5754 EXPECT_EQ(100, response->headers->GetContentLength());
5755 }
5756}
[email protected]89ceba9a2009-03-21 03:46:065757
[email protected]3c32c5f2010-05-18 15:18:125758// Tests that nonce count increments when multiple auth attempts
5759// are started with the same nonce.
[email protected]23e482282013-06-14 16:08:025760TEST_P(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:445761 HttpAuthHandlerDigest::Factory* digest_factory =
5762 new HttpAuthHandlerDigest::Factory();
5763 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
5764 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
5765 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:075766 session_deps_.http_auth_handler_factory.reset(digest_factory);
5767 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:125768
5769 // Transaction 1: authenticate (foo, bar) on MyRealm1
5770 {
[email protected]3c32c5f2010-05-18 15:18:125771 HttpRequestInfo request;
5772 request.method = "GET";
5773 request.url = GURL("http://www.google.com/x/y/z");
5774 request.load_flags = 0;
5775
[email protected]262eec82013-03-19 21:01:365776 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505777 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275778
[email protected]3c32c5f2010-05-18 15:18:125779 MockWrite data_writes1[] = {
5780 MockWrite("GET /x/y/z HTTP/1.1\r\n"
5781 "Host: www.google.com\r\n"
5782 "Connection: keep-alive\r\n\r\n"),
5783 };
5784
5785 MockRead data_reads1[] = {
5786 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5787 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
5788 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065789 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:125790 };
5791
5792 // Resend with authorization (username=foo, password=bar)
5793 MockWrite data_writes2[] = {
5794 MockWrite("GET /x/y/z HTTP/1.1\r\n"
5795 "Host: www.google.com\r\n"
5796 "Connection: keep-alive\r\n"
5797 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
5798 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
5799 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
5800 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
5801 };
5802
5803 // Sever accepts the authorization.
5804 MockRead data_reads2[] = {
5805 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:065806 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:125807 };
5808
5809 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5810 data_writes1, arraysize(data_writes1));
5811 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5812 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075813 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5814 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:125815
[email protected]49639fa2011-12-20 23:22:415816 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:125817
[email protected]49639fa2011-12-20 23:22:415818 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:125819 EXPECT_EQ(ERR_IO_PENDING, rv);
5820
5821 rv = callback1.WaitForResult();
5822 EXPECT_EQ(OK, rv);
5823
5824 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505825 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045826 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:125827
[email protected]49639fa2011-12-20 23:22:415828 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:125829
[email protected]49639fa2011-12-20 23:22:415830 rv = trans->RestartWithAuth(
5831 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]3c32c5f2010-05-18 15:18:125832 EXPECT_EQ(ERR_IO_PENDING, rv);
5833
5834 rv = callback2.WaitForResult();
5835 EXPECT_EQ(OK, rv);
5836
5837 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505838 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:125839 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5840 }
5841
5842 // ------------------------------------------------------------------------
5843
5844 // Transaction 2: Request another resource in digestive's protection space.
5845 // This will preemptively add an Authorization header which should have an
5846 // "nc" value of 2 (as compared to 1 in the first use.
5847 {
[email protected]3c32c5f2010-05-18 15:18:125848 HttpRequestInfo request;
5849 request.method = "GET";
5850 // Note that Transaction 1 was at /x/y/z, so this is in the same
5851 // protection space as digest.
5852 request.url = GURL("http://www.google.com/x/y/a/b");
5853 request.load_flags = 0;
5854
[email protected]262eec82013-03-19 21:01:365855 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505856 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275857
[email protected]3c32c5f2010-05-18 15:18:125858 MockWrite data_writes1[] = {
5859 MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
5860 "Host: www.google.com\r\n"
5861 "Connection: keep-alive\r\n"
5862 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
5863 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
5864 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
5865 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
5866 };
5867
5868 // Sever accepts the authorization.
5869 MockRead data_reads1[] = {
5870 MockRead("HTTP/1.0 200 OK\r\n"),
5871 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065872 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:125873 };
5874
5875 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5876 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075877 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:125878
[email protected]49639fa2011-12-20 23:22:415879 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:125880
[email protected]49639fa2011-12-20 23:22:415881 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:125882 EXPECT_EQ(ERR_IO_PENDING, rv);
5883
5884 rv = callback1.WaitForResult();
5885 EXPECT_EQ(OK, rv);
5886
5887 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505888 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:125889 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5890 }
5891}
5892
[email protected]89ceba9a2009-03-21 03:46:065893// Test the ResetStateForRestart() private method.
[email protected]23e482282013-06-14 16:08:025894TEST_P(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:065895 // Create a transaction (the dependencies aren't important).
[email protected]3fe8d2f82013-10-17 08:56:075896 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:405897 scoped_ptr<HttpNetworkTransaction> trans(
dcheng48459ac22014-08-26 00:46:415898 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]89ceba9a2009-03-21 03:46:065899
5900 // Setup some state (which we expect ResetStateForRestart() will clear).
[email protected]89ceba9a2009-03-21 03:46:065901 trans->read_buf_ = new IOBuffer(15);
5902 trans->read_buf_len_ = 15;
[email protected]b94f92d2010-10-27 16:45:205903 trans->request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:065904
5905 // Setup state in response_
[email protected]a7e41312009-12-16 23:18:145906 HttpResponseInfo* response = &trans->response_;
[email protected]0877e3d2009-10-17 22:29:575907 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:085908 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:575909 response->response_time = base::Time::Now();
5910 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:065911
5912 { // Setup state for response_.vary_data
5913 HttpRequestInfo request;
5914 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
5915 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:275916 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:435917 request.extra_headers.SetHeader("Foo", "1");
5918 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:505919 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:065920 }
5921
5922 // Cause the above state to be reset.
5923 trans->ResetStateForRestart();
5924
5925 // Verify that the state that needed to be reset, has been reset.
[email protected]9b6fee12009-09-29 18:13:075926 EXPECT_TRUE(trans->read_buf_.get() == NULL);
[email protected]89ceba9a2009-03-21 03:46:065927 EXPECT_EQ(0, trans->read_buf_len_);
[email protected]b94f92d2010-10-27 16:45:205928 EXPECT_TRUE(trans->request_headers_.IsEmpty());
[email protected]0877e3d2009-10-17 22:29:575929 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5930 EXPECT_TRUE(response->headers.get() == NULL);
[email protected]34f40942010-10-04 00:34:045931 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:085932 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:575933 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:065934}
5935
[email protected]bacff652009-03-31 17:50:335936// Test HTTPS connections to a site with a bad certificate
[email protected]23e482282013-06-14 16:08:025937TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:335938 HttpRequestInfo request;
5939 request.method = "GET";
5940 request.url = GURL("https://www.google.com/");
5941 request.load_flags = 0;
5942
[email protected]3fe8d2f82013-10-17 08:56:075943 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275944 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415945 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275946
[email protected]bacff652009-03-31 17:50:335947 MockWrite data_writes[] = {
5948 MockWrite("GET / HTTP/1.1\r\n"
5949 "Host: www.google.com\r\n"
5950 "Connection: keep-alive\r\n\r\n"),
5951 };
5952
5953 MockRead data_reads[] = {
5954 MockRead("HTTP/1.0 200 OK\r\n"),
5955 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5956 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065957 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:335958 };
5959
[email protected]5ecc992a42009-11-11 01:41:595960 StaticSocketDataProvider ssl_bad_certificate;
[email protected]31a2bfe2010-02-09 08:03:395961 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5962 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:065963 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
5964 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:335965
[email protected]bb88e1d32013-05-03 23:11:075966 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
5967 session_deps_.socket_factory->AddSocketDataProvider(&data);
5968 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
5969 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:335970
[email protected]49639fa2011-12-20 23:22:415971 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:335972
[email protected]49639fa2011-12-20 23:22:415973 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:335974 EXPECT_EQ(ERR_IO_PENDING, rv);
5975
5976 rv = callback.WaitForResult();
5977 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
5978
[email protected]49639fa2011-12-20 23:22:415979 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:335980 EXPECT_EQ(ERR_IO_PENDING, rv);
5981
5982 rv = callback.WaitForResult();
5983 EXPECT_EQ(OK, rv);
5984
5985 const HttpResponseInfo* response = trans->GetResponseInfo();
5986
[email protected]fe2255a2011-09-20 19:37:505987 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:335988 EXPECT_EQ(100, response->headers->GetContentLength());
5989}
5990
5991// Test HTTPS connections to a site with a bad certificate, going through a
5992// proxy
[email protected]23e482282013-06-14 16:08:025993TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
[email protected]bb88e1d32013-05-03 23:11:075994 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]bacff652009-03-31 17:50:335995
5996 HttpRequestInfo request;
5997 request.method = "GET";
5998 request.url = GURL("https://www.google.com/");
5999 request.load_flags = 0;
6000
6001 MockWrite proxy_writes[] = {
6002 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:456003 "Host: www.google.com\r\n"
6004 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:336005 };
6006
6007 MockRead proxy_reads[] = {
6008 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066009 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:336010 };
6011
6012 MockWrite data_writes[] = {
6013 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:456014 "Host: www.google.com\r\n"
6015 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:336016 MockWrite("GET / HTTP/1.1\r\n"
6017 "Host: www.google.com\r\n"
6018 "Connection: keep-alive\r\n\r\n"),
6019 };
6020
6021 MockRead data_reads[] = {
6022 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
6023 MockRead("HTTP/1.0 200 OK\r\n"),
6024 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6025 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066026 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:336027 };
6028
[email protected]31a2bfe2010-02-09 08:03:396029 StaticSocketDataProvider ssl_bad_certificate(
6030 proxy_reads, arraysize(proxy_reads),
6031 proxy_writes, arraysize(proxy_writes));
6032 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6033 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066034 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
6035 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:336036
[email protected]bb88e1d32013-05-03 23:11:076037 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
6038 session_deps_.socket_factory->AddSocketDataProvider(&data);
6039 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
6040 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:336041
[email protected]49639fa2011-12-20 23:22:416042 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:336043
6044 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:076045 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:336046
[email protected]3fe8d2f82013-10-17 08:56:076047 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:406048 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416049 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bacff652009-03-31 17:50:336050
[email protected]49639fa2011-12-20 23:22:416051 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:336052 EXPECT_EQ(ERR_IO_PENDING, rv);
6053
6054 rv = callback.WaitForResult();
6055 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
6056
[email protected]49639fa2011-12-20 23:22:416057 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:336058 EXPECT_EQ(ERR_IO_PENDING, rv);
6059
6060 rv = callback.WaitForResult();
6061 EXPECT_EQ(OK, rv);
6062
6063 const HttpResponseInfo* response = trans->GetResponseInfo();
6064
[email protected]fe2255a2011-09-20 19:37:506065 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:336066 EXPECT_EQ(100, response->headers->GetContentLength());
6067 }
6068}
6069
[email protected]2df19bb2010-08-25 20:13:466070
6071// Test HTTPS connections to a site, going through an HTTPS proxy
[email protected]23e482282013-06-14 16:08:026072TEST_P(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076073 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206074 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
6075 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076076 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:466077
6078 HttpRequestInfo request;
6079 request.method = "GET";
6080 request.url = GURL("https://www.google.com/");
6081 request.load_flags = 0;
6082
6083 MockWrite data_writes[] = {
6084 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6085 "Host: www.google.com\r\n"
6086 "Proxy-Connection: keep-alive\r\n\r\n"),
6087 MockWrite("GET / HTTP/1.1\r\n"
6088 "Host: www.google.com\r\n"
6089 "Connection: keep-alive\r\n\r\n"),
6090 };
6091
6092 MockRead data_reads[] = {
6093 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
6094 MockRead("HTTP/1.1 200 OK\r\n"),
6095 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6096 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066097 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:466098 };
6099
6100 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6101 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066102 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
6103 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:466104
[email protected]bb88e1d32013-05-03 23:11:076105 session_deps_.socket_factory->AddSocketDataProvider(&data);
6106 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
6107 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:466108
[email protected]49639fa2011-12-20 23:22:416109 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:466110
[email protected]3fe8d2f82013-10-17 08:56:076111 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:466112 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416113 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2df19bb2010-08-25 20:13:466114
[email protected]49639fa2011-12-20 23:22:416115 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:466116 EXPECT_EQ(ERR_IO_PENDING, rv);
6117
6118 rv = callback.WaitForResult();
6119 EXPECT_EQ(OK, rv);
6120 const HttpResponseInfo* response = trans->GetResponseInfo();
6121
[email protected]fe2255a2011-09-20 19:37:506122 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:466123
6124 EXPECT_TRUE(response->headers->IsKeepAlive());
6125 EXPECT_EQ(200, response->headers->response_code());
6126 EXPECT_EQ(100, response->headers->GetContentLength());
6127 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:206128
6129 LoadTimingInfo load_timing_info;
6130 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6131 TestLoadTimingNotReusedWithPac(load_timing_info,
6132 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:466133}
6134
[email protected]511f6f52010-12-17 03:58:296135// Test an HTTPS Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:026136TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076137 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206138 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
6139 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076140 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:296141
6142 HttpRequestInfo request;
6143 request.method = "GET";
6144 request.url = GURL("https://www.google.com/");
6145 request.load_flags = 0;
6146
6147 MockWrite data_writes[] = {
6148 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6149 "Host: www.google.com\r\n"
6150 "Proxy-Connection: keep-alive\r\n\r\n"),
6151 };
6152
6153 MockRead data_reads[] = {
6154 MockRead("HTTP/1.1 302 Redirect\r\n"),
6155 MockRead("Location: http://login.example.com/\r\n"),
6156 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066157 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:296158 };
6159
6160 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6161 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066162 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:296163
[email protected]bb88e1d32013-05-03 23:11:076164 session_deps_.socket_factory->AddSocketDataProvider(&data);
6165 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296166
[email protected]49639fa2011-12-20 23:22:416167 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296168
[email protected]3fe8d2f82013-10-17 08:56:076169 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296170 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416171 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:296172
[email protected]49639fa2011-12-20 23:22:416173 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296174 EXPECT_EQ(ERR_IO_PENDING, rv);
6175
6176 rv = callback.WaitForResult();
6177 EXPECT_EQ(OK, rv);
6178 const HttpResponseInfo* response = trans->GetResponseInfo();
6179
[email protected]fe2255a2011-09-20 19:37:506180 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:296181
6182 EXPECT_EQ(302, response->headers->response_code());
6183 std::string url;
6184 EXPECT_TRUE(response->headers->IsRedirect(&url));
6185 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:206186
6187 // In the case of redirects from proxies, HttpNetworkTransaction returns
6188 // timing for the proxy connection instead of the connection to the host,
6189 // and no send / receive times.
6190 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
6191 LoadTimingInfo load_timing_info;
6192 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6193
6194 EXPECT_FALSE(load_timing_info.socket_reused);
6195 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
6196
6197 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
6198 EXPECT_LE(load_timing_info.proxy_resolve_start,
6199 load_timing_info.proxy_resolve_end);
6200 EXPECT_LE(load_timing_info.proxy_resolve_end,
6201 load_timing_info.connect_timing.connect_start);
6202 ExpectConnectTimingHasTimes(
6203 load_timing_info.connect_timing,
6204 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
6205
6206 EXPECT_TRUE(load_timing_info.send_start.is_null());
6207 EXPECT_TRUE(load_timing_info.send_end.is_null());
6208 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:296209}
6210
6211// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:026212TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
[email protected]bb88e1d32013-05-03 23:11:076213 session_deps_.proxy_service.reset(
[email protected]511f6f52010-12-17 03:58:296214 ProxyService::CreateFixed("https://proxy:70"));
6215
6216 HttpRequestInfo request;
6217 request.method = "GET";
6218 request.url = GURL("https://www.google.com/");
6219 request.load_flags = 0;
6220
lgarrona91df87f2014-12-05 00:51:346221 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(
6222 NULL, 0, 1, LOWEST, HostPortPair("www.google.com", 443)));
[email protected]c10b20852013-05-15 21:29:206223 scoped_ptr<SpdyFrame> goaway(
6224 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:296225 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:066226 CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
[email protected]57d2dfa2013-06-24 06:04:126227 CreateMockWrite(*goaway.get(), 3, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:296228 };
6229
6230 static const char* const kExtraHeaders[] = {
6231 "location",
6232 "http://login.example.com/",
6233 };
[email protected]ff98d7f02012-03-22 21:44:196234 scoped_ptr<SpdyFrame> resp(
[email protected]23e482282013-06-14 16:08:026235 spdy_util_.ConstructSpdySynReplyError("302 Redirect", kExtraHeaders,
[email protected]511f6f52010-12-17 03:58:296236 arraysize(kExtraHeaders)/2, 1));
6237 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:066238 CreateMockRead(*resp.get(), 1, SYNCHRONOUS),
6239 MockRead(ASYNC, 0, 2), // EOF
[email protected]511f6f52010-12-17 03:58:296240 };
6241
[email protected]dd54bd82012-07-19 23:44:576242 DelayedSocketData data(
6243 1, // wait for one write to finish before reading.
6244 data_reads, arraysize(data_reads),
6245 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066246 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]23e482282013-06-14 16:08:026247 proxy_ssl.SetNextProto(GetParam());
[email protected]511f6f52010-12-17 03:58:296248
[email protected]bb88e1d32013-05-03 23:11:076249 session_deps_.socket_factory->AddSocketDataProvider(&data);
6250 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296251
[email protected]49639fa2011-12-20 23:22:416252 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296253
[email protected]3fe8d2f82013-10-17 08:56:076254 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296255 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416256 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:296257
[email protected]49639fa2011-12-20 23:22:416258 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296259 EXPECT_EQ(ERR_IO_PENDING, rv);
6260
6261 rv = callback.WaitForResult();
6262 EXPECT_EQ(OK, rv);
6263 const HttpResponseInfo* response = trans->GetResponseInfo();
6264
[email protected]fe2255a2011-09-20 19:37:506265 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:296266
6267 EXPECT_EQ(302, response->headers->response_code());
6268 std::string url;
6269 EXPECT_TRUE(response->headers->IsRedirect(&url));
6270 EXPECT_EQ("http://login.example.com/", url);
6271}
6272
[email protected]4eddbc732012-08-09 05:40:176273// Test that an HTTPS proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:026274TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:176275 ErrorResponseToHttpsConnectViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076276 session_deps_.proxy_service.reset(
[email protected]511f6f52010-12-17 03:58:296277 ProxyService::CreateFixed("https://proxy:70"));
6278
6279 HttpRequestInfo request;
6280 request.method = "GET";
6281 request.url = GURL("https://www.google.com/");
6282 request.load_flags = 0;
6283
6284 MockWrite data_writes[] = {
6285 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6286 "Host: www.google.com\r\n"
6287 "Proxy-Connection: keep-alive\r\n\r\n"),
6288 };
6289
6290 MockRead data_reads[] = {
6291 MockRead("HTTP/1.1 404 Not Found\r\n"),
6292 MockRead("Content-Length: 23\r\n\r\n"),
6293 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:066294 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:296295 };
6296
6297 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6298 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066299 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:296300
[email protected]bb88e1d32013-05-03 23:11:076301 session_deps_.socket_factory->AddSocketDataProvider(&data);
6302 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296303
[email protected]49639fa2011-12-20 23:22:416304 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296305
[email protected]3fe8d2f82013-10-17 08:56:076306 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296307 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416308 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:296309
[email protected]49639fa2011-12-20 23:22:416310 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296311 EXPECT_EQ(ERR_IO_PENDING, rv);
6312
6313 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:176314 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:296315
[email protected]4eddbc732012-08-09 05:40:176316 // TODO(ttuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:296317}
6318
[email protected]4eddbc732012-08-09 05:40:176319// Test that a SPDY proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:026320TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:176321 ErrorResponseToHttpsConnectViaSpdyProxy) {
[email protected]bb88e1d32013-05-03 23:11:076322 session_deps_.proxy_service.reset(
6323 ProxyService::CreateFixed("https://proxy:70"));
[email protected]511f6f52010-12-17 03:58:296324
6325 HttpRequestInfo request;
6326 request.method = "GET";
6327 request.url = GURL("https://www.google.com/");
6328 request.load_flags = 0;
6329
lgarrona91df87f2014-12-05 00:51:346330 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(
6331 NULL, 0, 1, LOWEST, HostPortPair("www.google.com", 443)));
[email protected]c10b20852013-05-15 21:29:206332 scoped_ptr<SpdyFrame> rst(
6333 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:296334 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:066335 CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
[email protected]4eddbc732012-08-09 05:40:176336 CreateMockWrite(*rst.get(), 3, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:296337 };
6338
6339 static const char* const kExtraHeaders[] = {
6340 "location",
6341 "http://login.example.com/",
6342 };
[email protected]ff98d7f02012-03-22 21:44:196343 scoped_ptr<SpdyFrame> resp(
[email protected]23e482282013-06-14 16:08:026344 spdy_util_.ConstructSpdySynReplyError("404 Not Found", kExtraHeaders,
[email protected]511f6f52010-12-17 03:58:296345 arraysize(kExtraHeaders)/2, 1));
[email protected]ff98d7f02012-03-22 21:44:196346 scoped_ptr<SpdyFrame> body(
[email protected]23e482282013-06-14 16:08:026347 spdy_util_.ConstructSpdyBodyFrame(
6348 1, "The host does not exist", 23, true));
[email protected]511f6f52010-12-17 03:58:296349 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:066350 CreateMockRead(*resp.get(), 1, SYNCHRONOUS),
6351 CreateMockRead(*body.get(), 2, SYNCHRONOUS),
[email protected]4eddbc732012-08-09 05:40:176352 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:296353 };
6354
[email protected]dd54bd82012-07-19 23:44:576355 DelayedSocketData data(
6356 1, // wait for one write to finish before reading.
6357 data_reads, arraysize(data_reads),
6358 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066359 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]23e482282013-06-14 16:08:026360 proxy_ssl.SetNextProto(GetParam());
[email protected]511f6f52010-12-17 03:58:296361
[email protected]bb88e1d32013-05-03 23:11:076362 session_deps_.socket_factory->AddSocketDataProvider(&data);
6363 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296364
[email protected]49639fa2011-12-20 23:22:416365 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296366
[email protected]3fe8d2f82013-10-17 08:56:076367 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296368 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416369 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:296370
[email protected]49639fa2011-12-20 23:22:416371 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296372 EXPECT_EQ(ERR_IO_PENDING, rv);
6373
6374 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:176375 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:296376
[email protected]4eddbc732012-08-09 05:40:176377 // TODO(ttuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:296378}
6379
[email protected]0c5fb722012-02-28 11:50:356380// Test the request-challenge-retry sequence for basic auth, through
6381// a SPDY proxy over a single SPDY session.
[email protected]23e482282013-06-14 16:08:026382TEST_P(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:356383 HttpRequestInfo request;
6384 request.method = "GET";
6385 request.url = GURL("https://www.google.com/");
6386 // when the no authentication data flag is set.
6387 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
6388
6389 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076390 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206391 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
[email protected]333bdf62012-06-08 22:57:296392 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076393 session_deps_.net_log = log.bound().net_log();
6394 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:356395
6396 // Since we have proxy, should try to establish tunnel.
lgarrona91df87f2014-12-05 00:51:346397 scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyConnect(
6398 NULL, 0, 1, LOWEST, HostPortPair("www.google.com", 443)));
[email protected]c10b20852013-05-15 21:29:206399 scoped_ptr<SpdyFrame> rst(
6400 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]0c5fb722012-02-28 11:50:356401
6402 // After calling trans->RestartWithAuth(), this is the request we should
6403 // be issuing -- the final header line contains the credentials.
6404 const char* const kAuthCredentials[] = {
6405 "proxy-authorization", "Basic Zm9vOmJhcg==",
6406 };
[email protected]fba2dbde2013-05-24 16:09:016407 scoped_ptr<SpdyFrame> connect2(spdy_util_.ConstructSpdyConnect(
lgarrona91df87f2014-12-05 00:51:346408 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST,
6409 HostPortPair("www.google.com", 443)));
[email protected]0c5fb722012-02-28 11:50:356410 // fetch https://www.google.com/ via HTTP
6411 const char get[] = "GET / HTTP/1.1\r\n"
6412 "Host: www.google.com\r\n"
6413 "Connection: keep-alive\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:196414 scoped_ptr<SpdyFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:026415 spdy_util_.ConstructSpdyBodyFrame(3, get, strlen(get), false));
[email protected]0c5fb722012-02-28 11:50:356416
6417 MockWrite spdy_writes[] = {
[email protected]3d7c43f2012-07-10 21:26:206418 CreateMockWrite(*req, 1, ASYNC),
[email protected]c92f4b4542012-07-26 23:53:216419 CreateMockWrite(*rst, 4, ASYNC),
6420 CreateMockWrite(*connect2, 5),
[email protected]3d7c43f2012-07-10 21:26:206421 CreateMockWrite(*wrapped_get, 8),
[email protected]0c5fb722012-02-28 11:50:356422 };
6423
6424 // The proxy responds to the connect with a 407, using a persistent
6425 // connection.
[email protected]745aa9c2014-06-27 02:21:296426 const char* const kAuthStatus = "407";
[email protected]0c5fb722012-02-28 11:50:356427 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:356428 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
6429 };
[email protected]745aa9c2014-06-27 02:21:296430 scoped_ptr<SpdyFrame> conn_auth_resp(spdy_util_.ConstructSpdySynReplyError(
6431 kAuthStatus, kAuthChallenge, arraysize(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:356432
[email protected]23e482282013-06-14 16:08:026433 scoped_ptr<SpdyFrame> conn_resp(
6434 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:356435 const char resp[] = "HTTP/1.1 200 OK\r\n"
6436 "Content-Length: 5\r\n\r\n";
6437
[email protected]ff98d7f02012-03-22 21:44:196438 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:026439 spdy_util_.ConstructSpdyBodyFrame(3, resp, strlen(resp), false));
[email protected]ff98d7f02012-03-22 21:44:196440 scoped_ptr<SpdyFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:026441 spdy_util_.ConstructSpdyBodyFrame(3, "hello", 5, false));
[email protected]0c5fb722012-02-28 11:50:356442 MockRead spdy_reads[] = {
[email protected]3d7c43f2012-07-10 21:26:206443 CreateMockRead(*conn_auth_resp, 2, ASYNC),
6444 CreateMockRead(*conn_resp, 6, ASYNC),
6445 CreateMockRead(*wrapped_get_resp, 9, ASYNC),
6446 CreateMockRead(*wrapped_body, 10, ASYNC),
6447 MockRead(ASYNC, OK, 11), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:356448 };
6449
[email protected]dd54bd82012-07-19 23:44:576450 OrderedSocketData spdy_data(
6451 spdy_reads, arraysize(spdy_reads),
6452 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:076453 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:356454 // Negotiate SPDY to the proxy
6455 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:026456 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:076457 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:356458 // Vanilla SSL to the server
6459 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076460 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:356461
6462 TestCompletionCallback callback1;
6463
[email protected]262eec82013-03-19 21:01:366464 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506465 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0c5fb722012-02-28 11:50:356466
6467 int rv = trans->Start(&request, callback1.callback(), log.bound());
6468 EXPECT_EQ(ERR_IO_PENDING, rv);
6469
6470 rv = callback1.WaitForResult();
6471 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:576472 net::CapturingNetLog::CapturedEntryList entries;
[email protected]0c5fb722012-02-28 11:50:356473 log.GetEntries(&entries);
6474 size_t pos = ExpectLogContainsSomewhere(
6475 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
6476 NetLog::PHASE_NONE);
6477 ExpectLogContainsSomewhere(
6478 entries, pos,
6479 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
6480 NetLog::PHASE_NONE);
6481
6482 const HttpResponseInfo* response = trans->GetResponseInfo();
6483 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:506484 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]0c5fb722012-02-28 11:50:356485 EXPECT_EQ(407, response->headers->response_code());
6486 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6487 EXPECT_TRUE(response->auth_challenge.get() != NULL);
6488 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
6489
6490 TestCompletionCallback callback2;
6491
6492 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
6493 callback2.callback());
6494 EXPECT_EQ(ERR_IO_PENDING, rv);
6495
6496 rv = callback2.WaitForResult();
6497 EXPECT_EQ(OK, rv);
6498
6499 response = trans->GetResponseInfo();
6500 ASSERT_TRUE(response != NULL);
6501
6502 EXPECT_TRUE(response->headers->IsKeepAlive());
6503 EXPECT_EQ(200, response->headers->response_code());
6504 EXPECT_EQ(5, response->headers->GetContentLength());
6505 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6506
6507 // The password prompt info should not be set.
6508 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6509
[email protected]029c83b62013-01-24 05:28:206510 LoadTimingInfo load_timing_info;
6511 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6512 TestLoadTimingNotReusedWithPac(load_timing_info,
6513 CONNECT_TIMING_HAS_SSL_TIMES);
6514
[email protected]0c5fb722012-02-28 11:50:356515 trans.reset();
6516 session->CloseAllConnections();
6517}
6518
[email protected]7c6f7ba2012-04-03 04:09:296519// Test that an explicitly trusted SPDY proxy can push a resource from an
6520// origin that is different from that of its associated resource.
[email protected]23e482282013-06-14 16:08:026521TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPush) {
[email protected]7c6f7ba2012-04-03 04:09:296522 HttpRequestInfo request;
6523 HttpRequestInfo push_request;
6524
[email protected]7c6f7ba2012-04-03 04:09:296525 request.method = "GET";
6526 request.url = GURL("http://www.google.com/");
6527 push_request.method = "GET";
6528 push_request.url = GURL("http://www.another-origin.com/foo.dat");
6529
[email protected]7c6f7ba2012-04-03 04:09:296530 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076531 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206532 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
[email protected]333bdf62012-06-08 22:57:296533 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076534 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:506535
6536 // Enable cross-origin push.
[email protected]bb88e1d32013-05-03 23:11:076537 session_deps_.trusted_spdy_proxy = "myproxy:70";
[email protected]61b4efc2012-04-27 18:12:506538
[email protected]bb88e1d32013-05-03 23:11:076539 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:296540
[email protected]cdf8f7e72013-05-23 10:56:466541 scoped_ptr<SpdyFrame> stream1_syn(
6542 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]7c6f7ba2012-04-03 04:09:296543
6544 MockWrite spdy_writes[] = {
[email protected]cdf8f7e72013-05-23 10:56:466545 CreateMockWrite(*stream1_syn, 1, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:296546 };
6547
6548 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026549 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:296550
6551 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026552 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:296553
6554 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026555 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
[email protected]7c6f7ba2012-04-03 04:09:296556 0,
6557 2,
6558 1,
6559 "http://www.another-origin.com/foo.dat"));
[email protected]8a0fc822013-06-27 20:52:436560 const char kPushedData[] = "pushed";
6561 scoped_ptr<SpdyFrame> stream2_body(
6562 spdy_util_.ConstructSpdyBodyFrame(
6563 2, kPushedData, strlen(kPushedData), true));
[email protected]7c6f7ba2012-04-03 04:09:296564
6565 MockRead spdy_reads[] = {
6566 CreateMockRead(*stream1_reply, 2, ASYNC),
6567 CreateMockRead(*stream2_syn, 3, ASYNC),
6568 CreateMockRead(*stream1_body, 4, ASYNC),
[email protected]8a0fc822013-06-27 20:52:436569 CreateMockRead(*stream2_body, 5, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:296570 MockRead(ASYNC, ERR_IO_PENDING, 6), // Force a pause
6571 };
6572
[email protected]dd54bd82012-07-19 23:44:576573 OrderedSocketData spdy_data(
6574 spdy_reads, arraysize(spdy_reads),
6575 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:076576 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:296577 // Negotiate SPDY to the proxy
6578 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:026579 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:076580 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:296581
[email protected]262eec82013-03-19 21:01:366582 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506583 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7c6f7ba2012-04-03 04:09:296584 TestCompletionCallback callback;
6585 int rv = trans->Start(&request, callback.callback(), log.bound());
6586 EXPECT_EQ(ERR_IO_PENDING, rv);
6587
6588 rv = callback.WaitForResult();
6589 EXPECT_EQ(OK, rv);
6590 const HttpResponseInfo* response = trans->GetResponseInfo();
6591
[email protected]262eec82013-03-19 21:01:366592 scoped_ptr<HttpTransaction> push_trans(
[email protected]90499482013-06-01 00:39:506593 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
6594 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
[email protected]7c6f7ba2012-04-03 04:09:296595 EXPECT_EQ(ERR_IO_PENDING, rv);
6596
6597 rv = callback.WaitForResult();
6598 EXPECT_EQ(OK, rv);
6599 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
6600
6601 ASSERT_TRUE(response != NULL);
6602 EXPECT_TRUE(response->headers->IsKeepAlive());
6603
6604 EXPECT_EQ(200, response->headers->response_code());
6605 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6606
6607 std::string response_data;
6608 rv = ReadTransaction(trans.get(), &response_data);
6609 EXPECT_EQ(OK, rv);
6610 EXPECT_EQ("hello!", response_data);
6611
[email protected]029c83b62013-01-24 05:28:206612 LoadTimingInfo load_timing_info;
6613 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6614 TestLoadTimingNotReusedWithPac(load_timing_info,
6615 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6616
[email protected]7c6f7ba2012-04-03 04:09:296617 // Verify the pushed stream.
[email protected]90499482013-06-01 00:39:506618 EXPECT_TRUE(push_response->headers.get() != NULL);
[email protected]7c6f7ba2012-04-03 04:09:296619 EXPECT_EQ(200, push_response->headers->response_code());
6620
6621 rv = ReadTransaction(push_trans.get(), &response_data);
6622 EXPECT_EQ(OK, rv);
6623 EXPECT_EQ("pushed", response_data);
6624
[email protected]029c83b62013-01-24 05:28:206625 LoadTimingInfo push_load_timing_info;
6626 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
6627 TestLoadTimingReusedWithPac(push_load_timing_info);
6628 // The transactions should share a socket ID, despite being for different
6629 // origins.
6630 EXPECT_EQ(load_timing_info.socket_log_id,
6631 push_load_timing_info.socket_log_id);
6632
[email protected]7c6f7ba2012-04-03 04:09:296633 trans.reset();
6634 push_trans.reset();
6635 session->CloseAllConnections();
6636}
6637
[email protected]8c843192012-04-05 07:15:006638// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
[email protected]23e482282013-06-14 16:08:026639TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
[email protected]8c843192012-04-05 07:15:006640 HttpRequestInfo request;
6641
6642 request.method = "GET";
6643 request.url = GURL("http://www.google.com/");
6644
[email protected]8c843192012-04-05 07:15:006645 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076646 session_deps_.proxy_service.reset(
[email protected]8c843192012-04-05 07:15:006647 ProxyService::CreateFixed("https://myproxy:70"));
[email protected]333bdf62012-06-08 22:57:296648 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076649 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:506650
6651 // Enable cross-origin push.
[email protected]bb88e1d32013-05-03 23:11:076652 session_deps_.trusted_spdy_proxy = "myproxy:70";
[email protected]61b4efc2012-04-27 18:12:506653
[email protected]bb88e1d32013-05-03 23:11:076654 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:006655
[email protected]cdf8f7e72013-05-23 10:56:466656 scoped_ptr<SpdyFrame> stream1_syn(
6657 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]8c843192012-04-05 07:15:006658
6659 scoped_ptr<SpdyFrame> push_rst(
[email protected]c10b20852013-05-15 21:29:206660 spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:006661
6662 MockWrite spdy_writes[] = {
6663 CreateMockWrite(*stream1_syn, 1, ASYNC),
6664 CreateMockWrite(*push_rst, 4),
6665 };
6666
6667 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026668 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:006669
6670 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026671 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8c843192012-04-05 07:15:006672
6673 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026674 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
[email protected]8c843192012-04-05 07:15:006675 0,
6676 2,
6677 1,
6678 "https://www.another-origin.com/foo.dat"));
6679
6680 MockRead spdy_reads[] = {
6681 CreateMockRead(*stream1_reply, 2, ASYNC),
6682 CreateMockRead(*stream2_syn, 3, ASYNC),
6683 CreateMockRead(*stream1_body, 5, ASYNC),
6684 MockRead(ASYNC, ERR_IO_PENDING, 6), // Force a pause
6685 };
6686
[email protected]dd54bd82012-07-19 23:44:576687 OrderedSocketData spdy_data(
6688 spdy_reads, arraysize(spdy_reads),
6689 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:076690 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:006691 // Negotiate SPDY to the proxy
6692 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:026693 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:076694 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:006695
[email protected]262eec82013-03-19 21:01:366696 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506697 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c843192012-04-05 07:15:006698 TestCompletionCallback callback;
6699 int rv = trans->Start(&request, callback.callback(), log.bound());
6700 EXPECT_EQ(ERR_IO_PENDING, rv);
6701
6702 rv = callback.WaitForResult();
6703 EXPECT_EQ(OK, rv);
6704 const HttpResponseInfo* response = trans->GetResponseInfo();
6705
6706 ASSERT_TRUE(response != NULL);
6707 EXPECT_TRUE(response->headers->IsKeepAlive());
6708
6709 EXPECT_EQ(200, response->headers->response_code());
6710 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6711
6712 std::string response_data;
6713 rv = ReadTransaction(trans.get(), &response_data);
6714 EXPECT_EQ(OK, rv);
6715 EXPECT_EQ("hello!", response_data);
6716
6717 trans.reset();
6718 session->CloseAllConnections();
6719}
6720
[email protected]2df19bb2010-08-25 20:13:466721// Test HTTPS connections to a site with a bad certificate, going through an
6722// HTTPS proxy
[email protected]23e482282013-06-14 16:08:026723TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076724 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:116725 "https://proxy:70"));
[email protected]2df19bb2010-08-25 20:13:466726
6727 HttpRequestInfo request;
6728 request.method = "GET";
6729 request.url = GURL("https://www.google.com/");
6730 request.load_flags = 0;
6731
6732 // Attempt to fetch the URL from a server with a bad cert
6733 MockWrite bad_cert_writes[] = {
6734 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6735 "Host: www.google.com\r\n"
6736 "Proxy-Connection: keep-alive\r\n\r\n"),
6737 };
6738
6739 MockRead bad_cert_reads[] = {
6740 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066741 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:466742 };
6743
6744 // Attempt to fetch the URL with a good cert
6745 MockWrite good_data_writes[] = {
6746 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6747 "Host: www.google.com\r\n"
6748 "Proxy-Connection: keep-alive\r\n\r\n"),
6749 MockWrite("GET / HTTP/1.1\r\n"
6750 "Host: www.google.com\r\n"
6751 "Connection: keep-alive\r\n\r\n"),
6752 };
6753
6754 MockRead good_cert_reads[] = {
6755 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
6756 MockRead("HTTP/1.0 200 OK\r\n"),
6757 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6758 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066759 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:466760 };
6761
6762 StaticSocketDataProvider ssl_bad_certificate(
6763 bad_cert_reads, arraysize(bad_cert_reads),
6764 bad_cert_writes, arraysize(bad_cert_writes));
6765 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
6766 good_data_writes, arraysize(good_data_writes));
[email protected]8ddf8322012-02-23 18:08:066767 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
6768 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:466769
6770 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:076771 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6772 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
6773 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:466774
6775 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:076776 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6777 session_deps_.socket_factory->AddSocketDataProvider(&data);
6778 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:466779
[email protected]49639fa2011-12-20 23:22:416780 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:466781
[email protected]3fe8d2f82013-10-17 08:56:076782 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:466783 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416784 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2df19bb2010-08-25 20:13:466785
[email protected]49639fa2011-12-20 23:22:416786 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:466787 EXPECT_EQ(ERR_IO_PENDING, rv);
6788
6789 rv = callback.WaitForResult();
6790 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
6791
[email protected]49639fa2011-12-20 23:22:416792 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]2df19bb2010-08-25 20:13:466793 EXPECT_EQ(ERR_IO_PENDING, rv);
6794
6795 rv = callback.WaitForResult();
6796 EXPECT_EQ(OK, rv);
6797
6798 const HttpResponseInfo* response = trans->GetResponseInfo();
6799
[email protected]fe2255a2011-09-20 19:37:506800 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:466801 EXPECT_EQ(100, response->headers->GetContentLength());
6802}
6803
[email protected]23e482282013-06-14 16:08:026804TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:426805 HttpRequestInfo request;
6806 request.method = "GET";
6807 request.url = GURL("http://www.google.com/");
[email protected]8c76ae22010-04-20 22:15:436808 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
6809 "Chromium Ultra Awesome X Edition");
[email protected]1c773ea12009-04-28 19:58:426810
[email protected]3fe8d2f82013-10-17 08:56:076811 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276812 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416813 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276814
[email protected]1c773ea12009-04-28 19:58:426815 MockWrite data_writes[] = {
6816 MockWrite("GET / HTTP/1.1\r\n"
6817 "Host: www.google.com\r\n"
6818 "Connection: keep-alive\r\n"
6819 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
6820 };
6821
6822 // Lastly, the server responds with the actual content.
6823 MockRead data_reads[] = {
6824 MockRead("HTTP/1.0 200 OK\r\n"),
6825 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6826 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066827 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426828 };
6829
[email protected]31a2bfe2010-02-09 08:03:396830 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6831 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076832 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426833
[email protected]49639fa2011-12-20 23:22:416834 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426835
[email protected]49639fa2011-12-20 23:22:416836 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426837 EXPECT_EQ(ERR_IO_PENDING, rv);
6838
6839 rv = callback.WaitForResult();
6840 EXPECT_EQ(OK, rv);
6841}
6842
[email protected]23e482282013-06-14 16:08:026843TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:296844 HttpRequestInfo request;
6845 request.method = "GET";
6846 request.url = GURL("https://www.google.com/");
6847 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
6848 "Chromium Ultra Awesome X Edition");
6849
[email protected]bb88e1d32013-05-03 23:11:076850 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]3fe8d2f82013-10-17 08:56:076851 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276852 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416853 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276854
[email protected]da81f132010-08-18 23:39:296855 MockWrite data_writes[] = {
6856 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6857 "Host: www.google.com\r\n"
6858 "Proxy-Connection: keep-alive\r\n"
6859 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
6860 };
6861 MockRead data_reads[] = {
6862 // Return an error, so the transaction stops here (this test isn't
6863 // interested in the rest).
6864 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
6865 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6866 MockRead("Proxy-Connection: close\r\n\r\n"),
6867 };
6868
6869 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6870 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076871 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:296872
[email protected]49639fa2011-12-20 23:22:416873 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:296874
[email protected]49639fa2011-12-20 23:22:416875 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]da81f132010-08-18 23:39:296876 EXPECT_EQ(ERR_IO_PENDING, rv);
6877
6878 rv = callback.WaitForResult();
6879 EXPECT_EQ(OK, rv);
6880}
6881
[email protected]23e482282013-06-14 16:08:026882TEST_P(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:426883 HttpRequestInfo request;
6884 request.method = "GET";
6885 request.url = GURL("http://www.google.com/");
6886 request.load_flags = 0;
[email protected]c10450102011-06-27 09:06:166887 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
6888 "http://the.previous.site.com/");
[email protected]1c773ea12009-04-28 19:58:426889
[email protected]3fe8d2f82013-10-17 08:56:076890 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276891 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416892 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276893
[email protected]1c773ea12009-04-28 19:58:426894 MockWrite data_writes[] = {
6895 MockWrite("GET / HTTP/1.1\r\n"
6896 "Host: www.google.com\r\n"
6897 "Connection: keep-alive\r\n"
6898 "Referer: http://the.previous.site.com/\r\n\r\n"),
6899 };
6900
6901 // Lastly, the server responds with the actual content.
6902 MockRead data_reads[] = {
6903 MockRead("HTTP/1.0 200 OK\r\n"),
6904 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6905 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066906 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426907 };
6908
[email protected]31a2bfe2010-02-09 08:03:396909 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6910 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076911 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426912
[email protected]49639fa2011-12-20 23:22:416913 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426914
[email protected]49639fa2011-12-20 23:22:416915 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426916 EXPECT_EQ(ERR_IO_PENDING, rv);
6917
6918 rv = callback.WaitForResult();
6919 EXPECT_EQ(OK, rv);
6920}
6921
[email protected]23e482282013-06-14 16:08:026922TEST_P(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:426923 HttpRequestInfo request;
6924 request.method = "POST";
6925 request.url = GURL("http://www.google.com/");
6926
[email protected]3fe8d2f82013-10-17 08:56:076927 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276928 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416929 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276930
[email protected]1c773ea12009-04-28 19:58:426931 MockWrite data_writes[] = {
6932 MockWrite("POST / HTTP/1.1\r\n"
6933 "Host: www.google.com\r\n"
6934 "Connection: keep-alive\r\n"
6935 "Content-Length: 0\r\n\r\n"),
6936 };
6937
6938 // Lastly, the server responds with the actual content.
6939 MockRead data_reads[] = {
6940 MockRead("HTTP/1.0 200 OK\r\n"),
6941 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6942 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066943 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426944 };
6945
[email protected]31a2bfe2010-02-09 08:03:396946 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6947 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076948 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426949
[email protected]49639fa2011-12-20 23:22:416950 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426951
[email protected]49639fa2011-12-20 23:22:416952 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426953 EXPECT_EQ(ERR_IO_PENDING, rv);
6954
6955 rv = callback.WaitForResult();
6956 EXPECT_EQ(OK, rv);
6957}
6958
[email protected]23e482282013-06-14 16:08:026959TEST_P(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:426960 HttpRequestInfo request;
6961 request.method = "PUT";
6962 request.url = GURL("http://www.google.com/");
6963
[email protected]3fe8d2f82013-10-17 08:56:076964 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276965 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416966 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276967
[email protected]1c773ea12009-04-28 19:58:426968 MockWrite data_writes[] = {
6969 MockWrite("PUT / HTTP/1.1\r\n"
6970 "Host: www.google.com\r\n"
6971 "Connection: keep-alive\r\n"
6972 "Content-Length: 0\r\n\r\n"),
6973 };
6974
6975 // Lastly, the server responds with the actual content.
6976 MockRead data_reads[] = {
6977 MockRead("HTTP/1.0 200 OK\r\n"),
6978 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6979 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066980 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426981 };
6982
[email protected]31a2bfe2010-02-09 08:03:396983 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6984 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076985 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426986
[email protected]49639fa2011-12-20 23:22:416987 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426988
[email protected]49639fa2011-12-20 23:22:416989 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426990 EXPECT_EQ(ERR_IO_PENDING, rv);
6991
6992 rv = callback.WaitForResult();
6993 EXPECT_EQ(OK, rv);
6994}
6995
[email protected]23e482282013-06-14 16:08:026996TEST_P(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:426997 HttpRequestInfo request;
6998 request.method = "HEAD";
6999 request.url = GURL("http://www.google.com/");
7000
[email protected]3fe8d2f82013-10-17 08:56:077001 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277002 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417003 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277004
[email protected]1c773ea12009-04-28 19:58:427005 MockWrite data_writes[] = {
7006 MockWrite("HEAD / HTTP/1.1\r\n"
7007 "Host: www.google.com\r\n"
7008 "Connection: keep-alive\r\n"
7009 "Content-Length: 0\r\n\r\n"),
7010 };
7011
7012 // Lastly, the server responds with the actual content.
7013 MockRead data_reads[] = {
7014 MockRead("HTTP/1.0 200 OK\r\n"),
7015 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7016 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067017 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427018 };
7019
[email protected]31a2bfe2010-02-09 08:03:397020 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7021 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077022 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427023
[email protected]49639fa2011-12-20 23:22:417024 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427025
[email protected]49639fa2011-12-20 23:22:417026 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427027 EXPECT_EQ(ERR_IO_PENDING, rv);
7028
7029 rv = callback.WaitForResult();
7030 EXPECT_EQ(OK, rv);
7031}
7032
[email protected]23e482282013-06-14 16:08:027033TEST_P(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:427034 HttpRequestInfo request;
7035 request.method = "GET";
7036 request.url = GURL("http://www.google.com/");
7037 request.load_flags = LOAD_BYPASS_CACHE;
7038
[email protected]3fe8d2f82013-10-17 08:56:077039 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277040 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417041 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277042
[email protected]1c773ea12009-04-28 19:58:427043 MockWrite data_writes[] = {
7044 MockWrite("GET / HTTP/1.1\r\n"
7045 "Host: www.google.com\r\n"
7046 "Connection: keep-alive\r\n"
7047 "Pragma: no-cache\r\n"
7048 "Cache-Control: no-cache\r\n\r\n"),
7049 };
7050
7051 // Lastly, the server responds with the actual content.
7052 MockRead data_reads[] = {
7053 MockRead("HTTP/1.0 200 OK\r\n"),
7054 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7055 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067056 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427057 };
7058
[email protected]31a2bfe2010-02-09 08:03:397059 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7060 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077061 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427062
[email protected]49639fa2011-12-20 23:22:417063 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427064
[email protected]49639fa2011-12-20 23:22:417065 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427066 EXPECT_EQ(ERR_IO_PENDING, rv);
7067
7068 rv = callback.WaitForResult();
7069 EXPECT_EQ(OK, rv);
7070}
7071
[email protected]23e482282013-06-14 16:08:027072TEST_P(HttpNetworkTransactionTest,
[email protected]1c773ea12009-04-28 19:58:427073 BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:427074 HttpRequestInfo request;
7075 request.method = "GET";
7076 request.url = GURL("http://www.google.com/");
7077 request.load_flags = LOAD_VALIDATE_CACHE;
7078
[email protected]3fe8d2f82013-10-17 08:56:077079 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277080 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417081 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277082
[email protected]1c773ea12009-04-28 19:58:427083 MockWrite data_writes[] = {
7084 MockWrite("GET / HTTP/1.1\r\n"
7085 "Host: www.google.com\r\n"
7086 "Connection: keep-alive\r\n"
7087 "Cache-Control: max-age=0\r\n\r\n"),
7088 };
7089
7090 // Lastly, the server responds with the actual content.
7091 MockRead data_reads[] = {
7092 MockRead("HTTP/1.0 200 OK\r\n"),
7093 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7094 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067095 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427096 };
7097
[email protected]31a2bfe2010-02-09 08:03:397098 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7099 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077100 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427101
[email protected]49639fa2011-12-20 23:22:417102 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427103
[email protected]49639fa2011-12-20 23:22:417104 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427105 EXPECT_EQ(ERR_IO_PENDING, rv);
7106
7107 rv = callback.WaitForResult();
7108 EXPECT_EQ(OK, rv);
7109}
7110
[email protected]23e482282013-06-14 16:08:027111TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:427112 HttpRequestInfo request;
7113 request.method = "GET";
7114 request.url = GURL("http://www.google.com/");
[email protected]8c76ae22010-04-20 22:15:437115 request.extra_headers.SetHeader("FooHeader", "Bar");
[email protected]1c773ea12009-04-28 19:58:427116
[email protected]3fe8d2f82013-10-17 08:56:077117 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277118 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417119 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277120
[email protected]1c773ea12009-04-28 19:58:427121 MockWrite data_writes[] = {
7122 MockWrite("GET / HTTP/1.1\r\n"
7123 "Host: www.google.com\r\n"
7124 "Connection: keep-alive\r\n"
7125 "FooHeader: Bar\r\n\r\n"),
7126 };
7127
7128 // Lastly, the server responds with the actual content.
7129 MockRead data_reads[] = {
7130 MockRead("HTTP/1.0 200 OK\r\n"),
7131 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7132 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067133 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427134 };
7135
[email protected]31a2bfe2010-02-09 08:03:397136 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7137 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077138 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427139
[email protected]49639fa2011-12-20 23:22:417140 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427141
[email protected]49639fa2011-12-20 23:22:417142 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427143 EXPECT_EQ(ERR_IO_PENDING, rv);
7144
7145 rv = callback.WaitForResult();
7146 EXPECT_EQ(OK, rv);
7147}
7148
[email protected]23e482282013-06-14 16:08:027149TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:477150 HttpRequestInfo request;
7151 request.method = "GET";
7152 request.url = GURL("http://www.google.com/");
[email protected]8c76ae22010-04-20 22:15:437153 request.extra_headers.SetHeader("referer", "www.foo.com");
7154 request.extra_headers.SetHeader("hEllo", "Kitty");
7155 request.extra_headers.SetHeader("FoO", "bar");
[email protected]270c6412010-03-29 22:02:477156
[email protected]3fe8d2f82013-10-17 08:56:077157 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277158 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417159 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277160
[email protected]270c6412010-03-29 22:02:477161 MockWrite data_writes[] = {
7162 MockWrite("GET / HTTP/1.1\r\n"
7163 "Host: www.google.com\r\n"
7164 "Connection: keep-alive\r\n"
[email protected]c10450102011-06-27 09:06:167165 "referer: www.foo.com\r\n"
[email protected]270c6412010-03-29 22:02:477166 "hEllo: Kitty\r\n"
7167 "FoO: bar\r\n\r\n"),
7168 };
7169
7170 // Lastly, the server responds with the actual content.
7171 MockRead data_reads[] = {
7172 MockRead("HTTP/1.0 200 OK\r\n"),
7173 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7174 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067175 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:477176 };
7177
7178 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7179 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077180 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:477181
[email protected]49639fa2011-12-20 23:22:417182 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:477183
[email protected]49639fa2011-12-20 23:22:417184 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]270c6412010-03-29 22:02:477185 EXPECT_EQ(ERR_IO_PENDING, rv);
7186
7187 rv = callback.WaitForResult();
7188 EXPECT_EQ(OK, rv);
7189}
7190
[email protected]23e482282013-06-14 16:08:027191TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277192 HttpRequestInfo request;
7193 request.method = "GET";
7194 request.url = GURL("http://www.google.com/");
7195 request.load_flags = 0;
7196
[email protected]bb88e1d32013-05-03 23:11:077197 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207198 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
7199 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077200 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:027201
[email protected]3fe8d2f82013-10-17 08:56:077202 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3cd17242009-06-23 02:59:027203 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417204 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3cd17242009-06-23 02:59:027205
[email protected]3cd17242009-06-23 02:59:027206 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
7207 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7208
7209 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:067210 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
[email protected]3cd17242009-06-23 02:59:027211 MockWrite("GET / HTTP/1.1\r\n"
7212 "Host: www.google.com\r\n"
7213 "Connection: keep-alive\r\n\r\n")
7214 };
7215
7216 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:067217 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:027218 MockRead("HTTP/1.0 200 OK\r\n"),
7219 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7220 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067221 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:027222 };
7223
[email protected]31a2bfe2010-02-09 08:03:397224 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7225 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077226 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:027227
[email protected]49639fa2011-12-20 23:22:417228 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:027229
[email protected]49639fa2011-12-20 23:22:417230 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:027231 EXPECT_EQ(ERR_IO_PENDING, rv);
7232
7233 rv = callback.WaitForResult();
7234 EXPECT_EQ(OK, rv);
7235
7236 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507237 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:027238
[email protected]029c83b62013-01-24 05:28:207239 LoadTimingInfo load_timing_info;
7240 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7241 TestLoadTimingNotReusedWithPac(load_timing_info,
7242 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7243
[email protected]3cd17242009-06-23 02:59:027244 std::string response_text;
7245 rv = ReadTransaction(trans.get(), &response_text);
7246 EXPECT_EQ(OK, rv);
7247 EXPECT_EQ("Payload", response_text);
7248}
7249
[email protected]23e482282013-06-14 16:08:027250TEST_P(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277251 HttpRequestInfo request;
7252 request.method = "GET";
7253 request.url = GURL("https://www.google.com/");
7254 request.load_flags = 0;
7255
[email protected]bb88e1d32013-05-03 23:11:077256 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207257 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
7258 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077259 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:027260
[email protected]3fe8d2f82013-10-17 08:56:077261 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3cd17242009-06-23 02:59:027262 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417263 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3cd17242009-06-23 02:59:027264
[email protected]3cd17242009-06-23 02:59:027265 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
7266 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7267
7268 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:067269 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
[email protected]e0c27be2009-07-15 13:09:357270 arraysize(write_buffer)),
[email protected]3cd17242009-06-23 02:59:027271 MockWrite("GET / HTTP/1.1\r\n"
7272 "Host: www.google.com\r\n"
7273 "Connection: keep-alive\r\n\r\n")
7274 };
7275
7276 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:017277 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
7278 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:357279 MockRead("HTTP/1.0 200 OK\r\n"),
7280 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7281 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067282 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:357283 };
7284
[email protected]31a2bfe2010-02-09 08:03:397285 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7286 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077287 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:357288
[email protected]8ddf8322012-02-23 18:08:067289 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077290 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:357291
[email protected]49639fa2011-12-20 23:22:417292 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:357293
[email protected]49639fa2011-12-20 23:22:417294 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:357295 EXPECT_EQ(ERR_IO_PENDING, rv);
7296
7297 rv = callback.WaitForResult();
7298 EXPECT_EQ(OK, rv);
7299
[email protected]029c83b62013-01-24 05:28:207300 LoadTimingInfo load_timing_info;
7301 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7302 TestLoadTimingNotReusedWithPac(load_timing_info,
7303 CONNECT_TIMING_HAS_SSL_TIMES);
7304
[email protected]e0c27be2009-07-15 13:09:357305 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507306 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:357307
7308 std::string response_text;
7309 rv = ReadTransaction(trans.get(), &response_text);
7310 EXPECT_EQ(OK, rv);
7311 EXPECT_EQ("Payload", response_text);
7312}
7313
[email protected]23e482282013-06-14 16:08:027314TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:207315 HttpRequestInfo request;
7316 request.method = "GET";
7317 request.url = GURL("http://www.google.com/");
7318 request.load_flags = 0;
7319
[email protected]bb88e1d32013-05-03 23:11:077320 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207321 ProxyService::CreateFixed("socks4://myproxy:1080"));
7322 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077323 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:207324
[email protected]3fe8d2f82013-10-17 08:56:077325 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:207326 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417327 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:207328
7329 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
7330 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7331
7332 MockWrite data_writes[] = {
7333 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
7334 MockWrite("GET / HTTP/1.1\r\n"
7335 "Host: www.google.com\r\n"
7336 "Connection: keep-alive\r\n\r\n")
7337 };
7338
7339 MockRead data_reads[] = {
7340 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
7341 MockRead("HTTP/1.0 200 OK\r\n"),
7342 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7343 MockRead("Payload"),
7344 MockRead(SYNCHRONOUS, OK)
7345 };
7346
7347 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7348 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077349 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:207350
7351 TestCompletionCallback callback;
7352
7353 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7354 EXPECT_EQ(ERR_IO_PENDING, rv);
7355
7356 rv = callback.WaitForResult();
7357 EXPECT_EQ(OK, rv);
7358
7359 const HttpResponseInfo* response = trans->GetResponseInfo();
7360 ASSERT_TRUE(response != NULL);
7361
7362 LoadTimingInfo load_timing_info;
7363 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7364 TestLoadTimingNotReused(load_timing_info,
7365 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7366
7367 std::string response_text;
7368 rv = ReadTransaction(trans.get(), &response_text);
7369 EXPECT_EQ(OK, rv);
7370 EXPECT_EQ("Payload", response_text);
7371}
7372
[email protected]23e482282013-06-14 16:08:027373TEST_P(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277374 HttpRequestInfo request;
7375 request.method = "GET";
7376 request.url = GURL("http://www.google.com/");
7377 request.load_flags = 0;
7378
[email protected]bb88e1d32013-05-03 23:11:077379 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207380 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
7381 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077382 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:357383
[email protected]3fe8d2f82013-10-17 08:56:077384 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e0c27be2009-07-15 13:09:357385 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417386 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]e0c27be2009-07-15 13:09:357387
[email protected]e0c27be2009-07-15 13:09:357388 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
7389 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:377390 const char kSOCKS5OkRequest[] = {
7391 0x05, // Version
7392 0x01, // Command (CONNECT)
7393 0x00, // Reserved.
7394 0x03, // Address type (DOMAINNAME).
7395 0x0E, // Length of domain (14)
7396 // Domain string:
7397 'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
7398 0x00, 0x50, // 16-bit port (80)
7399 };
[email protected]e0c27be2009-07-15 13:09:357400 const char kSOCKS5OkResponse[] =
7401 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
7402
7403 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:067404 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
7405 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
[email protected]e0c27be2009-07-15 13:09:357406 MockWrite("GET / HTTP/1.1\r\n"
7407 "Host: www.google.com\r\n"
7408 "Connection: keep-alive\r\n\r\n")
7409 };
7410
7411 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:017412 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
7413 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:357414 MockRead("HTTP/1.0 200 OK\r\n"),
7415 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7416 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067417 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:357418 };
7419
[email protected]31a2bfe2010-02-09 08:03:397420 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7421 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077422 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:357423
[email protected]49639fa2011-12-20 23:22:417424 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:357425
[email protected]49639fa2011-12-20 23:22:417426 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:357427 EXPECT_EQ(ERR_IO_PENDING, rv);
7428
7429 rv = callback.WaitForResult();
7430 EXPECT_EQ(OK, rv);
7431
7432 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507433 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:357434
[email protected]029c83b62013-01-24 05:28:207435 LoadTimingInfo load_timing_info;
7436 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7437 TestLoadTimingNotReusedWithPac(load_timing_info,
7438 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7439
[email protected]e0c27be2009-07-15 13:09:357440 std::string response_text;
7441 rv = ReadTransaction(trans.get(), &response_text);
7442 EXPECT_EQ(OK, rv);
7443 EXPECT_EQ("Payload", response_text);
7444}
7445
[email protected]23e482282013-06-14 16:08:027446TEST_P(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277447 HttpRequestInfo request;
7448 request.method = "GET";
7449 request.url = GURL("https://www.google.com/");
7450 request.load_flags = 0;
7451
[email protected]bb88e1d32013-05-03 23:11:077452 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207453 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
7454 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077455 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:357456
[email protected]3fe8d2f82013-10-17 08:56:077457 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e0c27be2009-07-15 13:09:357458 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417459 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]e0c27be2009-07-15 13:09:357460
[email protected]e0c27be2009-07-15 13:09:357461 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
7462 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:377463 const unsigned char kSOCKS5OkRequest[] = {
7464 0x05, // Version
7465 0x01, // Command (CONNECT)
7466 0x00, // Reserved.
7467 0x03, // Address type (DOMAINNAME).
7468 0x0E, // Length of domain (14)
7469 // Domain string:
7470 'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
7471 0x01, 0xBB, // 16-bit port (443)
7472 };
7473
[email protected]e0c27be2009-07-15 13:09:357474 const char kSOCKS5OkResponse[] =
7475 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
7476
7477 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:067478 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
7479 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
[email protected]e0c27be2009-07-15 13:09:357480 arraysize(kSOCKS5OkRequest)),
7481 MockWrite("GET / HTTP/1.1\r\n"
7482 "Host: www.google.com\r\n"
7483 "Connection: keep-alive\r\n\r\n")
7484 };
7485
7486 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:017487 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
7488 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:027489 MockRead("HTTP/1.0 200 OK\r\n"),
7490 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7491 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067492 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:027493 };
7494
[email protected]31a2bfe2010-02-09 08:03:397495 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7496 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077497 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:027498
[email protected]8ddf8322012-02-23 18:08:067499 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077500 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:027501
[email protected]49639fa2011-12-20 23:22:417502 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:027503
[email protected]49639fa2011-12-20 23:22:417504 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:027505 EXPECT_EQ(ERR_IO_PENDING, rv);
7506
7507 rv = callback.WaitForResult();
7508 EXPECT_EQ(OK, rv);
7509
7510 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507511 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:027512
[email protected]029c83b62013-01-24 05:28:207513 LoadTimingInfo load_timing_info;
7514 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7515 TestLoadTimingNotReusedWithPac(load_timing_info,
7516 CONNECT_TIMING_HAS_SSL_TIMES);
7517
[email protected]3cd17242009-06-23 02:59:027518 std::string response_text;
7519 rv = ReadTransaction(trans.get(), &response_text);
7520 EXPECT_EQ(OK, rv);
7521 EXPECT_EQ("Payload", response_text);
7522}
7523
[email protected]448d4ca52012-03-04 04:12:237524namespace {
7525
[email protected]04e5be32009-06-26 20:00:317526// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:067527
7528struct GroupNameTest {
7529 std::string proxy_server;
7530 std::string url;
7531 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:187532 bool ssl;
[email protected]2d731a32010-04-29 01:04:067533};
7534
7535scoped_refptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]8a0fc822013-06-27 20:52:437536 NextProto next_proto,
[email protected]bb88e1d32013-05-03 23:11:077537 SpdySessionDependencies* session_deps_) {
7538 scoped_refptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:067539
[email protected]30d4c022013-07-18 22:58:167540 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:537541 session->http_server_properties();
7542 http_server_properties->SetAlternateProtocol(
[email protected]2d731a32010-04-29 01:04:067543 HostPortPair("host.with.alternate", 80), 443,
[email protected]287d9412014-07-08 23:01:007544 AlternateProtocolFromNextProto(next_proto), 1);
[email protected]2d731a32010-04-29 01:04:067545
7546 return session;
7547}
7548
7549int GroupNameTransactionHelper(
7550 const std::string& url,
7551 const scoped_refptr<HttpNetworkSession>& session) {
[email protected]2d731a32010-04-29 01:04:067552 HttpRequestInfo request;
7553 request.method = "GET";
7554 request.url = GURL(url);
7555 request.load_flags = 0;
7556
[email protected]262eec82013-03-19 21:01:367557 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507558 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277559
[email protected]49639fa2011-12-20 23:22:417560 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:067561
7562 // We do not complete this request, the dtor will clean the transaction up.
[email protected]49639fa2011-12-20 23:22:417563 return trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d731a32010-04-29 01:04:067564}
7565
[email protected]448d4ca52012-03-04 04:12:237566} // namespace
7567
[email protected]23e482282013-06-14 16:08:027568TEST_P(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:067569 const GroupNameTest tests[] = {
[email protected]04e5be32009-06-26 20:00:317570 {
[email protected]2d731a32010-04-29 01:04:067571 "", // unused
[email protected]04e5be32009-06-26 20:00:317572 "http://www.google.com/direct",
[email protected]2ff8b312010-04-26 22:20:547573 "www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:187574 false,
[email protected]2ff8b312010-04-26 22:20:547575 },
7576 {
[email protected]2d731a32010-04-29 01:04:067577 "", // unused
[email protected]2ff8b312010-04-26 22:20:547578 "http://[2001:1418:13:1::25]/direct",
7579 "[2001:1418:13:1::25]:80",
[email protected]e60e47a2010-07-14 03:37:187580 false,
[email protected]04e5be32009-06-26 20:00:317581 },
[email protected]04e5be32009-06-26 20:00:317582
7583 // SSL Tests
7584 {
[email protected]2d731a32010-04-29 01:04:067585 "", // unused
[email protected]04e5be32009-06-26 20:00:317586 "https://www.google.com/direct_ssl",
[email protected]0e88ad602010-05-04 23:47:027587 "ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:187588 true,
[email protected]04e5be32009-06-26 20:00:317589 },
7590 {
[email protected]2d731a32010-04-29 01:04:067591 "", // unused
7592 "https://[2001:1418:13:1::25]/direct",
[email protected]0e88ad602010-05-04 23:47:027593 "ssl/[2001:1418:13:1::25]:443",
[email protected]e60e47a2010-07-14 03:37:187594 true,
[email protected]04e5be32009-06-26 20:00:317595 },
7596 {
[email protected]2d731a32010-04-29 01:04:067597 "", // unused
[email protected]2ff8b312010-04-26 22:20:547598 "http://host.with.alternate/direct",
[email protected]0e88ad602010-05-04 23:47:027599 "ssl/host.with.alternate:443",
[email protected]e60e47a2010-07-14 03:37:187600 true,
[email protected]2ff8b312010-04-26 22:20:547601 },
[email protected]2d731a32010-04-29 01:04:067602 };
[email protected]2ff8b312010-04-26 22:20:547603
[email protected]d7599122014-05-24 03:37:237604 session_deps_.use_alternate_protocols = true;
[email protected]2d731a32010-04-29 01:04:067605
viettrungluue4a8b882014-10-16 06:17:387606 for (size_t i = 0; i < arraysize(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:077607 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:027608 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:067609 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:437610 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:067611
7612 HttpNetworkSessionPeer peer(session);
[email protected]ab739042011-04-07 15:22:287613 CaptureGroupNameTransportSocketPool* transport_conn_pool =
7614 new CaptureGroupNameTransportSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:137615 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347616 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]831e4a32013-11-14 02:14:447617 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
7618 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:027619 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
7620 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
dchenge3d1ddc2014-10-15 19:30:517621 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]2d731a32010-04-29 01:04:067622
7623 EXPECT_EQ(ERR_IO_PENDING,
7624 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:187625 if (tests[i].ssl)
7626 EXPECT_EQ(tests[i].expected_group_name,
7627 ssl_conn_pool->last_group_name_received());
7628 else
7629 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:287630 transport_conn_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:067631 }
7632
[email protected]2d731a32010-04-29 01:04:067633}
7634
[email protected]23e482282013-06-14 16:08:027635TEST_P(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:067636 const GroupNameTest tests[] = {
7637 {
7638 "http_proxy",
7639 "http://www.google.com/http_proxy_normal",
7640 "www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:187641 false,
[email protected]2d731a32010-04-29 01:04:067642 },
7643
7644 // SSL Tests
7645 {
7646 "http_proxy",
7647 "https://www.google.com/http_connect_ssl",
[email protected]0e88ad602010-05-04 23:47:027648 "ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:187649 true,
[email protected]2d731a32010-04-29 01:04:067650 },
[email protected]af3490e2010-10-16 21:02:297651
[email protected]9faeded92010-04-29 20:03:057652 {
7653 "http_proxy",
7654 "http://host.with.alternate/direct",
[email protected]0e88ad602010-05-04 23:47:027655 "ssl/host.with.alternate:443",
[email protected]e60e47a2010-07-14 03:37:187656 true,
[email protected]9faeded92010-04-29 20:03:057657 },
[email protected]45499252013-01-23 17:12:567658
7659 {
7660 "http_proxy",
7661 "ftp://ftp.google.com/http_proxy_normal",
7662 "ftp/ftp.google.com:21",
7663 false,
7664 },
[email protected]2d731a32010-04-29 01:04:067665 };
7666
[email protected]d7599122014-05-24 03:37:237667 session_deps_.use_alternate_protocols = true;
[email protected]2d731a32010-04-29 01:04:067668
viettrungluue4a8b882014-10-16 06:17:387669 for (size_t i = 0; i < arraysize(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:077670 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:027671 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:067672 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:437673 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:067674
7675 HttpNetworkSessionPeer peer(session);
7676
[email protected]e60e47a2010-07-14 03:37:187677 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:137678 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:347679 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:137680 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347681 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:027682
[email protected]831e4a32013-11-14 02:14:447683 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
7684 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:027685 mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool);
7686 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
dchenge3d1ddc2014-10-15 19:30:517687 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]2d731a32010-04-29 01:04:067688
7689 EXPECT_EQ(ERR_IO_PENDING,
7690 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:187691 if (tests[i].ssl)
7692 EXPECT_EQ(tests[i].expected_group_name,
7693 ssl_conn_pool->last_group_name_received());
7694 else
7695 EXPECT_EQ(tests[i].expected_group_name,
7696 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:067697 }
[email protected]2d731a32010-04-29 01:04:067698}
7699
[email protected]23e482282013-06-14 16:08:027700TEST_P(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:067701 const GroupNameTest tests[] = {
7702 {
7703 "socks4://socks_proxy:1080",
7704 "http://www.google.com/socks4_direct",
7705 "socks4/www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:187706 false,
[email protected]2d731a32010-04-29 01:04:067707 },
7708 {
7709 "socks5://socks_proxy:1080",
7710 "http://www.google.com/socks5_direct",
7711 "socks5/www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:187712 false,
[email protected]2d731a32010-04-29 01:04:067713 },
7714
7715 // SSL Tests
7716 {
7717 "socks4://socks_proxy:1080",
7718 "https://www.google.com/socks4_ssl",
[email protected]0e88ad602010-05-04 23:47:027719 "socks4/ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:187720 true,
[email protected]2d731a32010-04-29 01:04:067721 },
7722 {
7723 "socks5://socks_proxy:1080",
7724 "https://www.google.com/socks5_ssl",
[email protected]0e88ad602010-05-04 23:47:027725 "socks5/ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:187726 true,
[email protected]2d731a32010-04-29 01:04:067727 },
[email protected]af3490e2010-10-16 21:02:297728
[email protected]9faeded92010-04-29 20:03:057729 {
7730 "socks4://socks_proxy:1080",
7731 "http://host.with.alternate/direct",
[email protected]0e88ad602010-05-04 23:47:027732 "socks4/ssl/host.with.alternate:443",
[email protected]e60e47a2010-07-14 03:37:187733 true,
[email protected]9faeded92010-04-29 20:03:057734 },
[email protected]04e5be32009-06-26 20:00:317735 };
7736
[email protected]d7599122014-05-24 03:37:237737 session_deps_.use_alternate_protocols = true;
[email protected]2ff8b312010-04-26 22:20:547738
viettrungluue4a8b882014-10-16 06:17:387739 for (size_t i = 0; i < arraysize(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:077740 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:027741 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:067742 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:437743 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]8b114dd72011-03-25 05:33:027744
[email protected]2d731a32010-04-29 01:04:067745 HttpNetworkSessionPeer peer(session);
[email protected]04e5be32009-06-26 20:00:317746
[email protected]e60e47a2010-07-14 03:37:187747 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:137748 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347749 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:137750 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347751 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:027752
[email protected]831e4a32013-11-14 02:14:447753 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
7754 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:027755 mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_conn_pool);
7756 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
dchenge3d1ddc2014-10-15 19:30:517757 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]04e5be32009-06-26 20:00:317758
[email protected]262eec82013-03-19 21:01:367759 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507760 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]04e5be32009-06-26 20:00:317761
[email protected]2d731a32010-04-29 01:04:067762 EXPECT_EQ(ERR_IO_PENDING,
7763 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:187764 if (tests[i].ssl)
7765 EXPECT_EQ(tests[i].expected_group_name,
7766 ssl_conn_pool->last_group_name_received());
7767 else
7768 EXPECT_EQ(tests[i].expected_group_name,
7769 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:317770 }
7771}
7772
[email protected]23e482282013-06-14 16:08:027773TEST_P(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:277774 HttpRequestInfo request;
7775 request.method = "GET";
7776 request.url = GURL("http://www.google.com/");
7777
[email protected]bb88e1d32013-05-03 23:11:077778 session_deps_.proxy_service.reset(
[email protected]81cdfcd2010-10-16 00:49:007779 ProxyService::CreateFixed("myproxy:70;foobar:80"));
[email protected]b59ff372009-07-15 22:04:327780
[email protected]69719062010-01-05 20:09:217781 // This simulates failure resolving all hostnames; that means we will fail
7782 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:077783 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:327784
[email protected]3fe8d2f82013-10-17 08:56:077785 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]9172a982009-06-06 00:30:257786 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417787 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]9172a982009-06-06 00:30:257788
[email protected]49639fa2011-12-20 23:22:417789 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:257790
[email protected]49639fa2011-12-20 23:22:417791 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9172a982009-06-06 00:30:257792 EXPECT_EQ(ERR_IO_PENDING, rv);
7793
[email protected]9172a982009-06-06 00:30:257794 rv = callback.WaitForResult();
[email protected]f7fccee2010-09-16 20:53:017795 EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
[email protected]9172a982009-06-06 00:30:257796}
7797
[email protected]685af592010-05-11 19:31:247798// Base test to make sure that when the load flags for a request specify to
7799// bypass the cache, the DNS cache is not used.
[email protected]23e482282013-06-14 16:08:027800void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
[email protected]bb88e1d32013-05-03 23:11:077801 int load_flags) {
[email protected]cb9bf6ca2011-01-28 13:15:277802 // Issue a request, asking to bypass the cache(s).
7803 HttpRequestInfo request;
7804 request.method = "GET";
7805 request.load_flags = load_flags;
7806 request.url = GURL("http://www.google.com/");
7807
[email protected]a2c2fb92009-07-18 07:31:047808 // Select a host resolver that does caching.
[email protected]bb88e1d32013-05-03 23:11:077809 session_deps_.host_resolver.reset(new MockCachingHostResolver);
[email protected]b59ff372009-07-15 22:04:327810
[email protected]3fe8d2f82013-10-17 08:56:077811 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7812 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417813 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3b9cca42009-06-16 01:08:287814
[email protected]6e78dfb2011-07-28 21:34:477815 // Warm up the host cache so it has an entry for "www.google.com".
[email protected]3b9cca42009-06-16 01:08:287816 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:297817 TestCompletionCallback callback;
[email protected]bb88e1d32013-05-03 23:11:077818 int rv = session_deps_.host_resolver->Resolve(
[email protected]5109c1952013-08-20 18:44:107819 HostResolver::RequestInfo(HostPortPair("www.google.com", 80)),
7820 DEFAULT_PRIORITY,
[email protected]b9823c02013-08-16 21:24:417821 &addrlist,
7822 callback.callback(),
7823 NULL,
7824 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:477825 EXPECT_EQ(ERR_IO_PENDING, rv);
7826 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:287827 EXPECT_EQ(OK, rv);
7828
7829 // Verify that it was added to host cache, by doing a subsequent async lookup
7830 // and confirming it completes synchronously.
[email protected]bb88e1d32013-05-03 23:11:077831 rv = session_deps_.host_resolver->Resolve(
[email protected]5109c1952013-08-20 18:44:107832 HostResolver::RequestInfo(HostPortPair("www.google.com", 80)),
7833 DEFAULT_PRIORITY,
[email protected]b9823c02013-08-16 21:24:417834 &addrlist,
7835 callback.callback(),
7836 NULL,
7837 BoundNetLog());
[email protected]b59ff372009-07-15 22:04:327838 ASSERT_EQ(OK, rv);
[email protected]3b9cca42009-06-16 01:08:287839
7840 // Inject a failure the next time that "www.google.com" is resolved. This way
7841 // we can tell if the next lookup hit the cache, or the "network".
7842 // (cache --> success, "network" --> failure).
[email protected]bb88e1d32013-05-03 23:11:077843 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.google.com");
[email protected]3b9cca42009-06-16 01:08:287844
7845 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
7846 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:067847 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
[email protected]31a2bfe2010-02-09 08:03:397848 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077849 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:287850
[email protected]3b9cca42009-06-16 01:08:287851 // Run the request.
[email protected]49639fa2011-12-20 23:22:417852 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3b9cca42009-06-16 01:08:287853 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:417854 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:287855
7856 // If we bypassed the cache, we would have gotten a failure while resolving
7857 // "www.google.com".
7858 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
7859}
7860
[email protected]685af592010-05-11 19:31:247861// There are multiple load flags that should trigger the host cache bypass.
7862// Test each in isolation:
[email protected]23e482282013-06-14 16:08:027863TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
[email protected]685af592010-05-11 19:31:247864 BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
7865}
7866
[email protected]23e482282013-06-14 16:08:027867TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
[email protected]685af592010-05-11 19:31:247868 BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
7869}
7870
[email protected]23e482282013-06-14 16:08:027871TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
[email protected]685af592010-05-11 19:31:247872 BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
7873}
7874
[email protected]0877e3d2009-10-17 22:29:577875// Make sure we can handle an error when writing the request.
[email protected]23e482282013-06-14 16:08:027876TEST_P(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:577877 HttpRequestInfo request;
7878 request.method = "GET";
7879 request.url = GURL("http://www.foo.com/");
7880 request.load_flags = 0;
7881
7882 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:067883 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:577884 };
[email protected]31a2bfe2010-02-09 08:03:397885 StaticSocketDataProvider data(NULL, 0,
7886 write_failure, arraysize(write_failure));
[email protected]bb88e1d32013-05-03 23:11:077887 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3fe8d2f82013-10-17 08:56:077888 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:577889
[email protected]49639fa2011-12-20 23:22:417890 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:577891
7892 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417893 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:577894
[email protected]49639fa2011-12-20 23:22:417895 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:577896 EXPECT_EQ(ERR_IO_PENDING, rv);
7897
7898 rv = callback.WaitForResult();
7899 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
7900}
7901
7902// Check that a connection closed after the start of the headers finishes ok.
[email protected]23e482282013-06-14 16:08:027903TEST_P(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:577904 HttpRequestInfo request;
7905 request.method = "GET";
7906 request.url = GURL("http://www.foo.com/");
7907 request.load_flags = 0;
7908
7909 MockRead data_reads[] = {
7910 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:067911 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:577912 };
7913
[email protected]31a2bfe2010-02-09 08:03:397914 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077915 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3fe8d2f82013-10-17 08:56:077916 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:577917
[email protected]49639fa2011-12-20 23:22:417918 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:577919
7920 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417921 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:577922
[email protected]49639fa2011-12-20 23:22:417923 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:577924 EXPECT_EQ(ERR_IO_PENDING, rv);
7925
7926 rv = callback.WaitForResult();
7927 EXPECT_EQ(OK, rv);
7928
7929 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507930 ASSERT_TRUE(response != NULL);
[email protected]0877e3d2009-10-17 22:29:577931
[email protected]90499482013-06-01 00:39:507932 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]0877e3d2009-10-17 22:29:577933 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
7934
7935 std::string response_data;
7936 rv = ReadTransaction(trans.get(), &response_data);
7937 EXPECT_EQ(OK, rv);
7938 EXPECT_EQ("", response_data);
7939}
7940
7941// Make sure that a dropped connection while draining the body for auth
7942// restart does the right thing.
[email protected]23e482282013-06-14 16:08:027943TEST_P(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:577944 HttpRequestInfo request;
7945 request.method = "GET";
7946 request.url = GURL("http://www.google.com/");
7947 request.load_flags = 0;
7948
7949 MockWrite data_writes1[] = {
7950 MockWrite("GET / HTTP/1.1\r\n"
7951 "Host: www.google.com\r\n"
7952 "Connection: keep-alive\r\n\r\n"),
7953 };
7954
7955 MockRead data_reads1[] = {
7956 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
7957 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7958 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7959 MockRead("Content-Length: 14\r\n\r\n"),
7960 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:067961 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:577962 };
7963
[email protected]31a2bfe2010-02-09 08:03:397964 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7965 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:077966 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:577967
7968 // After calling trans->RestartWithAuth(), this is the request we should
7969 // be issuing -- the final header line contains the credentials.
7970 MockWrite data_writes2[] = {
7971 MockWrite("GET / HTTP/1.1\r\n"
7972 "Host: www.google.com\r\n"
7973 "Connection: keep-alive\r\n"
7974 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
7975 };
7976
7977 // Lastly, the server responds with the actual content.
7978 MockRead data_reads2[] = {
7979 MockRead("HTTP/1.1 200 OK\r\n"),
7980 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7981 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067982 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:577983 };
7984
[email protected]31a2bfe2010-02-09 08:03:397985 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7986 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077987 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3fe8d2f82013-10-17 08:56:077988 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:577989
[email protected]49639fa2011-12-20 23:22:417990 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:577991
[email protected]262eec82013-03-19 21:01:367992 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507993 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:507994
[email protected]49639fa2011-12-20 23:22:417995 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:577996 EXPECT_EQ(ERR_IO_PENDING, rv);
7997
7998 rv = callback1.WaitForResult();
7999 EXPECT_EQ(OK, rv);
8000
8001 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508002 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048003 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:578004
[email protected]49639fa2011-12-20 23:22:418005 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:578006
[email protected]49639fa2011-12-20 23:22:418007 rv = trans->RestartWithAuth(
8008 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]0877e3d2009-10-17 22:29:578009 EXPECT_EQ(ERR_IO_PENDING, rv);
8010
8011 rv = callback2.WaitForResult();
8012 EXPECT_EQ(OK, rv);
8013
8014 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508015 ASSERT_TRUE(response != NULL);
[email protected]0877e3d2009-10-17 22:29:578016 EXPECT_TRUE(response->auth_challenge.get() == NULL);
8017 EXPECT_EQ(100, response->headers->GetContentLength());
8018}
8019
8020// Test HTTPS connections going through a proxy that sends extra data.
[email protected]23e482282013-06-14 16:08:028021TEST_P(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
[email protected]bb88e1d32013-05-03 23:11:078022 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]0877e3d2009-10-17 22:29:578023
8024 HttpRequestInfo request;
8025 request.method = "GET";
8026 request.url = GURL("https://www.google.com/");
8027 request.load_flags = 0;
8028
8029 MockRead proxy_reads[] = {
8030 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:068031 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:578032 };
8033
[email protected]31a2bfe2010-02-09 08:03:398034 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
[email protected]8ddf8322012-02-23 18:08:068035 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:578036
[email protected]bb88e1d32013-05-03 23:11:078037 session_deps_.socket_factory->AddSocketDataProvider(&data);
8038 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:578039
[email protected]49639fa2011-12-20 23:22:418040 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:578041
[email protected]bb88e1d32013-05-03 23:11:078042 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:578043
[email protected]3fe8d2f82013-10-17 08:56:078044 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578045 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418046 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:578047
[email protected]49639fa2011-12-20 23:22:418048 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578049 EXPECT_EQ(ERR_IO_PENDING, rv);
8050
8051 rv = callback.WaitForResult();
8052 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
8053}
8054
[email protected]23e482282013-06-14 16:08:028055TEST_P(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:468056 HttpRequestInfo request;
8057 request.method = "GET";
8058 request.url = GURL("http://www.google.com/");
8059 request.load_flags = 0;
8060
[email protected]3fe8d2f82013-10-17 08:56:078061 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:278062 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418063 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278064
[email protected]e22e1362009-11-23 21:31:128065 MockRead data_reads[] = {
8066 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068067 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:128068 };
[email protected]9492e4a2010-02-24 00:58:468069
8070 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078071 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:468072
[email protected]49639fa2011-12-20 23:22:418073 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:468074
[email protected]49639fa2011-12-20 23:22:418075 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9492e4a2010-02-24 00:58:468076 EXPECT_EQ(ERR_IO_PENDING, rv);
8077
8078 EXPECT_EQ(OK, callback.WaitForResult());
8079
8080 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508081 ASSERT_TRUE(response != NULL);
[email protected]9492e4a2010-02-24 00:58:468082
[email protected]90499482013-06-01 00:39:508083 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]9492e4a2010-02-24 00:58:468084 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
8085
8086 std::string response_data;
8087 rv = ReadTransaction(trans.get(), &response_data);
[email protected]5543cbb2012-04-20 16:35:238088 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
[email protected]e22e1362009-11-23 21:31:128089}
8090
[email protected]23e482282013-06-14 16:08:028091TEST_P(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:158092 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:528093 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
[email protected]95d88ffe2010-02-04 21:25:338094 const uint64 kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:218095 UploadFileElementReader::ScopedOverridingContentLengthForTests
8096 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:338097
[email protected]b2d26cfd2012-12-11 10:36:068098 ScopedVector<UploadElementReader> element_readers;
8099 element_readers.push_back(
[email protected]cadac622013-06-11 16:46:368100 new UploadFileElementReader(base::MessageLoopProxy::current().get(),
8101 temp_file_path,
8102 0,
8103 kuint64max,
8104 base::Time()));
mmenkecbc2b712014-10-09 20:29:078105 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:278106
8107 HttpRequestInfo request;
8108 request.method = "POST";
8109 request.url = GURL("http://www.google.com/upload");
8110 request.upload_data_stream = &upload_data_stream;
8111 request.load_flags = 0;
8112
[email protected]3fe8d2f82013-10-17 08:56:078113 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]329b68b2012-11-14 17:54:278114 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418115 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]95d88ffe2010-02-04 21:25:338116
8117 MockRead data_reads[] = {
8118 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
8119 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068120 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:338121 };
[email protected]31a2bfe2010-02-09 08:03:398122 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078123 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:338124
[email protected]49639fa2011-12-20 23:22:418125 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:338126
[email protected]49639fa2011-12-20 23:22:418127 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]95d88ffe2010-02-04 21:25:338128 EXPECT_EQ(ERR_IO_PENDING, rv);
8129
8130 rv = callback.WaitForResult();
8131 EXPECT_EQ(OK, rv);
8132
8133 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508134 ASSERT_TRUE(response != NULL);
[email protected]95d88ffe2010-02-04 21:25:338135
[email protected]90499482013-06-01 00:39:508136 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]95d88ffe2010-02-04 21:25:338137 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
8138
8139 std::string response_data;
8140 rv = ReadTransaction(trans.get(), &response_data);
8141 EXPECT_EQ(OK, rv);
8142 EXPECT_EQ("hello world", response_data);
8143
[email protected]dd3aa792013-07-16 19:10:238144 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:338145}
8146
[email protected]23e482282013-06-14 16:08:028147TEST_P(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:158148 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:528149 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:368150 std::string temp_file_content("Unreadable file.");
[email protected]e5c2a22e2014-03-06 20:42:308151 ASSERT_TRUE(base::WriteFile(temp_file, temp_file_content.c_str(),
[email protected]6624b4622010-03-29 19:58:368152 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:118153 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:368154
[email protected]b2d26cfd2012-12-11 10:36:068155 ScopedVector<UploadElementReader> element_readers;
8156 element_readers.push_back(
[email protected]cadac622013-06-11 16:46:368157 new UploadFileElementReader(base::MessageLoopProxy::current().get(),
8158 temp_file,
8159 0,
8160 kuint64max,
8161 base::Time()));
mmenkecbc2b712014-10-09 20:29:078162 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:278163
8164 HttpRequestInfo request;
8165 request.method = "POST";
8166 request.url = GURL("http://www.google.com/upload");
8167 request.upload_data_stream = &upload_data_stream;
8168 request.load_flags = 0;
8169
[email protected]999dd8c2013-11-12 06:45:548170 // If we try to upload an unreadable file, the transaction should fail.
[email protected]3fe8d2f82013-10-17 08:56:078171 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]329b68b2012-11-14 17:54:278172 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418173 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]6624b4622010-03-29 19:58:368174
[email protected]999dd8c2013-11-12 06:45:548175 StaticSocketDataProvider data(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078176 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:368177
[email protected]49639fa2011-12-20 23:22:418178 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:368179
[email protected]49639fa2011-12-20 23:22:418180 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]6624b4622010-03-29 19:58:368181 EXPECT_EQ(ERR_IO_PENDING, rv);
8182
8183 rv = callback.WaitForResult();
[email protected]999dd8c2013-11-12 06:45:548184 EXPECT_EQ(ERR_ACCESS_DENIED, rv);
[email protected]6624b4622010-03-29 19:58:368185
8186 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]999dd8c2013-11-12 06:45:548187 EXPECT_FALSE(response);
[email protected]6624b4622010-03-29 19:58:368188
[email protected]dd3aa792013-07-16 19:10:238189 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:368190}
8191
[email protected]02cad5d2013-10-02 08:14:038192TEST_P(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
8193 class FakeUploadElementReader : public UploadElementReader {
8194 public:
8195 FakeUploadElementReader() {}
dchengb03027d2014-10-21 12:00:208196 ~FakeUploadElementReader() override {}
[email protected]02cad5d2013-10-02 08:14:038197
8198 const CompletionCallback& callback() const { return callback_; }
8199
8200 // UploadElementReader overrides:
dchengb03027d2014-10-21 12:00:208201 int Init(const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:038202 callback_ = callback;
8203 return ERR_IO_PENDING;
8204 }
dchengb03027d2014-10-21 12:00:208205 uint64 GetContentLength() const override { return 0; }
8206 uint64 BytesRemaining() const override { return 0; }
8207 int Read(IOBuffer* buf,
8208 int buf_length,
8209 const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:038210 return ERR_FAILED;
8211 }
8212
8213 private:
8214 CompletionCallback callback_;
8215 };
8216
8217 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
8218 ScopedVector<UploadElementReader> element_readers;
8219 element_readers.push_back(fake_reader);
mmenkecbc2b712014-10-09 20:29:078220 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02cad5d2013-10-02 08:14:038221
8222 HttpRequestInfo request;
8223 request.method = "POST";
8224 request.url = GURL("http://www.google.com/upload");
8225 request.upload_data_stream = &upload_data_stream;
8226 request.load_flags = 0;
8227
[email protected]3fe8d2f82013-10-17 08:56:078228 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02cad5d2013-10-02 08:14:038229 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418230 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02cad5d2013-10-02 08:14:038231
8232 StaticSocketDataProvider data;
8233 session_deps_.socket_factory->AddSocketDataProvider(&data);
8234
8235 TestCompletionCallback callback;
8236 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8237 EXPECT_EQ(ERR_IO_PENDING, rv);
8238 base::MessageLoop::current()->RunUntilIdle();
8239
8240 // Transaction is pending on request body initialization.
8241 ASSERT_FALSE(fake_reader->callback().is_null());
8242
8243 // Return Init()'s result after the transaction gets destroyed.
8244 trans.reset();
8245 fake_reader->callback().Run(OK); // Should not crash.
8246}
8247
[email protected]aeefc9e82010-02-19 16:18:278248// Tests that changes to Auth realms are treated like auth rejections.
[email protected]23e482282013-06-14 16:08:028249TEST_P(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:278250
8251 HttpRequestInfo request;
8252 request.method = "GET";
8253 request.url = GURL("http://www.google.com/");
8254 request.load_flags = 0;
8255
8256 // First transaction will request a resource and receive a Basic challenge
8257 // with realm="first_realm".
8258 MockWrite data_writes1[] = {
8259 MockWrite("GET / HTTP/1.1\r\n"
8260 "Host: www.google.com\r\n"
8261 "Connection: keep-alive\r\n"
8262 "\r\n"),
8263 };
8264 MockRead data_reads1[] = {
8265 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8266 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
8267 "\r\n"),
8268 };
8269
8270 // After calling trans->RestartWithAuth(), provide an Authentication header
8271 // for first_realm. The server will reject and provide a challenge with
8272 // second_realm.
8273 MockWrite data_writes2[] = {
8274 MockWrite("GET / HTTP/1.1\r\n"
8275 "Host: www.google.com\r\n"
8276 "Connection: keep-alive\r\n"
8277 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
8278 "\r\n"),
8279 };
8280 MockRead data_reads2[] = {
8281 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8282 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
8283 "\r\n"),
8284 };
8285
8286 // This again fails, and goes back to first_realm. Make sure that the
8287 // entry is removed from cache.
8288 MockWrite data_writes3[] = {
8289 MockWrite("GET / HTTP/1.1\r\n"
8290 "Host: www.google.com\r\n"
8291 "Connection: keep-alive\r\n"
8292 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
8293 "\r\n"),
8294 };
8295 MockRead data_reads3[] = {
8296 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8297 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
8298 "\r\n"),
8299 };
8300
8301 // Try one last time (with the correct password) and get the resource.
8302 MockWrite data_writes4[] = {
8303 MockWrite("GET / HTTP/1.1\r\n"
8304 "Host: www.google.com\r\n"
8305 "Connection: keep-alive\r\n"
8306 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
8307 "\r\n"),
8308 };
8309 MockRead data_reads4[] = {
8310 MockRead("HTTP/1.1 200 OK\r\n"
8311 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:508312 "Content-Length: 5\r\n"
8313 "\r\n"
8314 "hello"),
[email protected]aeefc9e82010-02-19 16:18:278315 };
8316
8317 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8318 data_writes1, arraysize(data_writes1));
8319 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8320 data_writes2, arraysize(data_writes2));
8321 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
8322 data_writes3, arraysize(data_writes3));
8323 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
8324 data_writes4, arraysize(data_writes4));
[email protected]bb88e1d32013-05-03 23:11:078325 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8326 session_deps_.socket_factory->AddSocketDataProvider(&data2);
8327 session_deps_.socket_factory->AddSocketDataProvider(&data3);
8328 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:278329
[email protected]49639fa2011-12-20 23:22:418330 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:278331
[email protected]3fe8d2f82013-10-17 08:56:078332 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0b0bf032010-09-21 18:08:508333 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418334 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:508335
[email protected]aeefc9e82010-02-19 16:18:278336 // Issue the first request with Authorize headers. There should be a
8337 // password prompt for first_realm waiting to be filled in after the
8338 // transaction completes.
[email protected]49639fa2011-12-20 23:22:418339 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]aeefc9e82010-02-19 16:18:278340 EXPECT_EQ(ERR_IO_PENDING, rv);
8341 rv = callback1.WaitForResult();
8342 EXPECT_EQ(OK, rv);
8343 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508344 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048345 const AuthChallengeInfo* challenge = response->auth_challenge.get();
8346 ASSERT_FALSE(challenge == NULL);
8347 EXPECT_FALSE(challenge->is_proxy);
8348 EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
8349 EXPECT_EQ("first_realm", challenge->realm);
8350 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278351
8352 // Issue the second request with an incorrect password. There should be a
8353 // password prompt for second_realm waiting to be filled in after the
8354 // transaction completes.
[email protected]49639fa2011-12-20 23:22:418355 TestCompletionCallback callback2;
8356 rv = trans->RestartWithAuth(
8357 AuthCredentials(kFirst, kBaz), callback2.callback());
[email protected]aeefc9e82010-02-19 16:18:278358 EXPECT_EQ(ERR_IO_PENDING, rv);
8359 rv = callback2.WaitForResult();
8360 EXPECT_EQ(OK, rv);
8361 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508362 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048363 challenge = response->auth_challenge.get();
8364 ASSERT_FALSE(challenge == NULL);
8365 EXPECT_FALSE(challenge->is_proxy);
8366 EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
8367 EXPECT_EQ("second_realm", challenge->realm);
8368 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278369
8370 // Issue the third request with another incorrect password. There should be
8371 // a password prompt for first_realm waiting to be filled in. If the password
8372 // prompt is not present, it indicates that the HttpAuthCacheEntry for
8373 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:418374 TestCompletionCallback callback3;
8375 rv = trans->RestartWithAuth(
8376 AuthCredentials(kSecond, kFou), callback3.callback());
[email protected]aeefc9e82010-02-19 16:18:278377 EXPECT_EQ(ERR_IO_PENDING, rv);
8378 rv = callback3.WaitForResult();
8379 EXPECT_EQ(OK, rv);
8380 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508381 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048382 challenge = response->auth_challenge.get();
8383 ASSERT_FALSE(challenge == NULL);
8384 EXPECT_FALSE(challenge->is_proxy);
8385 EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
8386 EXPECT_EQ("first_realm", challenge->realm);
8387 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278388
8389 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:418390 TestCompletionCallback callback4;
8391 rv = trans->RestartWithAuth(
8392 AuthCredentials(kFirst, kBar), callback4.callback());
[email protected]aeefc9e82010-02-19 16:18:278393 EXPECT_EQ(ERR_IO_PENDING, rv);
8394 rv = callback4.WaitForResult();
8395 EXPECT_EQ(OK, rv);
8396 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508397 ASSERT_TRUE(response != NULL);
[email protected]aeefc9e82010-02-19 16:18:278398 EXPECT_TRUE(response->auth_challenge.get() == NULL);
8399}
8400
[email protected]23e482282013-06-14 16:08:028401TEST_P(HttpNetworkTransactionTest, HonorAlternateProtocolHeader) {
[email protected]d7599122014-05-24 03:37:238402 session_deps_.next_protos = SpdyNextProtos();
8403 session_deps_.use_alternate_protocols = true;
[email protected]a2cb8122010-03-10 17:22:428404
[email protected]8a0fc822013-06-27 20:52:438405 std::string alternate_protocol_http_header =
8406 GetAlternateProtocolHttpHeader();
8407
[email protected]564b4912010-03-09 16:30:428408 MockRead data_reads[] = {
8409 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438410 MockRead(alternate_protocol_http_header.c_str()),
[email protected]564b4912010-03-09 16:30:428411 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068412 MockRead(SYNCHRONOUS, OK),
[email protected]564b4912010-03-09 16:30:428413 };
8414
8415 HttpRequestInfo request;
8416 request.method = "GET";
8417 request.url = GURL("http://www.google.com/");
8418 request.load_flags = 0;
8419
8420 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
8421
[email protected]bb88e1d32013-05-03 23:11:078422 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]564b4912010-03-09 16:30:428423
[email protected]49639fa2011-12-20 23:22:418424 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:428425
[email protected]bb88e1d32013-05-03 23:11:078426 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:368427 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508428 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]564b4912010-03-09 16:30:428429
[email protected]49639fa2011-12-20 23:22:418430 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:428431 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]9e743cd2010-03-16 07:03:538432
[email protected]2fbaecf22010-07-22 22:20:358433 HostPortPair http_host_port_pair("www.google.com", 80);
[email protected]9801e3702014-03-07 09:33:558434 HttpServerProperties& http_server_properties =
[email protected]17291a022011-10-10 07:32:538435 *session->http_server_properties();
[email protected]564b4912010-03-09 16:30:428436 EXPECT_FALSE(
[email protected]17291a022011-10-10 07:32:538437 http_server_properties.HasAlternateProtocol(http_host_port_pair));
[email protected]564b4912010-03-09 16:30:428438
8439 EXPECT_EQ(OK, callback.WaitForResult());
8440
8441 const HttpResponseInfo* response = trans->GetResponseInfo();
8442 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508443 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:428444 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:538445 EXPECT_FALSE(response->was_fetched_via_spdy);
8446 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]564b4912010-03-09 16:30:428447
8448 std::string response_data;
8449 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8450 EXPECT_EQ("hello world", response_data);
8451
[email protected]17291a022011-10-10 07:32:538452 ASSERT_TRUE(http_server_properties.HasAlternateProtocol(http_host_port_pair));
[email protected]287d9412014-07-08 23:01:008453 const AlternateProtocolInfo alternate =
[email protected]17291a022011-10-10 07:32:538454 http_server_properties.GetAlternateProtocol(http_host_port_pair);
[email protected]287d9412014-07-08 23:01:008455 AlternateProtocolInfo expected_alternate(
8456 443, AlternateProtocolFromNextProto(GetParam()), 1);
[email protected]564b4912010-03-09 16:30:428457 EXPECT_TRUE(expected_alternate.Equals(alternate));
8458}
8459
[email protected]23e482282013-06-14 16:08:028460TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238461 MarkBrokenAlternateProtocolAndFallback) {
[email protected]d7599122014-05-24 03:37:238462 session_deps_.use_alternate_protocols = true;
[email protected]564b4912010-03-09 16:30:428463
8464 HttpRequestInfo request;
8465 request.method = "GET";
8466 request.url = GURL("http://www.google.com/");
8467 request.load_flags = 0;
8468
[email protected]d973e99a2012-02-17 21:02:368469 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:428470 StaticSocketDataProvider first_data;
8471 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078472 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]564b4912010-03-09 16:30:428473
8474 MockRead data_reads[] = {
8475 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8476 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068477 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:428478 };
8479 StaticSocketDataProvider second_data(
8480 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078481 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:428482
[email protected]bb88e1d32013-05-03 23:11:078483 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:428484
[email protected]30d4c022013-07-18 22:58:168485 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538486 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118487 // Port must be < 1024, or the header will be ignored (since initial port was
8488 // port 80 (another restricted port).
[email protected]17291a022011-10-10 07:32:538489 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118490 HostPortPair::FromURL(request.url),
8491 666 /* port is ignored by MockConnect anyway */,
[email protected]287d9412014-07-08 23:01:008492 AlternateProtocolFromNextProto(GetParam()), 1);
[email protected]564b4912010-03-09 16:30:428493
[email protected]262eec82013-03-19 21:01:368494 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508495 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418496 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:428497
[email protected]49639fa2011-12-20 23:22:418498 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:428499 EXPECT_EQ(ERR_IO_PENDING, rv);
8500 EXPECT_EQ(OK, callback.WaitForResult());
8501
8502 const HttpResponseInfo* response = trans->GetResponseInfo();
8503 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508504 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:428505 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8506
8507 std::string response_data;
8508 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8509 EXPECT_EQ("hello world", response_data);
8510
[email protected]17291a022011-10-10 07:32:538511 ASSERT_TRUE(http_server_properties->HasAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118512 HostPortPair::FromURL(request.url)));
[email protected]287d9412014-07-08 23:01:008513 const AlternateProtocolInfo alternate =
[email protected]17291a022011-10-10 07:32:538514 http_server_properties->GetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118515 HostPortPair::FromURL(request.url));
bnccbd55d5f2014-11-06 19:50:408516 EXPECT_TRUE(alternate.is_broken);
[email protected]564b4912010-03-09 16:30:428517}
8518
[email protected]23e482282013-06-14 16:08:028519TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238520 AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:118521 // Ensure that we're not allowed to redirect traffic via an alternate
8522 // protocol to an unrestricted (port >= 1024) when the original traffic was
8523 // on a restricted port (port < 1024). Ensure that we can redirect in all
8524 // other cases.
[email protected]d7599122014-05-24 03:37:238525 session_deps_.use_alternate_protocols = true;
[email protected]3912662a32011-10-04 00:51:118526
8527 HttpRequestInfo restricted_port_request;
8528 restricted_port_request.method = "GET";
8529 restricted_port_request.url = GURL("http://www.google.com:1023/");
8530 restricted_port_request.load_flags = 0;
8531
[email protected]d973e99a2012-02-17 21:02:368532 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118533 StaticSocketDataProvider first_data;
8534 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078535 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118536
8537 MockRead data_reads[] = {
8538 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8539 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068540 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118541 };
8542 StaticSocketDataProvider second_data(
8543 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078544 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118545
[email protected]bb88e1d32013-05-03 23:11:078546 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118547
[email protected]30d4c022013-07-18 22:58:168548 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538549 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118550 const int kUnrestrictedAlternatePort = 1024;
[email protected]17291a022011-10-10 07:32:538551 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118552 HostPortPair::FromURL(restricted_port_request.url),
8553 kUnrestrictedAlternatePort,
[email protected]287d9412014-07-08 23:01:008554 AlternateProtocolFromNextProto(GetParam()), 1);
[email protected]3912662a32011-10-04 00:51:118555
[email protected]262eec82013-03-19 21:01:368556 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508557 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418558 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118559
[email protected]49639fa2011-12-20 23:22:418560 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:368561 &restricted_port_request,
8562 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118563 EXPECT_EQ(ERR_IO_PENDING, rv);
8564 // Invalid change to unrestricted port should fail.
8565 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.WaitForResult());
[email protected]c54c6962013-02-01 04:53:198566}
[email protected]3912662a32011-10-04 00:51:118567
[email protected]23e482282013-06-14 16:08:028568TEST_P(HttpNetworkTransactionTest,
[email protected]c54c6962013-02-01 04:53:198569 AlternateProtocolPortRestrictedPermitted) {
8570 // Ensure that we're allowed to redirect traffic via an alternate
8571 // protocol to an unrestricted (port >= 1024) when the original traffic was
8572 // on a restricted port (port < 1024) if we set
8573 // enable_user_alternate_protocol_ports.
8574
[email protected]d7599122014-05-24 03:37:238575 session_deps_.use_alternate_protocols = true;
[email protected]bb88e1d32013-05-03 23:11:078576 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:198577
8578 HttpRequestInfo restricted_port_request;
8579 restricted_port_request.method = "GET";
8580 restricted_port_request.url = GURL("http://www.google.com:1023/");
8581 restricted_port_request.load_flags = 0;
8582
8583 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
8584 StaticSocketDataProvider first_data;
8585 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078586 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:198587
8588 MockRead data_reads[] = {
8589 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8590 MockRead("hello world"),
8591 MockRead(ASYNC, OK),
8592 };
8593 StaticSocketDataProvider second_data(
8594 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078595 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]c54c6962013-02-01 04:53:198596
[email protected]bb88e1d32013-05-03 23:11:078597 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:198598
[email protected]30d4c022013-07-18 22:58:168599 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]c54c6962013-02-01 04:53:198600 session->http_server_properties();
8601 const int kUnrestrictedAlternatePort = 1024;
8602 http_server_properties->SetAlternateProtocol(
8603 HostPortPair::FromURL(restricted_port_request.url),
8604 kUnrestrictedAlternatePort,
[email protected]287d9412014-07-08 23:01:008605 AlternateProtocolFromNextProto(GetParam()), 1);
[email protected]c54c6962013-02-01 04:53:198606
[email protected]262eec82013-03-19 21:01:368607 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508608 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]c54c6962013-02-01 04:53:198609 TestCompletionCallback callback;
8610
8611 EXPECT_EQ(ERR_IO_PENDING, trans->Start(
[email protected]262eec82013-03-19 21:01:368612 &restricted_port_request,
8613 callback.callback(), BoundNetLog()));
[email protected]c54c6962013-02-01 04:53:198614 // Change to unrestricted port should succeed.
8615 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:118616}
8617
[email protected]23e482282013-06-14 16:08:028618TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238619 AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:118620 // Ensure that we're not allowed to redirect traffic via an alternate
8621 // protocol to an unrestricted (port >= 1024) when the original traffic was
8622 // on a restricted port (port < 1024). Ensure that we can redirect in all
8623 // other cases.
[email protected]d7599122014-05-24 03:37:238624 session_deps_.use_alternate_protocols = true;
[email protected]3912662a32011-10-04 00:51:118625
8626 HttpRequestInfo restricted_port_request;
8627 restricted_port_request.method = "GET";
8628 restricted_port_request.url = GURL("http://www.google.com:1023/");
8629 restricted_port_request.load_flags = 0;
8630
[email protected]d973e99a2012-02-17 21:02:368631 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118632 StaticSocketDataProvider first_data;
8633 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078634 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118635
8636 MockRead data_reads[] = {
8637 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8638 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068639 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118640 };
8641 StaticSocketDataProvider second_data(
8642 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078643 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118644
[email protected]bb88e1d32013-05-03 23:11:078645 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118646
[email protected]30d4c022013-07-18 22:58:168647 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538648 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118649 const int kRestrictedAlternatePort = 80;
[email protected]17291a022011-10-10 07:32:538650 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118651 HostPortPair::FromURL(restricted_port_request.url),
8652 kRestrictedAlternatePort,
[email protected]287d9412014-07-08 23:01:008653 AlternateProtocolFromNextProto(GetParam()), 1);
[email protected]3912662a32011-10-04 00:51:118654
[email protected]262eec82013-03-19 21:01:368655 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508656 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418657 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118658
[email protected]49639fa2011-12-20 23:22:418659 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:368660 &restricted_port_request,
8661 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118662 EXPECT_EQ(ERR_IO_PENDING, rv);
8663 // Valid change to restricted port should pass.
8664 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:118665}
8666
[email protected]23e482282013-06-14 16:08:028667TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238668 AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:118669 // Ensure that we're not allowed to redirect traffic via an alternate
8670 // protocol to an unrestricted (port >= 1024) when the original traffic was
8671 // on a restricted port (port < 1024). Ensure that we can redirect in all
8672 // other cases.
[email protected]d7599122014-05-24 03:37:238673 session_deps_.use_alternate_protocols = true;
[email protected]3912662a32011-10-04 00:51:118674
8675 HttpRequestInfo unrestricted_port_request;
8676 unrestricted_port_request.method = "GET";
8677 unrestricted_port_request.url = GURL("http://www.google.com:1024/");
8678 unrestricted_port_request.load_flags = 0;
8679
[email protected]d973e99a2012-02-17 21:02:368680 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118681 StaticSocketDataProvider first_data;
8682 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078683 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118684
8685 MockRead data_reads[] = {
8686 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8687 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068688 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118689 };
8690 StaticSocketDataProvider second_data(
8691 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078692 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118693
[email protected]bb88e1d32013-05-03 23:11:078694 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118695
[email protected]30d4c022013-07-18 22:58:168696 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538697 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118698 const int kRestrictedAlternatePort = 80;
[email protected]17291a022011-10-10 07:32:538699 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118700 HostPortPair::FromURL(unrestricted_port_request.url),
8701 kRestrictedAlternatePort,
[email protected]287d9412014-07-08 23:01:008702 AlternateProtocolFromNextProto(GetParam()), 1);
[email protected]3912662a32011-10-04 00:51:118703
[email protected]262eec82013-03-19 21:01:368704 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508705 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418706 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118707
[email protected]49639fa2011-12-20 23:22:418708 int rv = trans->Start(
8709 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118710 EXPECT_EQ(ERR_IO_PENDING, rv);
8711 // Valid change to restricted port should pass.
8712 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:118713}
8714
[email protected]23e482282013-06-14 16:08:028715TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238716 AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:118717 // Ensure that we're not allowed to redirect traffic via an alternate
8718 // protocol to an unrestricted (port >= 1024) when the original traffic was
8719 // on a restricted port (port < 1024). Ensure that we can redirect in all
8720 // other cases.
[email protected]d7599122014-05-24 03:37:238721 session_deps_.use_alternate_protocols = true;
[email protected]3912662a32011-10-04 00:51:118722
8723 HttpRequestInfo unrestricted_port_request;
8724 unrestricted_port_request.method = "GET";
8725 unrestricted_port_request.url = GURL("http://www.google.com:1024/");
8726 unrestricted_port_request.load_flags = 0;
8727
[email protected]d973e99a2012-02-17 21:02:368728 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118729 StaticSocketDataProvider first_data;
8730 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078731 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118732
8733 MockRead data_reads[] = {
8734 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8735 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068736 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118737 };
8738 StaticSocketDataProvider second_data(
8739 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078740 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118741
[email protected]bb88e1d32013-05-03 23:11:078742 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118743
[email protected]30d4c022013-07-18 22:58:168744 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538745 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118746 const int kUnrestrictedAlternatePort = 1024;
[email protected]17291a022011-10-10 07:32:538747 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118748 HostPortPair::FromURL(unrestricted_port_request.url),
8749 kUnrestrictedAlternatePort,
[email protected]287d9412014-07-08 23:01:008750 AlternateProtocolFromNextProto(GetParam()), 1);
[email protected]3912662a32011-10-04 00:51:118751
[email protected]262eec82013-03-19 21:01:368752 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508753 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418754 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118755
[email protected]49639fa2011-12-20 23:22:418756 int rv = trans->Start(
8757 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118758 EXPECT_EQ(ERR_IO_PENDING, rv);
8759 // Valid change to an unrestricted port should pass.
8760 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:118761}
8762
[email protected]d7599122014-05-24 03:37:238763TEST_P(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:028764 // Ensure that we're not allowed to redirect traffic via an alternate
8765 // protocol to an unsafe port, and that we resume the second
8766 // HttpStreamFactoryImpl::Job once the alternate protocol request fails.
[email protected]d7599122014-05-24 03:37:238767 session_deps_.use_alternate_protocols = true;
[email protected]eb6234e2012-01-19 01:50:028768
8769 HttpRequestInfo request;
8770 request.method = "GET";
8771 request.url = GURL("http://www.google.com/");
8772 request.load_flags = 0;
8773
8774 // The alternate protocol request will error out before we attempt to connect,
8775 // so only the standard HTTP request will try to connect.
8776 MockRead data_reads[] = {
8777 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8778 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068779 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:028780 };
8781 StaticSocketDataProvider data(
8782 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078783 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:028784
[email protected]bb88e1d32013-05-03 23:11:078785 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:028786
[email protected]30d4c022013-07-18 22:58:168787 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]eb6234e2012-01-19 01:50:028788 session->http_server_properties();
8789 const int kUnsafePort = 7;
8790 http_server_properties->SetAlternateProtocol(
8791 HostPortPair::FromURL(request.url),
8792 kUnsafePort,
[email protected]287d9412014-07-08 23:01:008793 AlternateProtocolFromNextProto(GetParam()), 1);
[email protected]eb6234e2012-01-19 01:50:028794
[email protected]262eec82013-03-19 21:01:368795 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508796 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]eb6234e2012-01-19 01:50:028797 TestCompletionCallback callback;
8798
8799 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8800 EXPECT_EQ(ERR_IO_PENDING, rv);
8801 // The HTTP request should succeed.
8802 EXPECT_EQ(OK, callback.WaitForResult());
8803
8804 // Disable alternate protocol before the asserts.
[email protected]d7599122014-05-24 03:37:238805 // HttpStreamFactory::set_use_alternate_protocols(false);
[email protected]eb6234e2012-01-19 01:50:028806
8807 const HttpResponseInfo* response = trans->GetResponseInfo();
8808 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508809 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]eb6234e2012-01-19 01:50:028810 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8811
8812 std::string response_data;
8813 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8814 EXPECT_EQ("hello world", response_data);
8815}
8816
[email protected]23e482282013-06-14 16:08:028817TEST_P(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]d7599122014-05-24 03:37:238818 session_deps_.use_alternate_protocols = true;
8819 session_deps_.next_protos = SpdyNextProtos();
[email protected]2ff8b312010-04-26 22:20:548820
8821 HttpRequestInfo request;
8822 request.method = "GET";
8823 request.url = GURL("http://www.google.com/");
8824 request.load_flags = 0;
8825
[email protected]8a0fc822013-06-27 20:52:438826 std::string alternate_protocol_http_header =
8827 GetAlternateProtocolHttpHeader();
8828
[email protected]2ff8b312010-04-26 22:20:548829 MockRead data_reads[] = {
8830 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438831 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2ff8b312010-04-26 22:20:548832 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:178833 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
8834 MockRead(ASYNC, OK)
[email protected]2ff8b312010-04-26 22:20:548835 };
8836
8837 StaticSocketDataProvider first_transaction(
8838 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078839 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:548840
[email protected]8ddf8322012-02-23 18:08:068841 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:028842 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:078843 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:548844
[email protected]cdf8f7e72013-05-23 10:56:468845 scoped_ptr<SpdyFrame> req(
8846 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]e7f75092010-07-01 22:39:138847 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
[email protected]2ff8b312010-04-26 22:20:548848
[email protected]23e482282013-06-14 16:08:028849 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
8850 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:548851 MockRead spdy_reads[] = {
[email protected]e7f75092010-07-01 22:39:138852 CreateMockRead(*resp),
8853 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:068854 MockRead(ASYNC, 0, 0),
[email protected]2ff8b312010-04-26 22:20:548855 };
8856
[email protected]dd54bd82012-07-19 23:44:578857 DelayedSocketData spdy_data(
8858 1, // wait for one write to finish before reading.
8859 spdy_reads, arraysize(spdy_reads),
8860 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078861 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:548862
[email protected]d973e99a2012-02-17 21:02:368863 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:558864 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
8865 NULL, 0, NULL, 0);
8866 hanging_non_alternate_protocol_socket.set_connect_data(
8867 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:078868 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:558869 &hanging_non_alternate_protocol_socket);
8870
[email protected]49639fa2011-12-20 23:22:418871 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:548872
[email protected]bb88e1d32013-05-03 23:11:078873 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:368874 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508875 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:548876
[email protected]49639fa2011-12-20 23:22:418877 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:548878 EXPECT_EQ(ERR_IO_PENDING, rv);
8879 EXPECT_EQ(OK, callback.WaitForResult());
8880
8881 const HttpResponseInfo* response = trans->GetResponseInfo();
8882 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508883 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:548884 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8885
8886 std::string response_data;
8887 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8888 EXPECT_EQ("hello world", response_data);
8889
[email protected]90499482013-06-01 00:39:508890 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:548891
[email protected]49639fa2011-12-20 23:22:418892 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:548893 EXPECT_EQ(ERR_IO_PENDING, rv);
8894 EXPECT_EQ(OK, callback.WaitForResult());
8895
8896 response = trans->GetResponseInfo();
8897 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508898 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:548899 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:538900 EXPECT_TRUE(response->was_fetched_via_spdy);
8901 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:548902
8903 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8904 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:548905}
8906
[email protected]23e482282013-06-14 16:08:028907TEST_P(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]d7599122014-05-24 03:37:238908 session_deps_.use_alternate_protocols = true;
8909 session_deps_.next_protos = SpdyNextProtos();
[email protected]2d6728692011-03-12 01:39:558910
8911 HttpRequestInfo request;
8912 request.method = "GET";
8913 request.url = GURL("http://www.google.com/");
8914 request.load_flags = 0;
8915
[email protected]8a0fc822013-06-27 20:52:438916 std::string alternate_protocol_http_header =
8917 GetAlternateProtocolHttpHeader();
8918
[email protected]2d6728692011-03-12 01:39:558919 MockRead data_reads[] = {
8920 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438921 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2d6728692011-03-12 01:39:558922 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:178923 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:068924 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:558925 };
8926
8927 StaticSocketDataProvider first_transaction(
8928 data_reads, arraysize(data_reads), NULL, 0);
8929 // Socket 1 is the HTTP transaction with the Alternate-Protocol header.
[email protected]bb88e1d32013-05-03 23:11:078930 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:558931
[email protected]d973e99a2012-02-17 21:02:368932 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:558933 StaticSocketDataProvider hanging_socket(
8934 NULL, 0, NULL, 0);
8935 hanging_socket.set_connect_data(never_finishing_connect);
8936 // Socket 2 and 3 are the hanging Alternate-Protocol and
8937 // non-Alternate-Protocol jobs from the 2nd transaction.
[email protected]bb88e1d32013-05-03 23:11:078938 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
8939 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
[email protected]2d6728692011-03-12 01:39:558940
[email protected]8ddf8322012-02-23 18:08:068941 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:028942 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:078943 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:558944
[email protected]cdf8f7e72013-05-23 10:56:468945 scoped_ptr<SpdyFrame> req1(
8946 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
8947 scoped_ptr<SpdyFrame> req2(
8948 spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
[email protected]2d6728692011-03-12 01:39:558949 MockWrite spdy_writes[] = {
8950 CreateMockWrite(*req1),
8951 CreateMockWrite(*req2),
8952 };
[email protected]23e482282013-06-14 16:08:028953 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
8954 scoped_ptr<SpdyFrame> data1(spdy_util_.ConstructSpdyBodyFrame(1, true));
8955 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
8956 scoped_ptr<SpdyFrame> data2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]2d6728692011-03-12 01:39:558957 MockRead spdy_reads[] = {
8958 CreateMockRead(*resp1),
8959 CreateMockRead(*data1),
8960 CreateMockRead(*resp2),
8961 CreateMockRead(*data2),
[email protected]8ddf8322012-02-23 18:08:068962 MockRead(ASYNC, 0, 0),
[email protected]2d6728692011-03-12 01:39:558963 };
8964
[email protected]dd54bd82012-07-19 23:44:578965 DelayedSocketData spdy_data(
8966 2, // wait for writes to finish before reading.
8967 spdy_reads, arraysize(spdy_reads),
8968 spdy_writes, arraysize(spdy_writes));
[email protected]2d6728692011-03-12 01:39:558969 // Socket 4 is the successful Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:078970 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:558971
8972 // Socket 5 is the unsuccessful non-Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:078973 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
[email protected]2d6728692011-03-12 01:39:558974
[email protected]bb88e1d32013-05-03 23:11:078975 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:418976 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:508977 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:558978
[email protected]49639fa2011-12-20 23:22:418979 int rv = trans1.Start(&request, callback1.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:558980 EXPECT_EQ(ERR_IO_PENDING, rv);
8981 EXPECT_EQ(OK, callback1.WaitForResult());
8982
8983 const HttpResponseInfo* response = trans1.GetResponseInfo();
8984 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508985 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:558986 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8987
8988 std::string response_data;
8989 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
8990 EXPECT_EQ("hello world", response_data);
8991
[email protected]49639fa2011-12-20 23:22:418992 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:508993 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:418994 rv = trans2.Start(&request, callback2.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:558995 EXPECT_EQ(ERR_IO_PENDING, rv);
8996
[email protected]49639fa2011-12-20 23:22:418997 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:508998 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:418999 rv = trans3.Start(&request, callback3.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559000 EXPECT_EQ(ERR_IO_PENDING, rv);
9001
9002 EXPECT_EQ(OK, callback2.WaitForResult());
9003 EXPECT_EQ(OK, callback3.WaitForResult());
9004
9005 response = trans2.GetResponseInfo();
9006 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509007 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559008 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9009 EXPECT_TRUE(response->was_fetched_via_spdy);
9010 EXPECT_TRUE(response->was_npn_negotiated);
9011 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
9012 EXPECT_EQ("hello!", response_data);
9013
9014 response = trans3.GetResponseInfo();
9015 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509016 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559017 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9018 EXPECT_TRUE(response->was_fetched_via_spdy);
9019 EXPECT_TRUE(response->was_npn_negotiated);
9020 ASSERT_EQ(OK, ReadTransaction(&trans3, &response_data));
9021 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:559022}
9023
[email protected]23e482282013-06-14 16:08:029024TEST_P(HttpNetworkTransactionTest, StallAlternateProtocolForNpnSpdy) {
[email protected]d7599122014-05-24 03:37:239025 session_deps_.use_alternate_protocols = true;
9026 session_deps_.next_protos = SpdyNextProtos();
[email protected]2d6728692011-03-12 01:39:559027
9028 HttpRequestInfo request;
9029 request.method = "GET";
9030 request.url = GURL("http://www.google.com/");
9031 request.load_flags = 0;
9032
[email protected]8a0fc822013-06-27 20:52:439033 std::string alternate_protocol_http_header =
9034 GetAlternateProtocolHttpHeader();
9035
[email protected]2d6728692011-03-12 01:39:559036 MockRead data_reads[] = {
9037 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439038 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2d6728692011-03-12 01:39:559039 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:179040 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:069041 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:559042 };
9043
9044 StaticSocketDataProvider first_transaction(
9045 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079046 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:559047
[email protected]8ddf8322012-02-23 18:08:069048 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029049 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:079050 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:559051
[email protected]d973e99a2012-02-17 21:02:369052 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559053 StaticSocketDataProvider hanging_alternate_protocol_socket(
9054 NULL, 0, NULL, 0);
9055 hanging_alternate_protocol_socket.set_connect_data(
9056 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:079057 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:559058 &hanging_alternate_protocol_socket);
9059
9060 // 2nd request is just a copy of the first one, over HTTP again.
[email protected]bb88e1d32013-05-03 23:11:079061 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:559062
[email protected]49639fa2011-12-20 23:22:419063 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:559064
[email protected]bb88e1d32013-05-03 23:11:079065 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369066 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509067 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:559068
[email protected]49639fa2011-12-20 23:22:419069 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559070 EXPECT_EQ(ERR_IO_PENDING, rv);
9071 EXPECT_EQ(OK, callback.WaitForResult());
9072
9073 const HttpResponseInfo* response = trans->GetResponseInfo();
9074 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509075 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559076 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9077
9078 std::string response_data;
9079 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9080 EXPECT_EQ("hello world", response_data);
9081
[email protected]90499482013-06-01 00:39:509082 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:559083
[email protected]49639fa2011-12-20 23:22:419084 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559085 EXPECT_EQ(ERR_IO_PENDING, rv);
9086 EXPECT_EQ(OK, callback.WaitForResult());
9087
9088 response = trans->GetResponseInfo();
9089 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509090 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559091 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9092 EXPECT_FALSE(response->was_fetched_via_spdy);
9093 EXPECT_FALSE(response->was_npn_negotiated);
9094
9095 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9096 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:559097}
9098
[email protected]631f1322010-04-30 17:59:119099class CapturingProxyResolver : public ProxyResolver {
9100 public:
9101 CapturingProxyResolver() : ProxyResolver(false /* expects_pac_bytes */) {}
dchengb03027d2014-10-21 12:00:209102 ~CapturingProxyResolver() override {}
[email protected]631f1322010-04-30 17:59:119103
dchengb03027d2014-10-21 12:00:209104 int GetProxyForURL(const GURL& url,
9105 ProxyInfo* results,
9106 const CompletionCallback& callback,
9107 RequestHandle* request,
9108 const BoundNetLog& net_log) override {
[email protected]fae7669f2010-08-02 21:49:409109 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
9110 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:429111 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:119112 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:429113 return OK;
[email protected]631f1322010-04-30 17:59:119114 }
9115
dchengb03027d2014-10-21 12:00:209116 void CancelRequest(RequestHandle request) override { NOTREACHED(); }
[email protected]631f1322010-04-30 17:59:119117
dchengb03027d2014-10-21 12:00:209118 LoadState GetLoadState(RequestHandle request) const override {
[email protected]f2c971f2011-11-08 00:33:179119 NOTREACHED();
9120 return LOAD_STATE_IDLE;
9121 }
9122
dchengb03027d2014-10-21 12:00:209123 void CancelSetPacScript() override { NOTREACHED(); }
[email protected]1e605472010-12-16 21:41:409124
dchengb03027d2014-10-21 12:00:209125 int SetPacScript(const scoped_refptr<ProxyResolverScriptData>&,
9126 const CompletionCallback& /*callback*/) override {
[email protected]d911f1b2010-05-05 22:39:429127 return OK;
[email protected]631f1322010-04-30 17:59:119128 }
9129
[email protected]24476402010-07-20 20:55:179130 const std::vector<GURL>& resolved() const { return resolved_; }
9131
9132 private:
[email protected]631f1322010-04-30 17:59:119133 std::vector<GURL> resolved_;
9134
9135 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
9136};
9137
[email protected]23e482282013-06-14 16:08:029138TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239139 UseAlternateProtocolForTunneledNpnSpdy) {
[email protected]d7599122014-05-24 03:37:239140 session_deps_.use_alternate_protocols = true;
9141 session_deps_.next_protos = SpdyNextProtos();
[email protected]631f1322010-04-30 17:59:119142
9143 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:429144 proxy_config.set_auto_detect(true);
9145 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:119146
[email protected]631f1322010-04-30 17:59:119147 CapturingProxyResolver* capturing_proxy_resolver =
9148 new CapturingProxyResolver();
[email protected]bb88e1d32013-05-03 23:11:079149 session_deps_.proxy_service.reset(new ProxyService(
[email protected]66761b952010-06-25 21:30:389150 new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver,
9151 NULL));
[email protected]029c83b62013-01-24 05:28:209152 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079153 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:119154
9155 HttpRequestInfo request;
9156 request.method = "GET";
9157 request.url = GURL("http://www.google.com/");
9158 request.load_flags = 0;
9159
[email protected]8a0fc822013-06-27 20:52:439160 std::string alternate_protocol_http_header =
9161 GetAlternateProtocolHttpHeader();
9162
[email protected]631f1322010-04-30 17:59:119163 MockRead data_reads[] = {
9164 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439165 MockRead(alternate_protocol_http_header.c_str()),
[email protected]631f1322010-04-30 17:59:119166 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:179167 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:069168 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:119169 };
9170
9171 StaticSocketDataProvider first_transaction(
9172 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079173 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]631f1322010-04-30 17:59:119174
[email protected]8ddf8322012-02-23 18:08:069175 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029176 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:079177 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]631f1322010-04-30 17:59:119178
[email protected]cdf8f7e72013-05-23 10:56:469179 scoped_ptr<SpdyFrame> req(
9180 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]631f1322010-04-30 17:59:119181 MockWrite spdy_writes[] = {
9182 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
9183 "Host: www.google.com\r\n"
[email protected]d911f1b2010-05-05 22:39:429184 "Proxy-Connection: keep-alive\r\n\r\n"), // 0
[email protected]cdf8f7e72013-05-23 10:56:469185 CreateMockWrite(*req), // 3
[email protected]631f1322010-04-30 17:59:119186 };
9187
[email protected]d911f1b2010-05-05 22:39:429188 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
9189
[email protected]23e482282013-06-14 16:08:029190 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9191 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]631f1322010-04-30 17:59:119192 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:069193 MockRead(ASYNC, kCONNECTResponse, arraysize(kCONNECTResponse) - 1, 1), // 1
[email protected]e7f75092010-07-01 22:39:139194 CreateMockRead(*resp.get(), 4), // 2, 4
9195 CreateMockRead(*data.get(), 4), // 5
[email protected]8ddf8322012-02-23 18:08:069196 MockRead(ASYNC, 0, 0, 4), // 6
[email protected]631f1322010-04-30 17:59:119197 };
9198
[email protected]dd54bd82012-07-19 23:44:579199 OrderedSocketData spdy_data(
9200 spdy_reads, arraysize(spdy_reads),
9201 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079202 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:119203
[email protected]d973e99a2012-02-17 21:02:369204 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559205 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
9206 NULL, 0, NULL, 0);
9207 hanging_non_alternate_protocol_socket.set_connect_data(
9208 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:079209 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:559210 &hanging_non_alternate_protocol_socket);
9211
[email protected]49639fa2011-12-20 23:22:419212 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:119213
[email protected]bb88e1d32013-05-03 23:11:079214 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369215 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509216 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:119217
[email protected]49639fa2011-12-20 23:22:419218 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:119219 EXPECT_EQ(ERR_IO_PENDING, rv);
9220 EXPECT_EQ(OK, callback.WaitForResult());
9221
9222 const HttpResponseInfo* response = trans->GetResponseInfo();
9223 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509224 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]631f1322010-04-30 17:59:119225 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539226 EXPECT_FALSE(response->was_fetched_via_spdy);
9227 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:119228
9229 std::string response_data;
9230 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9231 EXPECT_EQ("hello world", response_data);
9232
[email protected]90499482013-06-01 00:39:509233 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:119234
[email protected]49639fa2011-12-20 23:22:419235 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:119236 EXPECT_EQ(ERR_IO_PENDING, rv);
9237 EXPECT_EQ(OK, callback.WaitForResult());
9238
9239 response = trans->GetResponseInfo();
9240 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509241 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]631f1322010-04-30 17:59:119242 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539243 EXPECT_TRUE(response->was_fetched_via_spdy);
9244 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:119245
9246 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9247 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:559248 ASSERT_EQ(3u, capturing_proxy_resolver->resolved().size());
[email protected]d911f1b2010-05-05 22:39:429249 EXPECT_EQ("http://www.google.com/",
[email protected]631f1322010-04-30 17:59:119250 capturing_proxy_resolver->resolved()[0].spec());
[email protected]d911f1b2010-05-05 22:39:429251 EXPECT_EQ("https://www.google.com/",
9252 capturing_proxy_resolver->resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:119253
[email protected]029c83b62013-01-24 05:28:209254 LoadTimingInfo load_timing_info;
9255 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
9256 TestLoadTimingNotReusedWithPac(load_timing_info,
9257 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:119258}
[email protected]631f1322010-04-30 17:59:119259
[email protected]23e482282013-06-14 16:08:029260TEST_P(HttpNetworkTransactionTest,
[email protected]2ff8b312010-04-26 22:20:549261 UseAlternateProtocolForNpnSpdyWithExistingSpdySession) {
[email protected]d7599122014-05-24 03:37:239262 session_deps_.use_alternate_protocols = true;
9263 session_deps_.next_protos = SpdyNextProtos();
[email protected]2ff8b312010-04-26 22:20:549264
9265 HttpRequestInfo request;
9266 request.method = "GET";
9267 request.url = GURL("http://www.google.com/");
9268 request.load_flags = 0;
9269
[email protected]8a0fc822013-06-27 20:52:439270 std::string alternate_protocol_http_header =
9271 GetAlternateProtocolHttpHeader();
9272
[email protected]2ff8b312010-04-26 22:20:549273 MockRead data_reads[] = {
9274 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439275 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2ff8b312010-04-26 22:20:549276 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069277 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:549278 };
9279
9280 StaticSocketDataProvider first_transaction(
9281 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079282 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:549283
[email protected]8ddf8322012-02-23 18:08:069284 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029285 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:079286 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:549287
[email protected]cdf8f7e72013-05-23 10:56:469288 scoped_ptr<SpdyFrame> req(
9289 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]e7f75092010-07-01 22:39:139290 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
[email protected]2ff8b312010-04-26 22:20:549291
[email protected]23e482282013-06-14 16:08:029292 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9293 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:549294 MockRead spdy_reads[] = {
[email protected]e7f75092010-07-01 22:39:139295 CreateMockRead(*resp),
9296 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:069297 MockRead(ASYNC, 0, 0),
[email protected]2ff8b312010-04-26 22:20:549298 };
9299
[email protected]dd54bd82012-07-19 23:44:579300 DelayedSocketData spdy_data(
9301 1, // wait for one write to finish before reading.
9302 spdy_reads, arraysize(spdy_reads),
9303 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079304 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:549305
[email protected]83039bb2011-12-09 18:43:559306 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:549307
[email protected]bb88e1d32013-05-03 23:11:079308 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:549309
[email protected]262eec82013-03-19 21:01:369310 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509311 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:549312
[email protected]49639fa2011-12-20 23:22:419313 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:549314 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:419315 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:549316
9317 const HttpResponseInfo* response = trans->GetResponseInfo();
9318 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509319 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:549320 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9321
9322 std::string response_data;
9323 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9324 EXPECT_EQ("hello world", response_data);
9325
9326 // Set up an initial SpdySession in the pool to reuse.
[email protected]02b0c342010-09-25 21:09:389327 HostPortPair host_port_pair("www.google.com", 443);
[email protected]e6d017652013-05-17 18:01:409328 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:539329 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:279330 base::WeakPtr<SpdySession> spdy_session =
[email protected]41d64e82013-07-03 22:44:269331 CreateSecureSpdySession(session, key, BoundNetLog());
[email protected]02b0c342010-09-25 21:09:389332
[email protected]90499482013-06-01 00:39:509333 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:549334
[email protected]49639fa2011-12-20 23:22:419335 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:549336 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:419337 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:549338
9339 response = trans->GetResponseInfo();
9340 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509341 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:549342 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539343 EXPECT_TRUE(response->was_fetched_via_spdy);
9344 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:549345
9346 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9347 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:429348}
9349
[email protected]044de0642010-06-17 10:42:159350// GenerateAuthToken is a mighty big test.
9351// It tests all permutation of GenerateAuthToken behavior:
9352// - Synchronous and Asynchronous completion.
9353// - OK or error on completion.
9354// - Direct connection, non-authenticating proxy, and authenticating proxy.
9355// - HTTP or HTTPS backend (to include proxy tunneling).
9356// - Non-authenticating and authenticating backend.
9357//
[email protected]fe3b7dc2012-02-03 19:52:099358// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:159359// problems generating an auth token for an authenticating proxy, we don't
9360// need to test all permutations of the backend server).
9361//
9362// The test proceeds by going over each of the configuration cases, and
9363// potentially running up to three rounds in each of the tests. The TestConfig
9364// specifies both the configuration for the test as well as the expectations
9365// for the results.
[email protected]23e482282013-06-14 16:08:029366TEST_P(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:509367 static const char kServer[] = "http://www.example.com";
9368 static const char kSecureServer[] = "https://www.example.com";
9369 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:159370 const int kAuthErr = ERR_INVALID_AUTH_CREDENTIALS;
9371
9372 enum AuthTiming {
9373 AUTH_NONE,
9374 AUTH_SYNC,
9375 AUTH_ASYNC,
9376 };
9377
9378 const MockWrite kGet(
9379 "GET / HTTP/1.1\r\n"
9380 "Host: www.example.com\r\n"
9381 "Connection: keep-alive\r\n\r\n");
9382 const MockWrite kGetProxy(
9383 "GET http://www.example.com/ HTTP/1.1\r\n"
9384 "Host: www.example.com\r\n"
9385 "Proxy-Connection: keep-alive\r\n\r\n");
9386 const MockWrite kGetAuth(
9387 "GET / HTTP/1.1\r\n"
9388 "Host: www.example.com\r\n"
9389 "Connection: keep-alive\r\n"
9390 "Authorization: auth_token\r\n\r\n");
9391 const MockWrite kGetProxyAuth(
9392 "GET http://www.example.com/ HTTP/1.1\r\n"
9393 "Host: www.example.com\r\n"
9394 "Proxy-Connection: keep-alive\r\n"
9395 "Proxy-Authorization: auth_token\r\n\r\n");
9396 const MockWrite kGetAuthThroughProxy(
9397 "GET http://www.example.com/ HTTP/1.1\r\n"
9398 "Host: www.example.com\r\n"
9399 "Proxy-Connection: keep-alive\r\n"
9400 "Authorization: auth_token\r\n\r\n");
9401 const MockWrite kGetAuthWithProxyAuth(
9402 "GET http://www.example.com/ HTTP/1.1\r\n"
9403 "Host: www.example.com\r\n"
9404 "Proxy-Connection: keep-alive\r\n"
9405 "Proxy-Authorization: auth_token\r\n"
9406 "Authorization: auth_token\r\n\r\n");
9407 const MockWrite kConnect(
9408 "CONNECT www.example.com:443 HTTP/1.1\r\n"
9409 "Host: www.example.com\r\n"
9410 "Proxy-Connection: keep-alive\r\n\r\n");
9411 const MockWrite kConnectProxyAuth(
9412 "CONNECT www.example.com:443 HTTP/1.1\r\n"
9413 "Host: www.example.com\r\n"
9414 "Proxy-Connection: keep-alive\r\n"
9415 "Proxy-Authorization: auth_token\r\n\r\n");
9416
9417 const MockRead kSuccess(
9418 "HTTP/1.1 200 OK\r\n"
9419 "Content-Type: text/html; charset=iso-8859-1\r\n"
9420 "Content-Length: 3\r\n\r\n"
9421 "Yes");
9422 const MockRead kFailure(
9423 "Should not be called.");
9424 const MockRead kServerChallenge(
9425 "HTTP/1.1 401 Unauthorized\r\n"
9426 "WWW-Authenticate: Mock realm=server\r\n"
9427 "Content-Type: text/html; charset=iso-8859-1\r\n"
9428 "Content-Length: 14\r\n\r\n"
9429 "Unauthorized\r\n");
9430 const MockRead kProxyChallenge(
9431 "HTTP/1.1 407 Unauthorized\r\n"
9432 "Proxy-Authenticate: Mock realm=proxy\r\n"
9433 "Proxy-Connection: close\r\n"
9434 "Content-Type: text/html; charset=iso-8859-1\r\n"
9435 "Content-Length: 14\r\n\r\n"
9436 "Unauthorized\r\n");
9437 const MockRead kProxyConnected(
9438 "HTTP/1.1 200 Connection Established\r\n\r\n");
9439
9440 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
9441 // no constructors, but the C++ compiler on Windows warns about
9442 // unspecified data in compound literals. So, moved to using constructors,
9443 // and TestRound's created with the default constructor should not be used.
9444 struct TestRound {
9445 TestRound()
9446 : expected_rv(ERR_UNEXPECTED),
9447 extra_write(NULL),
9448 extra_read(NULL) {
9449 }
9450 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
9451 int expected_rv_arg)
9452 : write(write_arg),
9453 read(read_arg),
9454 expected_rv(expected_rv_arg),
9455 extra_write(NULL),
9456 extra_read(NULL) {
9457 }
9458 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
9459 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:019460 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:159461 : write(write_arg),
9462 read(read_arg),
9463 expected_rv(expected_rv_arg),
9464 extra_write(extra_write_arg),
9465 extra_read(extra_read_arg) {
9466 }
9467 MockWrite write;
9468 MockRead read;
9469 int expected_rv;
9470 const MockWrite* extra_write;
9471 const MockRead* extra_read;
9472 };
9473
9474 static const int kNoSSL = 500;
9475
9476 struct TestConfig {
9477 const char* proxy_url;
9478 AuthTiming proxy_auth_timing;
9479 int proxy_auth_rv;
9480 const char* server_url;
9481 AuthTiming server_auth_timing;
9482 int server_auth_rv;
9483 int num_auth_rounds;
9484 int first_ssl_round;
9485 TestRound rounds[3];
9486 } test_configs[] = {
9487 // Non-authenticating HTTP server with a direct connection.
9488 { NULL, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
9489 { TestRound(kGet, kSuccess, OK)}},
9490 // Authenticating HTTP server with a direct connection.
9491 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
9492 { TestRound(kGet, kServerChallenge, OK),
9493 TestRound(kGetAuth, kSuccess, OK)}},
9494 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
9495 { TestRound(kGet, kServerChallenge, OK),
9496 TestRound(kGetAuth, kFailure, kAuthErr)}},
9497 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
9498 { TestRound(kGet, kServerChallenge, OK),
9499 TestRound(kGetAuth, kSuccess, OK)}},
9500 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
9501 { TestRound(kGet, kServerChallenge, OK),
9502 TestRound(kGetAuth, kFailure, kAuthErr)}},
9503 // Non-authenticating HTTP server through a non-authenticating proxy.
9504 { kProxy, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
9505 { TestRound(kGetProxy, kSuccess, OK)}},
9506 // Authenticating HTTP server through a non-authenticating proxy.
9507 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
9508 { TestRound(kGetProxy, kServerChallenge, OK),
9509 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
9510 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
9511 { TestRound(kGetProxy, kServerChallenge, OK),
9512 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
9513 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
9514 { TestRound(kGetProxy, kServerChallenge, OK),
9515 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
9516 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
9517 { TestRound(kGetProxy, kServerChallenge, OK),
9518 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
9519 // Non-authenticating HTTP server through an authenticating proxy.
9520 { kProxy, AUTH_SYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
9521 { TestRound(kGetProxy, kProxyChallenge, OK),
9522 TestRound(kGetProxyAuth, kSuccess, OK)}},
9523 { kProxy, AUTH_SYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
9524 { TestRound(kGetProxy, kProxyChallenge, OK),
9525 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
9526 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
9527 { TestRound(kGetProxy, kProxyChallenge, OK),
9528 TestRound(kGetProxyAuth, kSuccess, OK)}},
9529 { kProxy, AUTH_ASYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
9530 { TestRound(kGetProxy, kProxyChallenge, OK),
9531 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
9532 // Authenticating HTTP server through an authenticating proxy.
9533 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
9534 { TestRound(kGetProxy, kProxyChallenge, OK),
9535 TestRound(kGetProxyAuth, kServerChallenge, OK),
9536 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9537 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
9538 { TestRound(kGetProxy, kProxyChallenge, OK),
9539 TestRound(kGetProxyAuth, kServerChallenge, OK),
9540 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9541 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
9542 { TestRound(kGetProxy, kProxyChallenge, OK),
9543 TestRound(kGetProxyAuth, kServerChallenge, OK),
9544 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9545 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
9546 { TestRound(kGetProxy, kProxyChallenge, OK),
9547 TestRound(kGetProxyAuth, kServerChallenge, OK),
9548 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9549 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
9550 { TestRound(kGetProxy, kProxyChallenge, OK),
9551 TestRound(kGetProxyAuth, kServerChallenge, OK),
9552 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9553 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
9554 { TestRound(kGetProxy, kProxyChallenge, OK),
9555 TestRound(kGetProxyAuth, kServerChallenge, OK),
9556 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9557 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
9558 { TestRound(kGetProxy, kProxyChallenge, OK),
9559 TestRound(kGetProxyAuth, kServerChallenge, OK),
9560 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9561 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
9562 { TestRound(kGetProxy, kProxyChallenge, OK),
9563 TestRound(kGetProxyAuth, kServerChallenge, OK),
9564 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9565 // Non-authenticating HTTPS server with a direct connection.
9566 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
9567 { TestRound(kGet, kSuccess, OK)}},
9568 // Authenticating HTTPS server with a direct connection.
9569 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
9570 { TestRound(kGet, kServerChallenge, OK),
9571 TestRound(kGetAuth, kSuccess, OK)}},
9572 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
9573 { TestRound(kGet, kServerChallenge, OK),
9574 TestRound(kGetAuth, kFailure, kAuthErr)}},
9575 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
9576 { TestRound(kGet, kServerChallenge, OK),
9577 TestRound(kGetAuth, kSuccess, OK)}},
9578 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
9579 { TestRound(kGet, kServerChallenge, OK),
9580 TestRound(kGetAuth, kFailure, kAuthErr)}},
9581 // Non-authenticating HTTPS server with a non-authenticating proxy.
9582 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
9583 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
9584 // Authenticating HTTPS server through a non-authenticating proxy.
9585 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
9586 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9587 TestRound(kGetAuth, kSuccess, OK)}},
9588 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
9589 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9590 TestRound(kGetAuth, kFailure, kAuthErr)}},
9591 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
9592 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9593 TestRound(kGetAuth, kSuccess, OK)}},
9594 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
9595 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9596 TestRound(kGetAuth, kFailure, kAuthErr)}},
9597 // Non-Authenticating HTTPS server through an authenticating proxy.
9598 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
9599 { TestRound(kConnect, kProxyChallenge, OK),
9600 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
9601 { kProxy, AUTH_SYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
9602 { TestRound(kConnect, kProxyChallenge, OK),
9603 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
9604 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
9605 { TestRound(kConnect, kProxyChallenge, OK),
9606 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
9607 { kProxy, AUTH_ASYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
9608 { TestRound(kConnect, kProxyChallenge, OK),
9609 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
9610 // Authenticating HTTPS server through an authenticating proxy.
9611 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
9612 { TestRound(kConnect, kProxyChallenge, OK),
9613 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9614 &kGet, &kServerChallenge),
9615 TestRound(kGetAuth, kSuccess, OK)}},
9616 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
9617 { TestRound(kConnect, kProxyChallenge, OK),
9618 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9619 &kGet, &kServerChallenge),
9620 TestRound(kGetAuth, kFailure, kAuthErr)}},
9621 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
9622 { TestRound(kConnect, kProxyChallenge, OK),
9623 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9624 &kGet, &kServerChallenge),
9625 TestRound(kGetAuth, kSuccess, OK)}},
9626 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
9627 { TestRound(kConnect, kProxyChallenge, OK),
9628 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9629 &kGet, &kServerChallenge),
9630 TestRound(kGetAuth, kFailure, kAuthErr)}},
9631 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
9632 { TestRound(kConnect, kProxyChallenge, OK),
9633 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9634 &kGet, &kServerChallenge),
9635 TestRound(kGetAuth, kSuccess, OK)}},
9636 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
9637 { TestRound(kConnect, kProxyChallenge, OK),
9638 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9639 &kGet, &kServerChallenge),
9640 TestRound(kGetAuth, kFailure, kAuthErr)}},
9641 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
9642 { TestRound(kConnect, kProxyChallenge, OK),
9643 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9644 &kGet, &kServerChallenge),
9645 TestRound(kGetAuth, kSuccess, OK)}},
9646 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
9647 { TestRound(kConnect, kProxyChallenge, OK),
9648 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9649 &kGet, &kServerChallenge),
9650 TestRound(kGetAuth, kFailure, kAuthErr)}},
9651 };
9652
viettrungluue4a8b882014-10-16 06:17:389653 for (size_t i = 0; i < arraysize(test_configs); ++i) {
[email protected]2d01c262011-08-11 23:07:089654 HttpAuthHandlerMock::Factory* auth_factory(
9655 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:079656 session_deps_.http_auth_handler_factory.reset(auth_factory);
[email protected]044de0642010-06-17 10:42:159657 const TestConfig& test_config = test_configs[i];
[email protected]65d34382010-07-01 18:12:269658
9659 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:159660 if (test_config.proxy_auth_timing != AUTH_NONE) {
[email protected]2d01c262011-08-11 23:07:089661 for (int n = 0; n < 2; n++) {
9662 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
9663 std::string auth_challenge = "Mock realm=proxy";
9664 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:249665 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
9666 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:089667 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
9668 origin, BoundNetLog());
9669 auth_handler->SetGenerateExpectation(
9670 test_config.proxy_auth_timing == AUTH_ASYNC,
9671 test_config.proxy_auth_rv);
9672 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
9673 }
[email protected]044de0642010-06-17 10:42:159674 }
9675 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:009676 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:159677 std::string auth_challenge = "Mock realm=server";
9678 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:249679 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
9680 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:159681 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
9682 origin, BoundNetLog());
9683 auth_handler->SetGenerateExpectation(
9684 test_config.server_auth_timing == AUTH_ASYNC,
9685 test_config.server_auth_rv);
[email protected]2d01c262011-08-11 23:07:089686 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:159687 }
9688 if (test_config.proxy_url) {
[email protected]bb88e1d32013-05-03 23:11:079689 session_deps_.proxy_service.reset(
[email protected]6104ea5d2011-04-27 21:37:129690 ProxyService::CreateFixed(test_config.proxy_url));
[email protected]044de0642010-06-17 10:42:159691 } else {
[email protected]bb88e1d32013-05-03 23:11:079692 session_deps_.proxy_service.reset(ProxyService::CreateDirect());
[email protected]044de0642010-06-17 10:42:159693 }
9694
9695 HttpRequestInfo request;
9696 request.method = "GET";
9697 request.url = GURL(test_config.server_url);
9698 request.load_flags = 0;
9699
[email protected]bb88e1d32013-05-03 23:11:079700 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
dcheng48459ac22014-08-26 00:46:419701 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]044de0642010-06-17 10:42:159702
9703 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
9704 const TestRound& read_write_round = test_config.rounds[round];
9705
9706 // Set up expected reads and writes.
9707 MockRead reads[2];
9708 reads[0] = read_write_round.read;
9709 size_t length_reads = 1;
9710 if (read_write_round.extra_read) {
9711 reads[1] = *read_write_round.extra_read;
9712 length_reads = 2;
9713 }
9714
9715 MockWrite writes[2];
9716 writes[0] = read_write_round.write;
9717 size_t length_writes = 1;
9718 if (read_write_round.extra_write) {
9719 writes[1] = *read_write_round.extra_write;
9720 length_writes = 2;
9721 }
9722 StaticSocketDataProvider data_provider(
9723 reads, length_reads, writes, length_writes);
[email protected]bb88e1d32013-05-03 23:11:079724 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]044de0642010-06-17 10:42:159725
9726 // Add an SSL sequence if necessary.
[email protected]8ddf8322012-02-23 18:08:069727 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
[email protected]044de0642010-06-17 10:42:159728 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:079729 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:159730 &ssl_socket_data_provider);
9731
9732 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:419733 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:159734 int rv;
9735 if (round == 0) {
[email protected]49639fa2011-12-20 23:22:419736 rv = trans.Start(&request, callback.callback(), BoundNetLog());
[email protected]044de0642010-06-17 10:42:159737 } else {
[email protected]49639fa2011-12-20 23:22:419738 rv = trans.RestartWithAuth(
9739 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:159740 }
9741 if (rv == ERR_IO_PENDING)
9742 rv = callback.WaitForResult();
9743
9744 // Compare results with expected data.
9745 EXPECT_EQ(read_write_round.expected_rv, rv);
[email protected]0b0bf032010-09-21 18:08:509746 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]044de0642010-06-17 10:42:159747 if (read_write_round.expected_rv == OK) {
[email protected]fe2255a2011-09-20 19:37:509748 ASSERT_TRUE(response != NULL);
[email protected]044de0642010-06-17 10:42:159749 } else {
9750 EXPECT_TRUE(response == NULL);
9751 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
9752 continue;
9753 }
9754 if (round + 1 < test_config.num_auth_rounds) {
9755 EXPECT_FALSE(response->auth_challenge.get() == NULL);
9756 } else {
9757 EXPECT_TRUE(response->auth_challenge.get() == NULL);
9758 }
9759 }
[email protected]e5ae96a2010-04-14 20:12:459760 }
9761}
9762
[email protected]23e482282013-06-14 16:08:029763TEST_P(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:149764 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:149765 HttpAuthHandlerMock::Factory* auth_factory(
9766 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:079767 session_deps_.http_auth_handler_factory.reset(auth_factory);
9768 session_deps_.proxy_service.reset(ProxyService::CreateDirect());
9769 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
9770 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:149771
9772 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
9773 auth_handler->set_connection_based(true);
9774 std::string auth_challenge = "Mock realm=server";
9775 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:249776 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
9777 auth_challenge.end());
[email protected]c871bce92010-07-15 21:51:149778 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
9779 origin, BoundNetLog());
[email protected]2d01c262011-08-11 23:07:089780 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:149781
[email protected]c871bce92010-07-15 21:51:149782 int rv = OK;
9783 const HttpResponseInfo* response = NULL;
9784 HttpRequestInfo request;
9785 request.method = "GET";
9786 request.url = origin;
9787 request.load_flags = 0;
[email protected]cb9bf6ca2011-01-28 13:15:279788
[email protected]bb88e1d32013-05-03 23:11:079789 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:109790
9791 // Use a TCP Socket Pool with only one connection per group. This is used
9792 // to validate that the TCP socket is not released to the pool between
9793 // each round of multi-round authentication.
9794 HttpNetworkSessionPeer session_peer(session);
[email protected]ab739042011-04-07 15:22:289795 ClientSocketPoolHistograms transport_pool_histograms("SmallTCP");
9796 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:109797 50, // Max sockets for pool
9798 1, // Max sockets per group
[email protected]ab739042011-04-07 15:22:289799 &transport_pool_histograms,
[email protected]bb88e1d32013-05-03 23:11:079800 session_deps_.host_resolver.get(),
9801 session_deps_.socket_factory.get(),
9802 session_deps_.net_log);
[email protected]831e4a32013-11-14 02:14:449803 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
9804 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:029805 mock_pool_manager->SetTransportSocketPool(transport_pool);
dchenge3d1ddc2014-10-15 19:30:519806 session_peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]7ef4cbbb2011-02-06 11:19:109807
[email protected]262eec82013-03-19 21:01:369808 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509809 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419810 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:149811
9812 const MockWrite kGet(
9813 "GET / HTTP/1.1\r\n"
9814 "Host: www.example.com\r\n"
9815 "Connection: keep-alive\r\n\r\n");
9816 const MockWrite kGetAuth(
9817 "GET / HTTP/1.1\r\n"
9818 "Host: www.example.com\r\n"
9819 "Connection: keep-alive\r\n"
9820 "Authorization: auth_token\r\n\r\n");
9821
9822 const MockRead kServerChallenge(
9823 "HTTP/1.1 401 Unauthorized\r\n"
9824 "WWW-Authenticate: Mock realm=server\r\n"
9825 "Content-Type: text/html; charset=iso-8859-1\r\n"
9826 "Content-Length: 14\r\n\r\n"
9827 "Unauthorized\r\n");
9828 const MockRead kSuccess(
9829 "HTTP/1.1 200 OK\r\n"
9830 "Content-Type: text/html; charset=iso-8859-1\r\n"
9831 "Content-Length: 3\r\n\r\n"
9832 "Yes");
9833
9834 MockWrite writes[] = {
9835 // First round
9836 kGet,
9837 // Second round
9838 kGetAuth,
9839 // Third round
9840 kGetAuth,
[email protected]eca50e122010-09-11 14:03:309841 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:109842 kGetAuth,
9843 // Competing request
9844 kGet,
[email protected]c871bce92010-07-15 21:51:149845 };
9846 MockRead reads[] = {
9847 // First round
9848 kServerChallenge,
9849 // Second round
9850 kServerChallenge,
9851 // Third round
[email protected]eca50e122010-09-11 14:03:309852 kServerChallenge,
9853 // Fourth round
[email protected]c871bce92010-07-15 21:51:149854 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:109855 // Competing response
9856 kSuccess,
[email protected]c871bce92010-07-15 21:51:149857 };
9858 StaticSocketDataProvider data_provider(reads, arraysize(reads),
9859 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:079860 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:149861
[email protected]7ef4cbbb2011-02-06 11:19:109862 const char* const kSocketGroup = "www.example.com:80";
9863
9864 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:149865 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:419866 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]c871bce92010-07-15 21:51:149867 if (rv == ERR_IO_PENDING)
9868 rv = callback.WaitForResult();
9869 EXPECT_EQ(OK, rv);
9870 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509871 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:149872 EXPECT_FALSE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:289873 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:149874
[email protected]7ef4cbbb2011-02-06 11:19:109875 // In between rounds, another request comes in for the same domain.
9876 // It should not be able to grab the TCP socket that trans has already
9877 // claimed.
9878 scoped_ptr<HttpTransaction> trans_compete(
[email protected]90499482013-06-01 00:39:509879 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419880 TestCompletionCallback callback_compete;
9881 rv = trans_compete->Start(
9882 &request, callback_compete.callback(), BoundNetLog());
[email protected]7ef4cbbb2011-02-06 11:19:109883 EXPECT_EQ(ERR_IO_PENDING, rv);
9884 // callback_compete.WaitForResult at this point would stall forever,
9885 // since the HttpNetworkTransaction does not release the request back to
9886 // the pool until after authentication completes.
9887
9888 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:149889 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:419890 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:149891 if (rv == ERR_IO_PENDING)
9892 rv = callback.WaitForResult();
9893 EXPECT_EQ(OK, rv);
9894 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509895 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:149896 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:289897 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:149898
[email protected]7ef4cbbb2011-02-06 11:19:109899 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:149900 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:419901 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:149902 if (rv == ERR_IO_PENDING)
9903 rv = callback.WaitForResult();
9904 EXPECT_EQ(OK, rv);
9905 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509906 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:149907 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:289908 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]eca50e122010-09-11 14:03:309909
[email protected]7ef4cbbb2011-02-06 11:19:109910 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:309911 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:419912 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:309913 if (rv == ERR_IO_PENDING)
9914 rv = callback.WaitForResult();
9915 EXPECT_EQ(OK, rv);
9916 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509917 ASSERT_TRUE(response != NULL);
[email protected]eca50e122010-09-11 14:03:309918 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:289919 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:109920
9921 // Read the body since the fourth round was successful. This will also
9922 // release the socket back to the pool.
9923 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
[email protected]90499482013-06-01 00:39:509924 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:109925 if (rv == ERR_IO_PENDING)
9926 rv = callback.WaitForResult();
9927 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:509928 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:109929 EXPECT_EQ(0, rv);
9930 // There are still 0 idle sockets, since the trans_compete transaction
9931 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:289932 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:109933
9934 // The competing request can now finish. Wait for the headers and then
9935 // read the body.
9936 rv = callback_compete.WaitForResult();
9937 EXPECT_EQ(OK, rv);
[email protected]90499482013-06-01 00:39:509938 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:109939 if (rv == ERR_IO_PENDING)
9940 rv = callback.WaitForResult();
9941 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:509942 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:109943 EXPECT_EQ(0, rv);
9944
9945 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:289946 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:149947}
9948
[email protected]65041fa2010-05-21 06:56:539949// This tests the case that a request is issued via http instead of spdy after
9950// npn is negotiated.
[email protected]23e482282013-06-14 16:08:029951TEST_P(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]d7599122014-05-24 03:37:239952 session_deps_.use_alternate_protocols = true;
9953 NextProtoVector next_protos;
[email protected]0ce3af82013-07-22 16:17:169954 next_protos.push_back(kProtoHTTP11);
[email protected]d7599122014-05-24 03:37:239955 session_deps_.next_protos = next_protos;
9956
[email protected]65041fa2010-05-21 06:56:539957 HttpRequestInfo request;
9958 request.method = "GET";
9959 request.url = GURL("https://www.google.com/");
9960 request.load_flags = 0;
9961
9962 MockWrite data_writes[] = {
9963 MockWrite("GET / HTTP/1.1\r\n"
9964 "Host: www.google.com\r\n"
9965 "Connection: keep-alive\r\n\r\n"),
9966 };
9967
[email protected]8a0fc822013-06-27 20:52:439968 std::string alternate_protocol_http_header =
9969 GetAlternateProtocolHttpHeader();
9970
[email protected]65041fa2010-05-21 06:56:539971 MockRead data_reads[] = {
9972 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439973 MockRead(alternate_protocol_http_header.c_str()),
[email protected]65041fa2010-05-21 06:56:539974 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069975 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:539976 };
9977
[email protected]8ddf8322012-02-23 18:08:069978 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]65041fa2010-05-21 06:56:539979 ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
9980 ssl.next_proto = "http/1.1";
[email protected]8e3c78cb2012-03-31 03:58:469981 ssl.protocol_negotiated = kProtoHTTP11;
[email protected]65041fa2010-05-21 06:56:539982
[email protected]bb88e1d32013-05-03 23:11:079983 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:539984
9985 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9986 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079987 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:539988
[email protected]49639fa2011-12-20 23:22:419989 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:539990
[email protected]bb88e1d32013-05-03 23:11:079991 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369992 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509993 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]65041fa2010-05-21 06:56:539994
[email protected]49639fa2011-12-20 23:22:419995 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]65041fa2010-05-21 06:56:539996
9997 EXPECT_EQ(ERR_IO_PENDING, rv);
9998 EXPECT_EQ(OK, callback.WaitForResult());
9999
10000 const HttpResponseInfo* response = trans->GetResponseInfo();
10001 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010002 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]65041fa2010-05-21 06:56:5310003 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10004
10005 std::string response_data;
10006 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10007 EXPECT_EQ("hello world", response_data);
10008
10009 EXPECT_FALSE(response->was_fetched_via_spdy);
10010 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]65041fa2010-05-21 06:56:5310011}
[email protected]26ef6582010-06-24 02:30:4710012
[email protected]23e482282013-06-14 16:08:0210013TEST_P(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:4710014 // Simulate the SSL handshake completing with an NPN negotiation
10015 // followed by an immediate server closing of the socket.
10016 // Fix crash: http://crbug.com/46369
[email protected]d7599122014-05-24 03:37:2310017 session_deps_.use_alternate_protocols = true;
10018 session_deps_.next_protos = SpdyNextProtos();
[email protected]26ef6582010-06-24 02:30:4710019
10020 HttpRequestInfo request;
10021 request.method = "GET";
10022 request.url = GURL("https://www.google.com/");
10023 request.load_flags = 0;
10024
[email protected]8ddf8322012-02-23 18:08:0610025 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210026 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710027 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4710028
[email protected]cdf8f7e72013-05-23 10:56:4610029 scoped_ptr<SpdyFrame> req(
10030 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]e7f75092010-07-01 22:39:1310031 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
[email protected]26ef6582010-06-24 02:30:4710032
10033 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0610034 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4710035 };
10036
[email protected]dd54bd82012-07-19 23:44:5710037 DelayedSocketData spdy_data(
10038 0, // don't wait in this case, immediate hangup.
10039 spdy_reads, arraysize(spdy_reads),
10040 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710041 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4710042
[email protected]49639fa2011-12-20 23:22:4110043 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4710044
[email protected]bb88e1d32013-05-03 23:11:0710045 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610046 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010047 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]26ef6582010-06-24 02:30:4710048
[email protected]49639fa2011-12-20 23:22:4110049 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]26ef6582010-06-24 02:30:4710050 EXPECT_EQ(ERR_IO_PENDING, rv);
10051 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult());
[email protected]26ef6582010-06-24 02:30:4710052}
[email protected]65d34382010-07-01 18:12:2610053
[email protected]795cbf82013-07-22 09:37:2710054// A subclass of HttpAuthHandlerMock that records the request URL when
10055// it gets it. This is needed since the auth handler may get destroyed
10056// before we get a chance to query it.
10057class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
10058 public:
10059 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
10060
dchengb03027d2014-10-21 12:00:2010061 ~UrlRecordingHttpAuthHandlerMock() override {}
[email protected]795cbf82013-07-22 09:37:2710062
10063 protected:
dchengb03027d2014-10-21 12:00:2010064 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
10065 const HttpRequestInfo* request,
10066 const CompletionCallback& callback,
10067 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2710068 *url_ = request->url;
10069 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
10070 credentials, request, callback, auth_token);
10071 }
10072
10073 private:
10074 GURL* url_;
10075};
10076
[email protected]23e482282013-06-14 16:08:0210077TEST_P(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) {
[email protected]f45c1ee2010-08-03 00:54:3010078 // This test ensures that the URL passed into the proxy is upgraded
10079 // to https when doing an Alternate Protocol upgrade.
[email protected]d7599122014-05-24 03:37:2310080 session_deps_.use_alternate_protocols = true;
10081 session_deps_.next_protos = SpdyNextProtos();
[email protected]f45c1ee2010-08-03 00:54:3010082
[email protected]bb88e1d32013-05-03 23:11:0710083 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:2010084 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
10085 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710086 session_deps_.net_log = &net_log;
[email protected]795cbf82013-07-22 09:37:2710087 GURL request_url;
10088 {
10089 HttpAuthHandlerMock::Factory* auth_factory =
10090 new HttpAuthHandlerMock::Factory();
10091 UrlRecordingHttpAuthHandlerMock* auth_handler =
10092 new UrlRecordingHttpAuthHandlerMock(&request_url);
10093 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
10094 auth_factory->set_do_init_from_challenge(true);
10095 session_deps_.http_auth_handler_factory.reset(auth_factory);
10096 }
[email protected]f45c1ee2010-08-03 00:54:3010097
10098 HttpRequestInfo request;
10099 request.method = "GET";
10100 request.url = GURL("http://www.google.com");
10101 request.load_flags = 0;
10102
10103 // First round goes unauthenticated through the proxy.
10104 MockWrite data_writes_1[] = {
10105 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
10106 "Host: www.google.com\r\n"
10107 "Proxy-Connection: keep-alive\r\n"
10108 "\r\n"),
10109 };
10110 MockRead data_reads_1[] = {
[email protected]8ddf8322012-02-23 18:08:0610111 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
bnc33b8cef42014-11-19 17:30:3810112 MockRead("HTTP/1.1 200 OK\r\n"),
10113 MockRead("Alternate-Protocol: 443:"),
10114 MockRead(GetAlternateProtocolFromParam()),
10115 MockRead("\r\n"),
10116 MockRead("Proxy-Connection: close\r\n"),
10117 MockRead("\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3010118 };
10119 StaticSocketDataProvider data_1(data_reads_1, arraysize(data_reads_1),
10120 data_writes_1, arraysize(data_writes_1));
10121
10122 // Second round tries to tunnel to www.google.com due to the
10123 // Alternate-Protocol announcement in the first round. It fails due
10124 // to a proxy authentication challenge.
[email protected]394816e92010-08-03 07:38:5910125 // After the failure, a tunnel is established to www.google.com using
10126 // Proxy-Authorization headers. There is then a SPDY request round.
10127 //
[email protected]fe3b7dc2012-02-03 19:52:0910128 // NOTE: Despite the "Proxy-Connection: Close", these are done on the
10129 // same MockTCPClientSocket since the underlying HttpNetworkClientSocket
10130 // does a Disconnect and Connect on the same socket, rather than trying
10131 // to obtain a new one.
10132 //
[email protected]394816e92010-08-03 07:38:5910133 // NOTE: Originally, the proxy response to the second CONNECT request
10134 // simply returned another 407 so the unit test could skip the SSL connection
10135 // establishment and SPDY framing issues. Alas, the
10136 // retry-http-when-alternate-protocol fails logic kicks in, which was more
[email protected]f45c1ee2010-08-03 00:54:3010137 // complicated to set up expectations for than the SPDY session.
[email protected]394816e92010-08-03 07:38:5910138
[email protected]cdf8f7e72013-05-23 10:56:4610139 scoped_ptr<SpdyFrame> req(
10140 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]23e482282013-06-14 16:08:0210141 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10142 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]f45c1ee2010-08-03 00:54:3010143
[email protected]394816e92010-08-03 07:38:5910144 MockWrite data_writes_2[] = {
10145 // First connection attempt without Proxy-Authorization.
10146 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
10147 "Host: www.google.com\r\n"
10148 "Proxy-Connection: keep-alive\r\n"
10149 "\r\n"),
10150
10151 // Second connection attempt with Proxy-Authorization.
[email protected]f45c1ee2010-08-03 00:54:3010152 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
10153 "Host: www.google.com\r\n"
10154 "Proxy-Connection: keep-alive\r\n"
10155 "Proxy-Authorization: auth_token\r\n"
10156 "\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3010157
[email protected]394816e92010-08-03 07:38:5910158 // SPDY request
10159 CreateMockWrite(*req),
[email protected]f45c1ee2010-08-03 00:54:3010160 };
[email protected]394816e92010-08-03 07:38:5910161 const char kRejectConnectResponse[] = ("HTTP/1.1 407 Unauthorized\r\n"
10162 "Proxy-Authenticate: Mock\r\n"
10163 "Proxy-Connection: close\r\n"
10164 "\r\n");
10165 const char kAcceptConnectResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
10166 MockRead data_reads_2[] = {
10167 // First connection attempt fails
[email protected]8ddf8322012-02-23 18:08:0610168 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ, 1),
10169 MockRead(ASYNC, kRejectConnectResponse,
[email protected]394816e92010-08-03 07:38:5910170 arraysize(kRejectConnectResponse) - 1, 1),
10171
10172 // Second connection attempt passes
[email protected]8ddf8322012-02-23 18:08:0610173 MockRead(ASYNC, kAcceptConnectResponse,
[email protected]fe3b7dc2012-02-03 19:52:0910174 arraysize(kAcceptConnectResponse) -1, 4),
[email protected]394816e92010-08-03 07:38:5910175
10176 // SPDY response
[email protected]fe3b7dc2012-02-03 19:52:0910177 CreateMockRead(*resp.get(), 6),
10178 CreateMockRead(*data.get(), 6),
[email protected]8ddf8322012-02-23 18:08:0610179 MockRead(ASYNC, 0, 0, 6),
[email protected]394816e92010-08-03 07:38:5910180 };
[email protected]dd54bd82012-07-19 23:44:5710181 OrderedSocketData data_2(
10182 data_reads_2, arraysize(data_reads_2),
10183 data_writes_2, arraysize(data_writes_2));
[email protected]f45c1ee2010-08-03 00:54:3010184
[email protected]8ddf8322012-02-23 18:08:0610185 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210186 ssl.SetNextProto(GetParam());
[email protected]f45c1ee2010-08-03 00:54:3010187
[email protected]d973e99a2012-02-17 21:02:3610188 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5510189 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
10190 NULL, 0, NULL, 0);
10191 hanging_non_alternate_protocol_socket.set_connect_data(
10192 never_finishing_connect);
10193
[email protected]bb88e1d32013-05-03 23:11:0710194 session_deps_.socket_factory->AddSocketDataProvider(&data_1);
10195 session_deps_.socket_factory->AddSocketDataProvider(&data_2);
10196 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10197 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5510198 &hanging_non_alternate_protocol_socket);
[email protected]bb88e1d32013-05-03 23:11:0710199 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f45c1ee2010-08-03 00:54:3010200
10201 // First round should work and provide the Alternate-Protocol state.
[email protected]49639fa2011-12-20 23:22:4110202 TestCompletionCallback callback_1;
[email protected]262eec82013-03-19 21:01:3610203 scoped_ptr<HttpTransaction> trans_1(
[email protected]90499482013-06-01 00:39:5010204 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110205 int rv = trans_1->Start(&request, callback_1.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:3010206 EXPECT_EQ(ERR_IO_PENDING, rv);
10207 EXPECT_EQ(OK, callback_1.WaitForResult());
10208
10209 // Second round should attempt a tunnel connect and get an auth challenge.
[email protected]49639fa2011-12-20 23:22:4110210 TestCompletionCallback callback_2;
[email protected]262eec82013-03-19 21:01:3610211 scoped_ptr<HttpTransaction> trans_2(
[email protected]90499482013-06-01 00:39:5010212 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110213 rv = trans_2->Start(&request, callback_2.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:3010214 EXPECT_EQ(ERR_IO_PENDING, rv);
10215 EXPECT_EQ(OK, callback_2.WaitForResult());
10216 const HttpResponseInfo* response = trans_2->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010217 ASSERT_TRUE(response != NULL);
[email protected]f45c1ee2010-08-03 00:54:3010218 ASSERT_FALSE(response->auth_challenge.get() == NULL);
10219
10220 // Restart with auth. Tunnel should work and response received.
[email protected]49639fa2011-12-20 23:22:4110221 TestCompletionCallback callback_3;
10222 rv = trans_2->RestartWithAuth(
10223 AuthCredentials(kFoo, kBar), callback_3.callback());
[email protected]f45c1ee2010-08-03 00:54:3010224 EXPECT_EQ(ERR_IO_PENDING, rv);
10225 EXPECT_EQ(OK, callback_3.WaitForResult());
10226
10227 // After all that work, these two lines (or actually, just the scheme) are
10228 // what this test is all about. Make sure it happens correctly.
[email protected]f45c1ee2010-08-03 00:54:3010229 EXPECT_EQ("https", request_url.scheme());
10230 EXPECT_EQ("www.google.com", request_url.host());
10231
[email protected]029c83b62013-01-24 05:28:2010232 LoadTimingInfo load_timing_info;
10233 EXPECT_TRUE(trans_2->GetLoadTimingInfo(&load_timing_info));
10234 TestLoadTimingNotReusedWithPac(load_timing_info,
10235 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]8e6441ca2010-08-19 05:56:3810236}
10237
10238// Test that if we cancel the transaction as the connection is completing, that
10239// everything tears down correctly.
[email protected]23e482282013-06-14 16:08:0210240TEST_P(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3810241 // Setup everything about the connection to complete synchronously, so that
10242 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
10243 // for is the callback from the HttpStreamRequest.
10244 // Then cancel the transaction.
10245 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3610246 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3810247 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0610248 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
10249 MockRead(SYNCHRONOUS, "hello world"),
10250 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3810251 };
10252
[email protected]8e6441ca2010-08-19 05:56:3810253 HttpRequestInfo request;
10254 request.method = "GET";
10255 request.url = GURL("http://www.google.com/");
10256 request.load_flags = 0;
10257
[email protected]bb88e1d32013-05-03 23:11:0710258 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]3fe8d2f82013-10-17 08:56:0710259 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:2710260 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4110261 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:2710262
[email protected]8e6441ca2010-08-19 05:56:3810263 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10264 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710265 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3810266
[email protected]49639fa2011-12-20 23:22:4110267 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3810268
[email protected]333bdf62012-06-08 22:57:2910269 CapturingBoundNetLog log;
[email protected]49639fa2011-12-20 23:22:4110270 int rv = trans->Start(&request, callback.callback(), log.bound());
[email protected]8e6441ca2010-08-19 05:56:3810271 EXPECT_EQ(ERR_IO_PENDING, rv);
10272 trans.reset(); // Cancel the transaction here.
10273
[email protected]2da659e2013-05-23 20:51:3410274 base::MessageLoop::current()->RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3010275}
10276
[email protected]ecab6e052014-05-16 14:58:1210277// Test that if a transaction is cancelled after receiving the headers, the
10278// stream is drained properly and added back to the socket pool. The main
10279// purpose of this test is to make sure that an HttpStreamParser can be read
10280// from after the HttpNetworkTransaction and the objects it owns have been
10281// deleted.
10282// See http://crbug.com/368418
10283TEST_P(HttpNetworkTransactionTest, CancelAfterHeaders) {
10284 MockRead data_reads[] = {
10285 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
10286 MockRead(ASYNC, "Content-Length: 2\r\n"),
10287 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
10288 MockRead(ASYNC, "1"),
10289 // 2 async reads are necessary to trigger a ReadResponseBody call after the
10290 // HttpNetworkTransaction has been deleted.
10291 MockRead(ASYNC, "2"),
10292 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
10293 };
10294 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10295 session_deps_.socket_factory->AddSocketDataProvider(&data);
10296
10297 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10298
10299 {
10300 HttpRequestInfo request;
10301 request.method = "GET";
10302 request.url = GURL("http://www.google.com/");
10303 request.load_flags = 0;
10304
dcheng48459ac22014-08-26 00:46:4110305 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1210306 TestCompletionCallback callback;
10307
10308 int rv = trans.Start(&request, callback.callback(), BoundNetLog());
10309 EXPECT_EQ(ERR_IO_PENDING, rv);
10310 callback.WaitForResult();
10311
10312 const HttpResponseInfo* response = trans.GetResponseInfo();
10313 ASSERT_TRUE(response != NULL);
10314 EXPECT_TRUE(response->headers.get() != NULL);
10315 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10316
10317 // The transaction and HttpRequestInfo are deleted.
10318 }
10319
10320 // Let the HttpResponseBodyDrainer drain the socket.
10321 base::MessageLoop::current()->RunUntilIdle();
10322
10323 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4110324 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1210325}
10326
[email protected]76a505b2010-08-25 06:23:0010327// Test a basic GET request through a proxy.
[email protected]23e482282013-06-14 16:08:0210328TEST_P(HttpNetworkTransactionTest, ProxyGet) {
[email protected]bb88e1d32013-05-03 23:11:0710329 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:2010330 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
[email protected]333bdf62012-06-08 22:57:2910331 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710332 session_deps_.net_log = log.bound().net_log();
10333 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0010334
[email protected]76a505b2010-08-25 06:23:0010335 HttpRequestInfo request;
10336 request.method = "GET";
10337 request.url = GURL("http://www.google.com/");
10338
10339 MockWrite data_writes1[] = {
10340 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
10341 "Host: www.google.com\r\n"
10342 "Proxy-Connection: keep-alive\r\n\r\n"),
10343 };
10344
10345 MockRead data_reads1[] = {
10346 MockRead("HTTP/1.1 200 OK\r\n"),
10347 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10348 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610349 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0010350 };
10351
10352 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10353 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710354 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0010355
[email protected]49639fa2011-12-20 23:22:4110356 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0010357
[email protected]262eec82013-03-19 21:01:3610358 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010359 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]597a1ab2014-06-26 08:12:2710360 BeforeProxyHeadersSentHandler proxy_headers_handler;
10361 trans->SetBeforeProxyHeadersSentCallback(
10362 base::Bind(&BeforeProxyHeadersSentHandler::OnBeforeProxyHeadersSent,
10363 base::Unretained(&proxy_headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5010364
[email protected]49639fa2011-12-20 23:22:4110365 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0010366 EXPECT_EQ(ERR_IO_PENDING, rv);
10367
10368 rv = callback1.WaitForResult();
10369 EXPECT_EQ(OK, rv);
10370
10371 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010372 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:0010373
10374 EXPECT_TRUE(response->headers->IsKeepAlive());
10375 EXPECT_EQ(200, response->headers->response_code());
10376 EXPECT_EQ(100, response->headers->GetContentLength());
10377 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]d8fc4722014-06-13 13:17:1510378 EXPECT_TRUE(
10379 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
[email protected]597a1ab2014-06-26 08:12:2710380 EXPECT_TRUE(proxy_headers_handler.observed_before_proxy_headers_sent());
10381 EXPECT_EQ("myproxy:70", proxy_headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0010382 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2010383
10384 LoadTimingInfo load_timing_info;
10385 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10386 TestLoadTimingNotReusedWithPac(load_timing_info,
10387 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0010388}
10389
10390// Test a basic HTTPS GET request through a proxy.
[email protected]23e482282013-06-14 16:08:0210391TEST_P(HttpNetworkTransactionTest, ProxyTunnelGet) {
[email protected]bb88e1d32013-05-03 23:11:0710392 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:2010393 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
[email protected]333bdf62012-06-08 22:57:2910394 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710395 session_deps_.net_log = log.bound().net_log();
10396 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0010397
[email protected]76a505b2010-08-25 06:23:0010398 HttpRequestInfo request;
10399 request.method = "GET";
10400 request.url = GURL("https://www.google.com/");
10401
10402 // Since we have proxy, should try to establish tunnel.
10403 MockWrite data_writes1[] = {
10404 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
10405 "Host: www.google.com\r\n"
10406 "Proxy-Connection: keep-alive\r\n\r\n"),
10407
10408 MockWrite("GET / HTTP/1.1\r\n"
10409 "Host: www.google.com\r\n"
10410 "Connection: keep-alive\r\n\r\n"),
10411 };
10412
10413 MockRead data_reads1[] = {
10414 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
10415
10416 MockRead("HTTP/1.1 200 OK\r\n"),
10417 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10418 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610419 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0010420 };
10421
10422 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10423 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710424 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0610425 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710426 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0010427
[email protected]49639fa2011-12-20 23:22:4110428 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0010429
[email protected]262eec82013-03-19 21:01:3610430 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010431 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5010432
[email protected]49639fa2011-12-20 23:22:4110433 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0010434 EXPECT_EQ(ERR_IO_PENDING, rv);
10435
10436 rv = callback1.WaitForResult();
10437 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:5710438 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:4010439 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0010440 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010441 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0010442 NetLog::PHASE_NONE);
10443 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010444 entries, pos,
[email protected]76a505b2010-08-25 06:23:0010445 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
10446 NetLog::PHASE_NONE);
10447
10448 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010449 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:0010450
10451 EXPECT_TRUE(response->headers->IsKeepAlive());
10452 EXPECT_EQ(200, response->headers->response_code());
10453 EXPECT_EQ(100, response->headers->GetContentLength());
10454 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10455 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]d8fc4722014-06-13 13:17:1510456 EXPECT_TRUE(
10457 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
[email protected]029c83b62013-01-24 05:28:2010458
10459 LoadTimingInfo load_timing_info;
10460 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10461 TestLoadTimingNotReusedWithPac(load_timing_info,
10462 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0010463}
10464
10465// Test a basic HTTPS GET request through a proxy, but the server hangs up
10466// while establishing the tunnel.
[email protected]23e482282013-06-14 16:08:0210467TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
[email protected]bb88e1d32013-05-03 23:11:0710468 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]333bdf62012-06-08 22:57:2910469 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710470 session_deps_.net_log = log.bound().net_log();
10471 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0010472
[email protected]76a505b2010-08-25 06:23:0010473 HttpRequestInfo request;
10474 request.method = "GET";
10475 request.url = GURL("https://www.google.com/");
10476
10477 // Since we have proxy, should try to establish tunnel.
10478 MockWrite data_writes1[] = {
10479 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
10480 "Host: www.google.com\r\n"
10481 "Proxy-Connection: keep-alive\r\n\r\n"),
10482
10483 MockWrite("GET / HTTP/1.1\r\n"
10484 "Host: www.google.com\r\n"
10485 "Connection: keep-alive\r\n\r\n"),
10486 };
10487
10488 MockRead data_reads1[] = {
[email protected]8ddf8322012-02-23 18:08:0610489 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:0010490 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610491 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0010492 };
10493
10494 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10495 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710496 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0610497 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710498 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0010499
[email protected]49639fa2011-12-20 23:22:4110500 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0010501
[email protected]262eec82013-03-19 21:01:3610502 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010503 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5010504
[email protected]49639fa2011-12-20 23:22:4110505 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0010506 EXPECT_EQ(ERR_IO_PENDING, rv);
10507
10508 rv = callback1.WaitForResult();
10509 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
[email protected]f3da152d2012-06-02 01:00:5710510 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:4010511 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0010512 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010513 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0010514 NetLog::PHASE_NONE);
10515 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010516 entries, pos,
[email protected]76a505b2010-08-25 06:23:0010517 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
10518 NetLog::PHASE_NONE);
10519}
10520
[email protected]749eefa82010-09-13 22:14:0310521// Test for crbug.com/55424.
[email protected]23e482282013-06-14 16:08:0210522TEST_P(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
[email protected]cdf8f7e72013-05-23 10:56:4610523 scoped_ptr<SpdyFrame> req(
10524 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
[email protected]749eefa82010-09-13 22:14:0310525 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
10526
[email protected]23e482282013-06-14 16:08:0210527 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10528 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0310529 MockRead spdy_reads[] = {
10530 CreateMockRead(*resp),
10531 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:0610532 MockRead(ASYNC, 0, 0),
[email protected]749eefa82010-09-13 22:14:0310533 };
10534
[email protected]dd54bd82012-07-19 23:44:5710535 DelayedSocketData spdy_data(
10536 1, // wait for one write to finish before reading.
10537 spdy_reads, arraysize(spdy_reads),
10538 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710539 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0310540
[email protected]8ddf8322012-02-23 18:08:0610541 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210542 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710543 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0310544
[email protected]bb88e1d32013-05-03 23:11:0710545 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0310546
10547 // Set up an initial SpdySession in the pool to reuse.
[email protected]02b0c342010-09-25 21:09:3810548 HostPortPair host_port_pair("www.google.com", 443);
[email protected]e6d017652013-05-17 18:01:4010549 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5310550 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2710551 base::WeakPtr<SpdySession> spdy_session =
[email protected]41d64e82013-07-03 22:44:2610552 CreateInsecureSpdySession(session, key, BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0310553
10554 HttpRequestInfo request;
10555 request.method = "GET";
10556 request.url = GURL("https://www.google.com/");
10557 request.load_flags = 0;
10558
10559 // This is the important line that marks this as a preconnect.
10560 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
10561
[email protected]262eec82013-03-19 21:01:3610562 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010563 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]749eefa82010-09-13 22:14:0310564
[email protected]41d64e82013-07-03 22:44:2610565 TestCompletionCallback callback;
[email protected]49639fa2011-12-20 23:22:4110566 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0310567 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110568 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]749eefa82010-09-13 22:14:0310569}
10570
[email protected]73b8dd222010-11-11 19:55:2410571// Given a net error, cause that error to be returned from the first Write()
10572// call and verify that the HttpTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0210573void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0710574 int error, IoMode mode) {
[email protected]cb9bf6ca2011-01-28 13:15:2710575 net::HttpRequestInfo request_info;
10576 request_info.url = GURL("https://www.example.com/");
10577 request_info.method = "GET";
10578 request_info.load_flags = net::LOAD_NORMAL;
10579
[email protected]8ddf8322012-02-23 18:08:0610580 SSLSocketDataProvider ssl_data(mode, OK);
[email protected]73b8dd222010-11-11 19:55:2410581 net::MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:0610582 net::MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2410583 };
10584 net::StaticSocketDataProvider data(NULL, 0,
10585 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0710586 session_deps_.socket_factory->AddSocketDataProvider(&data);
10587 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2410588
[email protected]bb88e1d32013-05-03 23:11:0710589 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610590 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010591 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]73b8dd222010-11-11 19:55:2410592
[email protected]49639fa2011-12-20 23:22:4110593 TestCompletionCallback callback;
10594 int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
[email protected]73b8dd222010-11-11 19:55:2410595 if (rv == net::ERR_IO_PENDING)
10596 rv = callback.WaitForResult();
10597 ASSERT_EQ(error, rv);
10598}
10599
[email protected]23e482282013-06-14 16:08:0210600TEST_P(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2410601 // Just check a grab bag of cert errors.
10602 static const int kErrors[] = {
10603 ERR_CERT_COMMON_NAME_INVALID,
10604 ERR_CERT_AUTHORITY_INVALID,
10605 ERR_CERT_DATE_INVALID,
10606 };
10607 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0610608 CheckErrorIsPassedBack(kErrors[i], ASYNC);
10609 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2410610 }
10611}
10612
[email protected]bd0b6772011-01-11 19:59:3010613// Ensure that a client certificate is removed from the SSL client auth
10614// cache when:
10615// 1) No proxy is involved.
10616// 2) TLS False Start is disabled.
10617// 3) The initial TLS handshake requests a client certificate.
10618// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0210619TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310620 ClientAuthCertCache_Direct_NoFalseStart) {
[email protected]cb9bf6ca2011-01-28 13:15:2710621 net::HttpRequestInfo request_info;
10622 request_info.url = GURL("https://www.example.com/");
10623 request_info.method = "GET";
10624 request_info.load_flags = net::LOAD_NORMAL;
10625
[email protected]bd0b6772011-01-11 19:59:3010626 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4110627 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3010628
10629 // [ssl_]data1 contains the data for the first SSL handshake. When a
10630 // CertificateRequest is received for the first time, the handshake will
10631 // be aborted to allow the caller to provide a certificate.
[email protected]8ddf8322012-02-23 18:08:0610632 SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3010633 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710634 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
[email protected]bd0b6772011-01-11 19:59:3010635 net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710636 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3010637
10638 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
10639 // False Start is not being used, the result of the SSL handshake will be
10640 // returned as part of the SSLClientSocket::Connect() call. This test
10641 // matches the result of a server sending a handshake_failure alert,
10642 // rather than a Finished message, because it requires a client
10643 // certificate and none was supplied.
[email protected]8ddf8322012-02-23 18:08:0610644 SSLSocketDataProvider ssl_data2(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3010645 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710646 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
[email protected]bd0b6772011-01-11 19:59:3010647 net::StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710648 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3010649
10650 // [ssl_]data3 contains the data for the third SSL handshake. When a
10651 // connection to a server fails during an SSL handshake,
[email protected]80c75f682012-05-26 16:22:1710652 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
10653 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3010654 // of the HttpNetworkTransaction. Because this test failure is due to
10655 // requiring a client certificate, this fallback handshake should also
10656 // fail.
[email protected]8ddf8322012-02-23 18:08:0610657 SSLSocketDataProvider ssl_data3(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3010658 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710659 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
[email protected]bd0b6772011-01-11 19:59:3010660 net::StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710661 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3010662
[email protected]80c75f682012-05-26 16:22:1710663 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
10664 // connection to a server fails during an SSL handshake,
10665 // HttpNetworkTransaction will attempt to fallback to SSLv3 if the previous
10666 // connection was attempted with TLSv1. This is transparent to the caller
10667 // of the HttpNetworkTransaction. Because this test failure is due to
10668 // requiring a client certificate, this fallback handshake should also
10669 // fail.
10670 SSLSocketDataProvider ssl_data4(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
10671 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710672 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
[email protected]80c75f682012-05-26 16:22:1710673 net::StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710674 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1710675
[email protected]7799de12013-05-30 05:52:5110676 // Need one more if TLSv1.2 is enabled.
10677 SSLSocketDataProvider ssl_data5(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
10678 ssl_data5.cert_request_info = cert_request.get();
10679 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
10680 net::StaticSocketDataProvider data5(NULL, 0, NULL, 0);
10681 session_deps_.socket_factory->AddSocketDataProvider(&data5);
10682
[email protected]bb88e1d32013-05-03 23:11:0710683 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610684 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010685 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3010686
[email protected]bd0b6772011-01-11 19:59:3010687 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4110688 TestCompletionCallback callback;
10689 int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
[email protected]bd0b6772011-01-11 19:59:3010690 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10691
10692 // Complete the SSL handshake, which should abort due to requiring a
10693 // client certificate.
10694 rv = callback.WaitForResult();
10695 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
10696
10697 // Indicate that no certificate should be supplied. From the perspective
10698 // of SSLClientCertCache, NULL is just as meaningful as a real
10699 // certificate, so this is the same as supply a
10700 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4110701 rv = trans->RestartWithCertificate(NULL, callback.callback());
[email protected]bd0b6772011-01-11 19:59:3010702 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10703
10704 // Ensure the certificate was added to the client auth cache before
10705 // allowing the connection to continue restarting.
10706 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4110707 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
10708 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3010709 ASSERT_EQ(NULL, client_cert.get());
10710
10711 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1710712 // then consume ssl_data3 and ssl_data4, both of which should also fail.
10713 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3010714 rv = callback.WaitForResult();
10715 ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
10716
10717 // Ensure that the client certificate is removed from the cache on a
10718 // handshake failure.
[email protected]791879c2013-12-17 07:22:4110719 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
10720 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3010721}
10722
10723// Ensure that a client certificate is removed from the SSL client auth
10724// cache when:
10725// 1) No proxy is involved.
10726// 2) TLS False Start is enabled.
10727// 3) The initial TLS handshake requests a client certificate.
10728// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0210729TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310730 ClientAuthCertCache_Direct_FalseStart) {
[email protected]cb9bf6ca2011-01-28 13:15:2710731 net::HttpRequestInfo request_info;
10732 request_info.url = GURL("https://www.example.com/");
10733 request_info.method = "GET";
10734 request_info.load_flags = net::LOAD_NORMAL;
10735
[email protected]bd0b6772011-01-11 19:59:3010736 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4110737 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3010738
10739 // When TLS False Start is used, SSLClientSocket::Connect() calls will
10740 // return successfully after reading up to the peer's Certificate message.
10741 // This is to allow the caller to call SSLClientSocket::Write(), which can
10742 // enqueue application data to be sent in the same packet as the
10743 // ChangeCipherSpec and Finished messages.
10744 // The actual handshake will be finished when SSLClientSocket::Read() is
10745 // called, which expects to process the peer's ChangeCipherSpec and
10746 // Finished messages. If there was an error negotiating with the peer,
10747 // such as due to the peer requiring a client certificate when none was
10748 // supplied, the alert sent by the peer won't be processed until Read() is
10749 // called.
10750
10751 // Like the non-False Start case, when a client certificate is requested by
10752 // the peer, the handshake is aborted during the Connect() call.
10753 // [ssl_]data1 represents the initial SSL handshake with the peer.
[email protected]8ddf8322012-02-23 18:08:0610754 SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3010755 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710756 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
[email protected]bd0b6772011-01-11 19:59:3010757 net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710758 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3010759
10760 // When a client certificate is supplied, Connect() will not be aborted
10761 // when the peer requests the certificate. Instead, the handshake will
10762 // artificially succeed, allowing the caller to write the HTTP request to
10763 // the socket. The handshake messages are not processed until Read() is
10764 // called, which then detects that the handshake was aborted, due to the
10765 // peer sending a handshake_failure because it requires a client
10766 // certificate.
[email protected]8ddf8322012-02-23 18:08:0610767 SSLSocketDataProvider ssl_data2(ASYNC, net::OK);
[email protected]bd0b6772011-01-11 19:59:3010768 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710769 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
[email protected]bd0b6772011-01-11 19:59:3010770 net::MockRead data2_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0610771 net::MockRead(ASYNC /* async */, net::ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3010772 };
10773 net::StaticSocketDataProvider data2(
10774 data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710775 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3010776
10777 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1710778 // the data for the SSL handshake once the TLSv1.1 connection falls back to
10779 // TLSv1. It has the same behaviour as [ssl_]data2.
[email protected]8ddf8322012-02-23 18:08:0610780 SSLSocketDataProvider ssl_data3(ASYNC, net::OK);
[email protected]bd0b6772011-01-11 19:59:3010781 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710782 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
[email protected]bd0b6772011-01-11 19:59:3010783 net::StaticSocketDataProvider data3(
10784 data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710785 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3010786
[email protected]80c75f682012-05-26 16:22:1710787 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
10788 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
10789 SSLSocketDataProvider ssl_data4(ASYNC, net::OK);
10790 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710791 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
[email protected]80c75f682012-05-26 16:22:1710792 net::StaticSocketDataProvider data4(
10793 data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710794 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1710795
[email protected]7799de12013-05-30 05:52:5110796 // Need one more if TLSv1.2 is enabled.
10797 SSLSocketDataProvider ssl_data5(ASYNC, net::OK);
10798 ssl_data5.cert_request_info = cert_request.get();
10799 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
10800 net::StaticSocketDataProvider data5(
10801 data2_reads, arraysize(data2_reads), NULL, 0);
10802 session_deps_.socket_factory->AddSocketDataProvider(&data5);
10803
[email protected]bb88e1d32013-05-03 23:11:0710804 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610805 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010806 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3010807
[email protected]bd0b6772011-01-11 19:59:3010808 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4110809 TestCompletionCallback callback;
10810 int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
[email protected]bd0b6772011-01-11 19:59:3010811 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10812
10813 // Complete the SSL handshake, which should abort due to requiring a
10814 // client certificate.
10815 rv = callback.WaitForResult();
10816 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
10817
10818 // Indicate that no certificate should be supplied. From the perspective
10819 // of SSLClientCertCache, NULL is just as meaningful as a real
10820 // certificate, so this is the same as supply a
10821 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4110822 rv = trans->RestartWithCertificate(NULL, callback.callback());
[email protected]bd0b6772011-01-11 19:59:3010823 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10824
10825 // Ensure the certificate was added to the client auth cache before
10826 // allowing the connection to continue restarting.
10827 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4110828 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
10829 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3010830 ASSERT_EQ(NULL, client_cert.get());
10831
[email protected]bd0b6772011-01-11 19:59:3010832 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1710833 // then consume ssl_data3 and ssl_data4, both of which should also fail.
10834 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3010835 rv = callback.WaitForResult();
10836 ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
10837
10838 // Ensure that the client certificate is removed from the cache on a
10839 // handshake failure.
[email protected]791879c2013-12-17 07:22:4110840 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
10841 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3010842}
10843
[email protected]8c405132011-01-11 22:03:1810844// Ensure that a client certificate is removed from the SSL client auth
10845// cache when:
10846// 1) An HTTPS proxy is involved.
10847// 3) The HTTPS proxy requests a client certificate.
10848// 4) The client supplies an invalid/unacceptable certificate for the
10849// proxy.
10850// The test is repeated twice, first for connecting to an HTTPS endpoint,
10851// then for connecting to an HTTP endpoint.
[email protected]23e482282013-06-14 16:08:0210852TEST_P(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
[email protected]bb88e1d32013-05-03 23:11:0710853 session_deps_.proxy_service.reset(
[email protected]8c405132011-01-11 22:03:1810854 ProxyService::CreateFixed("https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:2910855 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710856 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1810857
10858 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4110859 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1810860
10861 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
10862 // [ssl_]data[1-3]. Rather than represending the endpoint
10863 // (www.example.com:443), they represent failures with the HTTPS proxy
10864 // (proxy:70).
[email protected]8ddf8322012-02-23 18:08:0610865 SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1810866 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710867 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
[email protected]8c405132011-01-11 22:03:1810868 net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710869 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1810870
[email protected]8ddf8322012-02-23 18:08:0610871 SSLSocketDataProvider ssl_data2(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1810872 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710873 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
[email protected]8c405132011-01-11 22:03:1810874 net::StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710875 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1810876
[email protected]80c75f682012-05-26 16:22:1710877 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
10878#if 0
[email protected]8ddf8322012-02-23 18:08:0610879 SSLSocketDataProvider ssl_data3(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1810880 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710881 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
[email protected]8c405132011-01-11 22:03:1810882 net::StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710883 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1710884#endif
[email protected]8c405132011-01-11 22:03:1810885
10886 net::HttpRequestInfo requests[2];
10887 requests[0].url = GURL("https://www.example.com/");
10888 requests[0].method = "GET";
10889 requests[0].load_flags = net::LOAD_NORMAL;
10890
10891 requests[1].url = GURL("http://www.example.com/");
10892 requests[1].method = "GET";
10893 requests[1].load_flags = net::LOAD_NORMAL;
10894
10895 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0710896 session_deps_.socket_factory->ResetNextMockIndexes();
10897 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c405132011-01-11 22:03:1810898 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5010899 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c405132011-01-11 22:03:1810900
10901 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4110902 TestCompletionCallback callback;
10903 int rv = trans->Start(
10904 &requests[i], callback.callback(), net::BoundNetLog());
[email protected]8c405132011-01-11 22:03:1810905 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10906
10907 // Complete the SSL handshake, which should abort due to requiring a
10908 // client certificate.
10909 rv = callback.WaitForResult();
10910 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
10911
10912 // Indicate that no certificate should be supplied. From the perspective
10913 // of SSLClientCertCache, NULL is just as meaningful as a real
10914 // certificate, so this is the same as supply a
10915 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4110916 rv = trans->RestartWithCertificate(NULL, callback.callback());
[email protected]8c405132011-01-11 22:03:1810917 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10918
10919 // Ensure the certificate was added to the client auth cache before
10920 // allowing the connection to continue restarting.
10921 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4110922 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
10923 HostPortPair("proxy", 70), &client_cert));
[email protected]8c405132011-01-11 22:03:1810924 ASSERT_EQ(NULL, client_cert.get());
10925 // Ensure the certificate was NOT cached for the endpoint. This only
10926 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4110927 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
10928 HostPortPair("www.example.com", 443), &client_cert));
[email protected]8c405132011-01-11 22:03:1810929
10930 // Restart the handshake. This will consume ssl_data2, which fails, and
10931 // then consume ssl_data3, which should also fail. The result code is
10932 // checked against what ssl_data3 should return.
10933 rv = callback.WaitForResult();
10934 ASSERT_EQ(net::ERR_PROXY_CONNECTION_FAILED, rv);
10935
10936 // Now that the new handshake has failed, ensure that the client
10937 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4110938 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
10939 HostPortPair("proxy", 70), &client_cert));
10940 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
10941 HostPortPair("www.example.com", 443), &client_cert));
[email protected]8c405132011-01-11 22:03:1810942 }
10943}
10944
[email protected]23e482282013-06-14 16:08:0210945// Unlike TEST/TEST_F, which are macros that expand to further macros,
10946// TEST_P is a macro that expands directly to code that stringizes the
10947// arguments. As a result, macros passed as parameters (such as prefix
10948// or test_case_name) will not be expanded by the preprocessor. To
10949// work around this, indirect the macro for TEST_P, so that the
10950// pre-processor will expand macros such as MAYBE_test_name before
10951// instantiating the test.
10952#define WRAPPED_TEST_P(test_case_name, test_name) \
10953 TEST_P(test_case_name, test_name)
10954
[email protected]45b170822012-05-04 21:18:1410955// Times out on Win7 dbg(2) bot. http://crbug.com/124776
10956#if defined(OS_WIN)
10957#define MAYBE_UseIPConnectionPooling DISABLED_UseIPConnectionPooling
10958#else
10959#define MAYBE_UseIPConnectionPooling UseIPConnectionPooling
10960#endif
[email protected]23e482282013-06-14 16:08:0210961WRAPPED_TEST_P(HttpNetworkTransactionTest, MAYBE_UseIPConnectionPooling) {
[email protected]d7599122014-05-24 03:37:2310962 session_deps_.use_alternate_protocols = true;
10963 session_deps_.next_protos = SpdyNextProtos();
[email protected]e3ceb682011-06-28 23:55:4610964
10965 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0710966 session_deps_.host_resolver.reset(new MockCachingHostResolver());
10967 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2610968 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
10969 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4610970
[email protected]8ddf8322012-02-23 18:08:0610971 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210972 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710973 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4610974
[email protected]cdf8f7e72013-05-23 10:56:4610975 scoped_ptr<SpdyFrame> host1_req(
10976 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
10977 scoped_ptr<SpdyFrame> host2_req(
10978 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4610979 MockWrite spdy_writes[] = {
10980 CreateMockWrite(*host1_req, 1),
10981 CreateMockWrite(*host2_req, 4),
10982 };
[email protected]23e482282013-06-14 16:08:0210983 scoped_ptr<SpdyFrame> host1_resp(
10984 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10985 scoped_ptr<SpdyFrame> host1_resp_body(
10986 spdy_util_.ConstructSpdyBodyFrame(1, true));
10987 scoped_ptr<SpdyFrame> host2_resp(
10988 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
10989 scoped_ptr<SpdyFrame> host2_resp_body(
10990 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4610991 MockRead spdy_reads[] = {
10992 CreateMockRead(*host1_resp, 2),
10993 CreateMockRead(*host1_resp_body, 3),
10994 CreateMockRead(*host2_resp, 5),
10995 CreateMockRead(*host2_resp_body, 6),
[email protected]8ddf8322012-02-23 18:08:0610996 MockRead(ASYNC, 0, 7),
[email protected]e3ceb682011-06-28 23:55:4610997 };
10998
[email protected]d2b5f092012-06-08 23:55:0210999 IPAddressNumber ip;
11000 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
11001 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11002 MockConnect connect(ASYNC, OK, peer_addr);
[email protected]dd54bd82012-07-19 23:44:5711003 OrderedSocketData spdy_data(
11004 connect,
11005 spdy_reads, arraysize(spdy_reads),
11006 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711007 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4611008
[email protected]aa22b242011-11-16 18:58:2911009 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4611010 HttpRequestInfo request1;
11011 request1.method = "GET";
11012 request1.url = GURL("https://www.google.com/");
11013 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011014 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611015
[email protected]49639fa2011-12-20 23:22:4111016 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611017 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111018 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611019
11020 const HttpResponseInfo* response = trans1.GetResponseInfo();
11021 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011022 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611023 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11024
11025 std::string response_data;
11026 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
11027 EXPECT_EQ("hello!", response_data);
11028
11029 // Preload www.gmail.com into HostCache.
11030 HostPortPair host_port("www.gmail.com", 443);
[email protected]5109c1952013-08-20 18:44:1011031 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4611032 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1011033 rv = session_deps_.host_resolver->Resolve(resolve_info,
11034 DEFAULT_PRIORITY,
11035 &ignored,
11036 callback.callback(),
11037 NULL,
11038 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4711039 EXPECT_EQ(ERR_IO_PENDING, rv);
11040 rv = callback.WaitForResult();
11041 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4611042
11043 HttpRequestInfo request2;
11044 request2.method = "GET";
11045 request2.url = GURL("https://www.gmail.com/");
11046 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011047 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611048
[email protected]49639fa2011-12-20 23:22:4111049 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611050 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111051 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611052
11053 response = trans2.GetResponseInfo();
11054 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011055 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611056 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11057 EXPECT_TRUE(response->was_fetched_via_spdy);
11058 EXPECT_TRUE(response->was_npn_negotiated);
11059 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
11060 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4611061}
[email protected]45b170822012-05-04 21:18:1411062#undef MAYBE_UseIPConnectionPooling
[email protected]e3ceb682011-06-28 23:55:4611063
[email protected]23e482282013-06-14 16:08:0211064TEST_P(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d7599122014-05-24 03:37:2311065 session_deps_.use_alternate_protocols = true;
11066 session_deps_.next_protos = SpdyNextProtos();
[email protected]d2b5f092012-06-08 23:55:0211067
11068 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0711069 session_deps_.host_resolver.reset(new MockCachingHostResolver());
11070 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0211071 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
11072 pool_peer.DisableDomainAuthenticationVerification();
11073
11074 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211075 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711076 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]d2b5f092012-06-08 23:55:0211077
[email protected]cdf8f7e72013-05-23 10:56:4611078 scoped_ptr<SpdyFrame> host1_req(
11079 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
11080 scoped_ptr<SpdyFrame> host2_req(
11081 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0211082 MockWrite spdy_writes[] = {
11083 CreateMockWrite(*host1_req, 1),
11084 CreateMockWrite(*host2_req, 4),
11085 };
[email protected]23e482282013-06-14 16:08:0211086 scoped_ptr<SpdyFrame> host1_resp(
11087 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11088 scoped_ptr<SpdyFrame> host1_resp_body(
11089 spdy_util_.ConstructSpdyBodyFrame(1, true));
11090 scoped_ptr<SpdyFrame> host2_resp(
11091 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11092 scoped_ptr<SpdyFrame> host2_resp_body(
11093 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0211094 MockRead spdy_reads[] = {
11095 CreateMockRead(*host1_resp, 2),
11096 CreateMockRead(*host1_resp_body, 3),
11097 CreateMockRead(*host2_resp, 5),
11098 CreateMockRead(*host2_resp_body, 6),
11099 MockRead(ASYNC, 0, 7),
11100 };
11101
11102 IPAddressNumber ip;
11103 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
11104 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11105 MockConnect connect(ASYNC, OK, peer_addr);
[email protected]dd54bd82012-07-19 23:44:5711106 OrderedSocketData spdy_data(
11107 connect,
11108 spdy_reads, arraysize(spdy_reads),
11109 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711110 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0211111
11112 TestCompletionCallback callback;
11113 HttpRequestInfo request1;
11114 request1.method = "GET";
11115 request1.url = GURL("https://www.google.com/");
11116 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011117 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0211118
11119 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
11120 EXPECT_EQ(ERR_IO_PENDING, rv);
11121 EXPECT_EQ(OK, callback.WaitForResult());
11122
11123 const HttpResponseInfo* response = trans1.GetResponseInfo();
11124 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011125 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d2b5f092012-06-08 23:55:0211126 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11127
11128 std::string response_data;
11129 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
11130 EXPECT_EQ("hello!", response_data);
11131
11132 HttpRequestInfo request2;
11133 request2.method = "GET";
11134 request2.url = GURL("https://www.gmail.com/");
11135 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011136 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0211137
11138 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
11139 EXPECT_EQ(ERR_IO_PENDING, rv);
11140 EXPECT_EQ(OK, callback.WaitForResult());
11141
11142 response = trans2.GetResponseInfo();
11143 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011144 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d2b5f092012-06-08 23:55:0211145 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11146 EXPECT_TRUE(response->was_fetched_via_spdy);
11147 EXPECT_TRUE(response->was_npn_negotiated);
11148 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
11149 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0211150}
11151
[email protected]e3ceb682011-06-28 23:55:4611152class OneTimeCachingHostResolver : public net::HostResolver {
11153 public:
11154 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
11155 : host_port_(host_port) {}
dchengb03027d2014-10-21 12:00:2011156 ~OneTimeCachingHostResolver() override {}
[email protected]e3ceb682011-06-28 23:55:4611157
11158 RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); }
11159
11160 // HostResolver methods:
dchengb03027d2014-10-21 12:00:2011161 int Resolve(const RequestInfo& info,
11162 RequestPriority priority,
11163 AddressList* addresses,
11164 const CompletionCallback& callback,
11165 RequestHandle* out_req,
11166 const BoundNetLog& net_log) override {
[email protected]95a214c2011-08-04 21:50:4011167 return host_resolver_.Resolve(
[email protected]5109c1952013-08-20 18:44:1011168 info, priority, addresses, callback, out_req, net_log);
[email protected]95a214c2011-08-04 21:50:4011169 }
11170
dchengb03027d2014-10-21 12:00:2011171 int ResolveFromCache(const RequestInfo& info,
11172 AddressList* addresses,
11173 const BoundNetLog& net_log) override {
[email protected]95a214c2011-08-04 21:50:4011174 int rv = host_resolver_.ResolveFromCache(info, addresses, net_log);
11175 if (rv == OK && info.host_port_pair().Equals(host_port_))
[email protected]98e1cd012011-11-08 15:33:0911176 host_resolver_.GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4611177 return rv;
11178 }
11179
dchengb03027d2014-10-21 12:00:2011180 void CancelRequest(RequestHandle req) override {
[email protected]e3ceb682011-06-28 23:55:4611181 host_resolver_.CancelRequest(req);
11182 }
11183
[email protected]46da33be2011-07-19 21:58:0411184 MockCachingHostResolver* GetMockHostResolver() {
11185 return &host_resolver_;
11186 }
11187
[email protected]e3ceb682011-06-28 23:55:4611188 private:
11189 MockCachingHostResolver host_resolver_;
11190 const HostPortPair host_port_;
11191};
11192
[email protected]45b170822012-05-04 21:18:1411193// Times out on Win7 dbg(2) bot. http://crbug.com/124776
11194#if defined(OS_WIN)
[email protected]bb88e1d32013-05-03 23:11:0711195#define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \
11196 DISABLED_UseIPConnectionPoolingWithHostCacheExpiration
[email protected]45b170822012-05-04 21:18:1411197#else
[email protected]bb88e1d32013-05-03 23:11:0711198#define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \
11199 UseIPConnectionPoolingWithHostCacheExpiration
[email protected]45b170822012-05-04 21:18:1411200#endif
[email protected]23e482282013-06-14 16:08:0211201WRAPPED_TEST_P(HttpNetworkTransactionTest,
11202 MAYBE_UseIPConnectionPoolingWithHostCacheExpiration) {
[email protected]23e482282013-06-14 16:08:0211203// Times out on Win7 dbg(2) bot. http://crbug.com/124776 . (MAYBE_
11204// prefix doesn't work with parametrized tests).
11205#if defined(OS_WIN)
11206 return;
[email protected]88c7b4be2014-03-19 23:04:0111207#else
[email protected]d7599122014-05-24 03:37:2311208 session_deps_.use_alternate_protocols = true;
11209 session_deps_.next_protos = SpdyNextProtos();
[email protected]e3ceb682011-06-28 23:55:4611210
11211 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
[email protected]e3ceb682011-06-28 23:55:4611212 OneTimeCachingHostResolver host_resolver(HostPortPair("www.gmail.com", 443));
[email protected]c6bf8152012-12-02 07:43:3411213 HttpNetworkSession::Params params =
[email protected]bb88e1d32013-05-03 23:11:0711214 SpdySessionDependencies::CreateSessionParams(&session_deps_);
[email protected]e3ceb682011-06-28 23:55:4611215 params.host_resolver = &host_resolver;
[email protected]bb88e1d32013-05-03 23:11:0711216 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2611217 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
11218 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4611219
[email protected]8ddf8322012-02-23 18:08:0611220 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211221 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711222 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4611223
[email protected]cdf8f7e72013-05-23 10:56:4611224 scoped_ptr<SpdyFrame> host1_req(
11225 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
11226 scoped_ptr<SpdyFrame> host2_req(
11227 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4611228 MockWrite spdy_writes[] = {
11229 CreateMockWrite(*host1_req, 1),
11230 CreateMockWrite(*host2_req, 4),
11231 };
[email protected]23e482282013-06-14 16:08:0211232 scoped_ptr<SpdyFrame> host1_resp(
11233 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11234 scoped_ptr<SpdyFrame> host1_resp_body(
11235 spdy_util_.ConstructSpdyBodyFrame(1, true));
11236 scoped_ptr<SpdyFrame> host2_resp(
11237 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11238 scoped_ptr<SpdyFrame> host2_resp_body(
11239 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4611240 MockRead spdy_reads[] = {
11241 CreateMockRead(*host1_resp, 2),
11242 CreateMockRead(*host1_resp_body, 3),
11243 CreateMockRead(*host2_resp, 5),
11244 CreateMockRead(*host2_resp_body, 6),
[email protected]8ddf8322012-02-23 18:08:0611245 MockRead(ASYNC, 0, 7),
[email protected]e3ceb682011-06-28 23:55:4611246 };
11247
[email protected]d2b5f092012-06-08 23:55:0211248 IPAddressNumber ip;
11249 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
11250 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11251 MockConnect connect(ASYNC, OK, peer_addr);
[email protected]dd54bd82012-07-19 23:44:5711252 OrderedSocketData spdy_data(
11253 connect,
11254 spdy_reads, arraysize(spdy_reads),
11255 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711256 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4611257
[email protected]aa22b242011-11-16 18:58:2911258 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4611259 HttpRequestInfo request1;
11260 request1.method = "GET";
11261 request1.url = GURL("https://www.google.com/");
11262 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011263 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611264
[email protected]49639fa2011-12-20 23:22:4111265 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611266 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111267 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611268
11269 const HttpResponseInfo* response = trans1.GetResponseInfo();
11270 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011271 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611272 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11273
11274 std::string response_data;
11275 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
11276 EXPECT_EQ("hello!", response_data);
11277
11278 // Preload cache entries into HostCache.
[email protected]5109c1952013-08-20 18:44:1011279 HostResolver::RequestInfo resolve_info(HostPortPair("www.gmail.com", 443));
[email protected]e3ceb682011-06-28 23:55:4611280 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1011281 rv = host_resolver.Resolve(resolve_info,
11282 DEFAULT_PRIORITY,
11283 &ignored,
11284 callback.callback(),
11285 NULL,
11286 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4711287 EXPECT_EQ(ERR_IO_PENDING, rv);
11288 rv = callback.WaitForResult();
11289 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4611290
11291 HttpRequestInfo request2;
11292 request2.method = "GET";
11293 request2.url = GURL("https://www.gmail.com/");
11294 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011295 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611296
[email protected]49639fa2011-12-20 23:22:4111297 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611298 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111299 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611300
11301 response = trans2.GetResponseInfo();
11302 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011303 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611304 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11305 EXPECT_TRUE(response->was_fetched_via_spdy);
11306 EXPECT_TRUE(response->was_npn_negotiated);
11307 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
11308 EXPECT_EQ("hello!", response_data);
[email protected]88c7b4be2014-03-19 23:04:0111309#endif
[email protected]e3ceb682011-06-28 23:55:4611310}
[email protected]45b170822012-05-04 21:18:1411311#undef MAYBE_UseIPConnectionPoolingWithHostCacheExpiration
[email protected]e3ceb682011-06-28 23:55:4611312
[email protected]23e482282013-06-14 16:08:0211313TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
lgarrona91df87f2014-12-05 00:51:3411314 const std::string https_url = "https://www.google.com:8080/";
11315 const std::string http_url = "http://www.google.com:8080/";
[email protected]8450d722012-07-02 19:14:0411316
11317 // SPDY GET for HTTPS URL
[email protected]cdf8f7e72013-05-23 10:56:4611318 scoped_ptr<SpdyFrame> req1(
11319 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0411320
11321 MockWrite writes1[] = {
11322 CreateMockWrite(*req1, 0),
11323 };
11324
[email protected]23e482282013-06-14 16:08:0211325 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11326 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8450d722012-07-02 19:14:0411327 MockRead reads1[] = {
11328 CreateMockRead(*resp1, 1),
11329 CreateMockRead(*body1, 2),
11330 MockRead(ASYNC, ERR_IO_PENDING, 3)
11331 };
11332
[email protected]dd54bd82012-07-19 23:44:5711333 DelayedSocketData data1(
11334 1, reads1, arraysize(reads1),
11335 writes1, arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0411336 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5711337 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0411338
11339 // HTTP GET for the HTTP URL
11340 MockWrite writes2[] = {
lgarrona91df87f2014-12-05 00:51:3411341 MockWrite(ASYNC, 4,
11342 "GET / HTTP/1.1\r\n"
11343 "Host: www.google.com:8080\r\n"
11344 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0411345 };
11346
11347 MockRead reads2[] = {
11348 MockRead(ASYNC, 5, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
11349 MockRead(ASYNC, 6, "hello"),
11350 MockRead(ASYNC, 7, OK),
11351 };
11352
[email protected]dd54bd82012-07-19 23:44:5711353 DelayedSocketData data2(
11354 1, reads2, arraysize(reads2),
11355 writes2, arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0411356
[email protected]8450d722012-07-02 19:14:0411357 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211358 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711359 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11360 session_deps_.socket_factory->AddSocketDataProvider(&data1);
11361 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0411362
[email protected]bb88e1d32013-05-03 23:11:0711363 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0411364
11365 // Start the first transaction to set up the SpdySession
11366 HttpRequestInfo request1;
11367 request1.method = "GET";
11368 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0411369 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011370 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0411371 TestCompletionCallback callback1;
11372 EXPECT_EQ(ERR_IO_PENDING,
11373 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411374 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411375
11376 EXPECT_EQ(OK, callback1.WaitForResult());
11377 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11378
11379 // Now, start the HTTP request
11380 HttpRequestInfo request2;
11381 request2.method = "GET";
11382 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0411383 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011384 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0411385 TestCompletionCallback callback2;
11386 EXPECT_EQ(ERR_IO_PENDING,
11387 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411388 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411389
11390 EXPECT_EQ(OK, callback2.WaitForResult());
11391 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11392}
11393
[email protected]23e482282013-06-14 16:08:0211394TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
lgarrona91df87f2014-12-05 00:51:3411395 const std::string https_url = "https://www.google.com:8080/";
11396 const std::string http_url = "http://www.google.com:8080/";
[email protected]8450d722012-07-02 19:14:0411397
11398 // SPDY GET for HTTPS URL (through CONNECT tunnel)
lgarrona91df87f2014-12-05 00:51:3411399 const HostPortPair host_port_pair("www.google.com", 8080);
11400 scoped_ptr<SpdyFrame> connect(
11401 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
[email protected]cdf8f7e72013-05-23 10:56:4611402 scoped_ptr<SpdyFrame> req1(
11403 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]23e482282013-06-14 16:08:0211404 scoped_ptr<SpdyFrame> wrapped_req1(
11405 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3911406
11407 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
[email protected]745aa9c2014-06-27 02:21:2911408 SpdyHeaderBlock req2_block;
11409 req2_block[spdy_util_.GetMethodKey()] = "GET";
bnc33b8cef42014-11-19 17:30:3811410 req2_block[spdy_util_.GetPathKey()] = "/";
lgarrona91df87f2014-12-05 00:51:3411411 req2_block[spdy_util_.GetHostKey()] = "www.google.com:8080";
[email protected]745aa9c2014-06-27 02:21:2911412 req2_block[spdy_util_.GetSchemeKey()] = "http";
11413 spdy_util_.MaybeAddVersionHeader(&req2_block);
[email protected]601e03f12014-04-06 16:26:3911414 scoped_ptr<SpdyFrame> req2(
[email protected]745aa9c2014-06-27 02:21:2911415 spdy_util_.ConstructSpdySyn(3, req2_block, MEDIUM, false, true));
[email protected]8450d722012-07-02 19:14:0411416
11417 MockWrite writes1[] = {
11418 CreateMockWrite(*connect, 0),
11419 CreateMockWrite(*wrapped_req1, 2),
11420 CreateMockWrite(*req2, 5),
11421 };
11422
[email protected]23e482282013-06-14 16:08:0211423 scoped_ptr<SpdyFrame> conn_resp(
11424 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11425 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11426 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
11427 scoped_ptr<SpdyFrame> wrapped_resp1(
11428 spdy_util_.ConstructWrappedSpdyFrame(resp1, 1));
11429 scoped_ptr<SpdyFrame> wrapped_body1(
11430 spdy_util_.ConstructWrappedSpdyFrame(body1, 1));
11431 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11432 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]8450d722012-07-02 19:14:0411433 MockRead reads1[] = {
11434 CreateMockRead(*conn_resp, 1),
11435 CreateMockRead(*wrapped_resp1, 3),
11436 CreateMockRead(*wrapped_body1, 4),
11437 CreateMockRead(*resp2, 6),
11438 CreateMockRead(*body2, 7),
11439 MockRead(ASYNC, ERR_IO_PENDING, 8)
11440 };
11441
[email protected]dd54bd82012-07-19 23:44:5711442 DeterministicSocketData data1(reads1, arraysize(reads1),
11443 writes1, arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0411444 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5711445 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0411446
[email protected]bb88e1d32013-05-03 23:11:0711447 session_deps_.proxy_service.reset(
[email protected]f6c63db52013-02-02 00:35:2211448 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
11449 CapturingNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0711450 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0411451 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
[email protected]23e482282013-06-14 16:08:0211452 ssl1.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711453 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0411454 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
[email protected]23e482282013-06-14 16:08:0211455 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711456 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11457 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0411458
11459 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0711460 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]8450d722012-07-02 19:14:0411461
11462 // Start the first transaction to set up the SpdySession
11463 HttpRequestInfo request1;
11464 request1.method = "GET";
11465 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0411466 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011467 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0411468 TestCompletionCallback callback1;
11469 EXPECT_EQ(ERR_IO_PENDING,
11470 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411471 base::MessageLoop::current()->RunUntilIdle();
[email protected]dd54bd82012-07-19 23:44:5711472 data1.RunFor(4);
[email protected]8450d722012-07-02 19:14:0411473
11474 EXPECT_EQ(OK, callback1.WaitForResult());
11475 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11476
[email protected]f6c63db52013-02-02 00:35:2211477 LoadTimingInfo load_timing_info1;
11478 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
11479 TestLoadTimingNotReusedWithPac(load_timing_info1,
11480 CONNECT_TIMING_HAS_SSL_TIMES);
11481
[email protected]8450d722012-07-02 19:14:0411482 // Now, start the HTTP request
11483 HttpRequestInfo request2;
11484 request2.method = "GET";
11485 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0411486 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011487 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0411488 TestCompletionCallback callback2;
11489 EXPECT_EQ(ERR_IO_PENDING,
11490 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411491 base::MessageLoop::current()->RunUntilIdle();
[email protected]dd54bd82012-07-19 23:44:5711492 data1.RunFor(3);
[email protected]8450d722012-07-02 19:14:0411493
11494 EXPECT_EQ(OK, callback2.WaitForResult());
11495 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2211496
11497 LoadTimingInfo load_timing_info2;
11498 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
11499 // The established SPDY sessions is considered reused by the HTTP request.
11500 TestLoadTimingReusedWithPac(load_timing_info2);
11501 // HTTP requests over a SPDY session should have a different connection
11502 // socket_log_id than requests over a tunnel.
11503 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0411504}
11505
[email protected]23e482282013-06-14 16:08:0211506TEST_P(HttpNetworkTransactionTest, UseSpdySessionForHttpWhenForced) {
[email protected]d7599122014-05-24 03:37:2311507 session_deps_.force_spdy_always = true;
lgarrona91df87f2014-12-05 00:51:3411508 const std::string https_url = "https://www.google.com:8080/";
11509 const std::string http_url = "http://www.google.com:8080/";
[email protected]8450d722012-07-02 19:14:0411510
11511 // SPDY GET for HTTPS URL
[email protected]cdf8f7e72013-05-23 10:56:4611512 scoped_ptr<SpdyFrame> req1(
11513 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0411514 // SPDY GET for the HTTP URL
[email protected]cdf8f7e72013-05-23 10:56:4611515 scoped_ptr<SpdyFrame> req2(
11516 spdy_util_.ConstructSpdyGet(http_url.c_str(), false, 3, MEDIUM));
[email protected]8450d722012-07-02 19:14:0411517
11518 MockWrite writes[] = {
11519 CreateMockWrite(*req1, 1),
11520 CreateMockWrite(*req2, 4),
11521 };
11522
[email protected]23e482282013-06-14 16:08:0211523 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11524 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
11525 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11526 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]8450d722012-07-02 19:14:0411527 MockRead reads[] = {
11528 CreateMockRead(*resp1, 2),
11529 CreateMockRead(*body1, 3),
11530 CreateMockRead(*resp2, 5),
11531 CreateMockRead(*body2, 6),
11532 MockRead(ASYNC, ERR_IO_PENDING, 7)
11533 };
11534
[email protected]dd54bd82012-07-19 23:44:5711535 OrderedSocketData data(reads, arraysize(reads),
11536 writes, arraysize(writes));
[email protected]8450d722012-07-02 19:14:0411537
[email protected]8450d722012-07-02 19:14:0411538 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211539 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711540 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11541 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8450d722012-07-02 19:14:0411542
[email protected]bb88e1d32013-05-03 23:11:0711543 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0411544
11545 // Start the first transaction to set up the SpdySession
11546 HttpRequestInfo request1;
11547 request1.method = "GET";
11548 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0411549 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011550 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0411551 TestCompletionCallback callback1;
11552 EXPECT_EQ(ERR_IO_PENDING,
11553 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411554 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411555
11556 EXPECT_EQ(OK, callback1.WaitForResult());
11557 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11558
11559 // Now, start the HTTP request
11560 HttpRequestInfo request2;
11561 request2.method = "GET";
11562 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0411563 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011564 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0411565 TestCompletionCallback callback2;
11566 EXPECT_EQ(ERR_IO_PENDING,
11567 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411568 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411569
11570 EXPECT_EQ(OK, callback2.WaitForResult());
11571 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11572}
11573
[email protected]2d88e7d2012-07-19 17:55:1711574// Test that in the case where we have a SPDY session to a SPDY proxy
11575// that we do not pool other origins that resolve to the same IP when
11576// the certificate does not match the new origin.
11577// http://crbug.com/134690
[email protected]23e482282013-06-14 16:08:0211578TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
[email protected]2d88e7d2012-07-19 17:55:1711579 const std::string url1 = "http://www.google.com/";
11580 const std::string url2 = "https://mail.google.com/";
11581 const std::string ip_addr = "1.2.3.4";
11582
11583 // SPDY GET for HTTP URL (through SPDY proxy)
[email protected]23e482282013-06-14 16:08:0211584 scoped_ptr<SpdyHeaderBlock> headers(
11585 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/"));
[email protected]745aa9c2014-06-27 02:21:2911586 scoped_ptr<SpdyFrame> req1(
11587 spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, false, true));
[email protected]2d88e7d2012-07-19 17:55:1711588
11589 MockWrite writes1[] = {
11590 CreateMockWrite(*req1, 0),
11591 };
11592
[email protected]23e482282013-06-14 16:08:0211593 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11594 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1711595 MockRead reads1[] = {
11596 CreateMockRead(*resp1, 1),
11597 CreateMockRead(*body1, 2),
11598 MockRead(ASYNC, OK, 3) // EOF
11599 };
11600
11601 scoped_ptr<DeterministicSocketData> data1(
11602 new DeterministicSocketData(reads1, arraysize(reads1),
11603 writes1, arraysize(writes1)));
11604 IPAddressNumber ip;
11605 ASSERT_TRUE(ParseIPLiteralToNumber(ip_addr, &ip));
11606 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11607 MockConnect connect_data1(ASYNC, OK, peer_addr);
11608 data1->set_connect_data(connect_data1);
11609
11610 // SPDY GET for HTTPS URL (direct)
[email protected]cdf8f7e72013-05-23 10:56:4611611 scoped_ptr<SpdyFrame> req2(
11612 spdy_util_.ConstructSpdyGet(url2.c_str(), false, 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1711613
11614 MockWrite writes2[] = {
11615 CreateMockWrite(*req2, 0),
11616 };
11617
[email protected]23e482282013-06-14 16:08:0211618 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11619 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1711620 MockRead reads2[] = {
11621 CreateMockRead(*resp2, 1),
11622 CreateMockRead(*body2, 2),
11623 MockRead(ASYNC, OK, 3) // EOF
11624 };
11625
11626 scoped_ptr<DeterministicSocketData> data2(
11627 new DeterministicSocketData(reads2, arraysize(reads2),
11628 writes2, arraysize(writes2)));
11629 MockConnect connect_data2(ASYNC, OK);
11630 data2->set_connect_data(connect_data2);
11631
11632 // Set up a proxy config that sends HTTP requests to a proxy, and
11633 // all others direct.
11634 ProxyConfig proxy_config;
11635 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
11636 CapturingProxyResolver* capturing_proxy_resolver =
11637 new CapturingProxyResolver();
[email protected]bb88e1d32013-05-03 23:11:0711638 session_deps_.proxy_service.reset(new ProxyService(
[email protected]2d88e7d2012-07-19 17:55:1711639 new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver,
11640 NULL));
11641
11642 // Load a valid cert. Note, that this does not need to
11643 // be valid for proxy because the MockSSLClientSocket does
11644 // not actually verify it. But SpdySession will use this
11645 // to see if it is valid for the new origin
[email protected]6cdfd7f2013-02-08 20:40:1511646 base::FilePath certs_dir = GetTestCertsDirectory();
[email protected]2d88e7d2012-07-19 17:55:1711647 scoped_refptr<X509Certificate> server_cert(
11648 ImportCertFromFile(certs_dir, "ok_cert.pem"));
dcheng48459ac22014-08-26 00:46:4111649 ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert.get());
[email protected]2d88e7d2012-07-19 17:55:1711650
11651 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
[email protected]23e482282013-06-14 16:08:0211652 ssl1.SetNextProto(GetParam());
[email protected]2d88e7d2012-07-19 17:55:1711653 ssl1.cert = server_cert;
[email protected]bb88e1d32013-05-03 23:11:0711654 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
11655 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11656 data1.get());
[email protected]2d88e7d2012-07-19 17:55:1711657
11658 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
[email protected]23e482282013-06-14 16:08:0211659 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711660 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11661 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11662 data2.get());
[email protected]2d88e7d2012-07-19 17:55:1711663
[email protected]bb88e1d32013-05-03 23:11:0711664 session_deps_.host_resolver.reset(new MockCachingHostResolver());
11665 session_deps_.host_resolver->rules()->AddRule("mail.google.com", ip_addr);
11666 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1711667
11668 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0711669 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]2d88e7d2012-07-19 17:55:1711670
11671 // Start the first transaction to set up the SpdySession
11672 HttpRequestInfo request1;
11673 request1.method = "GET";
11674 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1711675 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011676 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1711677 TestCompletionCallback callback1;
11678 ASSERT_EQ(ERR_IO_PENDING,
11679 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
11680 data1->RunFor(3);
11681
11682 ASSERT_TRUE(callback1.have_result());
11683 EXPECT_EQ(OK, callback1.WaitForResult());
11684 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11685
11686 // Now, start the HTTP request
11687 HttpRequestInfo request2;
11688 request2.method = "GET";
11689 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1711690 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011691 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1711692 TestCompletionCallback callback2;
11693 EXPECT_EQ(ERR_IO_PENDING,
11694 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411695 base::MessageLoop::current()->RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1711696 data2->RunFor(3);
11697
11698 ASSERT_TRUE(callback2.have_result());
11699 EXPECT_EQ(OK, callback2.WaitForResult());
11700 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11701}
11702
[email protected]85f97342013-04-17 06:12:2411703// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
11704// error) in SPDY session, removes the socket from pool and closes the SPDY
11705// session. Verify that new url's from the same HttpNetworkSession (and a new
11706// SpdySession) do work. http://crbug.com/224701
[email protected]23e482282013-06-14 16:08:0211707TEST_P(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
[email protected]85f97342013-04-17 06:12:2411708 const std::string https_url = "https://www.google.com/";
11709
11710 MockRead reads1[] = {
11711 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
11712 };
11713
11714 scoped_ptr<DeterministicSocketData> data1(
11715 new DeterministicSocketData(reads1, arraysize(reads1), NULL, 0));
11716 data1->SetStop(1);
11717
[email protected]cdf8f7e72013-05-23 10:56:4611718 scoped_ptr<SpdyFrame> req2(
11719 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2411720 MockWrite writes2[] = {
11721 CreateMockWrite(*req2, 0),
11722 };
11723
[email protected]23e482282013-06-14 16:08:0211724 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11725 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]85f97342013-04-17 06:12:2411726 MockRead reads2[] = {
11727 CreateMockRead(*resp2, 1),
11728 CreateMockRead(*body2, 2),
11729 MockRead(ASYNC, OK, 3) // EOF
11730 };
11731
11732 scoped_ptr<DeterministicSocketData> data2(
11733 new DeterministicSocketData(reads2, arraysize(reads2),
11734 writes2, arraysize(writes2)));
11735
[email protected]85f97342013-04-17 06:12:2411736 SSLSocketDataProvider ssl1(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211737 ssl1.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711738 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
11739 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11740 data1.get());
[email protected]85f97342013-04-17 06:12:2411741
11742 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211743 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711744 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11745 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11746 data2.get());
[email protected]85f97342013-04-17 06:12:2411747
11748 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0711749 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]85f97342013-04-17 06:12:2411750
11751 // Start the first transaction to set up the SpdySession and verify that
11752 // connection was closed.
11753 HttpRequestInfo request1;
11754 request1.method = "GET";
11755 request1.url = GURL(https_url);
11756 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011757 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2411758 TestCompletionCallback callback1;
11759 EXPECT_EQ(ERR_IO_PENDING,
11760 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411761 base::MessageLoop::current()->RunUntilIdle();
[email protected]85f97342013-04-17 06:12:2411762 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback1.WaitForResult());
11763
11764 // Now, start the second request and make sure it succeeds.
11765 HttpRequestInfo request2;
11766 request2.method = "GET";
11767 request2.url = GURL(https_url);
11768 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011769 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2411770 TestCompletionCallback callback2;
11771 EXPECT_EQ(ERR_IO_PENDING,
11772 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411773 base::MessageLoop::current()->RunUntilIdle();
[email protected]85f97342013-04-17 06:12:2411774 data2->RunFor(3);
11775
11776 ASSERT_TRUE(callback2.have_result());
11777 EXPECT_EQ(OK, callback2.WaitForResult());
11778 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11779}
11780
[email protected]23e482282013-06-14 16:08:0211781TEST_P(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]d7599122014-05-24 03:37:2311782 session_deps_.next_protos = SpdyNextProtos();
[email protected]483fa202013-05-14 01:07:0311783 ClientSocketPoolManager::set_max_sockets_per_group(
11784 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
11785 ClientSocketPoolManager::set_max_sockets_per_pool(
11786 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
11787
11788 // Use two different hosts with different IPs so they don't get pooled.
11789 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
11790 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
11791 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11792
11793 SSLSocketDataProvider ssl1(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211794 ssl1.SetNextProto(GetParam());
[email protected]483fa202013-05-14 01:07:0311795 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211796 ssl2.SetNextProto(GetParam());
[email protected]483fa202013-05-14 01:07:0311797 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
11798 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
11799
[email protected]cdf8f7e72013-05-23 10:56:4611800 scoped_ptr<SpdyFrame> host1_req(spdy_util_.ConstructSpdyGet(
[email protected]483fa202013-05-14 01:07:0311801 "https://www.a.com", false, 1, DEFAULT_PRIORITY));
11802 MockWrite spdy1_writes[] = {
11803 CreateMockWrite(*host1_req, 1),
11804 };
[email protected]23e482282013-06-14 16:08:0211805 scoped_ptr<SpdyFrame> host1_resp(
11806 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11807 scoped_ptr<SpdyFrame> host1_resp_body(
11808 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0311809 MockRead spdy1_reads[] = {
11810 CreateMockRead(*host1_resp, 2),
11811 CreateMockRead(*host1_resp_body, 3),
11812 MockRead(ASYNC, ERR_IO_PENDING, 4),
11813 };
11814
11815 scoped_ptr<OrderedSocketData> spdy1_data(
11816 new OrderedSocketData(
11817 spdy1_reads, arraysize(spdy1_reads),
11818 spdy1_writes, arraysize(spdy1_writes)));
11819 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
11820
[email protected]cdf8f7e72013-05-23 10:56:4611821 scoped_ptr<SpdyFrame> host2_req(spdy_util_.ConstructSpdyGet(
[email protected]483fa202013-05-14 01:07:0311822 "https://www.b.com", false, 1, DEFAULT_PRIORITY));
11823 MockWrite spdy2_writes[] = {
11824 CreateMockWrite(*host2_req, 1),
11825 };
[email protected]23e482282013-06-14 16:08:0211826 scoped_ptr<SpdyFrame> host2_resp(
11827 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11828 scoped_ptr<SpdyFrame> host2_resp_body(
11829 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0311830 MockRead spdy2_reads[] = {
11831 CreateMockRead(*host2_resp, 2),
11832 CreateMockRead(*host2_resp_body, 3),
11833 MockRead(ASYNC, ERR_IO_PENDING, 4),
11834 };
11835
11836 scoped_ptr<OrderedSocketData> spdy2_data(
11837 new OrderedSocketData(
11838 spdy2_reads, arraysize(spdy2_reads),
11839 spdy2_writes, arraysize(spdy2_writes)));
11840 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
11841
11842 MockWrite http_write[] = {
11843 MockWrite("GET / HTTP/1.1\r\n"
11844 "Host: www.a.com\r\n"
11845 "Connection: keep-alive\r\n\r\n"),
11846 };
11847
11848 MockRead http_read[] = {
11849 MockRead("HTTP/1.1 200 OK\r\n"),
11850 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11851 MockRead("Content-Length: 6\r\n\r\n"),
11852 MockRead("hello!"),
11853 };
11854 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
11855 http_write, arraysize(http_write));
11856 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
11857
11858 HostPortPair host_port_pair_a("www.a.com", 443);
[email protected]e6d017652013-05-17 18:01:4011859 SpdySessionKey spdy_session_key_a(
[email protected]314b03992014-04-01 01:28:5311860 host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0311861 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611862 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0311863
11864 TestCompletionCallback callback;
11865 HttpRequestInfo request1;
11866 request1.method = "GET";
11867 request1.url = GURL("https://www.a.com/");
11868 request1.load_flags = 0;
11869 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5011870 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0311871
11872 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
11873 EXPECT_EQ(ERR_IO_PENDING, rv);
11874 EXPECT_EQ(OK, callback.WaitForResult());
11875
11876 const HttpResponseInfo* response = trans->GetResponseInfo();
11877 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011878 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0311879 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11880 EXPECT_TRUE(response->was_fetched_via_spdy);
11881 EXPECT_TRUE(response->was_npn_negotiated);
11882
11883 std::string response_data;
11884 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11885 EXPECT_EQ("hello!", response_data);
11886 trans.reset();
11887 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2611888 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0311889
11890 HostPortPair host_port_pair_b("www.b.com", 443);
[email protected]e6d017652013-05-17 18:01:4011891 SpdySessionKey spdy_session_key_b(
[email protected]314b03992014-04-01 01:28:5311892 host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0311893 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611894 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0311895 HttpRequestInfo request2;
11896 request2.method = "GET";
11897 request2.url = GURL("https://www.b.com/");
11898 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011899 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0311900
11901 rv = trans->Start(&request2, callback.callback(), BoundNetLog());
11902 EXPECT_EQ(ERR_IO_PENDING, rv);
11903 EXPECT_EQ(OK, callback.WaitForResult());
11904
11905 response = trans->GetResponseInfo();
11906 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011907 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0311908 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11909 EXPECT_TRUE(response->was_fetched_via_spdy);
11910 EXPECT_TRUE(response->was_npn_negotiated);
11911 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11912 EXPECT_EQ("hello!", response_data);
11913 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611914 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0311915 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2611916 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0311917
11918 HostPortPair host_port_pair_a1("www.a.com", 80);
[email protected]e6d017652013-05-17 18:01:4011919 SpdySessionKey spdy_session_key_a1(
[email protected]314b03992014-04-01 01:28:5311920 host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0311921 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611922 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0311923 HttpRequestInfo request3;
11924 request3.method = "GET";
11925 request3.url = GURL("http://www.a.com/");
11926 request3.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011927 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0311928
11929 rv = trans->Start(&request3, callback.callback(), BoundNetLog());
11930 EXPECT_EQ(ERR_IO_PENDING, rv);
11931 EXPECT_EQ(OK, callback.WaitForResult());
11932
11933 response = trans->GetResponseInfo();
11934 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011935 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0311936 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11937 EXPECT_FALSE(response->was_fetched_via_spdy);
11938 EXPECT_FALSE(response->was_npn_negotiated);
11939 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11940 EXPECT_EQ("hello!", response_data);
11941 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611942 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0311943 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611944 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0311945}
11946
[email protected]79e1fd62013-06-20 06:50:0411947TEST_P(HttpNetworkTransactionTest, HttpSyncConnectError) {
11948 HttpRequestInfo request;
11949 request.method = "GET";
11950 request.url = GURL("http://www.google.com/");
11951 request.load_flags = 0;
11952
[email protected]3fe8d2f82013-10-17 08:56:0711953 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0411954 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4111955 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0411956
11957 MockConnect mock_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
11958 StaticSocketDataProvider data;
11959 data.set_connect_data(mock_connect);
11960 session_deps_.socket_factory->AddSocketDataProvider(&data);
11961
11962 TestCompletionCallback callback;
11963
11964 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11965 EXPECT_EQ(ERR_IO_PENDING, rv);
11966
11967 rv = callback.WaitForResult();
11968 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
11969
11970 EXPECT_EQ(NULL, trans->GetResponseInfo());
11971
11972 // We don't care whether this succeeds or fails, but it shouldn't crash.
11973 HttpRequestHeaders request_headers;
11974 trans->GetFullRequestHeaders(&request_headers);
11975}
11976
11977TEST_P(HttpNetworkTransactionTest, HttpAsyncConnectError) {
11978 HttpRequestInfo request;
11979 request.method = "GET";
11980 request.url = GURL("http://www.google.com/");
11981 request.load_flags = 0;
11982
[email protected]3fe8d2f82013-10-17 08:56:0711983 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0411984 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4111985 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0411986
11987 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11988 StaticSocketDataProvider data;
11989 data.set_connect_data(mock_connect);
11990 session_deps_.socket_factory->AddSocketDataProvider(&data);
11991
11992 TestCompletionCallback callback;
11993
11994 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11995 EXPECT_EQ(ERR_IO_PENDING, rv);
11996
11997 rv = callback.WaitForResult();
11998 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
11999
12000 EXPECT_EQ(NULL, trans->GetResponseInfo());
12001
12002 // We don't care whether this succeeds or fails, but it shouldn't crash.
12003 HttpRequestHeaders request_headers;
12004 trans->GetFullRequestHeaders(&request_headers);
12005}
12006
12007TEST_P(HttpNetworkTransactionTest, HttpSyncWriteError) {
12008 HttpRequestInfo request;
12009 request.method = "GET";
12010 request.url = GURL("http://www.google.com/");
12011 request.load_flags = 0;
12012
[email protected]3fe8d2f82013-10-17 08:56:0712013 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412014 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112015 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412016
12017 MockWrite data_writes[] = {
12018 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
12019 };
12020 MockRead data_reads[] = {
12021 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
12022 };
12023
12024 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12025 data_writes, arraysize(data_writes));
12026 session_deps_.socket_factory->AddSocketDataProvider(&data);
12027
12028 TestCompletionCallback callback;
12029
12030 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12031 EXPECT_EQ(ERR_IO_PENDING, rv);
12032
12033 rv = callback.WaitForResult();
12034 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12035
12036 EXPECT_EQ(NULL, trans->GetResponseInfo());
12037
12038 HttpRequestHeaders request_headers;
12039 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12040 EXPECT_TRUE(request_headers.HasHeader("Host"));
12041}
12042
12043TEST_P(HttpNetworkTransactionTest, HttpAsyncWriteError) {
12044 HttpRequestInfo request;
12045 request.method = "GET";
12046 request.url = GURL("http://www.google.com/");
12047 request.load_flags = 0;
12048
[email protected]3fe8d2f82013-10-17 08:56:0712049 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412050 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112051 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412052
12053 MockWrite data_writes[] = {
12054 MockWrite(ASYNC, ERR_CONNECTION_RESET),
12055 };
12056 MockRead data_reads[] = {
12057 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
12058 };
12059
12060 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12061 data_writes, arraysize(data_writes));
12062 session_deps_.socket_factory->AddSocketDataProvider(&data);
12063
12064 TestCompletionCallback callback;
12065
12066 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12067 EXPECT_EQ(ERR_IO_PENDING, rv);
12068
12069 rv = callback.WaitForResult();
12070 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12071
12072 EXPECT_EQ(NULL, trans->GetResponseInfo());
12073
12074 HttpRequestHeaders request_headers;
12075 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12076 EXPECT_TRUE(request_headers.HasHeader("Host"));
12077}
12078
12079TEST_P(HttpNetworkTransactionTest, HttpSyncReadError) {
12080 HttpRequestInfo request;
12081 request.method = "GET";
12082 request.url = GURL("http://www.google.com/");
12083 request.load_flags = 0;
12084
[email protected]3fe8d2f82013-10-17 08:56:0712085 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412086 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112087 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412088
12089 MockWrite data_writes[] = {
12090 MockWrite("GET / HTTP/1.1\r\n"
12091 "Host: www.google.com\r\n"
12092 "Connection: keep-alive\r\n\r\n"),
12093 };
12094 MockRead data_reads[] = {
12095 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
12096 };
12097
12098 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12099 data_writes, arraysize(data_writes));
12100 session_deps_.socket_factory->AddSocketDataProvider(&data);
12101
12102 TestCompletionCallback callback;
12103
12104 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12105 EXPECT_EQ(ERR_IO_PENDING, rv);
12106
12107 rv = callback.WaitForResult();
12108 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12109
12110 EXPECT_EQ(NULL, trans->GetResponseInfo());
12111
12112 HttpRequestHeaders request_headers;
12113 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12114 EXPECT_TRUE(request_headers.HasHeader("Host"));
12115}
12116
12117TEST_P(HttpNetworkTransactionTest, HttpAsyncReadError) {
12118 HttpRequestInfo request;
12119 request.method = "GET";
12120 request.url = GURL("http://www.google.com/");
12121 request.load_flags = 0;
12122
[email protected]3fe8d2f82013-10-17 08:56:0712123 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412124 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112125 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412126
12127 MockWrite data_writes[] = {
12128 MockWrite("GET / HTTP/1.1\r\n"
12129 "Host: www.google.com\r\n"
12130 "Connection: keep-alive\r\n\r\n"),
12131 };
12132 MockRead data_reads[] = {
12133 MockRead(ASYNC, ERR_CONNECTION_RESET),
12134 };
12135
12136 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12137 data_writes, arraysize(data_writes));
12138 session_deps_.socket_factory->AddSocketDataProvider(&data);
12139
12140 TestCompletionCallback callback;
12141
12142 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12143 EXPECT_EQ(ERR_IO_PENDING, rv);
12144
12145 rv = callback.WaitForResult();
12146 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12147
12148 EXPECT_EQ(NULL, trans->GetResponseInfo());
12149
12150 HttpRequestHeaders request_headers;
12151 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12152 EXPECT_TRUE(request_headers.HasHeader("Host"));
12153}
12154
12155TEST_P(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
12156 HttpRequestInfo request;
12157 request.method = "GET";
12158 request.url = GURL("http://www.google.com/");
12159 request.load_flags = 0;
12160 request.extra_headers.SetHeader("X-Foo", "bar");
12161
[email protected]3fe8d2f82013-10-17 08:56:0712162 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412163 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112164 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412165
12166 MockWrite data_writes[] = {
12167 MockWrite("GET / HTTP/1.1\r\n"
12168 "Host: www.google.com\r\n"
12169 "Connection: keep-alive\r\n"
12170 "X-Foo: bar\r\n\r\n"),
12171 };
12172 MockRead data_reads[] = {
12173 MockRead("HTTP/1.1 200 OK\r\n"
12174 "Content-Length: 5\r\n\r\n"
12175 "hello"),
12176 MockRead(ASYNC, ERR_UNEXPECTED),
12177 };
12178
12179 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12180 data_writes, arraysize(data_writes));
12181 session_deps_.socket_factory->AddSocketDataProvider(&data);
12182
12183 TestCompletionCallback callback;
12184
12185 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12186 EXPECT_EQ(ERR_IO_PENDING, rv);
12187
12188 rv = callback.WaitForResult();
12189 EXPECT_EQ(OK, rv);
12190
12191 HttpRequestHeaders request_headers;
12192 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12193 std::string foo;
12194 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
12195 EXPECT_EQ("bar", foo);
12196}
12197
[email protected]bf828982013-08-14 18:01:4712198namespace {
12199
yhiranoa7e05bb2014-11-06 05:40:3912200// Fake HttpStream that simply records calls to SetPriority().
12201class FakeStream : public HttpStream,
[email protected]e86839fd2013-08-14 18:29:0312202 public base::SupportsWeakPtr<FakeStream> {
12203 public:
12204 explicit FakeStream(RequestPriority priority) : priority_(priority) {}
dchengb03027d2014-10-21 12:00:2012205 ~FakeStream() override {}
[email protected]e86839fd2013-08-14 18:29:0312206
12207 RequestPriority priority() const { return priority_; }
12208
dchengb03027d2014-10-21 12:00:2012209 int InitializeStream(const HttpRequestInfo* request_info,
12210 RequestPriority priority,
12211 const BoundNetLog& net_log,
12212 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0312213 return ERR_IO_PENDING;
12214 }
12215
dchengb03027d2014-10-21 12:00:2012216 int SendRequest(const HttpRequestHeaders& request_headers,
12217 HttpResponseInfo* response,
12218 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0312219 ADD_FAILURE();
12220 return ERR_UNEXPECTED;
12221 }
12222
dchengb03027d2014-10-21 12:00:2012223 int ReadResponseHeaders(const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0312224 ADD_FAILURE();
12225 return ERR_UNEXPECTED;
12226 }
12227
dchengb03027d2014-10-21 12:00:2012228 int ReadResponseBody(IOBuffer* buf,
12229 int buf_len,
12230 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0312231 ADD_FAILURE();
12232 return ERR_UNEXPECTED;
12233 }
12234
dchengb03027d2014-10-21 12:00:2012235 void Close(bool not_reusable) override {}
[email protected]e86839fd2013-08-14 18:29:0312236
dchengb03027d2014-10-21 12:00:2012237 bool IsResponseBodyComplete() const override {
[email protected]e86839fd2013-08-14 18:29:0312238 ADD_FAILURE();
12239 return false;
12240 }
12241
dchengb03027d2014-10-21 12:00:2012242 bool CanFindEndOfResponse() const override { return false; }
[email protected]e86839fd2013-08-14 18:29:0312243
dchengb03027d2014-10-21 12:00:2012244 bool IsConnectionReused() const override {
[email protected]e86839fd2013-08-14 18:29:0312245 ADD_FAILURE();
12246 return false;
12247 }
12248
dchengb03027d2014-10-21 12:00:2012249 void SetConnectionReused() override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0312250
dchengb03027d2014-10-21 12:00:2012251 bool IsConnectionReusable() const override {
[email protected]e86839fd2013-08-14 18:29:0312252 ADD_FAILURE();
12253 return false;
12254 }
12255
dchengb03027d2014-10-21 12:00:2012256 int64 GetTotalReceivedBytes() const override {
[email protected]bc92bc972013-12-13 08:32:5912257 ADD_FAILURE();
12258 return 0;
12259 }
12260
dchengb03027d2014-10-21 12:00:2012261 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
[email protected]e86839fd2013-08-14 18:29:0312262 ADD_FAILURE();
12263 return false;
12264 }
12265
dchengb03027d2014-10-21 12:00:2012266 void GetSSLInfo(SSLInfo* ssl_info) override { ADD_FAILURE(); }
12267
12268 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
[email protected]e86839fd2013-08-14 18:29:0312269 ADD_FAILURE();
12270 }
12271
dchengb03027d2014-10-21 12:00:2012272 bool IsSpdyHttpStream() const override {
[email protected]e86839fd2013-08-14 18:29:0312273 ADD_FAILURE();
12274 return false;
12275 }
12276
dchengb03027d2014-10-21 12:00:2012277 void Drain(HttpNetworkSession* session) override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0312278
dchengb03027d2014-10-21 12:00:2012279 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]e86839fd2013-08-14 18:29:0312280
yhiranoa7e05bb2014-11-06 05:40:3912281 UploadProgress GetUploadProgress() const override { return UploadProgress(); }
12282
12283 HttpStream* RenewStreamForAuth() override { return NULL; }
12284
[email protected]e86839fd2013-08-14 18:29:0312285 private:
12286 RequestPriority priority_;
12287
12288 DISALLOW_COPY_AND_ASSIGN(FakeStream);
12289};
12290
12291// Fake HttpStreamRequest that simply records calls to SetPriority()
12292// and vends FakeStreams with its current priority.
[email protected]bf828982013-08-14 18:01:4712293class FakeStreamRequest : public HttpStreamRequest,
12294 public base::SupportsWeakPtr<FakeStreamRequest> {
12295 public:
[email protected]e86839fd2013-08-14 18:29:0312296 FakeStreamRequest(RequestPriority priority,
12297 HttpStreamRequest::Delegate* delegate)
12298 : priority_(priority),
[email protected]831e4a32013-11-14 02:14:4412299 delegate_(delegate),
12300 websocket_stream_create_helper_(NULL) {}
12301
12302 FakeStreamRequest(RequestPriority priority,
12303 HttpStreamRequest::Delegate* delegate,
12304 WebSocketHandshakeStreamBase::CreateHelper* create_helper)
12305 : priority_(priority),
12306 delegate_(delegate),
12307 websocket_stream_create_helper_(create_helper) {}
[email protected]e86839fd2013-08-14 18:29:0312308
dchengb03027d2014-10-21 12:00:2012309 ~FakeStreamRequest() override {}
[email protected]bf828982013-08-14 18:01:4712310
12311 RequestPriority priority() const { return priority_; }
12312
[email protected]831e4a32013-11-14 02:14:4412313 const WebSocketHandshakeStreamBase::CreateHelper*
12314 websocket_stream_create_helper() const {
12315 return websocket_stream_create_helper_;
12316 }
12317
[email protected]e86839fd2013-08-14 18:29:0312318 // Create a new FakeStream and pass it to the request's
12319 // delegate. Returns a weak pointer to the FakeStream.
12320 base::WeakPtr<FakeStream> FinishStreamRequest() {
12321 FakeStream* fake_stream = new FakeStream(priority_);
12322 // Do this before calling OnStreamReady() as OnStreamReady() may
12323 // immediately delete |fake_stream|.
12324 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
12325 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), fake_stream);
12326 return weak_stream;
12327 }
12328
dchengb03027d2014-10-21 12:00:2012329 int RestartTunnelWithProxyAuth(const AuthCredentials& credentials) override {
[email protected]bf828982013-08-14 18:01:4712330 ADD_FAILURE();
12331 return ERR_UNEXPECTED;
12332 }
12333
dchengb03027d2014-10-21 12:00:2012334 LoadState GetLoadState() const override {
[email protected]bf828982013-08-14 18:01:4712335 ADD_FAILURE();
12336 return LoadState();
12337 }
12338
dchengb03027d2014-10-21 12:00:2012339 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]bf828982013-08-14 18:01:4712340
dchengb03027d2014-10-21 12:00:2012341 bool was_npn_negotiated() const override { return false; }
[email protected]bf828982013-08-14 18:01:4712342
dchengb03027d2014-10-21 12:00:2012343 NextProto protocol_negotiated() const override { return kProtoUnknown; }
[email protected]bf828982013-08-14 18:01:4712344
dchengb03027d2014-10-21 12:00:2012345 bool using_spdy() const override { return false; }
[email protected]bf828982013-08-14 18:01:4712346
12347 private:
12348 RequestPriority priority_;
[email protected]e86839fd2013-08-14 18:29:0312349 HttpStreamRequest::Delegate* const delegate_;
[email protected]831e4a32013-11-14 02:14:4412350 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
[email protected]bf828982013-08-14 18:01:4712351
12352 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
12353};
12354
12355// Fake HttpStreamFactory that vends FakeStreamRequests.
12356class FakeStreamFactory : public HttpStreamFactory {
12357 public:
12358 FakeStreamFactory() {}
dchengb03027d2014-10-21 12:00:2012359 ~FakeStreamFactory() override {}
[email protected]bf828982013-08-14 18:01:4712360
12361 // Returns a WeakPtr<> to the last HttpStreamRequest returned by
12362 // RequestStream() (which may be NULL if it was destroyed already).
12363 base::WeakPtr<FakeStreamRequest> last_stream_request() {
12364 return last_stream_request_;
12365 }
12366
dchengb03027d2014-10-21 12:00:2012367 HttpStreamRequest* RequestStream(const HttpRequestInfo& info,
12368 RequestPriority priority,
12369 const SSLConfig& server_ssl_config,
12370 const SSLConfig& proxy_ssl_config,
12371 HttpStreamRequest::Delegate* delegate,
12372 const BoundNetLog& net_log) override {
[email protected]e86839fd2013-08-14 18:29:0312373 FakeStreamRequest* fake_request = new FakeStreamRequest(priority, delegate);
[email protected]bf828982013-08-14 18:01:4712374 last_stream_request_ = fake_request->AsWeakPtr();
12375 return fake_request;
12376 }
12377
dchengb03027d2014-10-21 12:00:2012378 HttpStreamRequest* RequestWebSocketHandshakeStream(
[email protected]bf828982013-08-14 18:01:4712379 const HttpRequestInfo& info,
12380 RequestPriority priority,
12381 const SSLConfig& server_ssl_config,
12382 const SSLConfig& proxy_ssl_config,
12383 HttpStreamRequest::Delegate* delegate,
[email protected]467086b2013-11-12 08:19:4612384 WebSocketHandshakeStreamBase::CreateHelper* create_helper,
mostynbba063d6032014-10-09 11:01:1312385 const BoundNetLog& net_log) override {
[email protected]831e4a32013-11-14 02:14:4412386 FakeStreamRequest* fake_request =
12387 new FakeStreamRequest(priority, delegate, create_helper);
12388 last_stream_request_ = fake_request->AsWeakPtr();
12389 return fake_request;
[email protected]bf828982013-08-14 18:01:4712390 }
12391
dchengb03027d2014-10-21 12:00:2012392 void PreconnectStreams(int num_streams,
12393 const HttpRequestInfo& info,
12394 RequestPriority priority,
12395 const SSLConfig& server_ssl_config,
12396 const SSLConfig& proxy_ssl_config) override {
[email protected]bf828982013-08-14 18:01:4712397 ADD_FAILURE();
12398 }
12399
dchengb03027d2014-10-21 12:00:2012400 const HostMappingRules* GetHostMappingRules() const override {
[email protected]bf828982013-08-14 18:01:4712401 ADD_FAILURE();
12402 return NULL;
12403 }
12404
12405 private:
12406 base::WeakPtr<FakeStreamRequest> last_stream_request_;
12407
12408 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
12409};
12410
[email protected]831e4a32013-11-14 02:14:4412411// TODO(yhirano): Split this class out into a net/websockets file, if it is
12412// worth doing.
12413class FakeWebSocketStreamCreateHelper :
12414 public WebSocketHandshakeStreamBase::CreateHelper {
12415 public:
dchengb03027d2014-10-21 12:00:2012416 WebSocketHandshakeStreamBase* CreateBasicStream(
[email protected]7e841a52013-11-22 09:04:2112417 scoped_ptr<ClientSocketHandle> connection,
mostynbba063d6032014-10-09 11:01:1312418 bool using_proxy) override {
[email protected]831e4a32013-11-14 02:14:4412419 NOTREACHED();
12420 return NULL;
12421 }
12422
dchengb03027d2014-10-21 12:00:2012423 WebSocketHandshakeStreamBase* CreateSpdyStream(
[email protected]831e4a32013-11-14 02:14:4412424 const base::WeakPtr<SpdySession>& session,
mostynbba063d6032014-10-09 11:01:1312425 bool use_relative_url) override {
[email protected]831e4a32013-11-14 02:14:4412426 NOTREACHED();
12427 return NULL;
12428 };
12429
dchengb03027d2014-10-21 12:00:2012430 ~FakeWebSocketStreamCreateHelper() override {}
[email protected]831e4a32013-11-14 02:14:4412431
12432 virtual scoped_ptr<WebSocketStream> Upgrade() {
12433 NOTREACHED();
12434 return scoped_ptr<WebSocketStream>();
12435 }
12436};
12437
[email protected]bf828982013-08-14 18:01:4712438} // namespace
12439
12440// Make sure that HttpNetworkTransaction passes on its priority to its
12441// stream request on start.
12442TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
12443 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12444 HttpNetworkSessionPeer peer(session);
12445 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4412446 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4712447
dcheng48459ac22014-08-26 00:46:4112448 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4712449
12450 ASSERT_TRUE(fake_factory->last_stream_request() == NULL);
12451
12452 HttpRequestInfo request;
12453 TestCompletionCallback callback;
12454 EXPECT_EQ(ERR_IO_PENDING,
12455 trans.Start(&request, callback.callback(), BoundNetLog()));
12456
12457 base::WeakPtr<FakeStreamRequest> fake_request =
12458 fake_factory->last_stream_request();
12459 ASSERT_TRUE(fake_request != NULL);
12460 EXPECT_EQ(LOW, fake_request->priority());
12461}
12462
12463// Make sure that HttpNetworkTransaction passes on its priority
12464// updates to its stream request.
12465TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriority) {
12466 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12467 HttpNetworkSessionPeer peer(session);
12468 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4412469 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4712470
dcheng48459ac22014-08-26 00:46:4112471 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4712472
12473 HttpRequestInfo request;
12474 TestCompletionCallback callback;
12475 EXPECT_EQ(ERR_IO_PENDING,
12476 trans.Start(&request, callback.callback(), BoundNetLog()));
12477
12478 base::WeakPtr<FakeStreamRequest> fake_request =
12479 fake_factory->last_stream_request();
12480 ASSERT_TRUE(fake_request != NULL);
12481 EXPECT_EQ(LOW, fake_request->priority());
12482
12483 trans.SetPriority(LOWEST);
12484 ASSERT_TRUE(fake_request != NULL);
12485 EXPECT_EQ(LOWEST, fake_request->priority());
12486}
12487
[email protected]e86839fd2013-08-14 18:29:0312488// Make sure that HttpNetworkTransaction passes on its priority
12489// updates to its stream.
12490TEST_P(HttpNetworkTransactionTest, SetStreamPriority) {
12491 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12492 HttpNetworkSessionPeer peer(session);
12493 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4412494 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]e86839fd2013-08-14 18:29:0312495
dcheng48459ac22014-08-26 00:46:4112496 HttpNetworkTransaction trans(LOW, session.get());
[email protected]e86839fd2013-08-14 18:29:0312497
12498 HttpRequestInfo request;
12499 TestCompletionCallback callback;
12500 EXPECT_EQ(ERR_IO_PENDING,
12501 trans.Start(&request, callback.callback(), BoundNetLog()));
12502
12503 base::WeakPtr<FakeStreamRequest> fake_request =
12504 fake_factory->last_stream_request();
12505 ASSERT_TRUE(fake_request != NULL);
12506 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
12507 ASSERT_TRUE(fake_stream != NULL);
12508 EXPECT_EQ(LOW, fake_stream->priority());
12509
12510 trans.SetPriority(LOWEST);
12511 EXPECT_EQ(LOWEST, fake_stream->priority());
12512}
12513
[email protected]831e4a32013-11-14 02:14:4412514TEST_P(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
12515 // The same logic needs to be tested for both ws: and wss: schemes, but this
12516 // test is already parameterised on NextProto, so it uses a loop to verify
12517 // that the different schemes work.
12518 std::string test_cases[] = {"ws://www.google.com/", "wss://www.google.com/"};
12519 for (size_t i = 0; i < arraysize(test_cases); ++i) {
12520 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12521 HttpNetworkSessionPeer peer(session);
12522 FakeStreamFactory* fake_factory = new FakeStreamFactory();
12523 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
[email protected]0191b51c2013-11-18 10:55:2312524 peer.SetHttpStreamFactoryForWebSocket(
[email protected]831e4a32013-11-14 02:14:4412525 scoped_ptr<HttpStreamFactory>(fake_factory));
12526
dcheng48459ac22014-08-26 00:46:4112527 HttpNetworkTransaction trans(LOW, session.get());
[email protected]831e4a32013-11-14 02:14:4412528 trans.SetWebSocketHandshakeStreamCreateHelper(
12529 &websocket_stream_create_helper);
12530
12531 HttpRequestInfo request;
12532 TestCompletionCallback callback;
12533 request.method = "GET";
12534 request.url = GURL(test_cases[i]);
12535
12536 EXPECT_EQ(ERR_IO_PENDING,
12537 trans.Start(&request, callback.callback(), BoundNetLog()));
12538
12539 base::WeakPtr<FakeStreamRequest> fake_request =
12540 fake_factory->last_stream_request();
12541 ASSERT_TRUE(fake_request != NULL);
12542 EXPECT_EQ(&websocket_stream_create_helper,
12543 fake_request->websocket_stream_create_helper());
12544 }
12545}
12546
[email protected]043b68c82013-08-22 23:41:5212547// Tests that when a used socket is returned to the SSL socket pool, it's closed
12548// if the transport socket pool is stalled on the global socket limit.
12549TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
12550 ClientSocketPoolManager::set_max_sockets_per_group(
12551 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12552 ClientSocketPoolManager::set_max_sockets_per_pool(
12553 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12554
12555 // Set up SSL request.
12556
12557 HttpRequestInfo ssl_request;
12558 ssl_request.method = "GET";
12559 ssl_request.url = GURL("https://www.google.com/");
12560
12561 MockWrite ssl_writes[] = {
12562 MockWrite("GET / HTTP/1.1\r\n"
12563 "Host: www.google.com\r\n"
12564 "Connection: keep-alive\r\n\r\n"),
12565 };
12566 MockRead ssl_reads[] = {
12567 MockRead("HTTP/1.1 200 OK\r\n"),
12568 MockRead("Content-Length: 11\r\n\r\n"),
12569 MockRead("hello world"),
12570 MockRead(SYNCHRONOUS, OK),
12571 };
12572 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
12573 ssl_writes, arraysize(ssl_writes));
12574 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
12575
12576 SSLSocketDataProvider ssl(ASYNC, OK);
12577 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12578
12579 // Set up HTTP request.
12580
12581 HttpRequestInfo http_request;
12582 http_request.method = "GET";
12583 http_request.url = GURL("http://www.google.com/");
12584
12585 MockWrite http_writes[] = {
12586 MockWrite("GET / HTTP/1.1\r\n"
12587 "Host: www.google.com\r\n"
12588 "Connection: keep-alive\r\n\r\n"),
12589 };
12590 MockRead http_reads[] = {
12591 MockRead("HTTP/1.1 200 OK\r\n"),
12592 MockRead("Content-Length: 7\r\n\r\n"),
12593 MockRead("falafel"),
12594 MockRead(SYNCHRONOUS, OK),
12595 };
12596 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
12597 http_writes, arraysize(http_writes));
12598 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12599
12600 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12601
12602 // Start the SSL request.
12603 TestCompletionCallback ssl_callback;
12604 scoped_ptr<HttpTransaction> ssl_trans(
12605 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12606 ASSERT_EQ(ERR_IO_PENDING,
12607 ssl_trans->Start(&ssl_request, ssl_callback.callback(),
12608 BoundNetLog()));
12609
12610 // Start the HTTP request. Pool should stall.
12611 TestCompletionCallback http_callback;
12612 scoped_ptr<HttpTransaction> http_trans(
12613 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12614 ASSERT_EQ(ERR_IO_PENDING,
12615 http_trans->Start(&http_request, http_callback.callback(),
12616 BoundNetLog()));
dcheng48459ac22014-08-26 00:46:4112617 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5212618
12619 // Wait for response from SSL request.
12620 ASSERT_EQ(OK, ssl_callback.WaitForResult());
12621 std::string response_data;
12622 ASSERT_EQ(OK, ReadTransaction(ssl_trans.get(), &response_data));
12623 EXPECT_EQ("hello world", response_data);
12624
12625 // The SSL socket should automatically be closed, so the HTTP request can
12626 // start.
dcheng48459ac22014-08-26 00:46:4112627 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
12628 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5212629
12630 // The HTTP request can now complete.
12631 ASSERT_EQ(OK, http_callback.WaitForResult());
12632 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
12633 EXPECT_EQ("falafel", response_data);
12634
dcheng48459ac22014-08-26 00:46:4112635 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5212636}
12637
12638// Tests that when a SSL connection is established but there's no corresponding
12639// request that needs it, the new socket is closed if the transport socket pool
12640// is stalled on the global socket limit.
12641TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
12642 ClientSocketPoolManager::set_max_sockets_per_group(
12643 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12644 ClientSocketPoolManager::set_max_sockets_per_pool(
12645 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12646
12647 // Set up an ssl request.
12648
12649 HttpRequestInfo ssl_request;
12650 ssl_request.method = "GET";
12651 ssl_request.url = GURL("https://www.foopy.com/");
12652
12653 // No data will be sent on the SSL socket.
12654 StaticSocketDataProvider ssl_data;
12655 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
12656
12657 SSLSocketDataProvider ssl(ASYNC, OK);
12658 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12659
12660 // Set up HTTP request.
12661
12662 HttpRequestInfo http_request;
12663 http_request.method = "GET";
12664 http_request.url = GURL("http://www.google.com/");
12665
12666 MockWrite http_writes[] = {
12667 MockWrite("GET / HTTP/1.1\r\n"
12668 "Host: www.google.com\r\n"
12669 "Connection: keep-alive\r\n\r\n"),
12670 };
12671 MockRead http_reads[] = {
12672 MockRead("HTTP/1.1 200 OK\r\n"),
12673 MockRead("Content-Length: 7\r\n\r\n"),
12674 MockRead("falafel"),
12675 MockRead(SYNCHRONOUS, OK),
12676 };
12677 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
12678 http_writes, arraysize(http_writes));
12679 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12680
12681 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12682
12683 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
12684 // cancelled when a normal transaction is cancelled.
12685 net::HttpStreamFactory* http_stream_factory = session->http_stream_factory();
12686 net::SSLConfig ssl_config;
12687 session->ssl_config_service()->GetSSLConfig(&ssl_config);
12688 http_stream_factory->PreconnectStreams(1, ssl_request, DEFAULT_PRIORITY,
12689 ssl_config, ssl_config);
dcheng48459ac22014-08-26 00:46:4112690 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5212691
12692 // Start the HTTP request. Pool should stall.
12693 TestCompletionCallback http_callback;
12694 scoped_ptr<HttpTransaction> http_trans(
12695 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12696 ASSERT_EQ(ERR_IO_PENDING,
12697 http_trans->Start(&http_request, http_callback.callback(),
12698 BoundNetLog()));
dcheng48459ac22014-08-26 00:46:4112699 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5212700
12701 // The SSL connection will automatically be closed once the connection is
12702 // established, to let the HTTP request start.
12703 ASSERT_EQ(OK, http_callback.WaitForResult());
12704 std::string response_data;
12705 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
12706 EXPECT_EQ("falafel", response_data);
12707
dcheng48459ac22014-08-26 00:46:4112708 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5212709}
12710
[email protected]02d74a02014-04-23 18:10:5412711TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
12712 ScopedVector<UploadElementReader> element_readers;
12713 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0712714 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5412715
12716 HttpRequestInfo request;
12717 request.method = "POST";
12718 request.url = GURL("http://www.foo.com/");
12719 request.upload_data_stream = &upload_data_stream;
12720 request.load_flags = 0;
12721
12722 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12723 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112724 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5412725 // Send headers successfully, but get an error while sending the body.
12726 MockWrite data_writes[] = {
12727 MockWrite("POST / HTTP/1.1\r\n"
12728 "Host: www.foo.com\r\n"
12729 "Connection: keep-alive\r\n"
12730 "Content-Length: 3\r\n\r\n"),
12731 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
12732 };
12733
12734 MockRead data_reads[] = {
12735 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
12736 MockRead("hello world"),
12737 MockRead(SYNCHRONOUS, OK),
12738 };
12739 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
12740 arraysize(data_writes));
12741 session_deps_.socket_factory->AddSocketDataProvider(&data);
12742
12743 TestCompletionCallback callback;
12744
12745 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12746 EXPECT_EQ(ERR_IO_PENDING, rv);
12747
12748 rv = callback.WaitForResult();
12749 EXPECT_EQ(OK, rv);
12750
12751 const HttpResponseInfo* response = trans->GetResponseInfo();
12752 ASSERT_TRUE(response != NULL);
12753
12754 EXPECT_TRUE(response->headers.get() != NULL);
12755 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
12756
12757 std::string response_data;
12758 rv = ReadTransaction(trans.get(), &response_data);
12759 EXPECT_EQ(OK, rv);
12760 EXPECT_EQ("hello world", response_data);
12761}
12762
12763// This test makes sure the retry logic doesn't trigger when reading an error
12764// response from a server that rejected a POST with a CONNECTION_RESET.
12765TEST_P(HttpNetworkTransactionTest,
12766 PostReadsErrorResponseAfterResetOnReusedSocket) {
12767 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12768 MockWrite data_writes[] = {
12769 MockWrite("GET / HTTP/1.1\r\n"
12770 "Host: www.foo.com\r\n"
12771 "Connection: keep-alive\r\n\r\n"),
12772 MockWrite("POST / HTTP/1.1\r\n"
12773 "Host: www.foo.com\r\n"
12774 "Connection: keep-alive\r\n"
12775 "Content-Length: 3\r\n\r\n"),
12776 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
12777 };
12778
12779 MockRead data_reads[] = {
12780 MockRead("HTTP/1.1 200 Peachy\r\n"
12781 "Content-Length: 14\r\n\r\n"),
12782 MockRead("first response"),
12783 MockRead("HTTP/1.1 400 Not OK\r\n"
12784 "Content-Length: 15\r\n\r\n"),
12785 MockRead("second response"),
12786 MockRead(SYNCHRONOUS, OK),
12787 };
12788 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
12789 arraysize(data_writes));
12790 session_deps_.socket_factory->AddSocketDataProvider(&data);
12791
12792 TestCompletionCallback callback;
12793 HttpRequestInfo request1;
12794 request1.method = "GET";
12795 request1.url = GURL("http://www.foo.com/");
12796 request1.load_flags = 0;
12797
12798 scoped_ptr<HttpTransaction> trans1(
dcheng48459ac22014-08-26 00:46:4112799 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5412800 int rv = trans1->Start(&request1, callback.callback(), BoundNetLog());
12801 EXPECT_EQ(ERR_IO_PENDING, rv);
12802
12803 rv = callback.WaitForResult();
12804 EXPECT_EQ(OK, rv);
12805
12806 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
12807 ASSERT_TRUE(response1 != NULL);
12808
12809 EXPECT_TRUE(response1->headers.get() != NULL);
12810 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
12811
12812 std::string response_data1;
12813 rv = ReadTransaction(trans1.get(), &response_data1);
12814 EXPECT_EQ(OK, rv);
12815 EXPECT_EQ("first response", response_data1);
12816 // Delete the transaction to release the socket back into the socket pool.
12817 trans1.reset();
12818
12819 ScopedVector<UploadElementReader> element_readers;
12820 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0712821 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5412822
12823 HttpRequestInfo request2;
12824 request2.method = "POST";
12825 request2.url = GURL("http://www.foo.com/");
12826 request2.upload_data_stream = &upload_data_stream;
12827 request2.load_flags = 0;
12828
12829 scoped_ptr<HttpTransaction> trans2(
dcheng48459ac22014-08-26 00:46:4112830 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5412831 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
12832 EXPECT_EQ(ERR_IO_PENDING, rv);
12833
12834 rv = callback.WaitForResult();
12835 EXPECT_EQ(OK, rv);
12836
12837 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
12838 ASSERT_TRUE(response2 != NULL);
12839
12840 EXPECT_TRUE(response2->headers.get() != NULL);
12841 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
12842
12843 std::string response_data2;
12844 rv = ReadTransaction(trans2.get(), &response_data2);
12845 EXPECT_EQ(OK, rv);
12846 EXPECT_EQ("second response", response_data2);
12847}
12848
12849TEST_P(HttpNetworkTransactionTest,
12850 PostReadsErrorResponseAfterResetPartialBodySent) {
12851 ScopedVector<UploadElementReader> element_readers;
12852 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0712853 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5412854
12855 HttpRequestInfo request;
12856 request.method = "POST";
12857 request.url = GURL("http://www.foo.com/");
12858 request.upload_data_stream = &upload_data_stream;
12859 request.load_flags = 0;
12860
12861 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12862 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112863 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5412864 // Send headers successfully, but get an error while sending the body.
12865 MockWrite data_writes[] = {
12866 MockWrite("POST / HTTP/1.1\r\n"
12867 "Host: www.foo.com\r\n"
12868 "Connection: keep-alive\r\n"
12869 "Content-Length: 3\r\n\r\n"
12870 "fo"),
12871 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
12872 };
12873
12874 MockRead data_reads[] = {
12875 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
12876 MockRead("hello world"),
12877 MockRead(SYNCHRONOUS, OK),
12878 };
12879 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
12880 arraysize(data_writes));
12881 session_deps_.socket_factory->AddSocketDataProvider(&data);
12882
12883 TestCompletionCallback callback;
12884
12885 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12886 EXPECT_EQ(ERR_IO_PENDING, rv);
12887
12888 rv = callback.WaitForResult();
12889 EXPECT_EQ(OK, rv);
12890
12891 const HttpResponseInfo* response = trans->GetResponseInfo();
12892 ASSERT_TRUE(response != NULL);
12893
12894 EXPECT_TRUE(response->headers.get() != NULL);
12895 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
12896
12897 std::string response_data;
12898 rv = ReadTransaction(trans.get(), &response_data);
12899 EXPECT_EQ(OK, rv);
12900 EXPECT_EQ("hello world", response_data);
12901}
12902
12903// This tests the more common case than the previous test, where headers and
12904// body are not merged into a single request.
12905TEST_P(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
12906 ScopedVector<UploadElementReader> element_readers;
12907 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0712908 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5412909
12910 HttpRequestInfo request;
12911 request.method = "POST";
12912 request.url = GURL("http://www.foo.com/");
12913 request.upload_data_stream = &upload_data_stream;
12914 request.load_flags = 0;
12915
12916 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12917 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112918 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5412919 // Send headers successfully, but get an error while sending the body.
12920 MockWrite data_writes[] = {
12921 MockWrite("POST / HTTP/1.1\r\n"
12922 "Host: www.foo.com\r\n"
12923 "Connection: keep-alive\r\n"
12924 "Transfer-Encoding: chunked\r\n\r\n"),
12925 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
12926 };
12927
12928 MockRead data_reads[] = {
12929 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
12930 MockRead("hello world"),
12931 MockRead(SYNCHRONOUS, OK),
12932 };
12933 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
12934 arraysize(data_writes));
12935 session_deps_.socket_factory->AddSocketDataProvider(&data);
12936
12937 TestCompletionCallback callback;
12938
12939 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12940 EXPECT_EQ(ERR_IO_PENDING, rv);
12941 // Make sure the headers are sent before adding a chunk. This ensures that
12942 // they can't be merged with the body in a single send. Not currently
12943 // necessary since a chunked body is never merged with headers, but this makes
12944 // the test more future proof.
12945 base::RunLoop().RunUntilIdle();
12946
mmenkecbc2b712014-10-09 20:29:0712947 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5412948
12949 rv = callback.WaitForResult();
12950 EXPECT_EQ(OK, rv);
12951
12952 const HttpResponseInfo* response = trans->GetResponseInfo();
12953 ASSERT_TRUE(response != NULL);
12954
12955 EXPECT_TRUE(response->headers.get() != NULL);
12956 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
12957
12958 std::string response_data;
12959 rv = ReadTransaction(trans.get(), &response_data);
12960 EXPECT_EQ(OK, rv);
12961 EXPECT_EQ("hello world", response_data);
12962}
12963
12964TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
12965 ScopedVector<UploadElementReader> element_readers;
12966 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0712967 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5412968
12969 HttpRequestInfo request;
12970 request.method = "POST";
12971 request.url = GURL("http://www.foo.com/");
12972 request.upload_data_stream = &upload_data_stream;
12973 request.load_flags = 0;
12974
12975 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12976 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112977 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5412978
12979 MockWrite data_writes[] = {
12980 MockWrite("POST / HTTP/1.1\r\n"
12981 "Host: www.foo.com\r\n"
12982 "Connection: keep-alive\r\n"
12983 "Content-Length: 3\r\n\r\n"),
12984 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
12985 };
12986
12987 MockRead data_reads[] = {
12988 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
12989 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
12990 MockRead("hello world"),
12991 MockRead(SYNCHRONOUS, OK),
12992 };
12993 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
12994 arraysize(data_writes));
12995 session_deps_.socket_factory->AddSocketDataProvider(&data);
12996
12997 TestCompletionCallback callback;
12998
12999 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13000 EXPECT_EQ(ERR_IO_PENDING, rv);
13001
13002 rv = callback.WaitForResult();
13003 EXPECT_EQ(OK, rv);
13004
13005 const HttpResponseInfo* response = trans->GetResponseInfo();
13006 ASSERT_TRUE(response != NULL);
13007
13008 EXPECT_TRUE(response->headers.get() != NULL);
13009 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
13010
13011 std::string response_data;
13012 rv = ReadTransaction(trans.get(), &response_data);
13013 EXPECT_EQ(OK, rv);
13014 EXPECT_EQ("hello world", response_data);
13015}
13016
13017TEST_P(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
13018 ScopedVector<UploadElementReader> element_readers;
13019 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713020 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413021
13022 HttpRequestInfo request;
13023 request.method = "POST";
13024 request.url = GURL("http://www.foo.com/");
13025 request.upload_data_stream = &upload_data_stream;
13026 request.load_flags = 0;
13027
13028 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13029 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113030 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413031 // Send headers successfully, but get an error while sending the body.
13032 MockWrite data_writes[] = {
13033 MockWrite("POST / HTTP/1.1\r\n"
13034 "Host: www.foo.com\r\n"
13035 "Connection: keep-alive\r\n"
13036 "Content-Length: 3\r\n\r\n"),
13037 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13038 };
13039
13040 MockRead data_reads[] = {
13041 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
13042 MockRead("hello world"),
13043 MockRead(SYNCHRONOUS, OK),
13044 };
13045 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13046 arraysize(data_writes));
13047 session_deps_.socket_factory->AddSocketDataProvider(&data);
13048
13049 TestCompletionCallback callback;
13050
13051 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13052 EXPECT_EQ(ERR_IO_PENDING, rv);
13053
13054 rv = callback.WaitForResult();
13055 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13056
13057 const HttpResponseInfo* response = trans->GetResponseInfo();
13058 EXPECT_TRUE(response == NULL);
13059}
13060
13061TEST_P(HttpNetworkTransactionTest,
13062 PostIgnoresNonErrorResponseAfterResetAnd100) {
13063 ScopedVector<UploadElementReader> element_readers;
13064 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713065 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413066
13067 HttpRequestInfo request;
13068 request.method = "POST";
13069 request.url = GURL("http://www.foo.com/");
13070 request.upload_data_stream = &upload_data_stream;
13071 request.load_flags = 0;
13072
13073 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13074 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113075 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413076 // Send headers successfully, but get an error while sending the body.
13077 MockWrite data_writes[] = {
13078 MockWrite("POST / HTTP/1.1\r\n"
13079 "Host: www.foo.com\r\n"
13080 "Connection: keep-alive\r\n"
13081 "Content-Length: 3\r\n\r\n"),
13082 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13083 };
13084
13085 MockRead data_reads[] = {
13086 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
13087 MockRead("HTTP/1.0 302 Redirect\r\n"),
13088 MockRead("Location: http://somewhere-else.com/\r\n"),
13089 MockRead("Content-Length: 0\r\n\r\n"),
13090 MockRead(SYNCHRONOUS, OK),
13091 };
13092 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13093 arraysize(data_writes));
13094 session_deps_.socket_factory->AddSocketDataProvider(&data);
13095
13096 TestCompletionCallback callback;
13097
13098 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13099 EXPECT_EQ(ERR_IO_PENDING, rv);
13100
13101 rv = callback.WaitForResult();
13102 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13103
13104 const HttpResponseInfo* response = trans->GetResponseInfo();
13105 EXPECT_TRUE(response == NULL);
13106}
13107
13108TEST_P(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
13109 ScopedVector<UploadElementReader> element_readers;
13110 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713111 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413112
13113 HttpRequestInfo request;
13114 request.method = "POST";
13115 request.url = GURL("http://www.foo.com/");
13116 request.upload_data_stream = &upload_data_stream;
13117 request.load_flags = 0;
13118
13119 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13120 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113121 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413122 // Send headers successfully, but get an error while sending the body.
13123 MockWrite data_writes[] = {
13124 MockWrite("POST / HTTP/1.1\r\n"
13125 "Host: www.foo.com\r\n"
13126 "Connection: keep-alive\r\n"
13127 "Content-Length: 3\r\n\r\n"),
13128 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13129 };
13130
13131 MockRead data_reads[] = {
13132 MockRead("HTTP 0.9 rocks!"),
13133 MockRead(SYNCHRONOUS, OK),
13134 };
13135 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13136 arraysize(data_writes));
13137 session_deps_.socket_factory->AddSocketDataProvider(&data);
13138
13139 TestCompletionCallback callback;
13140
13141 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13142 EXPECT_EQ(ERR_IO_PENDING, rv);
13143
13144 rv = callback.WaitForResult();
13145 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13146
13147 const HttpResponseInfo* response = trans->GetResponseInfo();
13148 EXPECT_TRUE(response == NULL);
13149}
13150
13151TEST_P(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
13152 ScopedVector<UploadElementReader> element_readers;
13153 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713154 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413155
13156 HttpRequestInfo request;
13157 request.method = "POST";
13158 request.url = GURL("http://www.foo.com/");
13159 request.upload_data_stream = &upload_data_stream;
13160 request.load_flags = 0;
13161
13162 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13163 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113164 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413165 // Send headers successfully, but get an error while sending the body.
13166 MockWrite data_writes[] = {
13167 MockWrite("POST / HTTP/1.1\r\n"
13168 "Host: www.foo.com\r\n"
13169 "Connection: keep-alive\r\n"
13170 "Content-Length: 3\r\n\r\n"),
13171 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13172 };
13173
13174 MockRead data_reads[] = {
13175 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
13176 MockRead(SYNCHRONOUS, OK),
13177 };
13178 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13179 arraysize(data_writes));
13180 session_deps_.socket_factory->AddSocketDataProvider(&data);
13181
13182 TestCompletionCallback callback;
13183
13184 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13185 EXPECT_EQ(ERR_IO_PENDING, rv);
13186
13187 rv = callback.WaitForResult();
13188 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13189
13190 const HttpResponseInfo* response = trans->GetResponseInfo();
13191 EXPECT_TRUE(response == NULL);
13192}
13193
[email protected]89ceba9a2009-03-21 03:46:0613194} // namespace net