blob: 64e0026668c38ad94ba47f18adfb61ee85b9704a [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]95d88ffe2010-02-04 21:25:3314#include "base/file_util.h"
[email protected]57999812013-02-24 05:40:5215#include "base/files/file_path.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]125ef482013-06-11 18:32:4718#include "base/strings/string_util.h"
[email protected]750b2f3c2013-06-07 18:41:0519#include "base/strings/utf_string_conversions.h"
[email protected]f36a8132011-09-02 18:36:3320#include "base/test/test_file_util.h"
[email protected]277d5942010-08-11 21:02:3521#include "net/base/auth.h"
[email protected]169d0012010-05-10 23:20:1222#include "net/base/capturing_net_log.h"
[email protected]bacff652009-03-31 17:50:3323#include "net/base/completion_callback.h"
[email protected]58e32bb2013-01-21 18:23:2524#include "net/base/load_timing_info.h"
25#include "net/base/load_timing_info_test_util.h"
[email protected]169d0012010-05-10 23:20:1226#include "net/base/net_log.h"
27#include "net/base/net_log_unittest.h"
[email protected]ac790b42009-12-02 04:31:3128#include "net/base/request_priority.h"
initial.commit586acc5fe2008-07-26 22:42:5229#include "net/base/test_completion_callback.h"
[email protected]42fdb452012-11-01 12:44:4030#include "net/base/test_data_directory.h"
[email protected]b2d26cfd2012-12-11 10:36:0631#include "net/base/upload_bytes_element_reader.h"
[email protected]329b68b2012-11-14 17:54:2732#include "net/base/upload_data_stream.h"
[email protected]d98961652012-09-11 20:27:2133#include "net/base/upload_file_element_reader.h"
[email protected]6e7845ae2013-03-29 21:48:1134#include "net/cert/mock_cert_verifier.h"
[email protected]bc71b8772013-04-10 20:55:1635#include "net/dns/host_cache.h"
[email protected]f2cb3cf2013-03-21 01:40:5336#include "net/dns/mock_host_resolver.h"
[email protected]3c32c5f2010-05-18 15:18:1237#include "net/http/http_auth_handler_digest.h"
[email protected]3fd9dae2010-06-21 11:39:0038#include "net/http/http_auth_handler_mock.h"
[email protected]385a4672009-03-11 22:21:2939#include "net/http/http_auth_handler_ntlm.h"
[email protected]0877e3d2009-10-17 22:29:5740#include "net/http/http_basic_stream.h"
initial.commit586acc5fe2008-07-26 22:42:5241#include "net/http/http_network_session.h"
[email protected]87bfa3f2010-09-30 14:54:5642#include "net/http/http_network_session_peer.h"
[email protected]17291a022011-10-10 07:32:5343#include "net/http/http_server_properties_impl.h"
[email protected]0877e3d2009-10-17 22:29:5744#include "net/http/http_stream.h"
[email protected]8e6441ca2010-08-19 05:56:3845#include "net/http/http_stream_factory.h"
initial.commit586acc5fe2008-07-26 22:42:5246#include "net/http/http_transaction_unittest.h"
[email protected]51fff29d2008-12-19 22:17:5347#include "net/proxy/proxy_config_service_fixed.h"
[email protected]631f1322010-04-30 17:59:1148#include "net/proxy/proxy_resolver.h"
49#include "net/proxy/proxy_service.h"
[email protected]f7984fc62009-06-22 23:26:4450#include "net/socket/client_socket_factory.h"
[email protected]483fa202013-05-14 01:07:0351#include "net/socket/client_socket_pool_manager.h"
[email protected]a42dbd142011-11-17 16:42:0252#include "net/socket/mock_client_socket_pool_manager.h"
[email protected]bb88e1d32013-05-03 23:11:0753#include "net/socket/next_proto.h"
[email protected]f7984fc62009-06-22 23:26:4454#include "net/socket/socket_test_util.h"
55#include "net/socket/ssl_client_socket.h"
[email protected]2ff8b312010-04-26 22:20:5456#include "net/spdy/spdy_framer.h"
57#include "net/spdy/spdy_session.h"
58#include "net/spdy/spdy_session_pool.h"
[email protected]23e482282013-06-14 16:08:0259#include "net/spdy/spdy_test_util_common.h"
[email protected]536fd0b2013-03-14 17:41:5760#include "net/ssl/ssl_cert_request_info.h"
61#include "net/ssl/ssl_config_service_defaults.h"
62#include "net/ssl/ssl_info.h"
[email protected]6e7845ae2013-03-29 21:48:1163#include "net/test/cert_test_util.h"
initial.commit586acc5fe2008-07-26 22:42:5264#include "testing/gtest/include/gtest/gtest.h"
[email protected]23887f04f2008-12-02 19:20:1565#include "testing/platform_test.h"
[email protected]795cbf82013-07-22 09:37:2766#include "url/gurl.h"
initial.commit586acc5fe2008-07-26 22:42:5267
68//-----------------------------------------------------------------------------
69
[email protected]13c8a092010-07-29 06:15:4470namespace {
71
[email protected]42cba2fb2013-03-29 19:58:5772const base::string16 kBar(ASCIIToUTF16("bar"));
73const base::string16 kBar2(ASCIIToUTF16("bar2"));
74const base::string16 kBar3(ASCIIToUTF16("bar3"));
75const base::string16 kBaz(ASCIIToUTF16("baz"));
76const base::string16 kFirst(ASCIIToUTF16("first"));
77const base::string16 kFoo(ASCIIToUTF16("foo"));
78const base::string16 kFoo2(ASCIIToUTF16("foo2"));
79const base::string16 kFoo3(ASCIIToUTF16("foo3"));
80const base::string16 kFou(ASCIIToUTF16("fou"));
81const base::string16 kSecond(ASCIIToUTF16("second"));
82const base::string16 kTestingNTLM(ASCIIToUTF16("testing-ntlm"));
83const base::string16 kWrongPassword(ASCIIToUTF16("wrongpassword"));
[email protected]13c8a092010-07-29 06:15:4484
[email protected]e5c026642012-03-17 00:14:0285int GetIdleSocketCountInTransportSocketPool(net::HttpNetworkSession* session) {
86 return session->GetTransportSocketPool(
87 net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IdleSocketCount();
88}
89
90int GetIdleSocketCountInSSLSocketPool(net::HttpNetworkSession* session) {
91 return session->GetSSLSocketPool(
92 net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IdleSocketCount();
93}
94
[email protected]f3da152d2012-06-02 01:00:5795// Takes in a Value created from a NetLogHttpResponseParameter, and returns
96// a JSONified list of headers as a single string. Uses single quotes instead
97// of double quotes for easier comparison. Returns false on failure.
[email protected]ea5ef4c2013-06-13 22:50:2798bool GetHeaders(base::DictionaryValue* params, std::string* headers) {
[email protected]f3da152d2012-06-02 01:00:5799 if (!params)
100 return false;
[email protected]ea5ef4c2013-06-13 22:50:27101 base::ListValue* header_list;
[email protected]f3da152d2012-06-02 01:00:57102 if (!params->GetList("headers", &header_list))
103 return false;
104 std::string double_quote_headers;
105 base::JSONWriter::Write(header_list, &double_quote_headers);
106 ReplaceChars(double_quote_headers, "\"", "'", headers);
107 return true;
108}
109
[email protected]029c83b62013-01-24 05:28:20110// Tests LoadTimingInfo in the case a socket is reused and no PAC script is
111// used.
112void TestLoadTimingReused(const net::LoadTimingInfo& load_timing_info) {
113 EXPECT_TRUE(load_timing_info.socket_reused);
[email protected]58e32bb2013-01-21 18:23:25114 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
115
[email protected]029c83b62013-01-24 05:28:20116 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
117 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
118
119 net::ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
120 EXPECT_FALSE(load_timing_info.send_start.is_null());
[email protected]58e32bb2013-01-21 18:23:25121
122 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]58e32bb2013-01-21 18:23:25123
[email protected]3b23a222013-05-15 21:33:25124 // Set at a higher level.
[email protected]58e32bb2013-01-21 18:23:25125 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
126 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25127 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25128}
129
[email protected]029c83b62013-01-24 05:28:20130// Tests LoadTimingInfo in the case a new socket is used and no PAC script is
131// used.
[email protected]58e32bb2013-01-21 18:23:25132void TestLoadTimingNotReused(const net::LoadTimingInfo& load_timing_info,
133 int connect_timing_flags) {
[email protected]029c83b62013-01-24 05:28:20134 EXPECT_FALSE(load_timing_info.socket_reused);
135 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
136
137 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
138 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
139
140 net::ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
[email protected]3b23a222013-05-15 21:33:25141 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20142 EXPECT_LE(load_timing_info.connect_timing.connect_end,
143 load_timing_info.send_start);
144
145 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20146
[email protected]3b23a222013-05-15 21:33:25147 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20148 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
149 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25150 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20151}
152
153// Tests LoadTimingInfo in the case a socket is reused and a PAC script is
154// used.
155void TestLoadTimingReusedWithPac(const net::LoadTimingInfo& load_timing_info) {
156 EXPECT_TRUE(load_timing_info.socket_reused);
157 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
158
159 net::ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
160
161 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
162 EXPECT_LE(load_timing_info.proxy_resolve_start,
163 load_timing_info.proxy_resolve_end);
164 EXPECT_LE(load_timing_info.proxy_resolve_end,
165 load_timing_info.send_start);
166 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20167
[email protected]3b23a222013-05-15 21:33:25168 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20169 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
170 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25171 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20172}
173
174// Tests LoadTimingInfo in the case a new socket is used and a PAC script is
175// used.
176void TestLoadTimingNotReusedWithPac(const net::LoadTimingInfo& load_timing_info,
177 int connect_timing_flags) {
178 EXPECT_FALSE(load_timing_info.socket_reused);
179 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
180
181 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
182 EXPECT_LE(load_timing_info.proxy_resolve_start,
183 load_timing_info.proxy_resolve_end);
184 EXPECT_LE(load_timing_info.proxy_resolve_end,
185 load_timing_info.connect_timing.connect_start);
186 net::ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
187 connect_timing_flags);
188 EXPECT_LE(load_timing_info.connect_timing.connect_end,
189 load_timing_info.send_start);
190
191 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20192
[email protected]3b23a222013-05-15 21:33:25193 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20194 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
195 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25196 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25197}
198
[email protected]13c8a092010-07-29 06:15:44199} // namespace
200
[email protected]89ceba9a2009-03-21 03:46:06201namespace net {
202
[email protected]448d4ca52012-03-04 04:12:23203namespace {
204
[email protected]c6bf8152012-12-02 07:43:34205HttpNetworkSession* CreateSession(SpdySessionDependencies* session_deps) {
206 return SpdySessionDependencies::SpdyCreateSession(session_deps);
[email protected]e8d536192008-10-17 22:21:14207}
208
[email protected]448d4ca52012-03-04 04:12:23209} // namespace
210
[email protected]23e482282013-06-14 16:08:02211class HttpNetworkTransactionTest
212 : public PlatformTest,
213 public ::testing::WithParamInterface<NextProto> {
[email protected]483fa202013-05-14 01:07:03214 public:
[email protected]23e482282013-06-14 16:08:02215 virtual ~HttpNetworkTransactionTest() {
[email protected]483fa202013-05-14 01:07:03216 // Important to restore the per-pool limit first, since the pool limit must
217 // always be greater than group limit, and the tests reduce both limits.
218 ClientSocketPoolManager::set_max_sockets_per_pool(
219 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
220 ClientSocketPoolManager::set_max_sockets_per_group(
221 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
222 }
223
[email protected]e3ceb682011-06-28 23:55:46224 protected:
[email protected]23e482282013-06-14 16:08:02225 HttpNetworkTransactionTest()
226 : spdy_util_(GetParam()),
227 session_deps_(GetParam()),
[email protected]483fa202013-05-14 01:07:03228 old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
229 HttpNetworkSession::NORMAL_SOCKET_POOL)),
230 old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
231 HttpNetworkSession::NORMAL_SOCKET_POOL)) {
232 }
[email protected]bb88e1d32013-05-03 23:11:07233
[email protected]e3ceb682011-06-28 23:55:46234 struct SimpleGetHelperResult {
235 int rv;
236 std::string status_line;
237 std::string response_data;
[email protected]58e32bb2013-01-21 18:23:25238 LoadTimingInfo load_timing_info;
[email protected]e3ceb682011-06-28 23:55:46239 };
240
[email protected]2ff8b312010-04-26 22:20:54241 virtual void SetUp() {
[email protected]0b0bf032010-09-21 18:08:50242 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:34243 base::MessageLoop::current()->RunUntilIdle();
[email protected]2ff8b312010-04-26 22:20:54244 }
245
[email protected]0e75a732008-10-16 20:36:09246 virtual void TearDown() {
[email protected]0b0bf032010-09-21 18:08:50247 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:34248 base::MessageLoop::current()->RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09249 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:34250 base::MessageLoop::current()->RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09251 PlatformTest::TearDown();
[email protected]0b0bf032010-09-21 18:08:50252 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:34253 base::MessageLoop::current()->RunUntilIdle();
[email protected]c54c6962013-02-01 04:53:19254 HttpStreamFactory::set_use_alternate_protocols(false);
[email protected]0ce3af82013-07-22 16:17:16255 HttpStreamFactory::SetNextProtos(std::vector<NextProto>());
[email protected]0e75a732008-10-16 20:36:09256 }
257
[email protected]8a0fc822013-06-27 20:52:43258 // This is the expected return from a current server advertising SPDY.
259 std::string GetAlternateProtocolHttpHeader() {
260 return
261 std::string("Alternate-Protocol: 443:") +
262 AlternateProtocolToString(AlternateProtocolFromNextProto(GetParam())) +
263 "\r\n\r\n";
264 }
265
[email protected]202965992011-12-07 23:04:51266 // Either |write_failure| specifies a write failure or |read_failure|
267 // specifies a read failure when using a reused socket. In either case, the
268 // failure should cause the network transaction to resend the request, and the
269 // other argument should be NULL.
270 void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
271 const MockRead* read_failure);
initial.commit586acc5fe2008-07-26 22:42:52272
[email protected]5a60c8b2011-10-19 20:14:29273 SimpleGetHelperResult SimpleGetHelperForData(StaticSocketDataProvider* data[],
274 size_t data_count) {
[email protected]ff007e162009-05-23 09:13:15275 SimpleGetHelperResult out;
initial.commit586acc5fe2008-07-26 22:42:52276
[email protected]ff007e162009-05-23 09:13:15277 HttpRequestInfo request;
278 request.method = "GET";
279 request.url = GURL("http://www.google.com/");
280 request.load_flags = 0;
initial.commit586acc5fe2008-07-26 22:42:52281
[email protected]58e32bb2013-01-21 18:23:25282 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:07283 session_deps_.net_log = log.bound().net_log();
[email protected]cb9bf6ca2011-01-28 13:15:27284 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:36285 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:07286 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:27287
[email protected]5a60c8b2011-10-19 20:14:29288 for (size_t i = 0; i < data_count; ++i) {
[email protected]bb88e1d32013-05-03 23:11:07289 session_deps_.socket_factory->AddSocketDataProvider(data[i]);
[email protected]5a60c8b2011-10-19 20:14:29290 }
initial.commit586acc5fe2008-07-26 22:42:52291
[email protected]49639fa2011-12-20 23:22:41292 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52293
[email protected]3deb9a52010-11-11 00:24:40294 EXPECT_TRUE(log.bound().IsLoggingAllEvents());
[email protected]49639fa2011-12-20 23:22:41295 int rv = trans->Start(&request, callback.callback(), log.bound());
[email protected]ff007e162009-05-23 09:13:15296 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:52297
[email protected]ff007e162009-05-23 09:13:15298 out.rv = callback.WaitForResult();
[email protected]58e32bb2013-01-21 18:23:25299
300 // Even in the failure cases that use this function, connections are always
301 // successfully established before the error.
302 EXPECT_TRUE(trans->GetLoadTimingInfo(&out.load_timing_info));
303 TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
304
[email protected]ff007e162009-05-23 09:13:15305 if (out.rv != OK)
306 return out;
307
308 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50309 // Can't use ASSERT_* inside helper functions like this, so
310 // return an error.
[email protected]90499482013-06-01 00:39:50311 if (response == NULL || response->headers.get() == NULL) {
[email protected]fe2255a2011-09-20 19:37:50312 out.rv = ERR_UNEXPECTED;
313 return out;
314 }
[email protected]ff007e162009-05-23 09:13:15315 out.status_line = response->headers->GetStatusLine();
316
[email protected]80a09a82012-11-16 17:40:06317 EXPECT_EQ("127.0.0.1", response->socket_address.host());
318 EXPECT_EQ(80, response->socket_address.port());
[email protected]6d81b482011-02-22 19:47:19319
[email protected]ff007e162009-05-23 09:13:15320 rv = ReadTransaction(trans.get(), &out.response_data);
321 EXPECT_EQ(OK, rv);
[email protected]b2fcd0e2010-12-01 15:19:40322
[email protected]f3da152d2012-06-02 01:00:57323 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:40324 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:39325 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:40326 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
[email protected]169d0012010-05-10 23:20:12327 NetLog::PHASE_NONE);
[email protected]dbb83db2010-05-11 18:13:39328 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:40329 entries, pos,
[email protected]dbb83db2010-05-11 18:13:39330 NetLog::TYPE_HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
331 NetLog::PHASE_NONE);
[email protected]ff007e162009-05-23 09:13:15332
[email protected]f3da152d2012-06-02 01:00:57333 std::string line;
334 EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
335 EXPECT_EQ("GET / HTTP/1.1\r\n", line);
336
[email protected]79e1fd62013-06-20 06:50:04337 HttpRequestHeaders request_headers;
338 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
339 std::string value;
340 EXPECT_TRUE(request_headers.GetHeader("Host", &value));
341 EXPECT_EQ("www.google.com", value);
342 EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
343 EXPECT_EQ("keep-alive", value);
344
345 std::string response_headers;
346 EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
347 EXPECT_EQ("['Host: www.google.com','Connection: keep-alive']",
348 response_headers);
[email protected]3deb9a52010-11-11 00:24:40349
[email protected]aecfbf22008-10-16 02:02:47350 return out;
[email protected]ff007e162009-05-23 09:13:15351 }
initial.commit586acc5fe2008-07-26 22:42:52352
[email protected]5a60c8b2011-10-19 20:14:29353 SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[],
354 size_t reads_count) {
355 StaticSocketDataProvider reads(data_reads, reads_count, NULL, 0);
356 StaticSocketDataProvider* data[] = { &reads };
357 return SimpleGetHelperForData(data, 1);
358 }
359
[email protected]ff007e162009-05-23 09:13:15360 void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
361 int expected_status);
initial.commit586acc5fe2008-07-26 22:42:52362
[email protected]ff007e162009-05-23 09:13:15363 void ConnectStatusHelper(const MockRead& status);
[email protected]bb88e1d32013-05-03 23:11:07364
365 void BypassHostCacheOnRefreshHelper(int load_flags);
366
367 void CheckErrorIsPassedBack(int error, IoMode mode);
368
[email protected]4bd46222013-05-14 19:32:23369 SpdyTestUtil spdy_util_;
[email protected]bb88e1d32013-05-03 23:11:07370 SpdySessionDependencies session_deps_;
[email protected]483fa202013-05-14 01:07:03371
372 // Original socket limits. Some tests set these. Safest to always restore
373 // them once each test has been run.
374 int old_max_group_sockets_;
375 int old_max_pool_sockets_;
[email protected]ff007e162009-05-23 09:13:15376};
[email protected]231d5a32008-09-13 00:45:27377
[email protected]23e482282013-06-14 16:08:02378INSTANTIATE_TEST_CASE_P(
379 NextProto,
380 HttpNetworkTransactionTest,
381 testing::Values(kProtoSPDY2, kProtoSPDY3, kProtoSPDY31, kProtoSPDY4a2));
382
[email protected]448d4ca52012-03-04 04:12:23383namespace {
384
[email protected]15a5ccf82008-10-23 19:57:43385// Fill |str| with a long header list that consumes >= |size| bytes.
386void FillLargeHeadersString(std::string* str, int size) {
[email protected]4ddaf2502008-10-23 18:26:19387 const char* row =
388 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
389 const int sizeof_row = strlen(row);
390 const int num_rows = static_cast<int>(
391 ceil(static_cast<float>(size) / sizeof_row));
392 const int sizeof_data = num_rows * sizeof_row;
393 DCHECK(sizeof_data >= size);
[email protected]15a5ccf82008-10-23 19:57:43394 str->reserve(sizeof_data);
[email protected]372d34a2008-11-05 21:30:51395
[email protected]4ddaf2502008-10-23 18:26:19396 for (int i = 0; i < num_rows; ++i)
[email protected]15a5ccf82008-10-23 19:57:43397 str->append(row, sizeof_row);
[email protected]4ddaf2502008-10-23 18:26:19398}
399
[email protected]385a4672009-03-11 22:21:29400// Alternative functions that eliminate randomness and dependency on the local
401// host name so that the generated NTLM messages are reproducible.
[email protected]fe2bc6a2009-03-23 16:52:20402void MockGenerateRandom1(uint8* output, size_t n) {
[email protected]385a4672009-03-11 22:21:29403 static const uint8 bytes[] = {
404 0x55, 0x29, 0x66, 0x26, 0x6b, 0x9c, 0x73, 0x54
405 };
406 static size_t current_byte = 0;
407 for (size_t i = 0; i < n; ++i) {
408 output[i] = bytes[current_byte++];
409 current_byte %= arraysize(bytes);
410 }
411}
412
[email protected]fe2bc6a2009-03-23 16:52:20413void MockGenerateRandom2(uint8* output, size_t n) {
[email protected]385a4672009-03-11 22:21:29414 static const uint8 bytes[] = {
415 0x96, 0x79, 0x85, 0xe7, 0x49, 0x93, 0x70, 0xa1,
416 0x4e, 0xe7, 0x87, 0x45, 0x31, 0x5b, 0xd3, 0x1f
417 };
418 static size_t current_byte = 0;
419 for (size_t i = 0; i < n; ++i) {
420 output[i] = bytes[current_byte++];
421 current_byte %= arraysize(bytes);
422 }
423}
424
[email protected]fe2bc6a2009-03-23 16:52:20425std::string MockGetHostName() {
426 return "WTC-WIN7";
[email protected]385a4672009-03-11 22:21:29427}
428
[email protected]e60e47a2010-07-14 03:37:18429template<typename ParentPool>
430class CaptureGroupNameSocketPool : public ParentPool {
[email protected]04e5be32009-06-26 20:00:31431 public:
[email protected]9e1bdd32011-02-03 21:48:34432 CaptureGroupNameSocketPool(HostResolver* host_resolver,
433 CertVerifier* cert_verifier);
[email protected]e60e47a2010-07-14 03:37:18434
[email protected]d80a4322009-08-14 07:07:49435 const std::string last_group_name_received() const {
436 return last_group_name_;
437 }
438
[email protected]684970b2009-08-14 04:54:46439 virtual int RequestSocket(const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49440 const void* socket_params,
[email protected]ac790b42009-12-02 04:31:31441 RequestPriority priority,
[email protected]04e5be32009-06-26 20:00:31442 ClientSocketHandle* handle,
[email protected]49639fa2011-12-20 23:22:41443 const CompletionCallback& callback,
[email protected]9e743cd2010-03-16 07:03:53444 const BoundNetLog& net_log) {
[email protected]04e5be32009-06-26 20:00:31445 last_group_name_ = group_name;
446 return ERR_IO_PENDING;
447 }
[email protected]04e5be32009-06-26 20:00:31448 virtual void CancelRequest(const std::string& group_name,
[email protected]05ea9ff2010-07-15 19:08:21449 ClientSocketHandle* handle) {}
[email protected]04e5be32009-06-26 20:00:31450 virtual void ReleaseSocket(const std::string& group_name,
[email protected]3268023f2011-05-05 00:08:10451 StreamSocket* socket,
[email protected]9f95c692011-02-11 19:20:19452 int id) {}
[email protected]04e5be32009-06-26 20:00:31453 virtual void CloseIdleSockets() {}
[email protected]04e5be32009-06-26 20:00:31454 virtual int IdleSocketCount() const {
455 return 0;
456 }
457 virtual int IdleSocketCountInGroup(const std::string& group_name) const {
458 return 0;
459 }
460 virtual LoadState GetLoadState(const std::string& group_name,
461 const ClientSocketHandle* handle) const {
462 return LOAD_STATE_IDLE;
463 }
[email protected]a796bcec2010-03-22 17:17:26464 virtual base::TimeDelta ConnectionTimeout() const {
465 return base::TimeDelta();
466 }
[email protected]d80a4322009-08-14 07:07:49467
468 private:
[email protected]04e5be32009-06-26 20:00:31469 std::string last_group_name_;
470};
471
[email protected]ab739042011-04-07 15:22:28472typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
473CaptureGroupNameTransportSocketPool;
[email protected]e772db3f2010-07-12 18:11:13474typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
475CaptureGroupNameHttpProxySocketPool;
[email protected]2d731a32010-04-29 01:04:06476typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
[email protected]2227c692010-05-04 15:36:11477CaptureGroupNameSOCKSSocketPool;
[email protected]e60e47a2010-07-14 03:37:18478typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
479CaptureGroupNameSSLSocketPool;
480
481template<typename ParentPool>
482CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34483 HostResolver* host_resolver,
484 CertVerifier* /* cert_verifier */)
485 : ParentPool(0, 0, NULL, host_resolver, NULL, NULL) {}
[email protected]e60e47a2010-07-14 03:37:18486
487template<>
[email protected]2df19bb2010-08-25 20:13:46488CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34489 HostResolver* host_resolver,
490 CertVerifier* /* cert_verifier */)
491 : HttpProxyClientSocketPool(0, 0, NULL, host_resolver, NULL, NULL, NULL) {}
[email protected]2df19bb2010-08-25 20:13:46492
[email protected]007b3f82013-04-09 08:46:45493template <>
[email protected]e60e47a2010-07-14 03:37:18494CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34495 HostResolver* host_resolver,
496 CertVerifier* cert_verifier)
[email protected]007b3f82013-04-09 08:46:45497 : SSLClientSocketPool(0,
498 0,
499 NULL,
500 host_resolver,
501 cert_verifier,
502 NULL,
503 NULL,
504 std::string(),
505 NULL,
506 NULL,
507 NULL,
508 NULL,
509 NULL,
510 NULL) {}
[email protected]2227c692010-05-04 15:36:11511
[email protected]231d5a32008-09-13 00:45:27512//-----------------------------------------------------------------------------
513
[email protected]79cb5c12011-09-12 13:12:04514// Helper functions for validating that AuthChallengeInfo's are correctly
515// configured for common cases.
516bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
517 if (!auth_challenge)
518 return false;
519 EXPECT_FALSE(auth_challenge->is_proxy);
520 EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString());
521 EXPECT_EQ("MyRealm1", auth_challenge->realm);
522 EXPECT_EQ("basic", auth_challenge->scheme);
523 return true;
524}
525
526bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
527 if (!auth_challenge)
528 return false;
529 EXPECT_TRUE(auth_challenge->is_proxy);
530 EXPECT_EQ("myproxy:70", auth_challenge->challenger.ToString());
531 EXPECT_EQ("MyRealm1", auth_challenge->realm);
532 EXPECT_EQ("basic", auth_challenge->scheme);
533 return true;
534}
535
536bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
537 if (!auth_challenge)
538 return false;
539 EXPECT_FALSE(auth_challenge->is_proxy);
540 EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString());
541 EXPECT_EQ("digestive", auth_challenge->realm);
542 EXPECT_EQ("digest", auth_challenge->scheme);
543 return true;
544}
545
546bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
547 if (!auth_challenge)
548 return false;
549 EXPECT_FALSE(auth_challenge->is_proxy);
550 EXPECT_EQ("172.22.68.17:80", auth_challenge->challenger.ToString());
551 EXPECT_EQ(std::string(), auth_challenge->realm);
552 EXPECT_EQ("ntlm", auth_challenge->scheme);
553 return true;
554}
555
[email protected]448d4ca52012-03-04 04:12:23556} // namespace
557
[email protected]23e482282013-06-14 16:08:02558TEST_P(HttpNetworkTransactionTest, Basic) {
[email protected]d207a5f2009-06-04 05:28:40559 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:36560 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:07561 CreateSession(&session_deps_)));
[email protected]231d5a32008-09-13 00:45:27562}
563
[email protected]23e482282013-06-14 16:08:02564TEST_P(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27565 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35566 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
567 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06568 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27569 };
[email protected]31a2bfe2010-02-09 08:03:39570 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
571 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42572 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27573 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
574 EXPECT_EQ("hello world", out.response_data);
575}
576
577// Response with no status line.
[email protected]23e482282013-06-14 16:08:02578TEST_P(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27579 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35580 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06581 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27582 };
[email protected]31a2bfe2010-02-09 08:03:39583 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
584 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42585 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27586 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
587 EXPECT_EQ("hello world", out.response_data);
588}
589
590// Allow up to 4 bytes of junk to precede status line.
[email protected]23e482282013-06-14 16:08:02591TEST_P(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27592 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35593 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06594 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27595 };
[email protected]31a2bfe2010-02-09 08:03:39596 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
597 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42598 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27599 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
600 EXPECT_EQ("DATA", out.response_data);
601}
602
603// Allow up to 4 bytes of junk to precede status line.
[email protected]23e482282013-06-14 16:08:02604TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27605 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35606 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06607 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27608 };
[email protected]31a2bfe2010-02-09 08:03:39609 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
610 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42611 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27612 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
613 EXPECT_EQ("DATA", out.response_data);
614}
615
616// Beyond 4 bytes of slop and it should fail to find a status line.
[email protected]23e482282013-06-14 16:08:02617TEST_P(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27618 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35619 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06620 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27621 };
[email protected]31a2bfe2010-02-09 08:03:39622 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
623 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42624 EXPECT_EQ(OK, out.rv);
[email protected]3d2a59b2008-09-26 19:44:25625 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
626 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
[email protected]231d5a32008-09-13 00:45:27627}
628
629// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
[email protected]23e482282013-06-14 16:08:02630TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27631 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35632 MockRead("\n"),
633 MockRead("\n"),
634 MockRead("Q"),
635 MockRead("J"),
636 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06637 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27638 };
[email protected]31a2bfe2010-02-09 08:03:39639 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
640 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42641 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27642 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
643 EXPECT_EQ("DATA", out.response_data);
644}
645
646// Close the connection before enough bytes to have a status line.
[email protected]23e482282013-06-14 16:08:02647TEST_P(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:27648 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35649 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:06650 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27651 };
[email protected]31a2bfe2010-02-09 08:03:39652 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
653 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42654 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27655 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
656 EXPECT_EQ("HTT", out.response_data);
initial.commit586acc5fe2008-07-26 22:42:52657}
658
[email protected]f9d44aa2008-09-23 23:57:17659// Simulate a 204 response, lacking a Content-Length header, sent over a
660// persistent connection. The response should still terminate since a 204
661// cannot have a response body.
[email protected]23e482282013-06-14 16:08:02662TEST_P(HttpNetworkTransactionTest, StopsReading204) {
[email protected]f9d44aa2008-09-23 23:57:17663 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35664 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
665 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:06666 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:17667 };
[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]f9d44aa2008-09-23 23:57:17671 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
672 EXPECT_EQ("", out.response_data);
673}
674
[email protected]0877e3d2009-10-17 22:29:57675// A simple request using chunked encoding with some extra data after.
676// (Like might be seen in a pipelined response.)
[email protected]23e482282013-06-14 16:08:02677TEST_P(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]0877e3d2009-10-17 22:29:57678 MockRead data_reads[] = {
679 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
680 MockRead("5\r\nHello\r\n"),
681 MockRead("1\r\n"),
682 MockRead(" \r\n"),
683 MockRead("5\r\nworld\r\n"),
684 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:06685 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:57686 };
[email protected]31a2bfe2010-02-09 08:03:39687 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
688 arraysize(data_reads));
[email protected]0877e3d2009-10-17 22:29:57689 EXPECT_EQ(OK, out.rv);
690 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
691 EXPECT_EQ("Hello world", out.response_data);
692}
693
[email protected]9fe44f52010-09-23 18:36:00694// Next tests deal with http://crbug.com/56344.
695
[email protected]23e482282013-06-14 16:08:02696TEST_P(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00697 MultipleContentLengthHeadersNoTransferEncoding) {
698 MockRead data_reads[] = {
699 MockRead("HTTP/1.1 200 OK\r\n"),
700 MockRead("Content-Length: 10\r\n"),
701 MockRead("Content-Length: 5\r\n\r\n"),
702 };
703 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
704 arraysize(data_reads));
705 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
706}
707
[email protected]23e482282013-06-14 16:08:02708TEST_P(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04709 DuplicateContentLengthHeadersNoTransferEncoding) {
710 MockRead data_reads[] = {
711 MockRead("HTTP/1.1 200 OK\r\n"),
712 MockRead("Content-Length: 5\r\n"),
713 MockRead("Content-Length: 5\r\n\r\n"),
714 MockRead("Hello"),
715 };
716 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
717 arraysize(data_reads));
718 EXPECT_EQ(OK, out.rv);
719 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
720 EXPECT_EQ("Hello", out.response_data);
721}
722
[email protected]23e482282013-06-14 16:08:02723TEST_P(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04724 ComplexContentLengthHeadersNoTransferEncoding) {
725 // More than 2 dupes.
726 {
727 MockRead data_reads[] = {
728 MockRead("HTTP/1.1 200 OK\r\n"),
729 MockRead("Content-Length: 5\r\n"),
730 MockRead("Content-Length: 5\r\n"),
731 MockRead("Content-Length: 5\r\n\r\n"),
732 MockRead("Hello"),
733 };
734 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
735 arraysize(data_reads));
736 EXPECT_EQ(OK, out.rv);
737 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
738 EXPECT_EQ("Hello", out.response_data);
739 }
740 // HTTP/1.0
741 {
742 MockRead data_reads[] = {
743 MockRead("HTTP/1.0 200 OK\r\n"),
744 MockRead("Content-Length: 5\r\n"),
745 MockRead("Content-Length: 5\r\n"),
746 MockRead("Content-Length: 5\r\n\r\n"),
747 MockRead("Hello"),
748 };
749 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
750 arraysize(data_reads));
751 EXPECT_EQ(OK, out.rv);
752 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
753 EXPECT_EQ("Hello", out.response_data);
754 }
755 // 2 dupes and one mismatched.
756 {
757 MockRead data_reads[] = {
758 MockRead("HTTP/1.1 200 OK\r\n"),
759 MockRead("Content-Length: 10\r\n"),
760 MockRead("Content-Length: 10\r\n"),
761 MockRead("Content-Length: 5\r\n\r\n"),
762 };
763 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
764 arraysize(data_reads));
765 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
766 }
767}
768
[email protected]23e482282013-06-14 16:08:02769TEST_P(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00770 MultipleContentLengthHeadersTransferEncoding) {
771 MockRead data_reads[] = {
772 MockRead("HTTP/1.1 200 OK\r\n"),
773 MockRead("Content-Length: 666\r\n"),
774 MockRead("Content-Length: 1337\r\n"),
775 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
776 MockRead("5\r\nHello\r\n"),
777 MockRead("1\r\n"),
778 MockRead(" \r\n"),
779 MockRead("5\r\nworld\r\n"),
780 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:06781 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:00782 };
783 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
784 arraysize(data_reads));
785 EXPECT_EQ(OK, out.rv);
786 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
787 EXPECT_EQ("Hello world", out.response_data);
788}
789
[email protected]1628fe92011-10-04 23:04:55790// Next tests deal with http://crbug.com/98895.
791
792// Checks that a single Content-Disposition header results in no error.
[email protected]23e482282013-06-14 16:08:02793TEST_P(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:55794 MockRead data_reads[] = {
795 MockRead("HTTP/1.1 200 OK\r\n"),
796 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
797 MockRead("Content-Length: 5\r\n\r\n"),
798 MockRead("Hello"),
799 };
800 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
801 arraysize(data_reads));
802 EXPECT_EQ(OK, out.rv);
803 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
804 EXPECT_EQ("Hello", out.response_data);
805}
806
[email protected]54a9c6e52012-03-21 20:10:59807// Checks that two identical Content-Disposition headers result in no error.
[email protected]23e482282013-06-14 16:08:02808TEST_P(HttpNetworkTransactionTest,
[email protected]54a9c6e52012-03-21 20:10:59809 TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:55810 MockRead data_reads[] = {
811 MockRead("HTTP/1.1 200 OK\r\n"),
812 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
813 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
814 MockRead("Content-Length: 5\r\n\r\n"),
815 MockRead("Hello"),
816 };
817 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
818 arraysize(data_reads));
[email protected]54a9c6e52012-03-21 20:10:59819 EXPECT_EQ(OK, out.rv);
820 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
821 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:55822}
823
824// Checks that two distinct Content-Disposition headers result in an error.
[email protected]23e482282013-06-14 16:08:02825TEST_P(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:55826 MockRead data_reads[] = {
827 MockRead("HTTP/1.1 200 OK\r\n"),
828 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
829 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
830 MockRead("Content-Length: 5\r\n\r\n"),
831 MockRead("Hello"),
832 };
833 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
834 arraysize(data_reads));
835 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION, out.rv);
836}
837
[email protected]54a9c6e52012-03-21 20:10:59838// Checks that two identical Location headers result in no error.
839// Also tests Location header behavior.
[email protected]23e482282013-06-14 16:08:02840TEST_P(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:55841 MockRead data_reads[] = {
842 MockRead("HTTP/1.1 302 Redirect\r\n"),
843 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:59844 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:55845 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:06846 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:55847 };
848
849 HttpRequestInfo request;
850 request.method = "GET";
851 request.url = GURL("http://redirect.com/");
852 request.load_flags = 0;
853
[email protected]1628fe92011-10-04 23:04:55854 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:36855 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:07856 CreateSession(&session_deps_)));
[email protected]1628fe92011-10-04 23:04:55857
858 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:07859 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:55860
[email protected]49639fa2011-12-20 23:22:41861 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:55862
[email protected]49639fa2011-12-20 23:22:41863 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1628fe92011-10-04 23:04:55864 EXPECT_EQ(ERR_IO_PENDING, rv);
865
866 EXPECT_EQ(OK, callback.WaitForResult());
867
868 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]90499482013-06-01 00:39:50869 ASSERT_TRUE(response != NULL && response->headers.get() != NULL);
[email protected]1628fe92011-10-04 23:04:55870 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
871 std::string url;
872 EXPECT_TRUE(response->headers->IsRedirect(&url));
873 EXPECT_EQ("http://good.com/", url);
874}
875
[email protected]1628fe92011-10-04 23:04:55876// Checks that two distinct Location headers result in an error.
[email protected]23e482282013-06-14 16:08:02877TEST_P(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:55878 MockRead data_reads[] = {
879 MockRead("HTTP/1.1 302 Redirect\r\n"),
880 MockRead("Location: http://good.com/\r\n"),
881 MockRead("Location: http://evil.com/\r\n"),
882 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:06883 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:55884 };
885 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
886 arraysize(data_reads));
887 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION, out.rv);
888}
889
[email protected]ef0faf2e72009-03-05 23:27:23890// Do a request using the HEAD method. Verify that we don't try to read the
891// message body (since HEAD has none).
[email protected]23e482282013-06-14 16:08:02892TEST_P(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:42893 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:23894 request.method = "HEAD";
895 request.url = GURL("http://www.google.com/");
896 request.load_flags = 0;
897
[email protected]cb9bf6ca2011-01-28 13:15:27898 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:36899 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:07900 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:27901
[email protected]ef0faf2e72009-03-05 23:27:23902 MockWrite data_writes1[] = {
903 MockWrite("HEAD / HTTP/1.1\r\n"
904 "Host: www.google.com\r\n"
905 "Connection: keep-alive\r\n"
906 "Content-Length: 0\r\n\r\n"),
907 };
908 MockRead data_reads1[] = {
909 MockRead("HTTP/1.1 404 Not Found\r\n"),
910 MockRead("Server: Blah\r\n"),
911 MockRead("Content-Length: 1234\r\n\r\n"),
912
913 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:06914 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]ef0faf2e72009-03-05 23:27:23915 };
916
[email protected]31a2bfe2010-02-09 08:03:39917 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
918 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:07919 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:23920
[email protected]49639fa2011-12-20 23:22:41921 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:23922
[email protected]49639fa2011-12-20 23:22:41923 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:42924 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]ef0faf2e72009-03-05 23:27:23925
926 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:42927 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:23928
[email protected]1c773ea12009-04-28 19:58:42929 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50930 ASSERT_TRUE(response != NULL);
[email protected]ef0faf2e72009-03-05 23:27:23931
932 // Check that the headers got parsed.
[email protected]90499482013-06-01 00:39:50933 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]ef0faf2e72009-03-05 23:27:23934 EXPECT_EQ(1234, response->headers->GetContentLength());
935 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
936
937 std::string server_header;
938 void* iter = NULL;
939 bool has_server_header = response->headers->EnumerateHeader(
940 &iter, "Server", &server_header);
941 EXPECT_TRUE(has_server_header);
942 EXPECT_EQ("Blah", server_header);
943
944 // Reading should give EOF right away, since there is no message body
945 // (despite non-zero content-length).
946 std::string response_data;
947 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:42948 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:23949 EXPECT_EQ("", response_data);
950}
951
[email protected]23e482282013-06-14 16:08:02952TEST_P(HttpNetworkTransactionTest, ReuseConnection) {
[email protected]bb88e1d32013-05-03 23:11:07953 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:52954
955 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35956 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
957 MockRead("hello"),
958 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
959 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:06960 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:52961 };
[email protected]31a2bfe2010-02-09 08:03:39962 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:07963 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:52964
[email protected]0b0bf032010-09-21 18:08:50965 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:52966 "hello", "world"
967 };
968
969 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:42970 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:52971 request.method = "GET";
972 request.url = GURL("http://www.google.com/");
973 request.load_flags = 0;
974
[email protected]262eec82013-03-19 21:01:36975 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:50976 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:27977
[email protected]49639fa2011-12-20 23:22:41978 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52979
[email protected]49639fa2011-12-20 23:22:41980 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:42981 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:52982
983 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:42984 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:52985
[email protected]1c773ea12009-04-28 19:58:42986 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50987 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:52988
[email protected]90499482013-06-01 00:39:50989 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:25990 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:52991
992 std::string response_data;
[email protected]af4876d2008-10-21 23:10:57993 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:42994 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:25995 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:52996 }
997}
998
[email protected]23e482282013-06-14 16:08:02999TEST_P(HttpNetworkTransactionTest, Ignores100) {
[email protected]b2d26cfd2012-12-11 10:36:061000 ScopedVector<UploadElementReader> element_readers;
1001 element_readers.push_back(new UploadBytesElementReader("foo", 3));
1002 UploadDataStream upload_data_stream(&element_readers, 0);
[email protected]329b68b2012-11-14 17:54:271003
[email protected]1c773ea12009-04-28 19:58:421004 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521005 request.method = "POST";
1006 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271007 request.upload_data_stream = &upload_data_stream;
initial.commit586acc5fe2008-07-26 22:42:521008 request.load_flags = 0;
1009
[email protected]cb9bf6ca2011-01-28 13:15:271010 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:361011 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:071012 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:271013
initial.commit586acc5fe2008-07-26 22:42:521014 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351015 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1016 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1017 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061018 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521019 };
[email protected]31a2bfe2010-02-09 08:03:391020 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071021 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521022
[email protected]49639fa2011-12-20 23:22:411023 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521024
[email protected]49639fa2011-12-20 23:22:411025 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421026 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521027
1028 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421029 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521030
[email protected]1c773ea12009-04-28 19:58:421031 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501032 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521033
[email protected]90499482013-06-01 00:39:501034 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251035 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521036
1037 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571038 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421039 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251040 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521041}
1042
[email protected]3a2d3662009-03-27 03:49:141043// This test is almost the same as Ignores100 above, but the response contains
1044// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571045// HTTP/1.1 and the two status headers are read in one read.
[email protected]23e482282013-06-14 16:08:021046TEST_P(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421047 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141048 request.method = "GET";
1049 request.url = GURL("http://www.foo.com/");
1050 request.load_flags = 0;
1051
[email protected]cb9bf6ca2011-01-28 13:15:271052 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:361053 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:071054 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:271055
[email protected]3a2d3662009-03-27 03:49:141056 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571057 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1058 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141059 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061060 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141061 };
[email protected]31a2bfe2010-02-09 08:03:391062 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071063 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141064
[email protected]49639fa2011-12-20 23:22:411065 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141066
[email protected]49639fa2011-12-20 23:22:411067 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421068 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3a2d3662009-03-27 03:49:141069
1070 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421071 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:141072
[email protected]1c773ea12009-04-28 19:58:421073 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501074 ASSERT_TRUE(response != NULL);
[email protected]3a2d3662009-03-27 03:49:141075
[email protected]90499482013-06-01 00:39:501076 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3a2d3662009-03-27 03:49:141077 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1078
1079 std::string response_data;
1080 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421081 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:141082 EXPECT_EQ("hello world", response_data);
1083}
1084
[email protected]23e482282013-06-14 16:08:021085TEST_P(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
[email protected]ee9410e72010-01-07 01:42:381086 HttpRequestInfo request;
1087 request.method = "POST";
1088 request.url = GURL("http://www.foo.com/");
1089 request.load_flags = 0;
1090
[email protected]cb9bf6ca2011-01-28 13:15:271091 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:361092 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:071093 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:271094
[email protected]ee9410e72010-01-07 01:42:381095 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061096 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1097 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381098 };
[email protected]31a2bfe2010-02-09 08:03:391099 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071100 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381101
[email protected]49639fa2011-12-20 23:22:411102 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381103
[email protected]49639fa2011-12-20 23:22:411104 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]ee9410e72010-01-07 01:42:381105 EXPECT_EQ(ERR_IO_PENDING, rv);
1106
1107 rv = callback.WaitForResult();
1108 EXPECT_EQ(OK, rv);
1109
1110 std::string response_data;
1111 rv = ReadTransaction(trans.get(), &response_data);
1112 EXPECT_EQ(OK, rv);
1113 EXPECT_EQ("", response_data);
1114}
1115
[email protected]23e482282013-06-14 16:08:021116TEST_P(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381117 HttpRequestInfo request;
1118 request.method = "POST";
1119 request.url = GURL("http://www.foo.com/");
1120 request.load_flags = 0;
1121
[email protected]cb9bf6ca2011-01-28 13:15:271122 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:361123 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:071124 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:271125
[email protected]ee9410e72010-01-07 01:42:381126 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061127 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381128 };
[email protected]31a2bfe2010-02-09 08:03:391129 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071130 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381131
[email protected]49639fa2011-12-20 23:22:411132 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381133
[email protected]49639fa2011-12-20 23:22:411134 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]ee9410e72010-01-07 01:42:381135 EXPECT_EQ(ERR_IO_PENDING, rv);
1136
1137 rv = callback.WaitForResult();
1138 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
1139}
1140
[email protected]23e482282013-06-14 16:08:021141void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511142 const MockWrite* write_failure,
1143 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421144 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521145 request.method = "GET";
1146 request.url = GURL("http://www.foo.com/");
1147 request.load_flags = 0;
1148
[email protected]58e32bb2013-01-21 18:23:251149 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071150 session_deps_.net_log = &net_log;
1151 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271152
[email protected]202965992011-12-07 23:04:511153 // Written data for successfully sending both requests.
1154 MockWrite data1_writes[] = {
1155 MockWrite("GET / HTTP/1.1\r\n"
1156 "Host: www.foo.com\r\n"
1157 "Connection: keep-alive\r\n\r\n"),
1158 MockWrite("GET / HTTP/1.1\r\n"
1159 "Host: www.foo.com\r\n"
1160 "Connection: keep-alive\r\n\r\n")
1161 };
1162
1163 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521164 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351165 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1166 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061167 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521168 };
[email protected]202965992011-12-07 23:04:511169
1170 if (write_failure) {
1171 ASSERT_TRUE(!read_failure);
1172 data1_writes[1] = *write_failure;
1173 } else {
1174 ASSERT_TRUE(read_failure);
1175 data1_reads[2] = *read_failure;
1176 }
1177
1178 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
1179 data1_writes, arraysize(data1_writes));
[email protected]bb88e1d32013-05-03 23:11:071180 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521181
1182 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351183 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1184 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061185 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521186 };
[email protected]31a2bfe2010-02-09 08:03:391187 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071188 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521189
1190 const char* kExpectedResponseData[] = {
1191 "hello", "world"
1192 };
1193
[email protected]58e32bb2013-01-21 18:23:251194 uint32 first_socket_log_id = NetLog::Source::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521195 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411196 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521197
[email protected]262eec82013-03-19 21:01:361198 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501199 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
initial.commit586acc5fe2008-07-26 22:42:521200
[email protected]49639fa2011-12-20 23:22:411201 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421202 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521203
1204 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421205 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521206
[email protected]58e32bb2013-01-21 18:23:251207 LoadTimingInfo load_timing_info;
1208 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1209 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1210 if (i == 0) {
1211 first_socket_log_id = load_timing_info.socket_log_id;
1212 } else {
1213 // The second request should be using a new socket.
1214 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1215 }
1216
[email protected]1c773ea12009-04-28 19:58:421217 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501218 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521219
[email protected]90499482013-06-01 00:39:501220 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251221 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521222
1223 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571224 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421225 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251226 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521227 }
1228}
[email protected]3d2a59b2008-09-26 19:44:251229
[email protected]23e482282013-06-14 16:08:021230TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:231231 KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061232 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]202965992011-12-07 23:04:511233 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1234}
1235
[email protected]23e482282013-06-14 16:08:021236TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061237 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]202965992011-12-07 23:04:511238 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251239}
1240
[email protected]23e482282013-06-14 16:08:021241TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061242 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]202965992011-12-07 23:04:511243 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251244}
1245
[email protected]23e482282013-06-14 16:08:021246TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:421247 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:251248 request.method = "GET";
1249 request.url = GURL("http://www.google.com/");
1250 request.load_flags = 0;
1251
[email protected]cb9bf6ca2011-01-28 13:15:271252 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:361253 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:071254 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:271255
[email protected]3d2a59b2008-09-26 19:44:251256 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061257 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:351258 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1259 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061260 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251261 };
[email protected]31a2bfe2010-02-09 08:03:391262 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071263 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:251264
[email protected]49639fa2011-12-20 23:22:411265 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:251266
[email protected]49639fa2011-12-20 23:22:411267 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421268 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3d2a59b2008-09-26 19:44:251269
1270 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421271 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]3d2a59b2008-09-26 19:44:251272
[email protected]1c773ea12009-04-28 19:58:421273 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]3d2a59b2008-09-26 19:44:251274 EXPECT_TRUE(response == NULL);
[email protected]3d2a59b2008-09-26 19:44:251275}
1276
1277// What do various browsers do when the server closes a non-keepalive
1278// connection without sending any response header or body?
1279//
1280// IE7: error page
1281// Safari 3.1.2 (Windows): error page
1282// Firefox 3.0.1: blank page
1283// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:421284// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1285// Us: error page (EMPTY_RESPONSE)
[email protected]23e482282013-06-14 16:08:021286TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:251287 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061288 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:351289 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1290 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061291 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251292 };
[email protected]31a2bfe2010-02-09 08:03:391293 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1294 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:421295 EXPECT_EQ(ERR_EMPTY_RESPONSE, out.rv);
[email protected]3d2a59b2008-09-26 19:44:251296}
[email protected]038e9a32008-10-08 22:40:161297
[email protected]7a5378b2012-11-04 03:25:171298// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
1299// tests. There was a bug causing HttpNetworkTransaction to hang in the
1300// destructor in such situations.
1301// See http://crbug.com/154712 and http://crbug.com/156609.
[email protected]23e482282013-06-14 16:08:021302TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:171303 HttpRequestInfo request;
1304 request.method = "GET";
1305 request.url = GURL("http://www.google.com/");
1306 request.load_flags = 0;
1307
[email protected]bb88e1d32013-05-03 23:11:071308 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:361309 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501310 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171311
1312 MockRead data_reads[] = {
1313 MockRead("HTTP/1.0 200 OK\r\n"),
1314 MockRead("Connection: keep-alive\r\n"),
1315 MockRead("Content-Length: 100\r\n\r\n"),
1316 MockRead("hello"),
1317 MockRead(SYNCHRONOUS, 0),
1318 };
1319 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071320 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171321
1322 TestCompletionCallback callback;
1323
1324 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1325 EXPECT_EQ(ERR_IO_PENDING, rv);
1326
1327 rv = callback.WaitForResult();
1328 EXPECT_EQ(OK, rv);
1329
1330 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501331 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171332 if (rv == ERR_IO_PENDING)
1333 rv = callback.WaitForResult();
1334 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:501335 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171336 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1337
1338 trans.reset();
[email protected]2da659e2013-05-23 20:51:341339 base::MessageLoop::current()->RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171340 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1341}
1342
[email protected]23e482282013-06-14 16:08:021343TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:171344 HttpRequestInfo request;
1345 request.method = "GET";
1346 request.url = GURL("http://www.google.com/");
1347 request.load_flags = 0;
1348
[email protected]bb88e1d32013-05-03 23:11:071349 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:361350 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501351 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171352
1353 MockRead data_reads[] = {
1354 MockRead("HTTP/1.0 200 OK\r\n"),
1355 MockRead("Connection: keep-alive\r\n"),
1356 MockRead("Content-Length: 100\r\n\r\n"),
1357 MockRead(SYNCHRONOUS, 0),
1358 };
1359 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071360 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171361
1362 TestCompletionCallback callback;
1363
1364 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1365 EXPECT_EQ(ERR_IO_PENDING, rv);
1366
1367 rv = callback.WaitForResult();
1368 EXPECT_EQ(OK, rv);
1369
1370 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501371 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171372 if (rv == ERR_IO_PENDING)
1373 rv = callback.WaitForResult();
1374 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1375
1376 trans.reset();
[email protected]2da659e2013-05-23 20:51:341377 base::MessageLoop::current()->RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171378 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1379}
1380
[email protected]0b0bf032010-09-21 18:08:501381// Test that we correctly reuse a keep-alive connection after not explicitly
1382// reading the body.
[email protected]23e482282013-06-14 16:08:021383TEST_P(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:131384 HttpRequestInfo request;
1385 request.method = "GET";
1386 request.url = GURL("http://www.foo.com/");
1387 request.load_flags = 0;
1388
[email protected]58e32bb2013-01-21 18:23:251389 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071390 session_deps_.net_log = &net_log;
1391 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271392
[email protected]0b0bf032010-09-21 18:08:501393 // Note that because all these reads happen in the same
1394 // StaticSocketDataProvider, it shows that the same socket is being reused for
1395 // all transactions.
[email protected]fc31d6a42010-06-24 18:05:131396 MockRead data1_reads[] = {
[email protected]0b0bf032010-09-21 18:08:501397 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
1398 MockRead("HTTP/1.1 205 Reset Content\r\n\r\n"),
[email protected]fc31d6a42010-06-24 18:05:131399 MockRead("HTTP/1.1 304 Not Modified\r\n\r\n"),
[email protected]0b0bf032010-09-21 18:08:501400 MockRead("HTTP/1.1 302 Found\r\n"
1401 "Content-Length: 0\r\n\r\n"),
1402 MockRead("HTTP/1.1 302 Found\r\n"
1403 "Content-Length: 5\r\n\r\n"
1404 "hello"),
1405 MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1406 "Content-Length: 0\r\n\r\n"),
1407 MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1408 "Content-Length: 5\r\n\r\n"
1409 "hello"),
[email protected]fc31d6a42010-06-24 18:05:131410 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1411 MockRead("hello"),
1412 };
1413 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071414 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]fc31d6a42010-06-24 18:05:131415
1416 MockRead data2_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061417 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]fc31d6a42010-06-24 18:05:131418 };
1419 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071420 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]fc31d6a42010-06-24 18:05:131421
[email protected]0b0bf032010-09-21 18:08:501422 const int kNumUnreadBodies = arraysize(data1_reads) - 2;
1423 std::string response_lines[kNumUnreadBodies];
1424
[email protected]58e32bb2013-01-21 18:23:251425 uint32 first_socket_log_id = NetLog::Source::kInvalidId;
[email protected]0b0bf032010-09-21 18:08:501426 for (size_t i = 0; i < arraysize(data1_reads) - 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411427 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:131428
[email protected]262eec82013-03-19 21:01:361429 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501430 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]fc31d6a42010-06-24 18:05:131431
[email protected]49639fa2011-12-20 23:22:411432 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]fc31d6a42010-06-24 18:05:131433 EXPECT_EQ(ERR_IO_PENDING, rv);
1434
1435 rv = callback.WaitForResult();
1436 EXPECT_EQ(OK, rv);
1437
[email protected]58e32bb2013-01-21 18:23:251438 LoadTimingInfo load_timing_info;
1439 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1440 if (i == 0) {
1441 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1442 first_socket_log_id = load_timing_info.socket_log_id;
1443 } else {
1444 TestLoadTimingReused(load_timing_info);
1445 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
1446 }
1447
[email protected]fc31d6a42010-06-24 18:05:131448 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]0b0bf032010-09-21 18:08:501449 ASSERT_TRUE(response != NULL);
[email protected]fc31d6a42010-06-24 18:05:131450
[email protected]90499482013-06-01 00:39:501451 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]0b0bf032010-09-21 18:08:501452 response_lines[i] = response->headers->GetStatusLine();
1453
1454 // We intentionally don't read the response bodies.
[email protected]fc31d6a42010-06-24 18:05:131455 }
[email protected]0b0bf032010-09-21 18:08:501456
1457 const char* const kStatusLines[] = {
1458 "HTTP/1.1 204 No Content",
1459 "HTTP/1.1 205 Reset Content",
1460 "HTTP/1.1 304 Not Modified",
1461 "HTTP/1.1 302 Found",
1462 "HTTP/1.1 302 Found",
1463 "HTTP/1.1 301 Moved Permanently",
1464 "HTTP/1.1 301 Moved Permanently",
1465 };
1466
1467 COMPILE_ASSERT(kNumUnreadBodies == arraysize(kStatusLines),
1468 forgot_to_update_kStatusLines);
1469
1470 for (int i = 0; i < kNumUnreadBodies; ++i)
1471 EXPECT_EQ(kStatusLines[i], response_lines[i]);
1472
[email protected]49639fa2011-12-20 23:22:411473 TestCompletionCallback callback;
[email protected]262eec82013-03-19 21:01:361474 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501475 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:411476 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0b0bf032010-09-21 18:08:501477 EXPECT_EQ(ERR_IO_PENDING, rv);
1478 rv = callback.WaitForResult();
1479 EXPECT_EQ(OK, rv);
1480 const HttpResponseInfo* response = trans->GetResponseInfo();
1481 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:501482 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]0b0bf032010-09-21 18:08:501483 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1484 std::string response_data;
1485 rv = ReadTransaction(trans.get(), &response_data);
1486 EXPECT_EQ(OK, rv);
1487 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:131488}
1489
[email protected]038e9a32008-10-08 22:40:161490// Test the request-challenge-retry sequence for basic auth.
1491// (basic auth is the easiest to mock, because it has no randomness).
[email protected]23e482282013-06-14 16:08:021492TEST_P(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:421493 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:161494 request.method = "GET";
1495 request.url = GURL("http://www.google.com/");
1496 request.load_flags = 0;
1497
[email protected]58e32bb2013-01-21 18:23:251498 CapturingNetLog log;
[email protected]bb88e1d32013-05-03 23:11:071499 session_deps_.net_log = &log;
[email protected]cb9bf6ca2011-01-28 13:15:271500 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:361501 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:071502 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:271503
[email protected]f9ee6b52008-11-08 06:46:231504 MockWrite data_writes1[] = {
1505 MockWrite("GET / HTTP/1.1\r\n"
1506 "Host: www.google.com\r\n"
1507 "Connection: keep-alive\r\n\r\n"),
1508 };
1509
[email protected]038e9a32008-10-08 22:40:161510 MockRead data_reads1[] = {
1511 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
1512 // Give a couple authenticate options (only the middle one is actually
1513 // supported).
[email protected]22927ad2009-09-21 19:56:191514 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:161515 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1516 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
1517 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1518 // Large content-length -- won't matter, as connection will be reset.
1519 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061520 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:161521 };
1522
1523 // After calling trans->RestartWithAuth(), this is the request we should
1524 // be issuing -- the final header line contains the credentials.
1525 MockWrite data_writes2[] = {
1526 MockWrite("GET / HTTP/1.1\r\n"
1527 "Host: www.google.com\r\n"
1528 "Connection: keep-alive\r\n"
1529 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1530 };
1531
1532 // Lastly, the server responds with the actual content.
1533 MockRead data_reads2[] = {
1534 MockRead("HTTP/1.0 200 OK\r\n"),
1535 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1536 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061537 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:161538 };
1539
[email protected]31a2bfe2010-02-09 08:03:391540 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1541 data_writes1, arraysize(data_writes1));
1542 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1543 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:071544 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1545 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:161546
[email protected]49639fa2011-12-20 23:22:411547 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:161548
[email protected]49639fa2011-12-20 23:22:411549 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421550 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:161551
1552 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421553 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:161554
[email protected]58e32bb2013-01-21 18:23:251555 LoadTimingInfo load_timing_info1;
1556 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
1557 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
1558
[email protected]1c773ea12009-04-28 19:58:421559 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501560 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:041561 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:161562
[email protected]49639fa2011-12-20 23:22:411563 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:161564
[email protected]49639fa2011-12-20 23:22:411565 rv = trans->RestartWithAuth(
1566 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:421567 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:161568
1569 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421570 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:161571
[email protected]58e32bb2013-01-21 18:23:251572 LoadTimingInfo load_timing_info2;
1573 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
1574 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
1575 // The load timing after restart should have a new socket ID, and times after
1576 // those of the first load timing.
1577 EXPECT_LE(load_timing_info1.receive_headers_end,
1578 load_timing_info2.connect_timing.connect_start);
1579 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
1580
[email protected]038e9a32008-10-08 22:40:161581 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501582 ASSERT_TRUE(response != NULL);
[email protected]038e9a32008-10-08 22:40:161583 EXPECT_TRUE(response->auth_challenge.get() == NULL);
1584 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:161585}
1586
[email protected]23e482282013-06-14 16:08:021587TEST_P(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:461588 HttpRequestInfo request;
1589 request.method = "GET";
1590 request.url = GURL("http://www.google.com/");
1591 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
1592
[email protected]cb9bf6ca2011-01-28 13:15:271593 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:361594 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:071595 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:271596
[email protected]861fcd52009-08-26 02:33:461597 MockWrite data_writes[] = {
1598 MockWrite("GET / HTTP/1.1\r\n"
1599 "Host: www.google.com\r\n"
1600 "Connection: keep-alive\r\n\r\n"),
1601 };
1602
1603 MockRead data_reads[] = {
1604 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
1605 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1606 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1607 // Large content-length -- won't matter, as connection will be reset.
1608 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061609 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:461610 };
1611
[email protected]31a2bfe2010-02-09 08:03:391612 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
1613 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:071614 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:411615 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:461616
[email protected]49639fa2011-12-20 23:22:411617 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]861fcd52009-08-26 02:33:461618 EXPECT_EQ(ERR_IO_PENDING, rv);
1619
1620 rv = callback.WaitForResult();
1621 EXPECT_EQ(0, rv);
1622
1623 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501624 ASSERT_TRUE(response != NULL);
[email protected]861fcd52009-08-26 02:33:461625 EXPECT_TRUE(response->auth_challenge.get() == NULL);
1626}
1627
[email protected]2d2697f92009-02-18 21:00:321628// Test the request-challenge-retry sequence for basic auth, over a keep-alive
1629// connection.
[email protected]23e482282013-06-14 16:08:021630TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
[email protected]1c773ea12009-04-28 19:58:421631 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:321632 request.method = "GET";
1633 request.url = GURL("http://www.google.com/");
1634 request.load_flags = 0;
1635
[email protected]58e32bb2013-01-21 18:23:251636 CapturingNetLog log;
[email protected]bb88e1d32013-05-03 23:11:071637 session_deps_.net_log = &log;
1638 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271639
[email protected]2d2697f92009-02-18 21:00:321640 MockWrite data_writes1[] = {
1641 MockWrite("GET / HTTP/1.1\r\n"
1642 "Host: www.google.com\r\n"
1643 "Connection: keep-alive\r\n\r\n"),
1644
1645 // After calling trans->RestartWithAuth(), this is the request we should
1646 // be issuing -- the final header line contains the credentials.
1647 MockWrite("GET / HTTP/1.1\r\n"
1648 "Host: www.google.com\r\n"
1649 "Connection: keep-alive\r\n"
1650 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1651 };
1652
1653 MockRead data_reads1[] = {
1654 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
1655 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1656 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1657 MockRead("Content-Length: 14\r\n\r\n"),
1658 MockRead("Unauthorized\r\n"),
1659
1660 // Lastly, the server responds with the actual content.
1661 MockRead("HTTP/1.1 200 OK\r\n"),
1662 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:501663 MockRead("Content-Length: 5\r\n\r\n"),
1664 MockRead("Hello"),
[email protected]2d2697f92009-02-18 21:00:321665 };
1666
[email protected]2d0a4f92011-05-05 16:38:461667 // If there is a regression where we disconnect a Keep-Alive
1668 // connection during an auth roundtrip, we'll end up reading this.
1669 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:061670 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:461671 };
1672
[email protected]31a2bfe2010-02-09 08:03:391673 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1674 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:461675 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1676 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071677 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1678 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:321679
[email protected]49639fa2011-12-20 23:22:411680 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:321681
[email protected]262eec82013-03-19 21:01:361682 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501683 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:411684 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421685 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:321686
1687 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421688 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:321689
[email protected]58e32bb2013-01-21 18:23:251690 LoadTimingInfo load_timing_info1;
1691 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
1692 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
1693
[email protected]1c773ea12009-04-28 19:58:421694 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501695 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:041696 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:321697
[email protected]49639fa2011-12-20 23:22:411698 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:321699
[email protected]49639fa2011-12-20 23:22:411700 rv = trans->RestartWithAuth(
1701 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:421702 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:321703
1704 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421705 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:321706
[email protected]58e32bb2013-01-21 18:23:251707 LoadTimingInfo load_timing_info2;
1708 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
1709 TestLoadTimingReused(load_timing_info2);
1710 // The load timing after restart should have the same socket ID, and times
1711 // those of the first load timing.
1712 EXPECT_LE(load_timing_info1.receive_headers_end,
1713 load_timing_info2.send_start);
1714 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
1715
[email protected]2d2697f92009-02-18 21:00:321716 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501717 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:321718 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:501719 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:321720}
1721
1722// Test the request-challenge-retry sequence for basic auth, over a keep-alive
1723// connection and with no response body to drain.
[email protected]23e482282013-06-14 16:08:021724TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:421725 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:321726 request.method = "GET";
1727 request.url = GURL("http://www.google.com/");
1728 request.load_flags = 0;
1729
[email protected]bb88e1d32013-05-03 23:11:071730 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271731
[email protected]2d2697f92009-02-18 21:00:321732 MockWrite data_writes1[] = {
1733 MockWrite("GET / HTTP/1.1\r\n"
1734 "Host: www.google.com\r\n"
1735 "Connection: keep-alive\r\n\r\n"),
1736
1737 // After calling trans->RestartWithAuth(), this is the request we should
1738 // be issuing -- the final header line contains the credentials.
1739 MockWrite("GET / HTTP/1.1\r\n"
1740 "Host: www.google.com\r\n"
1741 "Connection: keep-alive\r\n"
1742 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1743 };
1744
[email protected]2d2697f92009-02-18 21:00:321745 MockRead data_reads1[] = {
1746 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
1747 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:311748 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:321749
1750 // Lastly, the server responds with the actual content.
1751 MockRead("HTTP/1.1 200 OK\r\n"),
1752 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:501753 MockRead("Content-Length: 5\r\n\r\n"),
1754 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:321755 };
1756
[email protected]2d0a4f92011-05-05 16:38:461757 // An incorrect reconnect would cause this to be read.
1758 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:061759 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:461760 };
1761
[email protected]31a2bfe2010-02-09 08:03:391762 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1763 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:461764 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1765 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071766 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1767 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:321768
[email protected]49639fa2011-12-20 23:22:411769 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:321770
[email protected]262eec82013-03-19 21:01:361771 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501772 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:411773 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421774 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:321775
1776 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421777 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:321778
[email protected]1c773ea12009-04-28 19:58:421779 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501780 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:041781 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:321782
[email protected]49639fa2011-12-20 23:22:411783 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:321784
[email protected]49639fa2011-12-20 23:22:411785 rv = trans->RestartWithAuth(
1786 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:421787 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:321788
1789 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421790 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:321791
1792 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501793 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:321794 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:501795 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:321796}
1797
1798// Test the request-challenge-retry sequence for basic auth, over a keep-alive
1799// connection and with a large response body to drain.
[email protected]23e482282013-06-14 16:08:021800TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:421801 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:321802 request.method = "GET";
1803 request.url = GURL("http://www.google.com/");
1804 request.load_flags = 0;
1805
[email protected]bb88e1d32013-05-03 23:11:071806 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271807
[email protected]2d2697f92009-02-18 21:00:321808 MockWrite data_writes1[] = {
1809 MockWrite("GET / HTTP/1.1\r\n"
1810 "Host: www.google.com\r\n"
1811 "Connection: keep-alive\r\n\r\n"),
1812
1813 // After calling trans->RestartWithAuth(), this is the request we should
1814 // be issuing -- the final header line contains the credentials.
1815 MockWrite("GET / HTTP/1.1\r\n"
1816 "Host: www.google.com\r\n"
1817 "Connection: keep-alive\r\n"
1818 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1819 };
1820
1821 // Respond with 5 kb of response body.
1822 std::string large_body_string("Unauthorized");
1823 large_body_string.append(5 * 1024, ' ');
1824 large_body_string.append("\r\n");
1825
1826 MockRead data_reads1[] = {
1827 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
1828 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1829 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1830 // 5134 = 12 + 5 * 1024 + 2
1831 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061832 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:321833
1834 // Lastly, the server responds with the actual content.
1835 MockRead("HTTP/1.1 200 OK\r\n"),
1836 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:501837 MockRead("Content-Length: 5\r\n\r\n"),
1838 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:321839 };
1840
[email protected]2d0a4f92011-05-05 16:38:461841 // An incorrect reconnect would cause this to be read.
1842 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:061843 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:461844 };
1845
[email protected]31a2bfe2010-02-09 08:03:391846 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1847 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:461848 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1849 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071850 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1851 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:321852
[email protected]49639fa2011-12-20 23:22:411853 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:321854
[email protected]262eec82013-03-19 21:01:361855 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501856 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:411857 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421858 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:321859
1860 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421861 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:321862
[email protected]1c773ea12009-04-28 19:58:421863 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501864 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:041865 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:321866
[email protected]49639fa2011-12-20 23:22:411867 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:321868
[email protected]49639fa2011-12-20 23:22:411869 rv = trans->RestartWithAuth(
1870 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:421871 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:321872
1873 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421874 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:321875
1876 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501877 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:321878 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:501879 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:321880}
1881
1882// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:311883// connection, but the server gets impatient and closes the connection.
[email protected]23e482282013-06-14 16:08:021884TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:311885 HttpRequestInfo request;
1886 request.method = "GET";
1887 request.url = GURL("http://www.google.com/");
1888 request.load_flags = 0;
1889
[email protected]bb88e1d32013-05-03 23:11:071890 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271891
[email protected]11203f012009-11-12 23:02:311892 MockWrite data_writes1[] = {
1893 MockWrite("GET / HTTP/1.1\r\n"
1894 "Host: www.google.com\r\n"
1895 "Connection: keep-alive\r\n\r\n"),
1896 // This simulates the seemingly successful write to a closed connection
1897 // if the bug is not fixed.
1898 MockWrite("GET / HTTP/1.1\r\n"
1899 "Host: www.google.com\r\n"
1900 "Connection: keep-alive\r\n"
1901 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1902 };
1903
1904 MockRead data_reads1[] = {
1905 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
1906 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1907 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1908 MockRead("Content-Length: 14\r\n\r\n"),
1909 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:061910 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:311911 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:061912 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:311913 };
1914
1915 // After calling trans->RestartWithAuth(), this is the request we should
1916 // be issuing -- the final header line contains the credentials.
1917 MockWrite data_writes2[] = {
1918 MockWrite("GET / HTTP/1.1\r\n"
1919 "Host: www.google.com\r\n"
1920 "Connection: keep-alive\r\n"
1921 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1922 };
1923
1924 // Lastly, the server responds with the actual content.
1925 MockRead data_reads2[] = {
1926 MockRead("HTTP/1.1 200 OK\r\n"),
1927 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:501928 MockRead("Content-Length: 5\r\n\r\n"),
1929 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:311930 };
1931
[email protected]31a2bfe2010-02-09 08:03:391932 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1933 data_writes1, arraysize(data_writes1));
1934 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1935 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:071936 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1937 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:311938
[email protected]49639fa2011-12-20 23:22:411939 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:311940
[email protected]262eec82013-03-19 21:01:361941 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501942 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:411943 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]11203f012009-11-12 23:02:311944 EXPECT_EQ(ERR_IO_PENDING, rv);
1945
1946 rv = callback1.WaitForResult();
1947 EXPECT_EQ(OK, rv);
1948
1949 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501950 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:041951 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:311952
[email protected]49639fa2011-12-20 23:22:411953 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:311954
[email protected]49639fa2011-12-20 23:22:411955 rv = trans->RestartWithAuth(
1956 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]11203f012009-11-12 23:02:311957 EXPECT_EQ(ERR_IO_PENDING, rv);
1958
1959 rv = callback2.WaitForResult();
1960 EXPECT_EQ(OK, rv);
1961
1962 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501963 ASSERT_TRUE(response != NULL);
[email protected]11203f012009-11-12 23:02:311964 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:501965 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:311966}
1967
[email protected]394816e92010-08-03 07:38:591968// Test the request-challenge-retry sequence for basic auth, over a connection
1969// that requires a restart when setting up an SSL tunnel.
[email protected]23e482282013-06-14 16:08:021970TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAlive) {
[email protected]394816e92010-08-03 07:38:591971 HttpRequestInfo request;
1972 request.method = "GET";
1973 request.url = GURL("https://www.google.com/");
1974 // when the no authentication data flag is set.
1975 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
1976
[email protected]cb9bf6ca2011-01-28 13:15:271977 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:071978 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:201979 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
[email protected]333bdf62012-06-08 22:57:291980 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:071981 session_deps_.net_log = log.bound().net_log();
1982 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271983
[email protected]394816e92010-08-03 07:38:591984 // Since we have proxy, should try to establish tunnel.
1985 MockWrite data_writes1[] = {
1986 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
1987 "Host: www.google.com\r\n"
1988 "Proxy-Connection: keep-alive\r\n\r\n"),
1989
1990 // After calling trans->RestartWithAuth(), this is the request we should
1991 // be issuing -- the final header line contains the credentials.
1992 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
1993 "Host: www.google.com\r\n"
1994 "Proxy-Connection: keep-alive\r\n"
1995 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1996
1997 MockWrite("GET / HTTP/1.1\r\n"
1998 "Host: www.google.com\r\n"
1999 "Connection: keep-alive\r\n\r\n"),
2000 };
2001
2002 // The proxy responds to the connect with a 407, using a persistent
2003 // connection.
2004 MockRead data_reads1[] = {
2005 // No credentials.
2006 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2007 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2008 MockRead("Proxy-Connection: close\r\n\r\n"),
2009
2010 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2011
2012 MockRead("HTTP/1.1 200 OK\r\n"),
2013 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502014 MockRead("Content-Length: 5\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062015 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:592016 };
2017
2018 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2019 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072020 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:062021 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072022 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:592023
[email protected]49639fa2011-12-20 23:22:412024 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:592025
[email protected]262eec82013-03-19 21:01:362026 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502027 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:502028
[email protected]49639fa2011-12-20 23:22:412029 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]394816e92010-08-03 07:38:592030 EXPECT_EQ(ERR_IO_PENDING, rv);
2031
2032 rv = callback1.WaitForResult();
2033 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:572034 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:402035 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:592036 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402037 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]394816e92010-08-03 07:38:592038 NetLog::PHASE_NONE);
2039 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402040 entries, pos,
[email protected]394816e92010-08-03 07:38:592041 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2042 NetLog::PHASE_NONE);
2043
2044 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502045 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502046 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]394816e92010-08-03 07:38:592047 EXPECT_EQ(407, response->headers->response_code());
2048 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042049 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:592050
[email protected]029c83b62013-01-24 05:28:202051 LoadTimingInfo load_timing_info;
2052 // CONNECT requests and responses are handled at the connect job level, so
2053 // the transaction does not yet have a connection.
2054 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
2055
[email protected]49639fa2011-12-20 23:22:412056 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:592057
[email protected]49639fa2011-12-20 23:22:412058 rv = trans->RestartWithAuth(
2059 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]394816e92010-08-03 07:38:592060 EXPECT_EQ(ERR_IO_PENDING, rv);
2061
2062 rv = callback2.WaitForResult();
2063 EXPECT_EQ(OK, rv);
2064
2065 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502066 ASSERT_TRUE(response != NULL);
[email protected]394816e92010-08-03 07:38:592067
2068 EXPECT_TRUE(response->headers->IsKeepAlive());
2069 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:502070 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:592071 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2072
2073 // The password prompt info should not be set.
2074 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502075
[email protected]029c83b62013-01-24 05:28:202076 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2077 TestLoadTimingNotReusedWithPac(load_timing_info,
2078 CONNECT_TIMING_HAS_SSL_TIMES);
2079
[email protected]0b0bf032010-09-21 18:08:502080 trans.reset();
[email protected]102e27c2011-02-23 01:01:312081 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:592082}
2083
[email protected]11203f012009-11-12 23:02:312084// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]2d2697f92009-02-18 21:00:322085// proxy connection, when setting up an SSL tunnel.
[email protected]23e482282013-06-14 16:08:022086TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAlive) {
[email protected]cb9bf6ca2011-01-28 13:15:272087 HttpRequestInfo request;
2088 request.method = "GET";
2089 request.url = GURL("https://www.google.com/");
2090 // Ensure that proxy authentication is attempted even
2091 // when the no authentication data flag is set.
2092 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
2093
[email protected]2d2697f92009-02-18 21:00:322094 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072095 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]333bdf62012-06-08 22:57:292096 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072097 session_deps_.net_log = log.bound().net_log();
2098 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:322099
[email protected]262eec82013-03-19 21:01:362100 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502101 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d2697f92009-02-18 21:00:322102
[email protected]2d2697f92009-02-18 21:00:322103 // Since we have proxy, should try to establish tunnel.
2104 MockWrite data_writes1[] = {
2105 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:452106 "Host: www.google.com\r\n"
2107 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322108
2109 // After calling trans->RestartWithAuth(), this is the request we should
2110 // be issuing -- the final header line contains the credentials.
2111 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2112 "Host: www.google.com\r\n"
[email protected]e44de5d2009-06-05 20:12:452113 "Proxy-Connection: keep-alive\r\n"
[email protected]2d2697f92009-02-18 21:00:322114 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
2115 };
2116
2117 // The proxy responds to the connect with a 407, using a persistent
2118 // connection.
2119 MockRead data_reads1[] = {
2120 // No credentials.
2121 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2122 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2123 MockRead("Content-Length: 10\r\n\r\n"),
2124 MockRead("0123456789"),
2125
2126 // Wrong credentials (wrong password).
2127 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2128 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2129 MockRead("Content-Length: 10\r\n\r\n"),
2130 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:062131 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]2d2697f92009-02-18 21:00:322132 };
2133
[email protected]31a2bfe2010-02-09 08:03:392134 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2135 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072136 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d2697f92009-02-18 21:00:322137
[email protected]49639fa2011-12-20 23:22:412138 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322139
[email protected]49639fa2011-12-20 23:22:412140 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]1c773ea12009-04-28 19:58:422141 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322142
2143 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422144 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:572145 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:402146 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:392147 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402148 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]dbb83db2010-05-11 18:13:392149 NetLog::PHASE_NONE);
2150 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402151 entries, pos,
[email protected]dbb83db2010-05-11 18:13:392152 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2153 NetLog::PHASE_NONE);
[email protected]2d2697f92009-02-18 21:00:322154
[email protected]1c773ea12009-04-28 19:58:422155 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502156 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502157 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]2d2697f92009-02-18 21:00:322158 EXPECT_TRUE(response->headers->IsKeepAlive());
2159 EXPECT_EQ(407, response->headers->response_code());
2160 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422161 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042162 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322163
[email protected]49639fa2011-12-20 23:22:412164 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322165
2166 // Wrong password (should be "bar").
[email protected]49639fa2011-12-20 23:22:412167 rv = trans->RestartWithAuth(
2168 AuthCredentials(kFoo, kBaz), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422169 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322170
2171 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422172 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322173
2174 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502175 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502176 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]2d2697f92009-02-18 21:00:322177 EXPECT_TRUE(response->headers->IsKeepAlive());
2178 EXPECT_EQ(407, response->headers->response_code());
2179 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422180 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042181 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]e772db3f2010-07-12 18:11:132182
[email protected]e60e47a2010-07-14 03:37:182183 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
2184 // out of scope.
[email protected]102e27c2011-02-23 01:01:312185 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:322186}
2187
[email protected]a8e9b162009-03-12 00:06:442188// Test that we don't read the response body when we fail to establish a tunnel,
2189// even if the user cancels the proxy's auth attempt.
[email protected]23e482282013-06-14 16:08:022190TEST_P(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:272191 HttpRequestInfo request;
2192 request.method = "GET";
2193 request.url = GURL("https://www.google.com/");
2194 request.load_flags = 0;
2195
[email protected]a8e9b162009-03-12 00:06:442196 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072197 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]a8e9b162009-03-12 00:06:442198
[email protected]bb88e1d32013-05-03 23:11:072199 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:442200
[email protected]262eec82013-03-19 21:01:362201 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502202 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]a8e9b162009-03-12 00:06:442203
[email protected]a8e9b162009-03-12 00:06:442204 // Since we have proxy, should try to establish tunnel.
2205 MockWrite data_writes[] = {
2206 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:452207 "Host: www.google.com\r\n"
2208 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:442209 };
2210
2211 // The proxy responds to the connect with a 407.
2212 MockRead data_reads[] = {
2213 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2214 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2215 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062216 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]a8e9b162009-03-12 00:06:442217 };
2218
[email protected]31a2bfe2010-02-09 08:03:392219 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2220 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072221 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:442222
[email protected]49639fa2011-12-20 23:22:412223 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:442224
[email protected]49639fa2011-12-20 23:22:412225 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422226 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a8e9b162009-03-12 00:06:442227
2228 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422229 EXPECT_EQ(OK, rv);
[email protected]a8e9b162009-03-12 00:06:442230
[email protected]1c773ea12009-04-28 19:58:422231 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502232 ASSERT_TRUE(response != NULL);
[email protected]a8e9b162009-03-12 00:06:442233
2234 EXPECT_TRUE(response->headers->IsKeepAlive());
2235 EXPECT_EQ(407, response->headers->response_code());
2236 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422237 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:442238
2239 std::string response_data;
2240 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:422241 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]e60e47a2010-07-14 03:37:182242
2243 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:312244 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:442245}
2246
[email protected]8fdbcd22010-05-05 02:54:522247// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
2248// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
[email protected]23e482282013-06-14 16:08:022249TEST_P(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:522250 HttpRequestInfo request;
2251 request.method = "GET";
2252 request.url = GURL("http://www.google.com/");
2253 request.load_flags = 0;
2254
[email protected]cb9bf6ca2011-01-28 13:15:272255 // We are using a DIRECT connection (i.e. no proxy) for this session.
[email protected]cb9bf6ca2011-01-28 13:15:272256 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:362257 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:072258 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:272259
[email protected]8fdbcd22010-05-05 02:54:522260 MockWrite data_writes1[] = {
2261 MockWrite("GET / HTTP/1.1\r\n"
2262 "Host: www.google.com\r\n"
2263 "Connection: keep-alive\r\n\r\n"),
2264 };
2265
2266 MockRead data_reads1[] = {
2267 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
2268 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2269 // Large content-length -- won't matter, as connection will be reset.
2270 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062271 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:522272 };
2273
2274 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2275 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072276 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:522277
[email protected]49639fa2011-12-20 23:22:412278 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:522279
[email protected]49639fa2011-12-20 23:22:412280 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]8fdbcd22010-05-05 02:54:522281 EXPECT_EQ(ERR_IO_PENDING, rv);
2282
2283 rv = callback.WaitForResult();
2284 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
2285}
2286
[email protected]7a67a8152010-11-05 18:31:102287// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
2288// through a non-authenticating proxy. The request should fail with
2289// ERR_UNEXPECTED_PROXY_AUTH.
2290// Note that it is impossible to detect if an HTTP server returns a 407 through
2291// a non-authenticating proxy - there is nothing to indicate whether the
2292// response came from the proxy or the server, so it is treated as if the proxy
2293// issued the challenge.
[email protected]23e482282013-06-14 16:08:022294TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:232295 HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:272296 HttpRequestInfo request;
2297 request.method = "GET";
2298 request.url = GURL("https://www.google.com/");
2299
[email protected]bb88e1d32013-05-03 23:11:072300 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]333bdf62012-06-08 22:57:292301 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072302 session_deps_.net_log = log.bound().net_log();
2303 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:102304
[email protected]7a67a8152010-11-05 18:31:102305 // Since we have proxy, should try to establish tunnel.
2306 MockWrite data_writes1[] = {
2307 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2308 "Host: www.google.com\r\n"
2309 "Proxy-Connection: keep-alive\r\n\r\n"),
2310
2311 MockWrite("GET / HTTP/1.1\r\n"
2312 "Host: www.google.com\r\n"
2313 "Connection: keep-alive\r\n\r\n"),
2314 };
2315
2316 MockRead data_reads1[] = {
2317 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2318
2319 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
2320 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2321 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:062322 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:102323 };
2324
2325 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2326 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072327 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:062328 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072329 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:102330
[email protected]49639fa2011-12-20 23:22:412331 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:102332
[email protected]262eec82013-03-19 21:01:362333 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502334 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a67a8152010-11-05 18:31:102335
[email protected]49639fa2011-12-20 23:22:412336 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7a67a8152010-11-05 18:31:102337 EXPECT_EQ(ERR_IO_PENDING, rv);
2338
2339 rv = callback1.WaitForResult();
2340 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
[email protected]f3da152d2012-06-02 01:00:572341 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:402342 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:102343 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402344 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]7a67a8152010-11-05 18:31:102345 NetLog::PHASE_NONE);
2346 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402347 entries, pos,
[email protected]7a67a8152010-11-05 18:31:102348 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2349 NetLog::PHASE_NONE);
2350}
[email protected]2df19bb2010-08-25 20:13:462351
[email protected]029c83b62013-01-24 05:28:202352// Test the load timing for HTTPS requests with an HTTP proxy.
[email protected]23e482282013-06-14 16:08:022353TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:202354 HttpRequestInfo request1;
2355 request1.method = "GET";
2356 request1.url = GURL("https://www.google.com/1");
2357
2358 HttpRequestInfo request2;
2359 request2.method = "GET";
2360 request2.url = GURL("https://www.google.com/2");
2361
2362 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072363 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:202364 ProxyService::CreateFixed("PROXY myproxy:70"));
2365 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072366 session_deps_.net_log = log.bound().net_log();
2367 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:202368
2369 // Since we have proxy, should try to establish tunnel.
2370 MockWrite data_writes1[] = {
2371 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2372 "Host: www.google.com\r\n"
2373 "Proxy-Connection: keep-alive\r\n\r\n"),
2374
2375 MockWrite("GET /1 HTTP/1.1\r\n"
2376 "Host: www.google.com\r\n"
2377 "Connection: keep-alive\r\n\r\n"),
2378
2379 MockWrite("GET /2 HTTP/1.1\r\n"
2380 "Host: www.google.com\r\n"
2381 "Connection: keep-alive\r\n\r\n"),
2382 };
2383
2384 // The proxy responds to the connect with a 407, using a persistent
2385 // connection.
2386 MockRead data_reads1[] = {
2387 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2388
2389 MockRead("HTTP/1.1 200 OK\r\n"),
2390 MockRead("Content-Length: 1\r\n\r\n"),
2391 MockRead(SYNCHRONOUS, "1"),
2392
2393 MockRead("HTTP/1.1 200 OK\r\n"),
2394 MockRead("Content-Length: 2\r\n\r\n"),
2395 MockRead(SYNCHRONOUS, "22"),
2396 };
2397
2398 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2399 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072400 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:202401 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072402 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:202403
2404 TestCompletionCallback callback1;
[email protected]262eec82013-03-19 21:01:362405 scoped_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:502406 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:202407
2408 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
2409 EXPECT_EQ(ERR_IO_PENDING, rv);
2410
2411 rv = callback1.WaitForResult();
2412 EXPECT_EQ(OK, rv);
2413
2414 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2415 ASSERT_TRUE(response1 != NULL);
[email protected]90499482013-06-01 00:39:502416 ASSERT_TRUE(response1->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:202417 EXPECT_EQ(1, response1->headers->GetContentLength());
2418
2419 LoadTimingInfo load_timing_info1;
2420 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
2421 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
2422
2423 trans1.reset();
2424
2425 TestCompletionCallback callback2;
[email protected]262eec82013-03-19 21:01:362426 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:502427 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:202428
2429 rv = trans2->Start(&request2, callback2.callback(), log.bound());
2430 EXPECT_EQ(ERR_IO_PENDING, rv);
2431
2432 rv = callback2.WaitForResult();
2433 EXPECT_EQ(OK, rv);
2434
2435 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2436 ASSERT_TRUE(response2 != NULL);
[email protected]90499482013-06-01 00:39:502437 ASSERT_TRUE(response2->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:202438 EXPECT_EQ(2, response2->headers->GetContentLength());
2439
2440 LoadTimingInfo load_timing_info2;
2441 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
2442 TestLoadTimingReused(load_timing_info2);
2443
2444 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2445
2446 trans2.reset();
2447 session->CloseAllConnections();
2448}
2449
2450// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
[email protected]23e482282013-06-14 16:08:022451TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:202452 HttpRequestInfo request1;
2453 request1.method = "GET";
2454 request1.url = GURL("https://www.google.com/1");
2455
2456 HttpRequestInfo request2;
2457 request2.method = "GET";
2458 request2.url = GURL("https://www.google.com/2");
2459
2460 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072461 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:202462 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
2463 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072464 session_deps_.net_log = log.bound().net_log();
2465 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:202466
2467 // Since we have proxy, should try to establish tunnel.
2468 MockWrite data_writes1[] = {
2469 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2470 "Host: www.google.com\r\n"
2471 "Proxy-Connection: keep-alive\r\n\r\n"),
2472
2473 MockWrite("GET /1 HTTP/1.1\r\n"
2474 "Host: www.google.com\r\n"
2475 "Connection: keep-alive\r\n\r\n"),
2476
2477 MockWrite("GET /2 HTTP/1.1\r\n"
2478 "Host: www.google.com\r\n"
2479 "Connection: keep-alive\r\n\r\n"),
2480 };
2481
2482 // The proxy responds to the connect with a 407, using a persistent
2483 // connection.
2484 MockRead data_reads1[] = {
2485 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2486
2487 MockRead("HTTP/1.1 200 OK\r\n"),
2488 MockRead("Content-Length: 1\r\n\r\n"),
2489 MockRead(SYNCHRONOUS, "1"),
2490
2491 MockRead("HTTP/1.1 200 OK\r\n"),
2492 MockRead("Content-Length: 2\r\n\r\n"),
2493 MockRead(SYNCHRONOUS, "22"),
2494 };
2495
2496 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2497 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072498 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:202499 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072500 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:202501
2502 TestCompletionCallback callback1;
[email protected]262eec82013-03-19 21:01:362503 scoped_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:502504 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:202505
2506 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
2507 EXPECT_EQ(ERR_IO_PENDING, rv);
2508
2509 rv = callback1.WaitForResult();
2510 EXPECT_EQ(OK, rv);
2511
2512 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2513 ASSERT_TRUE(response1 != NULL);
[email protected]90499482013-06-01 00:39:502514 ASSERT_TRUE(response1->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:202515 EXPECT_EQ(1, response1->headers->GetContentLength());
2516
2517 LoadTimingInfo load_timing_info1;
2518 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
2519 TestLoadTimingNotReusedWithPac(load_timing_info1,
2520 CONNECT_TIMING_HAS_SSL_TIMES);
2521
2522 trans1.reset();
2523
2524 TestCompletionCallback callback2;
[email protected]262eec82013-03-19 21:01:362525 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:502526 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:202527
2528 rv = trans2->Start(&request2, callback2.callback(), log.bound());
2529 EXPECT_EQ(ERR_IO_PENDING, rv);
2530
2531 rv = callback2.WaitForResult();
2532 EXPECT_EQ(OK, rv);
2533
2534 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2535 ASSERT_TRUE(response2 != NULL);
[email protected]90499482013-06-01 00:39:502536 ASSERT_TRUE(response2->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:202537 EXPECT_EQ(2, response2->headers->GetContentLength());
2538
2539 LoadTimingInfo load_timing_info2;
2540 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
2541 TestLoadTimingReusedWithPac(load_timing_info2);
2542
2543 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2544
2545 trans2.reset();
2546 session->CloseAllConnections();
2547}
2548
[email protected]2df19bb2010-08-25 20:13:462549// Test a simple get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:022550TEST_P(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:272551 HttpRequestInfo request;
2552 request.method = "GET";
2553 request.url = GURL("http://www.google.com/");
2554
[email protected]2df19bb2010-08-25 20:13:462555 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:072556 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:112557 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:292558 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072559 session_deps_.net_log = log.bound().net_log();
2560 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:462561
[email protected]2df19bb2010-08-25 20:13:462562 // Since we have proxy, should use full url
2563 MockWrite data_writes1[] = {
2564 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
2565 "Host: www.google.com\r\n"
2566 "Proxy-Connection: keep-alive\r\n\r\n"),
2567 };
2568
2569 MockRead data_reads1[] = {
2570 MockRead("HTTP/1.1 200 OK\r\n"),
2571 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2572 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062573 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:462574 };
2575
2576 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2577 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072578 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:062579 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072580 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:462581
[email protected]49639fa2011-12-20 23:22:412582 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:462583
[email protected]262eec82013-03-19 21:01:362584 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502585 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:502586
[email protected]49639fa2011-12-20 23:22:412587 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:462588 EXPECT_EQ(ERR_IO_PENDING, rv);
2589
2590 rv = callback1.WaitForResult();
2591 EXPECT_EQ(OK, rv);
2592
[email protected]58e32bb2013-01-21 18:23:252593 LoadTimingInfo load_timing_info;
2594 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2595 TestLoadTimingNotReused(load_timing_info,
2596 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
2597
[email protected]2df19bb2010-08-25 20:13:462598 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502599 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:462600
2601 EXPECT_TRUE(response->headers->IsKeepAlive());
2602 EXPECT_EQ(200, response->headers->response_code());
2603 EXPECT_EQ(100, response->headers->GetContentLength());
2604 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2605
2606 // The password prompt info should not be set.
2607 EXPECT_TRUE(response->auth_challenge.get() == NULL);
2608}
2609
[email protected]7642b5ae2010-09-01 20:55:172610// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:022611TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:272612 HttpRequestInfo request;
2613 request.method = "GET";
2614 request.url = GURL("http://www.google.com/");
2615 request.load_flags = 0;
2616
[email protected]7642b5ae2010-09-01 20:55:172617 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:072618 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:112619 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:292620 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072621 session_deps_.net_log = log.bound().net_log();
2622 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:172623
[email protected]7642b5ae2010-09-01 20:55:172624 // fetch http://www.google.com/ via SPDY
[email protected]cdf8f7e72013-05-23 10:56:462625 scoped_ptr<SpdyFrame> req(
2626 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]7642b5ae2010-09-01 20:55:172627 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
2628
[email protected]23e482282013-06-14 16:08:022629 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2630 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:172631 MockRead spdy_reads[] = {
2632 CreateMockRead(*resp),
2633 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:062634 MockRead(ASYNC, 0, 0),
[email protected]7642b5ae2010-09-01 20:55:172635 };
2636
[email protected]dd54bd82012-07-19 23:44:572637 DelayedSocketData spdy_data(
2638 1, // wait for one write to finish before reading.
2639 spdy_reads, arraysize(spdy_reads),
2640 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:072641 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:172642
[email protected]8ddf8322012-02-23 18:08:062643 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:022644 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:072645 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:172646
[email protected]49639fa2011-12-20 23:22:412647 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:172648
[email protected]262eec82013-03-19 21:01:362649 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502650 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:502651
[email protected]49639fa2011-12-20 23:22:412652 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7642b5ae2010-09-01 20:55:172653 EXPECT_EQ(ERR_IO_PENDING, rv);
2654
2655 rv = callback1.WaitForResult();
2656 EXPECT_EQ(OK, rv);
2657
[email protected]58e32bb2013-01-21 18:23:252658 LoadTimingInfo load_timing_info;
2659 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2660 TestLoadTimingNotReused(load_timing_info,
2661 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
2662
[email protected]7642b5ae2010-09-01 20:55:172663 const HttpResponseInfo* response = trans->GetResponseInfo();
2664 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502665 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]7642b5ae2010-09-01 20:55:172666 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2667
2668 std::string response_data;
2669 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:232670 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:172671}
2672
[email protected]dc7bd1c52010-11-12 00:01:132673// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:022674TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:272675 HttpRequestInfo request;
2676 request.method = "GET";
2677 request.url = GURL("http://www.google.com/");
2678 request.load_flags = 0;
2679
[email protected]79cb5c12011-09-12 13:12:042680 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072681 session_deps_.proxy_service.reset(
[email protected]79cb5c12011-09-12 13:12:042682 ProxyService::CreateFixed("https://myproxy:70"));
[email protected]333bdf62012-06-08 22:57:292683 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072684 session_deps_.net_log = log.bound().net_log();
2685 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:132686
[email protected]dc7bd1c52010-11-12 00:01:132687 // The first request will be a bare GET, the second request will be a
2688 // GET with a Proxy-Authorization header.
[email protected]ff98d7f02012-03-22 21:44:192689 scoped_ptr<SpdyFrame> req_get(
[email protected]cdf8f7e72013-05-23 10:56:462690 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]dc7bd1c52010-11-12 00:01:132691 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:462692 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:132693 };
[email protected]ff98d7f02012-03-22 21:44:192694 scoped_ptr<SpdyFrame> req_get_authorization(
[email protected]cdf8f7e72013-05-23 10:56:462695 spdy_util_.ConstructSpdyGet(kExtraAuthorizationHeaders,
2696 arraysize(kExtraAuthorizationHeaders) / 2,
2697 false,
2698 3,
2699 LOWEST,
2700 false));
[email protected]dc7bd1c52010-11-12 00:01:132701 MockWrite spdy_writes[] = {
2702 CreateMockWrite(*req_get, 1),
2703 CreateMockWrite(*req_get_authorization, 4),
2704 };
2705
2706 // The first response is a 407 proxy authentication challenge, and the second
2707 // response will be a 200 response since the second request includes a valid
2708 // Authorization header.
2709 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:462710 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:132711 };
[email protected]ff98d7f02012-03-22 21:44:192712 scoped_ptr<SpdyFrame> resp_authentication(
[email protected]23e482282013-06-14 16:08:022713 spdy_util_.ConstructSpdySynReplyError(
[email protected]dc7bd1c52010-11-12 00:01:132714 "407 Proxy Authentication Required",
2715 kExtraAuthenticationHeaders, arraysize(kExtraAuthenticationHeaders)/2,
2716 1));
[email protected]ff98d7f02012-03-22 21:44:192717 scoped_ptr<SpdyFrame> body_authentication(
[email protected]23e482282013-06-14 16:08:022718 spdy_util_.ConstructSpdyBodyFrame(1, true));
2719 scoped_ptr<SpdyFrame> resp_data(
2720 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
2721 scoped_ptr<SpdyFrame> body_data(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:132722 MockRead spdy_reads[] = {
2723 CreateMockRead(*resp_authentication, 2),
2724 CreateMockRead(*body_authentication, 3),
2725 CreateMockRead(*resp_data, 5),
2726 CreateMockRead(*body_data, 6),
[email protected]8ddf8322012-02-23 18:08:062727 MockRead(ASYNC, 0, 7),
[email protected]dc7bd1c52010-11-12 00:01:132728 };
2729
[email protected]dd54bd82012-07-19 23:44:572730 OrderedSocketData data(
2731 spdy_reads, arraysize(spdy_reads),
2732 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:072733 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:132734
[email protected]8ddf8322012-02-23 18:08:062735 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:022736 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:072737 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:132738
[email protected]49639fa2011-12-20 23:22:412739 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:132740
[email protected]262eec82013-03-19 21:01:362741 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502742 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]dc7bd1c52010-11-12 00:01:132743
[email protected]49639fa2011-12-20 23:22:412744 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]dc7bd1c52010-11-12 00:01:132745 EXPECT_EQ(ERR_IO_PENDING, rv);
2746
2747 rv = callback1.WaitForResult();
2748 EXPECT_EQ(OK, rv);
2749
2750 const HttpResponseInfo* const response = trans->GetResponseInfo();
2751
2752 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502753 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]dc7bd1c52010-11-12 00:01:132754 EXPECT_EQ(407, response->headers->response_code());
2755 EXPECT_TRUE(response->was_fetched_via_spdy);
[email protected]79cb5c12011-09-12 13:12:042756 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:132757
[email protected]49639fa2011-12-20 23:22:412758 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:132759
[email protected]49639fa2011-12-20 23:22:412760 rv = trans->RestartWithAuth(
2761 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]dc7bd1c52010-11-12 00:01:132762 EXPECT_EQ(ERR_IO_PENDING, rv);
2763
2764 rv = callback2.WaitForResult();
2765 EXPECT_EQ(OK, rv);
2766
2767 const HttpResponseInfo* const response_restart = trans->GetResponseInfo();
2768
2769 ASSERT_TRUE(response_restart != NULL);
[email protected]90499482013-06-01 00:39:502770 ASSERT_TRUE(response_restart->headers.get() != NULL);
[email protected]dc7bd1c52010-11-12 00:01:132771 EXPECT_EQ(200, response_restart->headers->response_code());
2772 // The password prompt info should not be set.
2773 EXPECT_TRUE(response_restart->auth_challenge.get() == NULL);
2774}
2775
[email protected]d9da5fe2010-10-13 22:37:162776// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
[email protected]23e482282013-06-14 16:08:022777TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:272778 HttpRequestInfo request;
2779 request.method = "GET";
2780 request.url = GURL("https://www.google.com/");
2781 request.load_flags = 0;
2782
[email protected]d9da5fe2010-10-13 22:37:162783 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:072784 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:112785 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:292786 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072787 session_deps_.net_log = log.bound().net_log();
2788 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:162789
[email protected]262eec82013-03-19 21:01:362790 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502791 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:162792
[email protected]d9da5fe2010-10-13 22:37:162793 // CONNECT to www.google.com:443 via SPDY
[email protected]fba2dbde2013-05-24 16:09:012794 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:162795 // fetch https://www.google.com/ via HTTP
2796
2797 const char get[] = "GET / HTTP/1.1\r\n"
2798 "Host: www.google.com\r\n"
2799 "Connection: keep-alive\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:192800 scoped_ptr<SpdyFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:022801 spdy_util_.ConstructSpdyBodyFrame(1, get, strlen(get), false));
2802 scoped_ptr<SpdyFrame> conn_resp(
2803 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:162804 const char resp[] = "HTTP/1.1 200 OK\r\n"
2805 "Content-Length: 10\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:192806 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:022807 spdy_util_.ConstructSpdyBodyFrame(1, resp, strlen(resp), false));
[email protected]ff98d7f02012-03-22 21:44:192808 scoped_ptr<SpdyFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:022809 spdy_util_.ConstructSpdyBodyFrame(1, "1234567890", 10, false));
[email protected]ff98d7f02012-03-22 21:44:192810 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:202811 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
[email protected]8d2f7012012-02-16 00:08:042812
2813 MockWrite spdy_writes[] = {
2814 CreateMockWrite(*connect, 1),
2815 CreateMockWrite(*wrapped_get, 3),
[email protected]cdf8f7e72013-05-23 10:56:462816 CreateMockWrite(*window_update, 5),
[email protected]8d2f7012012-02-16 00:08:042817 };
2818
[email protected]d9da5fe2010-10-13 22:37:162819 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:062820 CreateMockRead(*conn_resp, 2, ASYNC),
2821 CreateMockRead(*wrapped_get_resp, 4, ASYNC),
2822 CreateMockRead(*wrapped_body, 6, ASYNC),
2823 CreateMockRead(*wrapped_body, 7, ASYNC),
2824 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:162825 };
2826
[email protected]dd54bd82012-07-19 23:44:572827 OrderedSocketData spdy_data(
2828 spdy_reads, arraysize(spdy_reads),
2829 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:072830 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:162831
[email protected]8ddf8322012-02-23 18:08:062832 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:022833 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:072834 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:062835 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]d9da5fe2010-10-13 22:37:162836 ssl2.was_npn_negotiated = false;
[email protected]8e3c78cb2012-03-31 03:58:462837 ssl2.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:072838 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:162839
[email protected]49639fa2011-12-20 23:22:412840 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:162841
[email protected]49639fa2011-12-20 23:22:412842 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:162843 EXPECT_EQ(ERR_IO_PENDING, rv);
2844
2845 rv = callback1.WaitForResult();
2846 EXPECT_EQ(OK, rv);
2847
[email protected]58e32bb2013-01-21 18:23:252848 LoadTimingInfo load_timing_info;
2849 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2850 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
2851
[email protected]d9da5fe2010-10-13 22:37:162852 const HttpResponseInfo* response = trans->GetResponseInfo();
2853 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502854 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d9da5fe2010-10-13 22:37:162855 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2856
2857 std::string response_data;
2858 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
2859 EXPECT_EQ("1234567890", response_data);
2860}
2861
2862// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
[email protected]23e482282013-06-14 16:08:022863TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
[email protected]cb9bf6ca2011-01-28 13:15:272864 HttpRequestInfo request;
2865 request.method = "GET";
2866 request.url = GURL("https://www.google.com/");
2867 request.load_flags = 0;
2868
[email protected]d9da5fe2010-10-13 22:37:162869 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:072870 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:112871 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:292872 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072873 session_deps_.net_log = log.bound().net_log();
2874 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:162875
[email protected]262eec82013-03-19 21:01:362876 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502877 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:162878
[email protected]d9da5fe2010-10-13 22:37:162879 // CONNECT to www.google.com:443 via SPDY
[email protected]fba2dbde2013-05-24 16:09:012880 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:162881 // fetch https://www.google.com/ via SPDY
2882 const char* const kMyUrl = "https://www.google.com/";
[email protected]cdf8f7e72013-05-23 10:56:462883 scoped_ptr<SpdyFrame> get(
2884 spdy_util_.ConstructSpdyGet(kMyUrl, false, 1, LOWEST));
[email protected]23e482282013-06-14 16:08:022885 scoped_ptr<SpdyFrame> wrapped_get(
2886 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
2887 scoped_ptr<SpdyFrame> conn_resp(
2888 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2889 scoped_ptr<SpdyFrame> get_resp(
2890 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]ff98d7f02012-03-22 21:44:192891 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:022892 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
2893 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
2894 scoped_ptr<SpdyFrame> wrapped_body(
2895 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
[email protected]ff98d7f02012-03-22 21:44:192896 scoped_ptr<SpdyFrame> window_update_get_resp(
[email protected]c10b20852013-05-15 21:29:202897 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
[email protected]ff98d7f02012-03-22 21:44:192898 scoped_ptr<SpdyFrame> window_update_body(
[email protected]c10b20852013-05-15 21:29:202899 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body->size()));
[email protected]8d2f7012012-02-16 00:08:042900
2901 MockWrite spdy_writes[] = {
2902 CreateMockWrite(*connect, 1),
2903 CreateMockWrite(*wrapped_get, 3),
2904 CreateMockWrite(*window_update_get_resp, 5),
2905 CreateMockWrite(*window_update_body, 7),
2906 };
2907
[email protected]d9da5fe2010-10-13 22:37:162908 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:062909 CreateMockRead(*conn_resp, 2, ASYNC),
2910 CreateMockRead(*wrapped_get_resp, 4, ASYNC),
2911 CreateMockRead(*wrapped_body, 6, ASYNC),
2912 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:162913 };
2914
[email protected]dd54bd82012-07-19 23:44:572915 OrderedSocketData spdy_data(
2916 spdy_reads, arraysize(spdy_reads),
2917 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:072918 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:162919
[email protected]8ddf8322012-02-23 18:08:062920 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:022921 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:072922 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:062923 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:022924 ssl2.SetNextProto(GetParam());
2925 ssl2.protocol_negotiated = GetParam();
[email protected]bb88e1d32013-05-03 23:11:072926 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:162927
[email protected]49639fa2011-12-20 23:22:412928 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:162929
[email protected]49639fa2011-12-20 23:22:412930 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:162931 EXPECT_EQ(ERR_IO_PENDING, rv);
2932
2933 rv = callback1.WaitForResult();
2934 EXPECT_EQ(OK, rv);
2935
[email protected]58e32bb2013-01-21 18:23:252936 LoadTimingInfo load_timing_info;
2937 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2938 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
2939
[email protected]d9da5fe2010-10-13 22:37:162940 const HttpResponseInfo* response = trans->GetResponseInfo();
2941 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502942 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d9da5fe2010-10-13 22:37:162943 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2944
2945 std::string response_data;
2946 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:232947 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:162948}
2949
2950// Test a SPDY CONNECT failure through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:022951TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:272952 HttpRequestInfo request;
2953 request.method = "GET";
2954 request.url = GURL("https://www.google.com/");
2955 request.load_flags = 0;
2956
[email protected]d9da5fe2010-10-13 22:37:162957 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:072958 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:112959 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:292960 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072961 session_deps_.net_log = log.bound().net_log();
2962 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:162963
[email protected]262eec82013-03-19 21:01:362964 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502965 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:162966
[email protected]d9da5fe2010-10-13 22:37:162967 // CONNECT to www.google.com:443 via SPDY
[email protected]fba2dbde2013-05-24 16:09:012968 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1));
[email protected]c10b20852013-05-15 21:29:202969 scoped_ptr<SpdyFrame> get(
2970 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:162971
2972 MockWrite spdy_writes[] = {
2973 CreateMockWrite(*connect, 1),
2974 CreateMockWrite(*get, 3),
2975 };
2976
[email protected]23e482282013-06-14 16:08:022977 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdySynReplyError(1));
2978 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:162979 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:062980 CreateMockRead(*resp, 2, ASYNC),
2981 MockRead(ASYNC, 0, 4),
[email protected]d9da5fe2010-10-13 22:37:162982 };
2983
[email protected]dd54bd82012-07-19 23:44:572984 OrderedSocketData spdy_data(
2985 spdy_reads, arraysize(spdy_reads),
2986 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:072987 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:162988
[email protected]8ddf8322012-02-23 18:08:062989 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:022990 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:072991 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:062992 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:022993 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:072994 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:162995
[email protected]49639fa2011-12-20 23:22:412996 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:162997
[email protected]49639fa2011-12-20 23:22:412998 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:162999 EXPECT_EQ(ERR_IO_PENDING, rv);
3000
3001 rv = callback1.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:173002 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]d9da5fe2010-10-13 22:37:163003
[email protected]4eddbc732012-08-09 05:40:173004 // TODO(ttuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:163005}
3006
[email protected]f6c63db52013-02-02 00:35:223007// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
3008// HTTPS Proxy to different servers.
[email protected]23e482282013-06-14 16:08:023009TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:223010 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
3011 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073012 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:223013 "https://proxy:70"));
3014 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073015 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:223016 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:073017 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:223018
3019 HttpRequestInfo request1;
3020 request1.method = "GET";
3021 request1.url = GURL("https://www.google.com/");
3022 request1.load_flags = 0;
3023
3024 HttpRequestInfo request2;
3025 request2.method = "GET";
3026 request2.url = GURL("https://news.google.com/");
3027 request2.load_flags = 0;
3028
3029 // CONNECT to www.google.com:443 via SPDY.
[email protected]fba2dbde2013-05-24 16:09:013030 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(NULL, 0, 1));
[email protected]23e482282013-06-14 16:08:023031 scoped_ptr<SpdyFrame> conn_resp1(
3032 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:223033
3034 // Fetch https://www.google.com/ via HTTP.
3035 const char get1[] = "GET / HTTP/1.1\r\n"
3036 "Host: www.google.com\r\n"
3037 "Connection: keep-alive\r\n\r\n";
3038 scoped_ptr<SpdyFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:023039 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:223040 const char resp1[] = "HTTP/1.1 200 OK\r\n"
3041 "Content-Length: 1\r\n\r\n";
3042 scoped_ptr<SpdyFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:023043 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
3044 scoped_ptr<SpdyFrame> wrapped_body1(
3045 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
[email protected]f6c63db52013-02-02 00:35:223046 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203047 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:223048
3049 // CONNECT to news.google.com:443 via SPDY.
3050 const char* const kConnectHeaders2[] = {
[email protected]23e482282013-06-14 16:08:023051 spdy_util_.GetMethodKey(), "CONNECT",
3052 spdy_util_.GetPathKey(), "news.google.com:443",
3053 spdy_util_.GetHostKey(), "news.google.com",
3054 spdy_util_.GetVersionKey(), "HTTP/1.1",
[email protected]f6c63db52013-02-02 00:35:223055 };
3056 scoped_ptr<SpdyFrame> connect2(
[email protected]4bd46222013-05-14 19:32:233057 spdy_util_.ConstructSpdyControlFrame(NULL,
3058 0,
3059 /*compressed*/ false,
3060 3,
3061 LOWEST,
3062 SYN_STREAM,
3063 CONTROL_FLAG_NONE,
3064 kConnectHeaders2,
3065 arraysize(kConnectHeaders2),
3066 0));
[email protected]23e482282013-06-14 16:08:023067 scoped_ptr<SpdyFrame> conn_resp2(
3068 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:223069
3070 // Fetch https://news.google.com/ via HTTP.
3071 const char get2[] = "GET / HTTP/1.1\r\n"
3072 "Host: news.google.com\r\n"
3073 "Connection: keep-alive\r\n\r\n";
3074 scoped_ptr<SpdyFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:023075 spdy_util_.ConstructSpdyBodyFrame(3, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:223076 const char resp2[] = "HTTP/1.1 200 OK\r\n"
3077 "Content-Length: 2\r\n\r\n";
3078 scoped_ptr<SpdyFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:023079 spdy_util_.ConstructSpdyBodyFrame(3, resp2, strlen(resp2), false));
[email protected]f6c63db52013-02-02 00:35:223080 scoped_ptr<SpdyFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:023081 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:223082
3083 MockWrite spdy_writes[] = {
3084 CreateMockWrite(*connect1, 0),
3085 CreateMockWrite(*wrapped_get1, 2),
3086 CreateMockWrite(*connect2, 5),
3087 CreateMockWrite(*wrapped_get2, 7),
3088 };
3089
3090 MockRead spdy_reads[] = {
3091 CreateMockRead(*conn_resp1, 1, ASYNC),
3092 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
3093 CreateMockRead(*wrapped_body1, 4, ASYNC),
3094 CreateMockRead(*conn_resp2, 6, ASYNC),
3095 CreateMockRead(*wrapped_get_resp2, 8, ASYNC),
3096 CreateMockRead(*wrapped_body2, 9, ASYNC),
3097 MockRead(ASYNC, 0, 10),
3098 };
3099
3100 DeterministicSocketData spdy_data(
3101 spdy_reads, arraysize(spdy_reads),
3102 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073103 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:223104
3105 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023106 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073107 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:223108 SSLSocketDataProvider ssl2(ASYNC, OK);
3109 ssl2.was_npn_negotiated = false;
3110 ssl2.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:073111 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:223112 SSLSocketDataProvider ssl3(ASYNC, OK);
3113 ssl3.was_npn_negotiated = false;
3114 ssl3.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:073115 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:223116
3117 TestCompletionCallback callback;
3118
[email protected]262eec82013-03-19 21:01:363119 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503120 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223121 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
3122 EXPECT_EQ(ERR_IO_PENDING, rv);
3123 // The first connect and request, each of their responses, and the body.
3124 spdy_data.RunFor(5);
3125
3126 rv = callback.WaitForResult();
3127 EXPECT_EQ(OK, rv);
3128
3129 LoadTimingInfo load_timing_info;
3130 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3131 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3132
3133 const HttpResponseInfo* response = trans->GetResponseInfo();
3134 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503135 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:223136 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3137
3138 std::string response_data;
3139 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
[email protected]90499482013-06-01 00:39:503140 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223141
[email protected]262eec82013-03-19 21:01:363142 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503143 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223144 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
3145 EXPECT_EQ(ERR_IO_PENDING, rv);
3146
3147 // The second connect and request, each of their responses, and the body.
3148 spdy_data.RunFor(5);
3149 rv = callback.WaitForResult();
3150 EXPECT_EQ(OK, rv);
3151
3152 LoadTimingInfo load_timing_info2;
3153 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3154 // Even though the SPDY connection is reused, a new tunnelled connection has
3155 // to be created, so the socket's load timing looks like a fresh connection.
3156 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
3157
3158 // The requests should have different IDs, since they each are using their own
3159 // separate stream.
3160 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
3161
[email protected]90499482013-06-01 00:39:503162 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223163}
3164
3165// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
3166// HTTPS Proxy to the same server.
[email protected]23e482282013-06-14 16:08:023167TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:223168 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
3169 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073170 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:223171 "https://proxy:70"));
3172 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073173 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:223174 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:073175 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:223176
3177 HttpRequestInfo request1;
3178 request1.method = "GET";
3179 request1.url = GURL("https://www.google.com/");
3180 request1.load_flags = 0;
3181
3182 HttpRequestInfo request2;
3183 request2.method = "GET";
3184 request2.url = GURL("https://www.google.com/2");
3185 request2.load_flags = 0;
3186
3187 // CONNECT to www.google.com:443 via SPDY.
[email protected]fba2dbde2013-05-24 16:09:013188 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(NULL, 0, 1));
[email protected]23e482282013-06-14 16:08:023189 scoped_ptr<SpdyFrame> conn_resp1(
3190 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:223191
3192 // Fetch https://www.google.com/ via HTTP.
3193 const char get1[] = "GET / HTTP/1.1\r\n"
3194 "Host: www.google.com\r\n"
3195 "Connection: keep-alive\r\n\r\n";
3196 scoped_ptr<SpdyFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:023197 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:223198 const char resp1[] = "HTTP/1.1 200 OK\r\n"
3199 "Content-Length: 1\r\n\r\n";
3200 scoped_ptr<SpdyFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:023201 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
3202 scoped_ptr<SpdyFrame> wrapped_body1(
3203 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
[email protected]f6c63db52013-02-02 00:35:223204 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203205 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:223206
3207 // Fetch https://www.google.com/2 via HTTP.
3208 const char get2[] = "GET /2 HTTP/1.1\r\n"
3209 "Host: www.google.com\r\n"
3210 "Connection: keep-alive\r\n\r\n";
3211 scoped_ptr<SpdyFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:023212 spdy_util_.ConstructSpdyBodyFrame(1, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:223213 const char resp2[] = "HTTP/1.1 200 OK\r\n"
3214 "Content-Length: 2\r\n\r\n";
3215 scoped_ptr<SpdyFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:023216 spdy_util_.ConstructSpdyBodyFrame(1, resp2, strlen(resp2), false));
[email protected]f6c63db52013-02-02 00:35:223217 scoped_ptr<SpdyFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:023218 spdy_util_.ConstructSpdyBodyFrame(1, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:223219
3220 MockWrite spdy_writes[] = {
3221 CreateMockWrite(*connect1, 0),
3222 CreateMockWrite(*wrapped_get1, 2),
3223 CreateMockWrite(*wrapped_get2, 5),
3224 };
3225
3226 MockRead spdy_reads[] = {
3227 CreateMockRead(*conn_resp1, 1, ASYNC),
3228 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
3229 CreateMockRead(*wrapped_body1, 4, ASYNC),
3230 CreateMockRead(*wrapped_get_resp2, 6, ASYNC),
3231 CreateMockRead(*wrapped_body2, 7, ASYNC),
3232 MockRead(ASYNC, 0, 8),
3233 };
3234
3235 DeterministicSocketData spdy_data(
3236 spdy_reads, arraysize(spdy_reads),
3237 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073238 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:223239
3240 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023241 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073242 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:223243 SSLSocketDataProvider ssl2(ASYNC, OK);
3244 ssl2.was_npn_negotiated = false;
3245 ssl2.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:073246 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:223247
3248 TestCompletionCallback callback;
3249
[email protected]262eec82013-03-19 21:01:363250 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503251 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223252 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
3253 EXPECT_EQ(ERR_IO_PENDING, rv);
3254 // The first connect and request, each of their responses, and the body.
3255 spdy_data.RunFor(5);
3256
3257 rv = callback.WaitForResult();
3258 EXPECT_EQ(OK, rv);
3259
3260 LoadTimingInfo load_timing_info;
3261 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3262 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3263
3264 const HttpResponseInfo* response = trans->GetResponseInfo();
3265 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503266 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:223267 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3268
3269 std::string response_data;
3270 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
[email protected]90499482013-06-01 00:39:503271 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223272 trans.reset();
3273
[email protected]262eec82013-03-19 21:01:363274 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503275 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223276 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
3277 EXPECT_EQ(ERR_IO_PENDING, rv);
3278
3279 // The second request, response, and body. There should not be a second
3280 // connect.
3281 spdy_data.RunFor(3);
3282 rv = callback.WaitForResult();
3283 EXPECT_EQ(OK, rv);
3284
3285 LoadTimingInfo load_timing_info2;
3286 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3287 TestLoadTimingReused(load_timing_info2);
3288
3289 // The requests should have the same ID.
3290 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
3291
[email protected]90499482013-06-01 00:39:503292 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223293}
3294
3295// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
3296// Proxy to different servers.
[email protected]23e482282013-06-14 16:08:023297TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:223298 HttpsProxySpdyLoadTimingTwoHttpRequests) {
3299 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073300 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:223301 "https://proxy:70"));
3302 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073303 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:223304 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:073305 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:223306
3307 HttpRequestInfo request1;
3308 request1.method = "GET";
3309 request1.url = GURL("http://www.google.com/");
3310 request1.load_flags = 0;
3311
3312 HttpRequestInfo request2;
3313 request2.method = "GET";
3314 request2.url = GURL("http://news.google.com/");
3315 request2.load_flags = 0;
3316
3317 // http://www.google.com/
[email protected]23e482282013-06-14 16:08:023318 scoped_ptr<SpdyHeaderBlock> headers(
3319 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/"));
[email protected]4bd46222013-05-14 19:32:233320 scoped_ptr<SpdyFrame> get1(spdy_util_.ConstructSpdyControlFrame(
[email protected]23e482282013-06-14 16:08:023321 headers.Pass(), false, 1, LOWEST, SYN_STREAM, CONTROL_FLAG_FIN, 0));
3322 scoped_ptr<SpdyFrame> get_resp1(
3323 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3324 scoped_ptr<SpdyFrame> body1(
3325 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, true));
[email protected]f6c63db52013-02-02 00:35:223326
3327 // http://news.google.com/
[email protected]23e482282013-06-14 16:08:023328 scoped_ptr<SpdyHeaderBlock> headers2(
3329 spdy_util_.ConstructGetHeaderBlockForProxy("http://news.google.com/"));
[email protected]4bd46222013-05-14 19:32:233330 scoped_ptr<SpdyFrame> get2(spdy_util_.ConstructSpdyControlFrame(
[email protected]23e482282013-06-14 16:08:023331 headers2.Pass(), false, 3, LOWEST, SYN_STREAM, CONTROL_FLAG_FIN, 0));
3332 scoped_ptr<SpdyFrame> get_resp2(
3333 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
3334 scoped_ptr<SpdyFrame> body2(
3335 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, true));
[email protected]f6c63db52013-02-02 00:35:223336
3337 MockWrite spdy_writes[] = {
3338 CreateMockWrite(*get1, 0),
3339 CreateMockWrite(*get2, 3),
3340 };
3341
3342 MockRead spdy_reads[] = {
3343 CreateMockRead(*get_resp1, 1, ASYNC),
3344 CreateMockRead(*body1, 2, ASYNC),
3345 CreateMockRead(*get_resp2, 4, ASYNC),
3346 CreateMockRead(*body2, 5, ASYNC),
3347 MockRead(ASYNC, 0, 6),
3348 };
3349
3350 DeterministicSocketData spdy_data(
3351 spdy_reads, arraysize(spdy_reads),
3352 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073353 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:223354
3355 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023356 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073357 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:223358
3359 TestCompletionCallback callback;
3360
[email protected]262eec82013-03-19 21:01:363361 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503362 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223363 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
3364 EXPECT_EQ(ERR_IO_PENDING, rv);
3365 spdy_data.RunFor(2);
3366
3367 rv = callback.WaitForResult();
3368 EXPECT_EQ(OK, rv);
3369
3370 LoadTimingInfo load_timing_info;
3371 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3372 TestLoadTimingNotReused(load_timing_info,
3373 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3374
3375 const HttpResponseInfo* response = trans->GetResponseInfo();
3376 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503377 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:223378 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3379
3380 std::string response_data;
3381 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
[email protected]90499482013-06-01 00:39:503382 EXPECT_EQ(ERR_IO_PENDING, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223383 spdy_data.RunFor(1);
3384 EXPECT_EQ(1, callback.WaitForResult());
3385 // Delete the first request, so the second one can reuse the socket.
3386 trans.reset();
3387
[email protected]262eec82013-03-19 21:01:363388 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503389 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223390 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
3391 EXPECT_EQ(ERR_IO_PENDING, rv);
3392
3393 spdy_data.RunFor(2);
3394 rv = callback.WaitForResult();
3395 EXPECT_EQ(OK, rv);
3396
3397 LoadTimingInfo load_timing_info2;
3398 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3399 TestLoadTimingReused(load_timing_info2);
3400
3401 // The requests should have the same ID.
3402 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
3403
[email protected]90499482013-06-01 00:39:503404 EXPECT_EQ(ERR_IO_PENDING, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223405 spdy_data.RunFor(1);
3406 EXPECT_EQ(2, callback.WaitForResult());
3407}
3408
[email protected]2df19bb2010-08-25 20:13:463409// Test the challenge-response-retry sequence through an HTTPS Proxy
[email protected]23e482282013-06-14 16:08:023410TEST_P(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:463411 HttpRequestInfo request;
3412 request.method = "GET";
3413 request.url = GURL("http://www.google.com/");
3414 // when the no authentication data flag is set.
3415 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
3416
[email protected]79cb5c12011-09-12 13:12:043417 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073418 session_deps_.proxy_service.reset(
[email protected]79cb5c12011-09-12 13:12:043419 ProxyService::CreateFixed("https://myproxy:70"));
[email protected]333bdf62012-06-08 22:57:293420 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073421 session_deps_.net_log = log.bound().net_log();
3422 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273423
[email protected]2df19bb2010-08-25 20:13:463424 // Since we have proxy, should use full url
3425 MockWrite data_writes1[] = {
3426 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
3427 "Host: www.google.com\r\n"
3428 "Proxy-Connection: keep-alive\r\n\r\n"),
3429
3430 // After calling trans->RestartWithAuth(), this is the request we should
3431 // be issuing -- the final header line contains the credentials.
3432 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
3433 "Host: www.google.com\r\n"
3434 "Proxy-Connection: keep-alive\r\n"
3435 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3436 };
3437
3438 // The proxy responds to the GET with a 407, using a persistent
3439 // connection.
3440 MockRead data_reads1[] = {
3441 // No credentials.
3442 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3443 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3444 MockRead("Proxy-Connection: keep-alive\r\n"),
3445 MockRead("Content-Length: 0\r\n\r\n"),
3446
3447 MockRead("HTTP/1.1 200 OK\r\n"),
3448 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3449 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063450 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:463451 };
3452
3453 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3454 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073455 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063456 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073457 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:463458
[email protected]49639fa2011-12-20 23:22:413459 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:463460
[email protected]262eec82013-03-19 21:01:363461 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503462 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503463
[email protected]49639fa2011-12-20 23:22:413464 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:463465 EXPECT_EQ(ERR_IO_PENDING, rv);
3466
3467 rv = callback1.WaitForResult();
3468 EXPECT_EQ(OK, rv);
3469
[email protected]58e32bb2013-01-21 18:23:253470 LoadTimingInfo load_timing_info;
3471 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3472 TestLoadTimingNotReused(load_timing_info,
3473 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3474
[email protected]2df19bb2010-08-25 20:13:463475 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503476 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503477 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]2df19bb2010-08-25 20:13:463478 EXPECT_EQ(407, response->headers->response_code());
3479 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043480 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:463481
[email protected]49639fa2011-12-20 23:22:413482 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:463483
[email protected]49639fa2011-12-20 23:22:413484 rv = trans->RestartWithAuth(
3485 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]2df19bb2010-08-25 20:13:463486 EXPECT_EQ(ERR_IO_PENDING, rv);
3487
3488 rv = callback2.WaitForResult();
3489 EXPECT_EQ(OK, rv);
3490
[email protected]58e32bb2013-01-21 18:23:253491 load_timing_info = LoadTimingInfo();
3492 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3493 // Retrying with HTTP AUTH is considered to be reusing a socket.
3494 TestLoadTimingReused(load_timing_info);
3495
[email protected]2df19bb2010-08-25 20:13:463496 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503497 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:463498
3499 EXPECT_TRUE(response->headers->IsKeepAlive());
3500 EXPECT_EQ(200, response->headers->response_code());
3501 EXPECT_EQ(100, response->headers->GetContentLength());
3502 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3503
3504 // The password prompt info should not be set.
3505 EXPECT_TRUE(response->auth_challenge.get() == NULL);
3506}
3507
[email protected]23e482282013-06-14 16:08:023508void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:083509 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:423510 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:083511 request.method = "GET";
3512 request.url = GURL("https://www.google.com/");
3513 request.load_flags = 0;
3514
[email protected]cb9bf6ca2011-01-28 13:15:273515 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073516 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]cb9bf6ca2011-01-28 13:15:273517
[email protected]bb88e1d32013-05-03 23:11:073518 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273519
[email protected]c744cf22009-02-27 07:28:083520 // Since we have proxy, should try to establish tunnel.
3521 MockWrite data_writes[] = {
3522 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:453523 "Host: www.google.com\r\n"
3524 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:083525 };
3526
3527 MockRead data_reads[] = {
3528 status,
3529 MockRead("Content-Length: 10\r\n\r\n"),
3530 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:063531 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]c744cf22009-02-27 07:28:083532 };
3533
[email protected]31a2bfe2010-02-09 08:03:393534 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
3535 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:073536 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:083537
[email protected]49639fa2011-12-20 23:22:413538 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:083539
[email protected]262eec82013-03-19 21:01:363540 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503541 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503542
[email protected]49639fa2011-12-20 23:22:413543 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:423544 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]c744cf22009-02-27 07:28:083545
3546 rv = callback.WaitForResult();
3547 EXPECT_EQ(expected_status, rv);
3548}
3549
[email protected]23e482282013-06-14 16:08:023550void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:233551 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:083552 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:423553 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:083554}
3555
[email protected]23e482282013-06-14 16:08:023556TEST_P(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:083557 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
3558}
3559
[email protected]23e482282013-06-14 16:08:023560TEST_P(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:083561 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
3562}
3563
[email protected]23e482282013-06-14 16:08:023564TEST_P(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:083565 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
3566}
3567
[email protected]23e482282013-06-14 16:08:023568TEST_P(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:083569 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
3570}
3571
[email protected]23e482282013-06-14 16:08:023572TEST_P(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:083573 ConnectStatusHelper(
3574 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
3575}
3576
[email protected]23e482282013-06-14 16:08:023577TEST_P(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:083578 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
3579}
3580
[email protected]23e482282013-06-14 16:08:023581TEST_P(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:083582 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
3583}
3584
[email protected]23e482282013-06-14 16:08:023585TEST_P(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:083586 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
3587}
3588
[email protected]23e482282013-06-14 16:08:023589TEST_P(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:083590 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
3591}
3592
[email protected]23e482282013-06-14 16:08:023593TEST_P(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:083594 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
3595}
3596
[email protected]23e482282013-06-14 16:08:023597TEST_P(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:083598 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
3599}
3600
[email protected]23e482282013-06-14 16:08:023601TEST_P(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:083602 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
3603}
3604
[email protected]23e482282013-06-14 16:08:023605TEST_P(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:083606 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
3607}
3608
[email protected]23e482282013-06-14 16:08:023609TEST_P(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:083610 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
3611}
3612
[email protected]23e482282013-06-14 16:08:023613TEST_P(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:083614 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
3615}
3616
[email protected]23e482282013-06-14 16:08:023617TEST_P(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:083618 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
3619}
3620
[email protected]23e482282013-06-14 16:08:023621TEST_P(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:083622 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
3623}
3624
[email protected]23e482282013-06-14 16:08:023625TEST_P(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:083626 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
3627}
3628
[email protected]23e482282013-06-14 16:08:023629TEST_P(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:083630 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
3631}
3632
[email protected]23e482282013-06-14 16:08:023633TEST_P(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:083634 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
3635}
3636
[email protected]23e482282013-06-14 16:08:023637TEST_P(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:083638 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
3639}
3640
[email protected]23e482282013-06-14 16:08:023641TEST_P(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:083642 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
3643}
3644
[email protected]23e482282013-06-14 16:08:023645TEST_P(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:083646 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
3647}
3648
[email protected]23e482282013-06-14 16:08:023649TEST_P(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:083650 ConnectStatusHelperWithExpectedStatus(
3651 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:543652 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:083653}
3654
[email protected]23e482282013-06-14 16:08:023655TEST_P(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:083656 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
3657}
3658
[email protected]23e482282013-06-14 16:08:023659TEST_P(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:083660 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
3661}
3662
[email protected]23e482282013-06-14 16:08:023663TEST_P(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:083664 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
3665}
3666
[email protected]23e482282013-06-14 16:08:023667TEST_P(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:083668 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
3669}
3670
[email protected]23e482282013-06-14 16:08:023671TEST_P(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:083672 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
3673}
3674
[email protected]23e482282013-06-14 16:08:023675TEST_P(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:083676 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
3677}
3678
[email protected]23e482282013-06-14 16:08:023679TEST_P(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:083680 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
3681}
3682
[email protected]23e482282013-06-14 16:08:023683TEST_P(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:083684 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
3685}
3686
[email protected]23e482282013-06-14 16:08:023687TEST_P(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:083688 ConnectStatusHelper(
3689 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
3690}
3691
[email protected]23e482282013-06-14 16:08:023692TEST_P(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:083693 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
3694}
3695
[email protected]23e482282013-06-14 16:08:023696TEST_P(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:083697 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
3698}
3699
[email protected]23e482282013-06-14 16:08:023700TEST_P(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:083701 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
3702}
3703
[email protected]23e482282013-06-14 16:08:023704TEST_P(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:083705 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
3706}
3707
[email protected]23e482282013-06-14 16:08:023708TEST_P(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:083709 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
3710}
3711
[email protected]23e482282013-06-14 16:08:023712TEST_P(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:083713 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
3714}
3715
[email protected]23e482282013-06-14 16:08:023716TEST_P(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:083717 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
3718}
3719
[email protected]038e9a32008-10-08 22:40:163720// Test the flow when both the proxy server AND origin server require
3721// authentication. Again, this uses basic auth for both since that is
3722// the simplest to mock.
[email protected]23e482282013-06-14 16:08:023723TEST_P(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:273724 HttpRequestInfo request;
3725 request.method = "GET";
3726 request.url = GURL("http://www.google.com/");
3727 request.load_flags = 0;
3728
[email protected]bb88e1d32013-05-03 23:11:073729 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]db8f44c2008-12-13 04:52:013730
[email protected]038e9a32008-10-08 22:40:163731 // Configure against proxy server "myproxy:70".
[email protected]262eec82013-03-19 21:01:363732 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:073733 CreateSession(&session_deps_)));
[email protected]038e9a32008-10-08 22:40:163734
[email protected]f9ee6b52008-11-08 06:46:233735 MockWrite data_writes1[] = {
3736 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
3737 "Host: www.google.com\r\n"
3738 "Proxy-Connection: keep-alive\r\n\r\n"),
3739 };
3740
[email protected]038e9a32008-10-08 22:40:163741 MockRead data_reads1[] = {
3742 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
3743 // Give a couple authenticate options (only the middle one is actually
3744 // supported).
[email protected]22927ad2009-09-21 19:56:193745 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:163746 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3747 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
3748 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3749 // Large content-length -- won't matter, as connection will be reset.
3750 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063751 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:163752 };
3753
3754 // After calling trans->RestartWithAuth() the first time, this is the
3755 // request we should be issuing -- the final header line contains the
3756 // proxy's credentials.
3757 MockWrite data_writes2[] = {
3758 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
3759 "Host: www.google.com\r\n"
3760 "Proxy-Connection: keep-alive\r\n"
3761 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3762 };
3763
3764 // Now the proxy server lets the request pass through to origin server.
3765 // The origin server responds with a 401.
3766 MockRead data_reads2[] = {
3767 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
3768 // Note: We are using the same realm-name as the proxy server. This is
3769 // completely valid, as realms are unique across hosts.
3770 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3771 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3772 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063773 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:163774 };
3775
3776 // After calling trans->RestartWithAuth() the second time, we should send
3777 // the credentials for both the proxy and origin server.
3778 MockWrite data_writes3[] = {
3779 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
3780 "Host: www.google.com\r\n"
3781 "Proxy-Connection: keep-alive\r\n"
3782 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
3783 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
3784 };
3785
3786 // Lastly we get the desired content.
3787 MockRead data_reads3[] = {
3788 MockRead("HTTP/1.0 200 OK\r\n"),
3789 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3790 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063791 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:163792 };
3793
[email protected]31a2bfe2010-02-09 08:03:393794 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3795 data_writes1, arraysize(data_writes1));
3796 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3797 data_writes2, arraysize(data_writes2));
3798 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
3799 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:073800 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3801 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3802 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:163803
[email protected]49639fa2011-12-20 23:22:413804 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:163805
[email protected]49639fa2011-12-20 23:22:413806 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:423807 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:163808
3809 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:423810 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:163811
[email protected]1c773ea12009-04-28 19:58:423812 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503813 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:043814 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:163815
[email protected]49639fa2011-12-20 23:22:413816 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:163817
[email protected]49639fa2011-12-20 23:22:413818 rv = trans->RestartWithAuth(
3819 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:423820 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:163821
3822 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:423823 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:163824
3825 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503826 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:043827 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:163828
[email protected]49639fa2011-12-20 23:22:413829 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:163830
[email protected]49639fa2011-12-20 23:22:413831 rv = trans->RestartWithAuth(
3832 AuthCredentials(kFoo2, kBar2), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:423833 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:163834
3835 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:423836 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:163837
3838 response = trans->GetResponseInfo();
3839 EXPECT_TRUE(response->auth_challenge.get() == NULL);
3840 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:163841}
[email protected]4ddaf2502008-10-23 18:26:193842
[email protected]ea9dc9a2009-09-05 00:43:323843// For the NTLM implementation using SSPI, we skip the NTLM tests since we
3844// can't hook into its internals to cause it to generate predictable NTLM
3845// authorization headers.
3846#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:293847// The NTLM authentication unit tests were generated by capturing the HTTP
3848// requests and responses using Fiddler 2 and inspecting the generated random
3849// bytes in the debugger.
3850
3851// Enter the correct password and authenticate successfully.
[email protected]23e482282013-06-14 16:08:023852TEST_P(HttpNetworkTransactionTest, NTLMAuth1) {
[email protected]1c773ea12009-04-28 19:58:423853 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:243854 request.method = "GET";
3855 request.url = GURL("http://172.22.68.17/kids/login.aspx");
3856 request.load_flags = 0;
3857
[email protected]cb9bf6ca2011-01-28 13:15:273858 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
3859 MockGetHostName);
[email protected]bb88e1d32013-05-03 23:11:073860 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273861
[email protected]3f918782009-02-28 01:29:243862 MockWrite data_writes1[] = {
3863 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
3864 "Host: 172.22.68.17\r\n"
3865 "Connection: keep-alive\r\n\r\n"),
3866 };
3867
3868 MockRead data_reads1[] = {
3869 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:043870 // Negotiate and NTLM are often requested together. However, we only want
3871 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
3872 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:243873 MockRead("WWW-Authenticate: NTLM\r\n"),
3874 MockRead("Connection: close\r\n"),
3875 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:363876 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:243877 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:063878 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]3f918782009-02-28 01:29:243879 };
3880
3881 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:223882 // After restarting with a null identity, this is the
[email protected]3f918782009-02-28 01:29:243883 // request we should be issuing -- the final header line contains a Type
3884 // 1 message.
3885 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
3886 "Host: 172.22.68.17\r\n"
3887 "Connection: keep-alive\r\n"
3888 "Authorization: NTLM "
3889 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
3890
3891 // After calling trans->RestartWithAuth(), we should send a Type 3 message
3892 // (the credentials for the origin server). The second request continues
3893 // on the same connection.
3894 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
3895 "Host: 172.22.68.17\r\n"
3896 "Connection: keep-alive\r\n"
[email protected]385a4672009-03-11 22:21:293897 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
3898 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
3899 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
3900 "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
3901 "ahlhx5I=\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:243902 };
3903
3904 MockRead data_reads2[] = {
3905 // The origin server responds with a Type 2 message.
3906 MockRead("HTTP/1.1 401 Access Denied\r\n"),
3907 MockRead("WWW-Authenticate: NTLM "
[email protected]385a4672009-03-11 22:21:293908 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
[email protected]3f918782009-02-28 01:29:243909 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
3910 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
3911 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
3912 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
3913 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
3914 "BtAAAAAAA=\r\n"),
3915 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:363916 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:243917 MockRead("You are not authorized to view this page\r\n"),
3918
3919 // Lastly we get the desired content.
3920 MockRead("HTTP/1.1 200 OK\r\n"),
3921 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
3922 MockRead("Content-Length: 13\r\n\r\n"),
3923 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:063924 MockRead(SYNCHRONOUS, OK),
[email protected]3f918782009-02-28 01:29:243925 };
3926
[email protected]31a2bfe2010-02-09 08:03:393927 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3928 data_writes1, arraysize(data_writes1));
3929 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3930 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:073931 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3932 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:243933
[email protected]49639fa2011-12-20 23:22:413934 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:243935
[email protected]262eec82013-03-19 21:01:363936 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503937 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503938
[email protected]49639fa2011-12-20 23:22:413939 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:423940 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:243941
3942 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:423943 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:243944
[email protected]0757e7702009-03-27 04:00:223945 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
3946
[email protected]1c773ea12009-04-28 19:58:423947 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:043948 ASSERT_FALSE(response == NULL);
3949 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:243950
[email protected]49639fa2011-12-20 23:22:413951 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:253952
[email protected]f3cf9802011-10-28 18:44:583953 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:413954 callback2.callback());
[email protected]10af5fe72011-01-31 16:17:253955 EXPECT_EQ(ERR_IO_PENDING, rv);
3956
3957 rv = callback2.WaitForResult();
3958 EXPECT_EQ(OK, rv);
3959
3960 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
3961
3962 response = trans->GetResponseInfo();
3963 ASSERT_TRUE(response != NULL);
[email protected]10af5fe72011-01-31 16:17:253964 EXPECT_TRUE(response->auth_challenge.get() == NULL);
3965
[email protected]49639fa2011-12-20 23:22:413966 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:243967
[email protected]49639fa2011-12-20 23:22:413968 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:423969 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:243970
[email protected]0757e7702009-03-27 04:00:223971 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:423972 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:243973
3974 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503975 ASSERT_TRUE(response != NULL);
[email protected]3f918782009-02-28 01:29:243976 EXPECT_TRUE(response->auth_challenge.get() == NULL);
3977 EXPECT_EQ(13, response->headers->GetContentLength());
3978}
3979
[email protected]385a4672009-03-11 22:21:293980// Enter a wrong password, and then the correct one.
[email protected]23e482282013-06-14 16:08:023981TEST_P(HttpNetworkTransactionTest, NTLMAuth2) {
[email protected]1c773ea12009-04-28 19:58:423982 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:293983 request.method = "GET";
3984 request.url = GURL("http://172.22.68.17/kids/login.aspx");
3985 request.load_flags = 0;
3986
[email protected]cb9bf6ca2011-01-28 13:15:273987 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
3988 MockGetHostName);
[email protected]bb88e1d32013-05-03 23:11:073989 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273990
[email protected]385a4672009-03-11 22:21:293991 MockWrite data_writes1[] = {
3992 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
3993 "Host: 172.22.68.17\r\n"
3994 "Connection: keep-alive\r\n\r\n"),
3995 };
3996
3997 MockRead data_reads1[] = {
3998 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:043999 // Negotiate and NTLM are often requested together. However, we only want
4000 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
4001 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:294002 MockRead("WWW-Authenticate: NTLM\r\n"),
4003 MockRead("Connection: close\r\n"),
4004 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364005 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294006 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064007 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:294008 };
4009
4010 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:224011 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:294012 // request we should be issuing -- the final header line contains a Type
4013 // 1 message.
4014 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4015 "Host: 172.22.68.17\r\n"
4016 "Connection: keep-alive\r\n"
4017 "Authorization: NTLM "
4018 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4019
4020 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4021 // (the credentials for the origin server). The second request continues
4022 // on the same connection.
4023 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4024 "Host: 172.22.68.17\r\n"
4025 "Connection: keep-alive\r\n"
4026 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4027 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4028 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
4029 "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
4030 "4Ww7b7E=\r\n\r\n"),
4031 };
4032
4033 MockRead data_reads2[] = {
4034 // The origin server responds with a Type 2 message.
4035 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4036 MockRead("WWW-Authenticate: NTLM "
4037 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
4038 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4039 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4040 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4041 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4042 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4043 "BtAAAAAAA=\r\n"),
4044 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364045 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294046 MockRead("You are not authorized to view this page\r\n"),
4047
4048 // Wrong password.
4049 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]385a4672009-03-11 22:21:294050 MockRead("WWW-Authenticate: NTLM\r\n"),
4051 MockRead("Connection: close\r\n"),
4052 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364053 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294054 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064055 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:294056 };
4057
4058 MockWrite data_writes3[] = {
[email protected]0757e7702009-03-27 04:00:224059 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:294060 // request we should be issuing -- the final header line contains a Type
4061 // 1 message.
4062 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4063 "Host: 172.22.68.17\r\n"
4064 "Connection: keep-alive\r\n"
4065 "Authorization: NTLM "
4066 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4067
4068 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4069 // (the credentials for the origin server). The second request continues
4070 // on the same connection.
4071 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4072 "Host: 172.22.68.17\r\n"
4073 "Connection: keep-alive\r\n"
4074 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4075 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4076 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
4077 "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
4078 "+4MUm7c=\r\n\r\n"),
4079 };
4080
4081 MockRead data_reads3[] = {
4082 // The origin server responds with a Type 2 message.
4083 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4084 MockRead("WWW-Authenticate: NTLM "
4085 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
4086 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4087 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4088 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4089 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4090 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4091 "BtAAAAAAA=\r\n"),
4092 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364093 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294094 MockRead("You are not authorized to view this page\r\n"),
4095
4096 // Lastly we get the desired content.
4097 MockRead("HTTP/1.1 200 OK\r\n"),
4098 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
4099 MockRead("Content-Length: 13\r\n\r\n"),
4100 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:064101 MockRead(SYNCHRONOUS, OK),
[email protected]385a4672009-03-11 22:21:294102 };
4103
[email protected]31a2bfe2010-02-09 08:03:394104 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4105 data_writes1, arraysize(data_writes1));
4106 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4107 data_writes2, arraysize(data_writes2));
4108 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4109 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:074110 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4111 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4112 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:294113
[email protected]49639fa2011-12-20 23:22:414114 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:294115
[email protected]262eec82013-03-19 21:01:364116 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504117 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504118
[email protected]49639fa2011-12-20 23:22:414119 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424120 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:294121
4122 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424123 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:294124
[email protected]0757e7702009-03-27 04:00:224125 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:294126
[email protected]1c773ea12009-04-28 19:58:424127 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504128 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044129 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:294130
[email protected]49639fa2011-12-20 23:22:414131 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:294132
[email protected]0757e7702009-03-27 04:00:224133 // Enter the wrong password.
[email protected]f3cf9802011-10-28 18:44:584134 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword),
[email protected]49639fa2011-12-20 23:22:414135 callback2.callback());
[email protected]1c773ea12009-04-28 19:58:424136 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:294137
[email protected]10af5fe72011-01-31 16:17:254138 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424139 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:294140
[email protected]0757e7702009-03-27 04:00:224141 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:414142 TestCompletionCallback callback3;
4143 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424144 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]10af5fe72011-01-31 16:17:254145 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424146 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:224147 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4148
4149 response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:044150 ASSERT_FALSE(response == NULL);
4151 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:224152
[email protected]49639fa2011-12-20 23:22:414153 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:224154
4155 // Now enter the right password.
[email protected]f3cf9802011-10-28 18:44:584156 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:414157 callback4.callback());
[email protected]10af5fe72011-01-31 16:17:254158 EXPECT_EQ(ERR_IO_PENDING, rv);
4159
4160 rv = callback4.WaitForResult();
4161 EXPECT_EQ(OK, rv);
4162
4163 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4164
[email protected]49639fa2011-12-20 23:22:414165 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:254166
4167 // One more roundtrip
[email protected]49639fa2011-12-20 23:22:414168 rv = trans->RestartWithAuth(AuthCredentials(), callback5.callback());
[email protected]1c773ea12009-04-28 19:58:424169 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:224170
4171 rv = callback5.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424172 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:224173
[email protected]385a4672009-03-11 22:21:294174 response = trans->GetResponseInfo();
4175 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4176 EXPECT_EQ(13, response->headers->GetContentLength());
4177}
[email protected]ea9dc9a2009-09-05 00:43:324178#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:294179
[email protected]4ddaf2502008-10-23 18:26:194180// Test reading a server response which has only headers, and no body.
4181// After some maximum number of bytes is consumed, the transaction should
4182// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
[email protected]23e482282013-06-14 16:08:024183TEST_P(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:424184 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:194185 request.method = "GET";
4186 request.url = GURL("http://www.google.com/");
4187 request.load_flags = 0;
4188
[email protected]cb9bf6ca2011-01-28 13:15:274189 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:364190 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:074191 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:274192
[email protected]b75b7b2f2009-10-06 00:54:534193 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:434194 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:534195 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:194196
4197 MockRead data_reads[] = {
4198 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:064199 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:194200 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:064201 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:194202 };
[email protected]31a2bfe2010-02-09 08:03:394203 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:074204 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:194205
[email protected]49639fa2011-12-20 23:22:414206 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:194207
[email protected]49639fa2011-12-20 23:22:414208 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424209 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]4ddaf2502008-10-23 18:26:194210
4211 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424212 EXPECT_EQ(ERR_RESPONSE_HEADERS_TOO_BIG, rv);
[email protected]4ddaf2502008-10-23 18:26:194213
[email protected]1c773ea12009-04-28 19:58:424214 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]4ddaf2502008-10-23 18:26:194215 EXPECT_TRUE(response == NULL);
4216}
[email protected]f4e426b2008-11-05 00:24:494217
4218// Make sure that we don't try to reuse a TCPClientSocket when failing to
4219// establish tunnel.
4220// http://code.google.com/p/chromium/issues/detail?id=3772
[email protected]23e482282013-06-14 16:08:024221TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:234222 DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:274223 HttpRequestInfo request;
4224 request.method = "GET";
4225 request.url = GURL("https://www.google.com/");
4226 request.load_flags = 0;
4227
[email protected]f4e426b2008-11-05 00:24:494228 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:074229 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]db8f44c2008-12-13 04:52:014230
[email protected]bb88e1d32013-05-03 23:11:074231 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:494232
[email protected]262eec82013-03-19 21:01:364233 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504234 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f4e426b2008-11-05 00:24:494235
[email protected]f4e426b2008-11-05 00:24:494236 // Since we have proxy, should try to establish tunnel.
4237 MockWrite data_writes1[] = {
4238 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:454239 "Host: www.google.com\r\n"
4240 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:494241 };
4242
[email protected]77848d12008-11-14 00:00:224243 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:494244 // connection. Usually a proxy would return 501 (not implemented),
4245 // or 200 (tunnel established).
4246 MockRead data_reads1[] = {
4247 MockRead("HTTP/1.1 404 Not Found\r\n"),
4248 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064249 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]f4e426b2008-11-05 00:24:494250 };
4251
[email protected]31a2bfe2010-02-09 08:03:394252 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4253 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074254 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:494255
[email protected]49639fa2011-12-20 23:22:414256 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:494257
[email protected]49639fa2011-12-20 23:22:414258 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424259 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f4e426b2008-11-05 00:24:494260
4261 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424262 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]f4e426b2008-11-05 00:24:494263
[email protected]1c773ea12009-04-28 19:58:424264 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]c744cf22009-02-27 07:28:084265 EXPECT_TRUE(response == NULL);
[email protected]f4e426b2008-11-05 00:24:494266
[email protected]b4404c02009-04-10 16:38:524267 // Empty the current queue. This is necessary because idle sockets are
4268 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344269 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:524270
[email protected]f4e426b2008-11-05 00:24:494271 // We now check to make sure the TCPClientSocket was not added back to
4272 // the pool.
[email protected]90499482013-06-01 00:39:504273 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:494274 trans.reset();
[email protected]2da659e2013-05-23 20:51:344275 base::MessageLoop::current()->RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:494276 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:504277 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:494278}
[email protected]372d34a2008-11-05 21:30:514279
[email protected]1b157c02009-04-21 01:55:404280// Make sure that we recycle a socket after reading all of the response body.
[email protected]23e482282013-06-14 16:08:024281TEST_P(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:424282 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:404283 request.method = "GET";
4284 request.url = GURL("http://www.google.com/");
4285 request.load_flags = 0;
4286
[email protected]bb88e1d32013-05-03 23:11:074287 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274288
[email protected]262eec82013-03-19 21:01:364289 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504290 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:274291
[email protected]1b157c02009-04-21 01:55:404292 MockRead data_reads[] = {
4293 // A part of the response body is received with the response headers.
4294 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
4295 // The rest of the response body is received in two parts.
4296 MockRead("lo"),
4297 MockRead(" world"),
4298 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:064299 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:404300 };
4301
[email protected]31a2bfe2010-02-09 08:03:394302 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:074303 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:404304
[email protected]49639fa2011-12-20 23:22:414305 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:404306
[email protected]49639fa2011-12-20 23:22:414307 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424308 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]1b157c02009-04-21 01:55:404309
4310 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424311 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:404312
[email protected]1c773ea12009-04-28 19:58:424313 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504314 ASSERT_TRUE(response != NULL);
[email protected]1b157c02009-04-21 01:55:404315
[email protected]90499482013-06-01 00:39:504316 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]1b157c02009-04-21 01:55:404317 std::string status_line = response->headers->GetStatusLine();
4318 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
4319
[email protected]90499482013-06-01 00:39:504320 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:404321
4322 std::string response_data;
4323 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:424324 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:404325 EXPECT_EQ("hello world", response_data);
4326
4327 // Empty the current queue. This is necessary because idle sockets are
4328 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344329 base::MessageLoop::current()->RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:404330
4331 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504332 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:404333}
4334
[email protected]76a505b2010-08-25 06:23:004335// Make sure that we recycle a SSL socket after reading all of the response
4336// body.
[email protected]23e482282013-06-14 16:08:024337TEST_P(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:004338 HttpRequestInfo request;
4339 request.method = "GET";
4340 request.url = GURL("https://www.google.com/");
4341 request.load_flags = 0;
4342
4343 MockWrite data_writes[] = {
4344 MockWrite("GET / HTTP/1.1\r\n"
4345 "Host: www.google.com\r\n"
4346 "Connection: keep-alive\r\n\r\n"),
4347 };
4348
4349 MockRead data_reads[] = {
4350 MockRead("HTTP/1.1 200 OK\r\n"),
4351 MockRead("Content-Length: 11\r\n\r\n"),
4352 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:064353 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:004354 };
4355
[email protected]8ddf8322012-02-23 18:08:064356 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074357 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:004358
4359 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
4360 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:074361 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:004362
[email protected]49639fa2011-12-20 23:22:414363 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:004364
[email protected]bb88e1d32013-05-03 23:11:074365 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:364366 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504367 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:004368
[email protected]49639fa2011-12-20 23:22:414369 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:004370
4371 EXPECT_EQ(ERR_IO_PENDING, rv);
4372 EXPECT_EQ(OK, callback.WaitForResult());
4373
4374 const HttpResponseInfo* response = trans->GetResponseInfo();
4375 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504376 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:004377 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4378
[email protected]90499482013-06-01 00:39:504379 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004380
4381 std::string response_data;
4382 rv = ReadTransaction(trans.get(), &response_data);
4383 EXPECT_EQ(OK, rv);
4384 EXPECT_EQ("hello world", response_data);
4385
4386 // Empty the current queue. This is necessary because idle sockets are
4387 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344388 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:004389
4390 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504391 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004392}
4393
4394// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
4395// from the pool and make sure that we recover okay.
[email protected]23e482282013-06-14 16:08:024396TEST_P(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:004397 HttpRequestInfo request;
4398 request.method = "GET";
4399 request.url = GURL("https://www.google.com/");
4400 request.load_flags = 0;
4401
4402 MockWrite data_writes[] = {
4403 MockWrite("GET / HTTP/1.1\r\n"
4404 "Host: www.google.com\r\n"
4405 "Connection: keep-alive\r\n\r\n"),
4406 MockWrite("GET / HTTP/1.1\r\n"
4407 "Host: www.google.com\r\n"
4408 "Connection: keep-alive\r\n\r\n"),
4409 };
4410
4411 MockRead data_reads[] = {
4412 MockRead("HTTP/1.1 200 OK\r\n"),
4413 MockRead("Content-Length: 11\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064414 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:004415 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:064416 MockRead(ASYNC, 0, 0) // EOF
[email protected]76a505b2010-08-25 06:23:004417 };
4418
[email protected]8ddf8322012-02-23 18:08:064419 SSLSocketDataProvider ssl(ASYNC, OK);
4420 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074421 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4422 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:004423
4424 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
4425 data_writes, arraysize(data_writes));
4426 StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
4427 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:074428 session_deps_.socket_factory->AddSocketDataProvider(&data);
4429 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:004430
[email protected]49639fa2011-12-20 23:22:414431 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:004432
[email protected]bb88e1d32013-05-03 23:11:074433 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:364434 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504435 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:004436
[email protected]49639fa2011-12-20 23:22:414437 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:004438
4439 EXPECT_EQ(ERR_IO_PENDING, rv);
4440 EXPECT_EQ(OK, callback.WaitForResult());
4441
4442 const HttpResponseInfo* response = trans->GetResponseInfo();
4443 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504444 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:004445 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4446
[email protected]90499482013-06-01 00:39:504447 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004448
4449 std::string response_data;
4450 rv = ReadTransaction(trans.get(), &response_data);
4451 EXPECT_EQ(OK, rv);
4452 EXPECT_EQ("hello world", response_data);
4453
4454 // Empty the current queue. This is necessary because idle sockets are
4455 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344456 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:004457
4458 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504459 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004460
4461 // Now start the second transaction, which should reuse the previous socket.
4462
[email protected]90499482013-06-01 00:39:504463 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:004464
[email protected]49639fa2011-12-20 23:22:414465 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:004466
4467 EXPECT_EQ(ERR_IO_PENDING, rv);
4468 EXPECT_EQ(OK, callback.WaitForResult());
4469
4470 response = trans->GetResponseInfo();
4471 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504472 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:004473 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4474
[email protected]90499482013-06-01 00:39:504475 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004476
4477 rv = ReadTransaction(trans.get(), &response_data);
4478 EXPECT_EQ(OK, rv);
4479 EXPECT_EQ("hello world", response_data);
4480
4481 // Empty the current queue. This is necessary because idle sockets are
4482 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344483 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:004484
4485 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504486 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004487}
4488
[email protected]b4404c02009-04-10 16:38:524489// Make sure that we recycle a socket after a zero-length response.
4490// http://crbug.com/9880
[email protected]23e482282013-06-14 16:08:024491TEST_P(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:424492 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:524493 request.method = "GET";
4494 request.url = GURL("http://www.google.com/csi?v=3&s=web&action=&"
4495 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
4496 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
4497 "rt=prt.2642,ol.2649,xjs.2951");
4498 request.load_flags = 0;
4499
[email protected]bb88e1d32013-05-03 23:11:074500 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274501
[email protected]262eec82013-03-19 21:01:364502 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504503 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:274504
[email protected]b4404c02009-04-10 16:38:524505 MockRead data_reads[] = {
4506 MockRead("HTTP/1.1 204 No Content\r\n"
4507 "Content-Length: 0\r\n"
4508 "Content-Type: text/html\r\n\r\n"),
4509 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:064510 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:524511 };
4512
[email protected]31a2bfe2010-02-09 08:03:394513 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:074514 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:524515
[email protected]49639fa2011-12-20 23:22:414516 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:524517
[email protected]49639fa2011-12-20 23:22:414518 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424519 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]b4404c02009-04-10 16:38:524520
4521 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424522 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:524523
[email protected]1c773ea12009-04-28 19:58:424524 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504525 ASSERT_TRUE(response != NULL);
[email protected]b4404c02009-04-10 16:38:524526
[email protected]90499482013-06-01 00:39:504527 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]b4404c02009-04-10 16:38:524528 std::string status_line = response->headers->GetStatusLine();
4529 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
4530
[email protected]90499482013-06-01 00:39:504531 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:524532
4533 std::string response_data;
4534 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:424535 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:524536 EXPECT_EQ("", response_data);
4537
4538 // Empty the current queue. This is necessary because idle sockets are
4539 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344540 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:524541
4542 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504543 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:524544}
4545
[email protected]23e482282013-06-14 16:08:024546TEST_P(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
[email protected]b2d26cfd2012-12-11 10:36:064547 ScopedVector<UploadElementReader> element_readers;
4548 element_readers.push_back(new UploadBytesElementReader("foo", 3));
4549 UploadDataStream upload_data_stream(&element_readers, 0);
[email protected]329b68b2012-11-14 17:54:274550
[email protected]1c773ea12009-04-28 19:58:424551 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:514552 // Transaction 1: a GET request that succeeds. The socket is recycled
4553 // after use.
4554 request[0].method = "GET";
4555 request[0].url = GURL("http://www.google.com/");
4556 request[0].load_flags = 0;
4557 // Transaction 2: a POST request. Reuses the socket kept alive from
4558 // transaction 1. The first attempts fails when writing the POST data.
4559 // This causes the transaction to retry with a new socket. The second
4560 // attempt succeeds.
4561 request[1].method = "POST";
4562 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:274563 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:514564 request[1].load_flags = 0;
4565
[email protected]bb88e1d32013-05-03 23:11:074566 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:514567
4568 // The first socket is used for transaction 1 and the first attempt of
4569 // transaction 2.
4570
4571 // The response of transaction 1.
4572 MockRead data_reads1[] = {
4573 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
4574 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:064575 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:514576 };
4577 // The mock write results of transaction 1 and the first attempt of
4578 // transaction 2.
4579 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:064580 MockWrite(SYNCHRONOUS, 64), // GET
4581 MockWrite(SYNCHRONOUS, 93), // POST
4582 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:514583 };
[email protected]31a2bfe2010-02-09 08:03:394584 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4585 data_writes1, arraysize(data_writes1));
[email protected]372d34a2008-11-05 21:30:514586
4587 // The second socket is used for the second attempt of transaction 2.
4588
4589 // The response of transaction 2.
4590 MockRead data_reads2[] = {
4591 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
4592 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:064593 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:514594 };
4595 // The mock write results of the second attempt of transaction 2.
4596 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:064597 MockWrite(SYNCHRONOUS, 93), // POST
4598 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:514599 };
[email protected]31a2bfe2010-02-09 08:03:394600 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4601 data_writes2, arraysize(data_writes2));
[email protected]372d34a2008-11-05 21:30:514602
[email protected]bb88e1d32013-05-03 23:11:074603 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4604 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:514605
4606 const char* kExpectedResponseData[] = {
4607 "hello world", "welcome"
4608 };
4609
4610 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:424611 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504612 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]372d34a2008-11-05 21:30:514613
[email protected]49639fa2011-12-20 23:22:414614 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:514615
[email protected]49639fa2011-12-20 23:22:414616 int rv = trans->Start(&request[i], callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424617 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]372d34a2008-11-05 21:30:514618
4619 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424620 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:514621
[email protected]1c773ea12009-04-28 19:58:424622 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504623 ASSERT_TRUE(response != NULL);
[email protected]372d34a2008-11-05 21:30:514624
[email protected]90499482013-06-01 00:39:504625 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]372d34a2008-11-05 21:30:514626 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4627
4628 std::string response_data;
4629 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:424630 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:514631 EXPECT_EQ(kExpectedResponseData[i], response_data);
4632 }
4633}
[email protected]f9ee6b52008-11-08 06:46:234634
4635// Test the request-challenge-retry sequence for basic auth when there is
4636// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:164637// it fails the identity from the URL is used to answer the challenge.
[email protected]23e482282013-06-14 16:08:024638TEST_P(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:424639 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:234640 request.method = "GET";
[email protected]a97cca42009-08-14 01:00:294641 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:414642 request.load_flags = LOAD_NORMAL;
[email protected]a97cca42009-08-14 01:00:294643
[email protected]cb9bf6ca2011-01-28 13:15:274644 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:364645 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:074646 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:274647
[email protected]a97cca42009-08-14 01:00:294648 // The password contains an escaped character -- for this test to pass it
4649 // will need to be unescaped by HttpNetworkTransaction.
4650 EXPECT_EQ("b%40r", request.url.password());
4651
[email protected]f9ee6b52008-11-08 06:46:234652 MockWrite data_writes1[] = {
4653 MockWrite("GET / HTTP/1.1\r\n"
4654 "Host: www.google.com\r\n"
4655 "Connection: keep-alive\r\n\r\n"),
4656 };
4657
4658 MockRead data_reads1[] = {
4659 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4660 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4661 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064662 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:234663 };
4664
[email protected]2262e3a2012-05-22 16:08:164665 // After the challenge above, the transaction will be restarted using the
4666 // identity from the url (foo, b@r) to answer the challenge.
4667 MockWrite data_writes2[] = {
4668 MockWrite("GET / HTTP/1.1\r\n"
4669 "Host: www.google.com\r\n"
4670 "Connection: keep-alive\r\n"
4671 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
4672 };
4673
4674 MockRead data_reads2[] = {
4675 MockRead("HTTP/1.0 200 OK\r\n"),
4676 MockRead("Content-Length: 100\r\n\r\n"),
4677 MockRead(SYNCHRONOUS, OK),
4678 };
4679
[email protected]31a2bfe2010-02-09 08:03:394680 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4681 data_writes1, arraysize(data_writes1));
[email protected]2262e3a2012-05-22 16:08:164682 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4683 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:074684 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4685 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:234686
[email protected]49639fa2011-12-20 23:22:414687 TestCompletionCallback callback1;
[email protected]49639fa2011-12-20 23:22:414688 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424689 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:234690 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424691 EXPECT_EQ(OK, rv);
[email protected]2262e3a2012-05-22 16:08:164692 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4693
4694 TestCompletionCallback callback2;
4695 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
4696 EXPECT_EQ(ERR_IO_PENDING, rv);
4697 rv = callback2.WaitForResult();
4698 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:224699 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4700
[email protected]2262e3a2012-05-22 16:08:164701 const HttpResponseInfo* response = trans->GetResponseInfo();
4702 ASSERT_TRUE(response != NULL);
4703
4704 // There is no challenge info, since the identity in URL worked.
4705 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4706
4707 EXPECT_EQ(100, response->headers->GetContentLength());
4708
4709 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:344710 base::MessageLoop::current()->RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:164711}
4712
4713// Test the request-challenge-retry sequence for basic auth when there is an
4714// incorrect identity in the URL. The identity from the URL should be used only
4715// once.
[email protected]23e482282013-06-14 16:08:024716TEST_P(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:164717 HttpRequestInfo request;
4718 request.method = "GET";
4719 // Note: the URL has a username:password in it. The password "baz" is
4720 // wrong (should be "bar").
4721 request.url = GURL("http://foo:[email protected]/");
4722
4723 request.load_flags = LOAD_NORMAL;
4724
[email protected]2262e3a2012-05-22 16:08:164725 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:364726 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:074727 CreateSession(&session_deps_)));
[email protected]2262e3a2012-05-22 16:08:164728
4729 MockWrite data_writes1[] = {
4730 MockWrite("GET / HTTP/1.1\r\n"
4731 "Host: www.google.com\r\n"
4732 "Connection: keep-alive\r\n\r\n"),
4733 };
4734
4735 MockRead data_reads1[] = {
4736 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4737 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4738 MockRead("Content-Length: 10\r\n\r\n"),
4739 MockRead(SYNCHRONOUS, ERR_FAILED),
4740 };
4741
4742 // After the challenge above, the transaction will be restarted using the
4743 // identity from the url (foo, baz) to answer the challenge.
4744 MockWrite data_writes2[] = {
4745 MockWrite("GET / HTTP/1.1\r\n"
4746 "Host: www.google.com\r\n"
4747 "Connection: keep-alive\r\n"
4748 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
4749 };
4750
4751 MockRead data_reads2[] = {
4752 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4753 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4754 MockRead("Content-Length: 10\r\n\r\n"),
4755 MockRead(SYNCHRONOUS, ERR_FAILED),
4756 };
4757
4758 // After the challenge above, the transaction will be restarted using the
4759 // identity supplied by the user (foo, bar) to answer the challenge.
4760 MockWrite data_writes3[] = {
4761 MockWrite("GET / HTTP/1.1\r\n"
4762 "Host: www.google.com\r\n"
4763 "Connection: keep-alive\r\n"
4764 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
4765 };
4766
4767 MockRead data_reads3[] = {
4768 MockRead("HTTP/1.0 200 OK\r\n"),
4769 MockRead("Content-Length: 100\r\n\r\n"),
4770 MockRead(SYNCHRONOUS, OK),
4771 };
4772
4773 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4774 data_writes1, arraysize(data_writes1));
4775 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4776 data_writes2, arraysize(data_writes2));
4777 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4778 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:074779 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4780 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4781 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:164782
4783 TestCompletionCallback callback1;
4784
4785 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
4786 EXPECT_EQ(ERR_IO_PENDING, rv);
4787
4788 rv = callback1.WaitForResult();
4789 EXPECT_EQ(OK, rv);
4790
4791 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4792 TestCompletionCallback callback2;
4793 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
4794 EXPECT_EQ(ERR_IO_PENDING, rv);
4795 rv = callback2.WaitForResult();
4796 EXPECT_EQ(OK, rv);
4797 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4798
4799 const HttpResponseInfo* response = trans->GetResponseInfo();
4800 ASSERT_TRUE(response != NULL);
4801 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
4802
4803 TestCompletionCallback callback3;
4804 rv = trans->RestartWithAuth(
4805 AuthCredentials(kFoo, kBar), callback3.callback());
4806 EXPECT_EQ(ERR_IO_PENDING, rv);
4807 rv = callback3.WaitForResult();
4808 EXPECT_EQ(OK, rv);
4809 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4810
4811 response = trans->GetResponseInfo();
4812 ASSERT_TRUE(response != NULL);
4813
4814 // There is no challenge info, since the identity worked.
4815 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4816
4817 EXPECT_EQ(100, response->headers->GetContentLength());
4818
[email protected]ea9dc9a2009-09-05 00:43:324819 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:344820 base::MessageLoop::current()->RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:324821}
4822
[email protected]f9ee6b52008-11-08 06:46:234823// Test that previously tried username/passwords for a realm get re-used.
[email protected]23e482282013-06-14 16:08:024824TEST_P(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
[email protected]bb88e1d32013-05-03 23:11:074825 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:234826
4827 // Transaction 1: authenticate (foo, bar) on MyRealm1
4828 {
[email protected]1c773ea12009-04-28 19:58:424829 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:234830 request.method = "GET";
4831 request.url = GURL("http://www.google.com/x/y/z");
4832 request.load_flags = 0;
4833
[email protected]262eec82013-03-19 21:01:364834 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504835 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:274836
[email protected]f9ee6b52008-11-08 06:46:234837 MockWrite data_writes1[] = {
4838 MockWrite("GET /x/y/z HTTP/1.1\r\n"
4839 "Host: www.google.com\r\n"
4840 "Connection: keep-alive\r\n\r\n"),
4841 };
4842
4843 MockRead data_reads1[] = {
4844 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4845 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4846 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064847 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:234848 };
4849
4850 // Resend with authorization (username=foo, password=bar)
4851 MockWrite data_writes2[] = {
4852 MockWrite("GET /x/y/z HTTP/1.1\r\n"
4853 "Host: www.google.com\r\n"
4854 "Connection: keep-alive\r\n"
4855 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
4856 };
4857
4858 // Sever accepts the authorization.
4859 MockRead data_reads2[] = {
4860 MockRead("HTTP/1.0 200 OK\r\n"),
4861 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064862 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:234863 };
4864
[email protected]31a2bfe2010-02-09 08:03:394865 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4866 data_writes1, arraysize(data_writes1));
4867 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4868 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:074869 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4870 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:234871
[email protected]49639fa2011-12-20 23:22:414872 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:234873
[email protected]49639fa2011-12-20 23:22:414874 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424875 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:234876
4877 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424878 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:234879
[email protected]1c773ea12009-04-28 19:58:424880 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504881 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044882 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:234883
[email protected]49639fa2011-12-20 23:22:414884 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:234885
[email protected]49639fa2011-12-20 23:22:414886 rv = trans->RestartWithAuth(
4887 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:424888 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:234889
4890 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424891 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:234892
4893 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504894 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:234895 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4896 EXPECT_EQ(100, response->headers->GetContentLength());
4897 }
4898
4899 // ------------------------------------------------------------------------
4900
4901 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
4902 {
[email protected]1c773ea12009-04-28 19:58:424903 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:234904 request.method = "GET";
4905 // Note that Transaction 1 was at /x/y/z, so this is in the same
4906 // protection space as MyRealm1.
4907 request.url = GURL("http://www.google.com/x/y/a/b");
4908 request.load_flags = 0;
4909
[email protected]262eec82013-03-19 21:01:364910 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504911 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:274912
[email protected]f9ee6b52008-11-08 06:46:234913 MockWrite data_writes1[] = {
4914 MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
4915 "Host: www.google.com\r\n"
4916 "Connection: keep-alive\r\n"
4917 // Send preemptive authorization for MyRealm1
4918 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
4919 };
4920
4921 // The server didn't like the preemptive authorization, and
4922 // challenges us for a different realm (MyRealm2).
4923 MockRead data_reads1[] = {
4924 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4925 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
4926 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064927 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:234928 };
4929
4930 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
4931 MockWrite data_writes2[] = {
4932 MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
4933 "Host: www.google.com\r\n"
4934 "Connection: keep-alive\r\n"
4935 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
4936 };
4937
4938 // Sever accepts the authorization.
4939 MockRead data_reads2[] = {
4940 MockRead("HTTP/1.0 200 OK\r\n"),
4941 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064942 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:234943 };
4944
[email protected]31a2bfe2010-02-09 08:03:394945 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4946 data_writes1, arraysize(data_writes1));
4947 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4948 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:074949 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4950 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:234951
[email protected]49639fa2011-12-20 23:22:414952 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:234953
[email protected]49639fa2011-12-20 23:22:414954 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424955 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:234956
4957 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424958 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:234959
[email protected]1c773ea12009-04-28 19:58:424960 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504961 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044962 ASSERT_TRUE(response->auth_challenge.get());
4963 EXPECT_FALSE(response->auth_challenge->is_proxy);
4964 EXPECT_EQ("www.google.com:80",
4965 response->auth_challenge->challenger.ToString());
4966 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
4967 EXPECT_EQ("basic", response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:234968
[email protected]49639fa2011-12-20 23:22:414969 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:234970
[email protected]49639fa2011-12-20 23:22:414971 rv = trans->RestartWithAuth(
4972 AuthCredentials(kFoo2, kBar2), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:424973 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:234974
4975 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424976 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:234977
4978 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504979 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:234980 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4981 EXPECT_EQ(100, response->headers->GetContentLength());
4982 }
4983
4984 // ------------------------------------------------------------------------
4985
4986 // Transaction 3: Resend a request in MyRealm's protection space --
4987 // succeed with preemptive authorization.
4988 {
[email protected]1c773ea12009-04-28 19:58:424989 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:234990 request.method = "GET";
4991 request.url = GURL("http://www.google.com/x/y/z2");
4992 request.load_flags = 0;
4993
[email protected]262eec82013-03-19 21:01:364994 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504995 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:274996
[email protected]f9ee6b52008-11-08 06:46:234997 MockWrite data_writes1[] = {
4998 MockWrite("GET /x/y/z2 HTTP/1.1\r\n"
4999 "Host: www.google.com\r\n"
5000 "Connection: keep-alive\r\n"
5001 // The authorization for MyRealm1 gets sent preemptively
5002 // (since the url is in the same protection space)
5003 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5004 };
5005
5006 // Sever accepts the preemptive authorization
5007 MockRead data_reads1[] = {
5008 MockRead("HTTP/1.0 200 OK\r\n"),
5009 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065010 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235011 };
5012
[email protected]31a2bfe2010-02-09 08:03:395013 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5014 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075015 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:235016
[email protected]49639fa2011-12-20 23:22:415017 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235018
[email protected]49639fa2011-12-20 23:22:415019 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425020 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235021
5022 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425023 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235024
[email protected]1c773ea12009-04-28 19:58:425025 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505026 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235027
5028 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5029 EXPECT_EQ(100, response->headers->GetContentLength());
5030 }
5031
5032 // ------------------------------------------------------------------------
5033
5034 // Transaction 4: request another URL in MyRealm (however the
5035 // url is not known to belong to the protection space, so no pre-auth).
5036 {
[email protected]1c773ea12009-04-28 19:58:425037 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235038 request.method = "GET";
5039 request.url = GURL("http://www.google.com/x/1");
5040 request.load_flags = 0;
5041
[email protected]262eec82013-03-19 21:01:365042 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505043 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275044
[email protected]f9ee6b52008-11-08 06:46:235045 MockWrite data_writes1[] = {
5046 MockWrite("GET /x/1 HTTP/1.1\r\n"
5047 "Host: www.google.com\r\n"
5048 "Connection: keep-alive\r\n\r\n"),
5049 };
5050
5051 MockRead data_reads1[] = {
5052 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5053 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5054 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065055 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235056 };
5057
5058 // Resend with authorization from MyRealm's cache.
5059 MockWrite data_writes2[] = {
5060 MockWrite("GET /x/1 HTTP/1.1\r\n"
5061 "Host: www.google.com\r\n"
5062 "Connection: keep-alive\r\n"
5063 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5064 };
5065
5066 // Sever accepts the authorization.
5067 MockRead data_reads2[] = {
5068 MockRead("HTTP/1.0 200 OK\r\n"),
5069 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065070 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235071 };
5072
[email protected]31a2bfe2010-02-09 08:03:395073 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5074 data_writes1, arraysize(data_writes1));
5075 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5076 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075077 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5078 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235079
[email protected]49639fa2011-12-20 23:22:415080 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235081
[email protected]49639fa2011-12-20 23:22:415082 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425083 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235084
5085 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425086 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235087
[email protected]0757e7702009-03-27 04:00:225088 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:415089 TestCompletionCallback callback2;
5090 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425091 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:225092 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425093 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225094 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5095
[email protected]1c773ea12009-04-28 19:58:425096 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505097 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235098 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5099 EXPECT_EQ(100, response->headers->GetContentLength());
5100 }
5101
5102 // ------------------------------------------------------------------------
5103
5104 // Transaction 5: request a URL in MyRealm, but the server rejects the
5105 // cached identity. Should invalidate and re-prompt.
5106 {
[email protected]1c773ea12009-04-28 19:58:425107 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235108 request.method = "GET";
5109 request.url = GURL("http://www.google.com/p/q/t");
5110 request.load_flags = 0;
5111
[email protected]262eec82013-03-19 21:01:365112 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505113 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275114
[email protected]f9ee6b52008-11-08 06:46:235115 MockWrite data_writes1[] = {
5116 MockWrite("GET /p/q/t HTTP/1.1\r\n"
5117 "Host: www.google.com\r\n"
5118 "Connection: keep-alive\r\n\r\n"),
5119 };
5120
5121 MockRead data_reads1[] = {
5122 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5123 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5124 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065125 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235126 };
5127
5128 // Resend with authorization from cache for MyRealm.
5129 MockWrite data_writes2[] = {
5130 MockWrite("GET /p/q/t HTTP/1.1\r\n"
5131 "Host: www.google.com\r\n"
5132 "Connection: keep-alive\r\n"
5133 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5134 };
5135
5136 // Sever rejects the authorization.
5137 MockRead data_reads2[] = {
5138 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5139 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5140 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065141 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235142 };
5143
5144 // At this point we should prompt for new credentials for MyRealm.
5145 // Restart with username=foo3, password=foo4.
5146 MockWrite data_writes3[] = {
5147 MockWrite("GET /p/q/t HTTP/1.1\r\n"
5148 "Host: www.google.com\r\n"
5149 "Connection: keep-alive\r\n"
5150 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
5151 };
5152
5153 // Sever accepts the authorization.
5154 MockRead data_reads3[] = {
5155 MockRead("HTTP/1.0 200 OK\r\n"),
5156 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065157 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235158 };
5159
[email protected]31a2bfe2010-02-09 08:03:395160 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5161 data_writes1, arraysize(data_writes1));
5162 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5163 data_writes2, arraysize(data_writes2));
5164 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5165 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075166 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5167 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5168 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:235169
[email protected]49639fa2011-12-20 23:22:415170 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235171
[email protected]49639fa2011-12-20 23:22:415172 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425173 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235174
5175 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425176 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235177
[email protected]0757e7702009-03-27 04:00:225178 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:415179 TestCompletionCallback callback2;
5180 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425181 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:225182 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425183 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225184 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5185
[email protected]1c773ea12009-04-28 19:58:425186 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505187 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045188 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:235189
[email protected]49639fa2011-12-20 23:22:415190 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:235191
[email protected]49639fa2011-12-20 23:22:415192 rv = trans->RestartWithAuth(
5193 AuthCredentials(kFoo3, kBar3), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:425194 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235195
[email protected]0757e7702009-03-27 04:00:225196 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425197 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235198
5199 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505200 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235201 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5202 EXPECT_EQ(100, response->headers->GetContentLength());
5203 }
5204}
[email protected]89ceba9a2009-03-21 03:46:065205
[email protected]3c32c5f2010-05-18 15:18:125206// Tests that nonce count increments when multiple auth attempts
5207// are started with the same nonce.
[email protected]23e482282013-06-14 16:08:025208TEST_P(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:445209 HttpAuthHandlerDigest::Factory* digest_factory =
5210 new HttpAuthHandlerDigest::Factory();
5211 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
5212 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
5213 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:075214 session_deps_.http_auth_handler_factory.reset(digest_factory);
5215 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:125216
5217 // Transaction 1: authenticate (foo, bar) on MyRealm1
5218 {
[email protected]3c32c5f2010-05-18 15:18:125219 HttpRequestInfo request;
5220 request.method = "GET";
5221 request.url = GURL("http://www.google.com/x/y/z");
5222 request.load_flags = 0;
5223
[email protected]262eec82013-03-19 21:01:365224 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505225 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275226
[email protected]3c32c5f2010-05-18 15:18:125227 MockWrite data_writes1[] = {
5228 MockWrite("GET /x/y/z HTTP/1.1\r\n"
5229 "Host: www.google.com\r\n"
5230 "Connection: keep-alive\r\n\r\n"),
5231 };
5232
5233 MockRead data_reads1[] = {
5234 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5235 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
5236 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065237 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:125238 };
5239
5240 // Resend with authorization (username=foo, password=bar)
5241 MockWrite data_writes2[] = {
5242 MockWrite("GET /x/y/z HTTP/1.1\r\n"
5243 "Host: www.google.com\r\n"
5244 "Connection: keep-alive\r\n"
5245 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
5246 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
5247 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
5248 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
5249 };
5250
5251 // Sever accepts the authorization.
5252 MockRead data_reads2[] = {
5253 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:065254 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:125255 };
5256
5257 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5258 data_writes1, arraysize(data_writes1));
5259 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5260 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075261 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5262 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:125263
[email protected]49639fa2011-12-20 23:22:415264 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:125265
[email protected]49639fa2011-12-20 23:22:415266 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:125267 EXPECT_EQ(ERR_IO_PENDING, rv);
5268
5269 rv = callback1.WaitForResult();
5270 EXPECT_EQ(OK, rv);
5271
5272 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505273 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045274 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:125275
[email protected]49639fa2011-12-20 23:22:415276 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:125277
[email protected]49639fa2011-12-20 23:22:415278 rv = trans->RestartWithAuth(
5279 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]3c32c5f2010-05-18 15:18:125280 EXPECT_EQ(ERR_IO_PENDING, rv);
5281
5282 rv = callback2.WaitForResult();
5283 EXPECT_EQ(OK, rv);
5284
5285 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505286 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:125287 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5288 }
5289
5290 // ------------------------------------------------------------------------
5291
5292 // Transaction 2: Request another resource in digestive's protection space.
5293 // This will preemptively add an Authorization header which should have an
5294 // "nc" value of 2 (as compared to 1 in the first use.
5295 {
[email protected]3c32c5f2010-05-18 15:18:125296 HttpRequestInfo request;
5297 request.method = "GET";
5298 // Note that Transaction 1 was at /x/y/z, so this is in the same
5299 // protection space as digest.
5300 request.url = GURL("http://www.google.com/x/y/a/b");
5301 request.load_flags = 0;
5302
[email protected]262eec82013-03-19 21:01:365303 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505304 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275305
[email protected]3c32c5f2010-05-18 15:18:125306 MockWrite data_writes1[] = {
5307 MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
5308 "Host: www.google.com\r\n"
5309 "Connection: keep-alive\r\n"
5310 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
5311 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
5312 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
5313 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
5314 };
5315
5316 // Sever accepts the authorization.
5317 MockRead data_reads1[] = {
5318 MockRead("HTTP/1.0 200 OK\r\n"),
5319 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065320 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:125321 };
5322
5323 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5324 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075325 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:125326
[email protected]49639fa2011-12-20 23:22:415327 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:125328
[email protected]49639fa2011-12-20 23:22:415329 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:125330 EXPECT_EQ(ERR_IO_PENDING, rv);
5331
5332 rv = callback1.WaitForResult();
5333 EXPECT_EQ(OK, rv);
5334
5335 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505336 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:125337 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5338 }
5339}
5340
[email protected]89ceba9a2009-03-21 03:46:065341// Test the ResetStateForRestart() private method.
[email protected]23e482282013-06-14 16:08:025342TEST_P(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:065343 // Create a transaction (the dependencies aren't important).
[email protected]d207a5f2009-06-04 05:28:405344 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]262eec82013-03-19 21:01:365345 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:075346 CreateSession(&session_deps_)));
[email protected]89ceba9a2009-03-21 03:46:065347
5348 // Setup some state (which we expect ResetStateForRestart() will clear).
[email protected]89ceba9a2009-03-21 03:46:065349 trans->read_buf_ = new IOBuffer(15);
5350 trans->read_buf_len_ = 15;
[email protected]b94f92d2010-10-27 16:45:205351 trans->request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:065352
5353 // Setup state in response_
[email protected]a7e41312009-12-16 23:18:145354 HttpResponseInfo* response = &trans->response_;
[email protected]0877e3d2009-10-17 22:29:575355 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:085356 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:575357 response->response_time = base::Time::Now();
5358 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:065359
5360 { // Setup state for response_.vary_data
5361 HttpRequestInfo request;
5362 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
5363 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:275364 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:435365 request.extra_headers.SetHeader("Foo", "1");
5366 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:505367 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:065368 }
5369
5370 // Cause the above state to be reset.
5371 trans->ResetStateForRestart();
5372
5373 // Verify that the state that needed to be reset, has been reset.
[email protected]9b6fee12009-09-29 18:13:075374 EXPECT_TRUE(trans->read_buf_.get() == NULL);
[email protected]89ceba9a2009-03-21 03:46:065375 EXPECT_EQ(0, trans->read_buf_len_);
[email protected]b94f92d2010-10-27 16:45:205376 EXPECT_TRUE(trans->request_headers_.IsEmpty());
[email protected]0877e3d2009-10-17 22:29:575377 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5378 EXPECT_TRUE(response->headers.get() == NULL);
[email protected]34f40942010-10-04 00:34:045379 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:085380 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:575381 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:065382}
5383
[email protected]bacff652009-03-31 17:50:335384// Test HTTPS connections to a site with a bad certificate
[email protected]23e482282013-06-14 16:08:025385TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:335386 HttpRequestInfo request;
5387 request.method = "GET";
5388 request.url = GURL("https://www.google.com/");
5389 request.load_flags = 0;
5390
[email protected]cb9bf6ca2011-01-28 13:15:275391 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:365392 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:075393 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:275394
[email protected]bacff652009-03-31 17:50:335395 MockWrite data_writes[] = {
5396 MockWrite("GET / HTTP/1.1\r\n"
5397 "Host: www.google.com\r\n"
5398 "Connection: keep-alive\r\n\r\n"),
5399 };
5400
5401 MockRead data_reads[] = {
5402 MockRead("HTTP/1.0 200 OK\r\n"),
5403 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5404 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065405 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:335406 };
5407
[email protected]5ecc992a42009-11-11 01:41:595408 StaticSocketDataProvider ssl_bad_certificate;
[email protected]31a2bfe2010-02-09 08:03:395409 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5410 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:065411 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
5412 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:335413
[email protected]bb88e1d32013-05-03 23:11:075414 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
5415 session_deps_.socket_factory->AddSocketDataProvider(&data);
5416 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
5417 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:335418
[email protected]49639fa2011-12-20 23:22:415419 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:335420
[email protected]49639fa2011-12-20 23:22:415421 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:335422 EXPECT_EQ(ERR_IO_PENDING, rv);
5423
5424 rv = callback.WaitForResult();
5425 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
5426
[email protected]49639fa2011-12-20 23:22:415427 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:335428 EXPECT_EQ(ERR_IO_PENDING, rv);
5429
5430 rv = callback.WaitForResult();
5431 EXPECT_EQ(OK, rv);
5432
5433 const HttpResponseInfo* response = trans->GetResponseInfo();
5434
[email protected]fe2255a2011-09-20 19:37:505435 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:335436 EXPECT_EQ(100, response->headers->GetContentLength());
5437}
5438
5439// Test HTTPS connections to a site with a bad certificate, going through a
5440// proxy
[email protected]23e482282013-06-14 16:08:025441TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
[email protected]bb88e1d32013-05-03 23:11:075442 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]bacff652009-03-31 17:50:335443
5444 HttpRequestInfo request;
5445 request.method = "GET";
5446 request.url = GURL("https://www.google.com/");
5447 request.load_flags = 0;
5448
5449 MockWrite proxy_writes[] = {
5450 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:455451 "Host: www.google.com\r\n"
5452 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:335453 };
5454
5455 MockRead proxy_reads[] = {
5456 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065457 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:335458 };
5459
5460 MockWrite data_writes[] = {
5461 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:455462 "Host: www.google.com\r\n"
5463 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:335464 MockWrite("GET / HTTP/1.1\r\n"
5465 "Host: www.google.com\r\n"
5466 "Connection: keep-alive\r\n\r\n"),
5467 };
5468
5469 MockRead data_reads[] = {
5470 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
5471 MockRead("HTTP/1.0 200 OK\r\n"),
5472 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5473 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065474 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:335475 };
5476
[email protected]31a2bfe2010-02-09 08:03:395477 StaticSocketDataProvider ssl_bad_certificate(
5478 proxy_reads, arraysize(proxy_reads),
5479 proxy_writes, arraysize(proxy_writes));
5480 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5481 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:065482 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
5483 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:335484
[email protected]bb88e1d32013-05-03 23:11:075485 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
5486 session_deps_.socket_factory->AddSocketDataProvider(&data);
5487 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
5488 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:335489
[email protected]49639fa2011-12-20 23:22:415490 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:335491
5492 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:075493 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:335494
[email protected]d207a5f2009-06-04 05:28:405495 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:365496 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:075497 CreateSession(&session_deps_)));
[email protected]bacff652009-03-31 17:50:335498
[email protected]49639fa2011-12-20 23:22:415499 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:335500 EXPECT_EQ(ERR_IO_PENDING, rv);
5501
5502 rv = callback.WaitForResult();
5503 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
5504
[email protected]49639fa2011-12-20 23:22:415505 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:335506 EXPECT_EQ(ERR_IO_PENDING, rv);
5507
5508 rv = callback.WaitForResult();
5509 EXPECT_EQ(OK, rv);
5510
5511 const HttpResponseInfo* response = trans->GetResponseInfo();
5512
[email protected]fe2255a2011-09-20 19:37:505513 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:335514 EXPECT_EQ(100, response->headers->GetContentLength());
5515 }
5516}
5517
[email protected]2df19bb2010-08-25 20:13:465518
5519// Test HTTPS connections to a site, going through an HTTPS proxy
[email protected]23e482282013-06-14 16:08:025520TEST_P(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:075521 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:205522 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
5523 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:075524 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:465525
5526 HttpRequestInfo request;
5527 request.method = "GET";
5528 request.url = GURL("https://www.google.com/");
5529 request.load_flags = 0;
5530
5531 MockWrite data_writes[] = {
5532 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
5533 "Host: www.google.com\r\n"
5534 "Proxy-Connection: keep-alive\r\n\r\n"),
5535 MockWrite("GET / HTTP/1.1\r\n"
5536 "Host: www.google.com\r\n"
5537 "Connection: keep-alive\r\n\r\n"),
5538 };
5539
5540 MockRead data_reads[] = {
5541 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
5542 MockRead("HTTP/1.1 200 OK\r\n"),
5543 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5544 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065545 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:465546 };
5547
5548 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5549 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:065550 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
5551 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:465552
[email protected]bb88e1d32013-05-03 23:11:075553 session_deps_.socket_factory->AddSocketDataProvider(&data);
5554 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
5555 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:465556
[email protected]49639fa2011-12-20 23:22:415557 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:465558
5559 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:365560 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:075561 CreateSession(&session_deps_)));
[email protected]2df19bb2010-08-25 20:13:465562
[email protected]49639fa2011-12-20 23:22:415563 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:465564 EXPECT_EQ(ERR_IO_PENDING, rv);
5565
5566 rv = callback.WaitForResult();
5567 EXPECT_EQ(OK, rv);
5568 const HttpResponseInfo* response = trans->GetResponseInfo();
5569
[email protected]fe2255a2011-09-20 19:37:505570 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:465571
5572 EXPECT_TRUE(response->headers->IsKeepAlive());
5573 EXPECT_EQ(200, response->headers->response_code());
5574 EXPECT_EQ(100, response->headers->GetContentLength());
5575 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:205576
5577 LoadTimingInfo load_timing_info;
5578 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5579 TestLoadTimingNotReusedWithPac(load_timing_info,
5580 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:465581}
5582
[email protected]511f6f52010-12-17 03:58:295583// Test an HTTPS Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:025584TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:075585 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:205586 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
5587 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:075588 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:295589
5590 HttpRequestInfo request;
5591 request.method = "GET";
5592 request.url = GURL("https://www.google.com/");
5593 request.load_flags = 0;
5594
5595 MockWrite data_writes[] = {
5596 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
5597 "Host: www.google.com\r\n"
5598 "Proxy-Connection: keep-alive\r\n\r\n"),
5599 };
5600
5601 MockRead data_reads[] = {
5602 MockRead("HTTP/1.1 302 Redirect\r\n"),
5603 MockRead("Location: http://login.example.com/\r\n"),
5604 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065605 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:295606 };
5607
5608 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5609 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:065610 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:295611
[email protected]bb88e1d32013-05-03 23:11:075612 session_deps_.socket_factory->AddSocketDataProvider(&data);
5613 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:295614
[email protected]49639fa2011-12-20 23:22:415615 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:295616
5617 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:365618 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:075619 CreateSession(&session_deps_)));
[email protected]511f6f52010-12-17 03:58:295620
[email protected]49639fa2011-12-20 23:22:415621 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:295622 EXPECT_EQ(ERR_IO_PENDING, rv);
5623
5624 rv = callback.WaitForResult();
5625 EXPECT_EQ(OK, rv);
5626 const HttpResponseInfo* response = trans->GetResponseInfo();
5627
[email protected]fe2255a2011-09-20 19:37:505628 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:295629
5630 EXPECT_EQ(302, response->headers->response_code());
5631 std::string url;
5632 EXPECT_TRUE(response->headers->IsRedirect(&url));
5633 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:205634
5635 // In the case of redirects from proxies, HttpNetworkTransaction returns
5636 // timing for the proxy connection instead of the connection to the host,
5637 // and no send / receive times.
5638 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
5639 LoadTimingInfo load_timing_info;
5640 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5641
5642 EXPECT_FALSE(load_timing_info.socket_reused);
5643 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
5644
5645 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
5646 EXPECT_LE(load_timing_info.proxy_resolve_start,
5647 load_timing_info.proxy_resolve_end);
5648 EXPECT_LE(load_timing_info.proxy_resolve_end,
5649 load_timing_info.connect_timing.connect_start);
5650 ExpectConnectTimingHasTimes(
5651 load_timing_info.connect_timing,
5652 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
5653
5654 EXPECT_TRUE(load_timing_info.send_start.is_null());
5655 EXPECT_TRUE(load_timing_info.send_end.is_null());
5656 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:295657}
5658
5659// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:025660TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
[email protected]bb88e1d32013-05-03 23:11:075661 session_deps_.proxy_service.reset(
[email protected]511f6f52010-12-17 03:58:295662 ProxyService::CreateFixed("https://proxy:70"));
5663
5664 HttpRequestInfo request;
5665 request.method = "GET";
5666 request.url = GURL("https://www.google.com/");
5667 request.load_flags = 0;
5668
[email protected]fba2dbde2013-05-24 16:09:015669 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(NULL, 0, 1));
[email protected]c10b20852013-05-15 21:29:205670 scoped_ptr<SpdyFrame> goaway(
5671 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:295672 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:065673 CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
[email protected]57d2dfa2013-06-24 06:04:125674 CreateMockWrite(*goaway.get(), 3, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:295675 };
5676
5677 static const char* const kExtraHeaders[] = {
5678 "location",
5679 "http://login.example.com/",
5680 };
[email protected]ff98d7f02012-03-22 21:44:195681 scoped_ptr<SpdyFrame> resp(
[email protected]23e482282013-06-14 16:08:025682 spdy_util_.ConstructSpdySynReplyError("302 Redirect", kExtraHeaders,
[email protected]511f6f52010-12-17 03:58:295683 arraysize(kExtraHeaders)/2, 1));
5684 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:065685 CreateMockRead(*resp.get(), 1, SYNCHRONOUS),
5686 MockRead(ASYNC, 0, 2), // EOF
[email protected]511f6f52010-12-17 03:58:295687 };
5688
[email protected]dd54bd82012-07-19 23:44:575689 DelayedSocketData data(
5690 1, // wait for one write to finish before reading.
5691 data_reads, arraysize(data_reads),
5692 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:065693 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]23e482282013-06-14 16:08:025694 proxy_ssl.SetNextProto(GetParam());
[email protected]511f6f52010-12-17 03:58:295695
[email protected]bb88e1d32013-05-03 23:11:075696 session_deps_.socket_factory->AddSocketDataProvider(&data);
5697 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:295698
[email protected]49639fa2011-12-20 23:22:415699 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:295700
5701 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:365702 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:075703 CreateSession(&session_deps_)));
[email protected]511f6f52010-12-17 03:58:295704
[email protected]49639fa2011-12-20 23:22:415705 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:295706 EXPECT_EQ(ERR_IO_PENDING, rv);
5707
5708 rv = callback.WaitForResult();
5709 EXPECT_EQ(OK, rv);
5710 const HttpResponseInfo* response = trans->GetResponseInfo();
5711
[email protected]fe2255a2011-09-20 19:37:505712 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:295713
5714 EXPECT_EQ(302, response->headers->response_code());
5715 std::string url;
5716 EXPECT_TRUE(response->headers->IsRedirect(&url));
5717 EXPECT_EQ("http://login.example.com/", url);
5718}
5719
[email protected]4eddbc732012-08-09 05:40:175720// Test that an HTTPS proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:025721TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:175722 ErrorResponseToHttpsConnectViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:075723 session_deps_.proxy_service.reset(
[email protected]511f6f52010-12-17 03:58:295724 ProxyService::CreateFixed("https://proxy:70"));
5725
5726 HttpRequestInfo request;
5727 request.method = "GET";
5728 request.url = GURL("https://www.google.com/");
5729 request.load_flags = 0;
5730
5731 MockWrite data_writes[] = {
5732 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
5733 "Host: www.google.com\r\n"
5734 "Proxy-Connection: keep-alive\r\n\r\n"),
5735 };
5736
5737 MockRead data_reads[] = {
5738 MockRead("HTTP/1.1 404 Not Found\r\n"),
5739 MockRead("Content-Length: 23\r\n\r\n"),
5740 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:065741 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:295742 };
5743
5744 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5745 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:065746 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:295747
[email protected]bb88e1d32013-05-03 23:11:075748 session_deps_.socket_factory->AddSocketDataProvider(&data);
5749 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:295750
[email protected]49639fa2011-12-20 23:22:415751 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:295752
5753 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:365754 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:075755 CreateSession(&session_deps_)));
[email protected]511f6f52010-12-17 03:58:295756
[email protected]49639fa2011-12-20 23:22:415757 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:295758 EXPECT_EQ(ERR_IO_PENDING, rv);
5759
5760 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:175761 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:295762
[email protected]4eddbc732012-08-09 05:40:175763 // TODO(ttuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:295764}
5765
[email protected]4eddbc732012-08-09 05:40:175766// Test that a SPDY proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:025767TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:175768 ErrorResponseToHttpsConnectViaSpdyProxy) {
[email protected]bb88e1d32013-05-03 23:11:075769 session_deps_.proxy_service.reset(
5770 ProxyService::CreateFixed("https://proxy:70"));
[email protected]511f6f52010-12-17 03:58:295771
5772 HttpRequestInfo request;
5773 request.method = "GET";
5774 request.url = GURL("https://www.google.com/");
5775 request.load_flags = 0;
5776
[email protected]fba2dbde2013-05-24 16:09:015777 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(NULL, 0, 1));
[email protected]c10b20852013-05-15 21:29:205778 scoped_ptr<SpdyFrame> rst(
5779 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:295780 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:065781 CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
[email protected]4eddbc732012-08-09 05:40:175782 CreateMockWrite(*rst.get(), 3, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:295783 };
5784
5785 static const char* const kExtraHeaders[] = {
5786 "location",
5787 "http://login.example.com/",
5788 };
[email protected]ff98d7f02012-03-22 21:44:195789 scoped_ptr<SpdyFrame> resp(
[email protected]23e482282013-06-14 16:08:025790 spdy_util_.ConstructSpdySynReplyError("404 Not Found", kExtraHeaders,
[email protected]511f6f52010-12-17 03:58:295791 arraysize(kExtraHeaders)/2, 1));
[email protected]ff98d7f02012-03-22 21:44:195792 scoped_ptr<SpdyFrame> body(
[email protected]23e482282013-06-14 16:08:025793 spdy_util_.ConstructSpdyBodyFrame(
5794 1, "The host does not exist", 23, true));
[email protected]511f6f52010-12-17 03:58:295795 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:065796 CreateMockRead(*resp.get(), 1, SYNCHRONOUS),
5797 CreateMockRead(*body.get(), 2, SYNCHRONOUS),
[email protected]4eddbc732012-08-09 05:40:175798 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:295799 };
5800
[email protected]dd54bd82012-07-19 23:44:575801 DelayedSocketData data(
5802 1, // wait for one write to finish before reading.
5803 data_reads, arraysize(data_reads),
5804 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:065805 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]23e482282013-06-14 16:08:025806 proxy_ssl.SetNextProto(GetParam());
[email protected]511f6f52010-12-17 03:58:295807
[email protected]bb88e1d32013-05-03 23:11:075808 session_deps_.socket_factory->AddSocketDataProvider(&data);
5809 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:295810
[email protected]49639fa2011-12-20 23:22:415811 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:295812
5813 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:365814 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:075815 CreateSession(&session_deps_)));
[email protected]511f6f52010-12-17 03:58:295816
[email protected]49639fa2011-12-20 23:22:415817 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:295818 EXPECT_EQ(ERR_IO_PENDING, rv);
5819
5820 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:175821 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:295822
[email protected]4eddbc732012-08-09 05:40:175823 // TODO(ttuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:295824}
5825
[email protected]0c5fb722012-02-28 11:50:355826// Test the request-challenge-retry sequence for basic auth, through
5827// a SPDY proxy over a single SPDY session.
[email protected]23e482282013-06-14 16:08:025828TEST_P(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:355829 HttpRequestInfo request;
5830 request.method = "GET";
5831 request.url = GURL("https://www.google.com/");
5832 // when the no authentication data flag is set.
5833 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
5834
5835 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:075836 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:205837 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
[email protected]333bdf62012-06-08 22:57:295838 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075839 session_deps_.net_log = log.bound().net_log();
5840 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:355841
5842 // Since we have proxy, should try to establish tunnel.
[email protected]fba2dbde2013-05-24 16:09:015843 scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyConnect(NULL, 0, 1));
[email protected]c10b20852013-05-15 21:29:205844 scoped_ptr<SpdyFrame> rst(
5845 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]0c5fb722012-02-28 11:50:355846
5847 // After calling trans->RestartWithAuth(), this is the request we should
5848 // be issuing -- the final header line contains the credentials.
5849 const char* const kAuthCredentials[] = {
5850 "proxy-authorization", "Basic Zm9vOmJhcg==",
5851 };
[email protected]fba2dbde2013-05-24 16:09:015852 scoped_ptr<SpdyFrame> connect2(spdy_util_.ConstructSpdyConnect(
5853 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3));
[email protected]0c5fb722012-02-28 11:50:355854 // fetch https://www.google.com/ via HTTP
5855 const char get[] = "GET / HTTP/1.1\r\n"
5856 "Host: www.google.com\r\n"
5857 "Connection: keep-alive\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:195858 scoped_ptr<SpdyFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:025859 spdy_util_.ConstructSpdyBodyFrame(3, get, strlen(get), false));
[email protected]0c5fb722012-02-28 11:50:355860
5861 MockWrite spdy_writes[] = {
[email protected]3d7c43f2012-07-10 21:26:205862 CreateMockWrite(*req, 1, ASYNC),
[email protected]c92f4b4542012-07-26 23:53:215863 CreateMockWrite(*rst, 4, ASYNC),
5864 CreateMockWrite(*connect2, 5),
[email protected]3d7c43f2012-07-10 21:26:205865 CreateMockWrite(*wrapped_get, 8),
[email protected]0c5fb722012-02-28 11:50:355866 };
5867
5868 // The proxy responds to the connect with a 407, using a persistent
5869 // connection.
5870 const char* const kAuthChallenge[] = {
[email protected]23e482282013-06-14 16:08:025871 spdy_util_.GetStatusKey(), "407 Proxy Authentication Required",
5872 spdy_util_.GetVersionKey(), "HTTP/1.1",
[email protected]0c5fb722012-02-28 11:50:355873 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
5874 };
5875
[email protected]ff98d7f02012-03-22 21:44:195876 scoped_ptr<SpdyFrame> conn_auth_resp(
[email protected]4bd46222013-05-14 19:32:235877 spdy_util_.ConstructSpdyControlFrame(NULL,
5878 0,
5879 false,
5880 1,
5881 LOWEST,
5882 SYN_REPLY,
5883 CONTROL_FLAG_NONE,
5884 kAuthChallenge,
5885 arraysize(kAuthChallenge),
5886 0));
[email protected]0c5fb722012-02-28 11:50:355887
[email protected]23e482282013-06-14 16:08:025888 scoped_ptr<SpdyFrame> conn_resp(
5889 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:355890 const char resp[] = "HTTP/1.1 200 OK\r\n"
5891 "Content-Length: 5\r\n\r\n";
5892
[email protected]ff98d7f02012-03-22 21:44:195893 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:025894 spdy_util_.ConstructSpdyBodyFrame(3, resp, strlen(resp), false));
[email protected]ff98d7f02012-03-22 21:44:195895 scoped_ptr<SpdyFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:025896 spdy_util_.ConstructSpdyBodyFrame(3, "hello", 5, false));
[email protected]0c5fb722012-02-28 11:50:355897 MockRead spdy_reads[] = {
[email protected]3d7c43f2012-07-10 21:26:205898 CreateMockRead(*conn_auth_resp, 2, ASYNC),
5899 CreateMockRead(*conn_resp, 6, ASYNC),
5900 CreateMockRead(*wrapped_get_resp, 9, ASYNC),
5901 CreateMockRead(*wrapped_body, 10, ASYNC),
5902 MockRead(ASYNC, OK, 11), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:355903 };
5904
[email protected]dd54bd82012-07-19 23:44:575905 OrderedSocketData spdy_data(
5906 spdy_reads, arraysize(spdy_reads),
5907 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075908 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:355909 // Negotiate SPDY to the proxy
5910 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:025911 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:075912 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:355913 // Vanilla SSL to the server
5914 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075915 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:355916
5917 TestCompletionCallback callback1;
5918
[email protected]262eec82013-03-19 21:01:365919 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505920 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0c5fb722012-02-28 11:50:355921
5922 int rv = trans->Start(&request, callback1.callback(), log.bound());
5923 EXPECT_EQ(ERR_IO_PENDING, rv);
5924
5925 rv = callback1.WaitForResult();
5926 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:575927 net::CapturingNetLog::CapturedEntryList entries;
[email protected]0c5fb722012-02-28 11:50:355928 log.GetEntries(&entries);
5929 size_t pos = ExpectLogContainsSomewhere(
5930 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
5931 NetLog::PHASE_NONE);
5932 ExpectLogContainsSomewhere(
5933 entries, pos,
5934 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
5935 NetLog::PHASE_NONE);
5936
5937 const HttpResponseInfo* response = trans->GetResponseInfo();
5938 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:505939 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]0c5fb722012-02-28 11:50:355940 EXPECT_EQ(407, response->headers->response_code());
5941 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5942 EXPECT_TRUE(response->auth_challenge.get() != NULL);
5943 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
5944
5945 TestCompletionCallback callback2;
5946
5947 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
5948 callback2.callback());
5949 EXPECT_EQ(ERR_IO_PENDING, rv);
5950
5951 rv = callback2.WaitForResult();
5952 EXPECT_EQ(OK, rv);
5953
5954 response = trans->GetResponseInfo();
5955 ASSERT_TRUE(response != NULL);
5956
5957 EXPECT_TRUE(response->headers->IsKeepAlive());
5958 EXPECT_EQ(200, response->headers->response_code());
5959 EXPECT_EQ(5, response->headers->GetContentLength());
5960 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5961
5962 // The password prompt info should not be set.
5963 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5964
[email protected]029c83b62013-01-24 05:28:205965 LoadTimingInfo load_timing_info;
5966 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5967 TestLoadTimingNotReusedWithPac(load_timing_info,
5968 CONNECT_TIMING_HAS_SSL_TIMES);
5969
[email protected]0c5fb722012-02-28 11:50:355970 trans.reset();
5971 session->CloseAllConnections();
5972}
5973
[email protected]7c6f7ba2012-04-03 04:09:295974// Test that an explicitly trusted SPDY proxy can push a resource from an
5975// origin that is different from that of its associated resource.
[email protected]23e482282013-06-14 16:08:025976TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPush) {
[email protected]7c6f7ba2012-04-03 04:09:295977 HttpRequestInfo request;
5978 HttpRequestInfo push_request;
5979
[email protected]7c6f7ba2012-04-03 04:09:295980 request.method = "GET";
5981 request.url = GURL("http://www.google.com/");
5982 push_request.method = "GET";
5983 push_request.url = GURL("http://www.another-origin.com/foo.dat");
5984
[email protected]7c6f7ba2012-04-03 04:09:295985 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:075986 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:205987 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
[email protected]333bdf62012-06-08 22:57:295988 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075989 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:505990
5991 // Enable cross-origin push.
[email protected]bb88e1d32013-05-03 23:11:075992 session_deps_.trusted_spdy_proxy = "myproxy:70";
[email protected]61b4efc2012-04-27 18:12:505993
[email protected]bb88e1d32013-05-03 23:11:075994 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:295995
[email protected]cdf8f7e72013-05-23 10:56:465996 scoped_ptr<SpdyFrame> stream1_syn(
5997 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]7c6f7ba2012-04-03 04:09:295998
5999 MockWrite spdy_writes[] = {
[email protected]cdf8f7e72013-05-23 10:56:466000 CreateMockWrite(*stream1_syn, 1, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:296001 };
6002
6003 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026004 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:296005
6006 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026007 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:296008
6009 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026010 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
[email protected]7c6f7ba2012-04-03 04:09:296011 0,
6012 2,
6013 1,
6014 "http://www.another-origin.com/foo.dat"));
[email protected]8a0fc822013-06-27 20:52:436015 const char kPushedData[] = "pushed";
6016 scoped_ptr<SpdyFrame> stream2_body(
6017 spdy_util_.ConstructSpdyBodyFrame(
6018 2, kPushedData, strlen(kPushedData), true));
[email protected]7c6f7ba2012-04-03 04:09:296019
6020 MockRead spdy_reads[] = {
6021 CreateMockRead(*stream1_reply, 2, ASYNC),
6022 CreateMockRead(*stream2_syn, 3, ASYNC),
6023 CreateMockRead(*stream1_body, 4, ASYNC),
[email protected]8a0fc822013-06-27 20:52:436024 CreateMockRead(*stream2_body, 5, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:296025 MockRead(ASYNC, ERR_IO_PENDING, 6), // Force a pause
6026 };
6027
[email protected]dd54bd82012-07-19 23:44:576028 OrderedSocketData spdy_data(
6029 spdy_reads, arraysize(spdy_reads),
6030 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:076031 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:296032 // Negotiate SPDY to the proxy
6033 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:026034 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:076035 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:296036
[email protected]262eec82013-03-19 21:01:366037 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506038 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7c6f7ba2012-04-03 04:09:296039 TestCompletionCallback callback;
6040 int rv = trans->Start(&request, callback.callback(), log.bound());
6041 EXPECT_EQ(ERR_IO_PENDING, rv);
6042
6043 rv = callback.WaitForResult();
6044 EXPECT_EQ(OK, rv);
6045 const HttpResponseInfo* response = trans->GetResponseInfo();
6046
[email protected]262eec82013-03-19 21:01:366047 scoped_ptr<HttpTransaction> push_trans(
[email protected]90499482013-06-01 00:39:506048 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
6049 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
[email protected]7c6f7ba2012-04-03 04:09:296050 EXPECT_EQ(ERR_IO_PENDING, rv);
6051
6052 rv = callback.WaitForResult();
6053 EXPECT_EQ(OK, rv);
6054 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
6055
6056 ASSERT_TRUE(response != NULL);
6057 EXPECT_TRUE(response->headers->IsKeepAlive());
6058
6059 EXPECT_EQ(200, response->headers->response_code());
6060 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6061
6062 std::string response_data;
6063 rv = ReadTransaction(trans.get(), &response_data);
6064 EXPECT_EQ(OK, rv);
6065 EXPECT_EQ("hello!", response_data);
6066
[email protected]029c83b62013-01-24 05:28:206067 LoadTimingInfo load_timing_info;
6068 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6069 TestLoadTimingNotReusedWithPac(load_timing_info,
6070 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6071
[email protected]7c6f7ba2012-04-03 04:09:296072 // Verify the pushed stream.
[email protected]90499482013-06-01 00:39:506073 EXPECT_TRUE(push_response->headers.get() != NULL);
[email protected]7c6f7ba2012-04-03 04:09:296074 EXPECT_EQ(200, push_response->headers->response_code());
6075
6076 rv = ReadTransaction(push_trans.get(), &response_data);
6077 EXPECT_EQ(OK, rv);
6078 EXPECT_EQ("pushed", response_data);
6079
[email protected]029c83b62013-01-24 05:28:206080 LoadTimingInfo push_load_timing_info;
6081 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
6082 TestLoadTimingReusedWithPac(push_load_timing_info);
6083 // The transactions should share a socket ID, despite being for different
6084 // origins.
6085 EXPECT_EQ(load_timing_info.socket_log_id,
6086 push_load_timing_info.socket_log_id);
6087
[email protected]7c6f7ba2012-04-03 04:09:296088 trans.reset();
6089 push_trans.reset();
6090 session->CloseAllConnections();
6091}
6092
[email protected]8c843192012-04-05 07:15:006093// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
[email protected]23e482282013-06-14 16:08:026094TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
[email protected]8c843192012-04-05 07:15:006095 HttpRequestInfo request;
6096
6097 request.method = "GET";
6098 request.url = GURL("http://www.google.com/");
6099
[email protected]8c843192012-04-05 07:15:006100 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076101 session_deps_.proxy_service.reset(
[email protected]8c843192012-04-05 07:15:006102 ProxyService::CreateFixed("https://myproxy:70"));
[email protected]333bdf62012-06-08 22:57:296103 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076104 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:506105
6106 // Enable cross-origin push.
[email protected]bb88e1d32013-05-03 23:11:076107 session_deps_.trusted_spdy_proxy = "myproxy:70";
[email protected]61b4efc2012-04-27 18:12:506108
[email protected]bb88e1d32013-05-03 23:11:076109 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:006110
[email protected]cdf8f7e72013-05-23 10:56:466111 scoped_ptr<SpdyFrame> stream1_syn(
6112 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]8c843192012-04-05 07:15:006113
6114 scoped_ptr<SpdyFrame> push_rst(
[email protected]c10b20852013-05-15 21:29:206115 spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:006116
6117 MockWrite spdy_writes[] = {
6118 CreateMockWrite(*stream1_syn, 1, ASYNC),
6119 CreateMockWrite(*push_rst, 4),
6120 };
6121
6122 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026123 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:006124
6125 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026126 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8c843192012-04-05 07:15:006127
6128 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026129 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
[email protected]8c843192012-04-05 07:15:006130 0,
6131 2,
6132 1,
6133 "https://www.another-origin.com/foo.dat"));
6134
6135 MockRead spdy_reads[] = {
6136 CreateMockRead(*stream1_reply, 2, ASYNC),
6137 CreateMockRead(*stream2_syn, 3, ASYNC),
6138 CreateMockRead(*stream1_body, 5, ASYNC),
6139 MockRead(ASYNC, ERR_IO_PENDING, 6), // Force a pause
6140 };
6141
[email protected]dd54bd82012-07-19 23:44:576142 OrderedSocketData spdy_data(
6143 spdy_reads, arraysize(spdy_reads),
6144 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:076145 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:006146 // Negotiate SPDY to the proxy
6147 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:026148 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:076149 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:006150
[email protected]262eec82013-03-19 21:01:366151 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506152 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c843192012-04-05 07:15:006153 TestCompletionCallback callback;
6154 int rv = trans->Start(&request, callback.callback(), log.bound());
6155 EXPECT_EQ(ERR_IO_PENDING, rv);
6156
6157 rv = callback.WaitForResult();
6158 EXPECT_EQ(OK, rv);
6159 const HttpResponseInfo* response = trans->GetResponseInfo();
6160
6161 ASSERT_TRUE(response != NULL);
6162 EXPECT_TRUE(response->headers->IsKeepAlive());
6163
6164 EXPECT_EQ(200, response->headers->response_code());
6165 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6166
6167 std::string response_data;
6168 rv = ReadTransaction(trans.get(), &response_data);
6169 EXPECT_EQ(OK, rv);
6170 EXPECT_EQ("hello!", response_data);
6171
6172 trans.reset();
6173 session->CloseAllConnections();
6174}
6175
[email protected]2df19bb2010-08-25 20:13:466176// Test HTTPS connections to a site with a bad certificate, going through an
6177// HTTPS proxy
[email protected]23e482282013-06-14 16:08:026178TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076179 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:116180 "https://proxy:70"));
[email protected]2df19bb2010-08-25 20:13:466181
6182 HttpRequestInfo request;
6183 request.method = "GET";
6184 request.url = GURL("https://www.google.com/");
6185 request.load_flags = 0;
6186
6187 // Attempt to fetch the URL from a server with a bad cert
6188 MockWrite bad_cert_writes[] = {
6189 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6190 "Host: www.google.com\r\n"
6191 "Proxy-Connection: keep-alive\r\n\r\n"),
6192 };
6193
6194 MockRead bad_cert_reads[] = {
6195 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066196 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:466197 };
6198
6199 // Attempt to fetch the URL with a good cert
6200 MockWrite good_data_writes[] = {
6201 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6202 "Host: www.google.com\r\n"
6203 "Proxy-Connection: keep-alive\r\n\r\n"),
6204 MockWrite("GET / HTTP/1.1\r\n"
6205 "Host: www.google.com\r\n"
6206 "Connection: keep-alive\r\n\r\n"),
6207 };
6208
6209 MockRead good_cert_reads[] = {
6210 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
6211 MockRead("HTTP/1.0 200 OK\r\n"),
6212 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6213 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066214 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:466215 };
6216
6217 StaticSocketDataProvider ssl_bad_certificate(
6218 bad_cert_reads, arraysize(bad_cert_reads),
6219 bad_cert_writes, arraysize(bad_cert_writes));
6220 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
6221 good_data_writes, arraysize(good_data_writes));
[email protected]8ddf8322012-02-23 18:08:066222 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
6223 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:466224
6225 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:076226 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6227 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
6228 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:466229
6230 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:076231 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6232 session_deps_.socket_factory->AddSocketDataProvider(&data);
6233 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:466234
[email protected]49639fa2011-12-20 23:22:416235 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:466236
6237 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366238 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076239 CreateSession(&session_deps_)));
[email protected]2df19bb2010-08-25 20:13:466240
[email protected]49639fa2011-12-20 23:22:416241 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:466242 EXPECT_EQ(ERR_IO_PENDING, rv);
6243
6244 rv = callback.WaitForResult();
6245 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
6246
[email protected]49639fa2011-12-20 23:22:416247 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]2df19bb2010-08-25 20:13:466248 EXPECT_EQ(ERR_IO_PENDING, rv);
6249
6250 rv = callback.WaitForResult();
6251 EXPECT_EQ(OK, rv);
6252
6253 const HttpResponseInfo* response = trans->GetResponseInfo();
6254
[email protected]fe2255a2011-09-20 19:37:506255 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:466256 EXPECT_EQ(100, response->headers->GetContentLength());
6257}
6258
[email protected]23e482282013-06-14 16:08:026259TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:426260 HttpRequestInfo request;
6261 request.method = "GET";
6262 request.url = GURL("http://www.google.com/");
[email protected]8c76ae22010-04-20 22:15:436263 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
6264 "Chromium Ultra Awesome X Edition");
[email protected]1c773ea12009-04-28 19:58:426265
[email protected]cb9bf6ca2011-01-28 13:15:276266 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366267 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076268 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:276269
[email protected]1c773ea12009-04-28 19:58:426270 MockWrite data_writes[] = {
6271 MockWrite("GET / HTTP/1.1\r\n"
6272 "Host: www.google.com\r\n"
6273 "Connection: keep-alive\r\n"
6274 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
6275 };
6276
6277 // Lastly, the server responds with the actual content.
6278 MockRead data_reads[] = {
6279 MockRead("HTTP/1.0 200 OK\r\n"),
6280 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6281 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066282 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426283 };
6284
[email protected]31a2bfe2010-02-09 08:03:396285 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6286 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076287 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426288
[email protected]49639fa2011-12-20 23:22:416289 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426290
[email protected]49639fa2011-12-20 23:22:416291 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426292 EXPECT_EQ(ERR_IO_PENDING, rv);
6293
6294 rv = callback.WaitForResult();
6295 EXPECT_EQ(OK, rv);
6296}
6297
[email protected]23e482282013-06-14 16:08:026298TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:296299 HttpRequestInfo request;
6300 request.method = "GET";
6301 request.url = GURL("https://www.google.com/");
6302 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
6303 "Chromium Ultra Awesome X Edition");
6304
[email protected]bb88e1d32013-05-03 23:11:076305 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]cb9bf6ca2011-01-28 13:15:276306 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366307 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076308 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:276309
[email protected]da81f132010-08-18 23:39:296310 MockWrite data_writes[] = {
6311 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6312 "Host: www.google.com\r\n"
6313 "Proxy-Connection: keep-alive\r\n"
6314 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
6315 };
6316 MockRead data_reads[] = {
6317 // Return an error, so the transaction stops here (this test isn't
6318 // interested in the rest).
6319 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
6320 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6321 MockRead("Proxy-Connection: close\r\n\r\n"),
6322 };
6323
6324 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6325 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076326 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:296327
[email protected]49639fa2011-12-20 23:22:416328 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:296329
[email protected]49639fa2011-12-20 23:22:416330 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]da81f132010-08-18 23:39:296331 EXPECT_EQ(ERR_IO_PENDING, rv);
6332
6333 rv = callback.WaitForResult();
6334 EXPECT_EQ(OK, rv);
6335}
6336
[email protected]23e482282013-06-14 16:08:026337TEST_P(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:426338 HttpRequestInfo request;
6339 request.method = "GET";
6340 request.url = GURL("http://www.google.com/");
6341 request.load_flags = 0;
[email protected]c10450102011-06-27 09:06:166342 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
6343 "http://the.previous.site.com/");
[email protected]1c773ea12009-04-28 19:58:426344
[email protected]cb9bf6ca2011-01-28 13:15:276345 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366346 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076347 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:276348
[email protected]1c773ea12009-04-28 19:58:426349 MockWrite data_writes[] = {
6350 MockWrite("GET / HTTP/1.1\r\n"
6351 "Host: www.google.com\r\n"
6352 "Connection: keep-alive\r\n"
6353 "Referer: http://the.previous.site.com/\r\n\r\n"),
6354 };
6355
6356 // Lastly, the server responds with the actual content.
6357 MockRead data_reads[] = {
6358 MockRead("HTTP/1.0 200 OK\r\n"),
6359 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6360 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066361 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426362 };
6363
[email protected]31a2bfe2010-02-09 08:03:396364 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6365 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076366 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426367
[email protected]49639fa2011-12-20 23:22:416368 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426369
[email protected]49639fa2011-12-20 23:22:416370 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426371 EXPECT_EQ(ERR_IO_PENDING, rv);
6372
6373 rv = callback.WaitForResult();
6374 EXPECT_EQ(OK, rv);
6375}
6376
[email protected]23e482282013-06-14 16:08:026377TEST_P(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:426378 HttpRequestInfo request;
6379 request.method = "POST";
6380 request.url = GURL("http://www.google.com/");
6381
[email protected]cb9bf6ca2011-01-28 13:15:276382 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366383 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076384 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:276385
[email protected]1c773ea12009-04-28 19:58:426386 MockWrite data_writes[] = {
6387 MockWrite("POST / HTTP/1.1\r\n"
6388 "Host: www.google.com\r\n"
6389 "Connection: keep-alive\r\n"
6390 "Content-Length: 0\r\n\r\n"),
6391 };
6392
6393 // Lastly, the server responds with the actual content.
6394 MockRead data_reads[] = {
6395 MockRead("HTTP/1.0 200 OK\r\n"),
6396 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6397 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066398 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426399 };
6400
[email protected]31a2bfe2010-02-09 08:03:396401 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6402 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076403 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426404
[email protected]49639fa2011-12-20 23:22:416405 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426406
[email protected]49639fa2011-12-20 23:22:416407 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426408 EXPECT_EQ(ERR_IO_PENDING, rv);
6409
6410 rv = callback.WaitForResult();
6411 EXPECT_EQ(OK, rv);
6412}
6413
[email protected]23e482282013-06-14 16:08:026414TEST_P(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:426415 HttpRequestInfo request;
6416 request.method = "PUT";
6417 request.url = GURL("http://www.google.com/");
6418
[email protected]cb9bf6ca2011-01-28 13:15:276419 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366420 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076421 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:276422
[email protected]1c773ea12009-04-28 19:58:426423 MockWrite data_writes[] = {
6424 MockWrite("PUT / HTTP/1.1\r\n"
6425 "Host: www.google.com\r\n"
6426 "Connection: keep-alive\r\n"
6427 "Content-Length: 0\r\n\r\n"),
6428 };
6429
6430 // Lastly, the server responds with the actual content.
6431 MockRead data_reads[] = {
6432 MockRead("HTTP/1.0 200 OK\r\n"),
6433 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6434 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066435 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426436 };
6437
[email protected]31a2bfe2010-02-09 08:03:396438 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6439 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076440 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426441
[email protected]49639fa2011-12-20 23:22:416442 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426443
[email protected]49639fa2011-12-20 23:22:416444 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426445 EXPECT_EQ(ERR_IO_PENDING, rv);
6446
6447 rv = callback.WaitForResult();
6448 EXPECT_EQ(OK, rv);
6449}
6450
[email protected]23e482282013-06-14 16:08:026451TEST_P(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:426452 HttpRequestInfo request;
6453 request.method = "HEAD";
6454 request.url = GURL("http://www.google.com/");
6455
[email protected]cb9bf6ca2011-01-28 13:15:276456 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366457 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076458 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:276459
[email protected]1c773ea12009-04-28 19:58:426460 MockWrite data_writes[] = {
6461 MockWrite("HEAD / HTTP/1.1\r\n"
6462 "Host: www.google.com\r\n"
6463 "Connection: keep-alive\r\n"
6464 "Content-Length: 0\r\n\r\n"),
6465 };
6466
6467 // Lastly, the server responds with the actual content.
6468 MockRead data_reads[] = {
6469 MockRead("HTTP/1.0 200 OK\r\n"),
6470 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6471 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066472 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426473 };
6474
[email protected]31a2bfe2010-02-09 08:03:396475 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6476 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076477 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426478
[email protected]49639fa2011-12-20 23:22:416479 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426480
[email protected]49639fa2011-12-20 23:22:416481 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426482 EXPECT_EQ(ERR_IO_PENDING, rv);
6483
6484 rv = callback.WaitForResult();
6485 EXPECT_EQ(OK, rv);
6486}
6487
[email protected]23e482282013-06-14 16:08:026488TEST_P(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:426489 HttpRequestInfo request;
6490 request.method = "GET";
6491 request.url = GURL("http://www.google.com/");
6492 request.load_flags = LOAD_BYPASS_CACHE;
6493
[email protected]cb9bf6ca2011-01-28 13:15:276494 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366495 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076496 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:276497
[email protected]1c773ea12009-04-28 19:58:426498 MockWrite data_writes[] = {
6499 MockWrite("GET / HTTP/1.1\r\n"
6500 "Host: www.google.com\r\n"
6501 "Connection: keep-alive\r\n"
6502 "Pragma: no-cache\r\n"
6503 "Cache-Control: no-cache\r\n\r\n"),
6504 };
6505
6506 // Lastly, the server responds with the actual content.
6507 MockRead data_reads[] = {
6508 MockRead("HTTP/1.0 200 OK\r\n"),
6509 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6510 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066511 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426512 };
6513
[email protected]31a2bfe2010-02-09 08:03:396514 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6515 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076516 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426517
[email protected]49639fa2011-12-20 23:22:416518 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426519
[email protected]49639fa2011-12-20 23:22:416520 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426521 EXPECT_EQ(ERR_IO_PENDING, rv);
6522
6523 rv = callback.WaitForResult();
6524 EXPECT_EQ(OK, rv);
6525}
6526
[email protected]23e482282013-06-14 16:08:026527TEST_P(HttpNetworkTransactionTest,
[email protected]1c773ea12009-04-28 19:58:426528 BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:426529 HttpRequestInfo request;
6530 request.method = "GET";
6531 request.url = GURL("http://www.google.com/");
6532 request.load_flags = LOAD_VALIDATE_CACHE;
6533
[email protected]cb9bf6ca2011-01-28 13:15:276534 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366535 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076536 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:276537
[email protected]1c773ea12009-04-28 19:58:426538 MockWrite data_writes[] = {
6539 MockWrite("GET / HTTP/1.1\r\n"
6540 "Host: www.google.com\r\n"
6541 "Connection: keep-alive\r\n"
6542 "Cache-Control: max-age=0\r\n\r\n"),
6543 };
6544
6545 // Lastly, the server responds with the actual content.
6546 MockRead data_reads[] = {
6547 MockRead("HTTP/1.0 200 OK\r\n"),
6548 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6549 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066550 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426551 };
6552
[email protected]31a2bfe2010-02-09 08:03:396553 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6554 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076555 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426556
[email protected]49639fa2011-12-20 23:22:416557 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426558
[email protected]49639fa2011-12-20 23:22:416559 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426560 EXPECT_EQ(ERR_IO_PENDING, rv);
6561
6562 rv = callback.WaitForResult();
6563 EXPECT_EQ(OK, rv);
6564}
6565
[email protected]23e482282013-06-14 16:08:026566TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:426567 HttpRequestInfo request;
6568 request.method = "GET";
6569 request.url = GURL("http://www.google.com/");
[email protected]8c76ae22010-04-20 22:15:436570 request.extra_headers.SetHeader("FooHeader", "Bar");
[email protected]1c773ea12009-04-28 19:58:426571
[email protected]cb9bf6ca2011-01-28 13:15:276572 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366573 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076574 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:276575
[email protected]1c773ea12009-04-28 19:58:426576 MockWrite data_writes[] = {
6577 MockWrite("GET / HTTP/1.1\r\n"
6578 "Host: www.google.com\r\n"
6579 "Connection: keep-alive\r\n"
6580 "FooHeader: Bar\r\n\r\n"),
6581 };
6582
6583 // Lastly, the server responds with the actual content.
6584 MockRead data_reads[] = {
6585 MockRead("HTTP/1.0 200 OK\r\n"),
6586 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6587 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066588 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426589 };
6590
[email protected]31a2bfe2010-02-09 08:03:396591 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6592 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076593 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426594
[email protected]49639fa2011-12-20 23:22:416595 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426596
[email protected]49639fa2011-12-20 23:22:416597 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426598 EXPECT_EQ(ERR_IO_PENDING, rv);
6599
6600 rv = callback.WaitForResult();
6601 EXPECT_EQ(OK, rv);
6602}
6603
[email protected]23e482282013-06-14 16:08:026604TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:476605 HttpRequestInfo request;
6606 request.method = "GET";
6607 request.url = GURL("http://www.google.com/");
[email protected]8c76ae22010-04-20 22:15:436608 request.extra_headers.SetHeader("referer", "www.foo.com");
6609 request.extra_headers.SetHeader("hEllo", "Kitty");
6610 request.extra_headers.SetHeader("FoO", "bar");
[email protected]270c6412010-03-29 22:02:476611
[email protected]cb9bf6ca2011-01-28 13:15:276612 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366613 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076614 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:276615
[email protected]270c6412010-03-29 22:02:476616 MockWrite data_writes[] = {
6617 MockWrite("GET / HTTP/1.1\r\n"
6618 "Host: www.google.com\r\n"
6619 "Connection: keep-alive\r\n"
[email protected]c10450102011-06-27 09:06:166620 "referer: www.foo.com\r\n"
[email protected]270c6412010-03-29 22:02:476621 "hEllo: Kitty\r\n"
6622 "FoO: bar\r\n\r\n"),
6623 };
6624
6625 // Lastly, the server responds with the actual content.
6626 MockRead data_reads[] = {
6627 MockRead("HTTP/1.0 200 OK\r\n"),
6628 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6629 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066630 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:476631 };
6632
6633 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6634 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076635 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:476636
[email protected]49639fa2011-12-20 23:22:416637 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:476638
[email protected]49639fa2011-12-20 23:22:416639 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]270c6412010-03-29 22:02:476640 EXPECT_EQ(ERR_IO_PENDING, rv);
6641
6642 rv = callback.WaitForResult();
6643 EXPECT_EQ(OK, rv);
6644}
6645
[email protected]23e482282013-06-14 16:08:026646TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:276647 HttpRequestInfo request;
6648 request.method = "GET";
6649 request.url = GURL("http://www.google.com/");
6650 request.load_flags = 0;
6651
[email protected]bb88e1d32013-05-03 23:11:076652 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206653 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
6654 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076655 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:026656
6657 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366658 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076659 CreateSession(&session_deps_)));
[email protected]3cd17242009-06-23 02:59:026660
[email protected]3cd17242009-06-23 02:59:026661 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
6662 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
6663
6664 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:066665 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
[email protected]3cd17242009-06-23 02:59:026666 MockWrite("GET / HTTP/1.1\r\n"
6667 "Host: www.google.com\r\n"
6668 "Connection: keep-alive\r\n\r\n")
6669 };
6670
6671 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:066672 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:026673 MockRead("HTTP/1.0 200 OK\r\n"),
6674 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
6675 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:066676 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:026677 };
6678
[email protected]31a2bfe2010-02-09 08:03:396679 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6680 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076681 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:026682
[email protected]49639fa2011-12-20 23:22:416683 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:026684
[email protected]49639fa2011-12-20 23:22:416685 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:026686 EXPECT_EQ(ERR_IO_PENDING, rv);
6687
6688 rv = callback.WaitForResult();
6689 EXPECT_EQ(OK, rv);
6690
6691 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506692 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:026693
[email protected]029c83b62013-01-24 05:28:206694 LoadTimingInfo load_timing_info;
6695 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6696 TestLoadTimingNotReusedWithPac(load_timing_info,
6697 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6698
[email protected]3cd17242009-06-23 02:59:026699 std::string response_text;
6700 rv = ReadTransaction(trans.get(), &response_text);
6701 EXPECT_EQ(OK, rv);
6702 EXPECT_EQ("Payload", response_text);
6703}
6704
[email protected]23e482282013-06-14 16:08:026705TEST_P(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:276706 HttpRequestInfo request;
6707 request.method = "GET";
6708 request.url = GURL("https://www.google.com/");
6709 request.load_flags = 0;
6710
[email protected]bb88e1d32013-05-03 23:11:076711 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206712 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
6713 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076714 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:026715
6716 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366717 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076718 CreateSession(&session_deps_)));
[email protected]3cd17242009-06-23 02:59:026719
[email protected]3cd17242009-06-23 02:59:026720 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
6721 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
6722
6723 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:066724 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
[email protected]e0c27be2009-07-15 13:09:356725 arraysize(write_buffer)),
[email protected]3cd17242009-06-23 02:59:026726 MockWrite("GET / HTTP/1.1\r\n"
6727 "Host: www.google.com\r\n"
6728 "Connection: keep-alive\r\n\r\n")
6729 };
6730
6731 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:016732 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
6733 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:356734 MockRead("HTTP/1.0 200 OK\r\n"),
6735 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
6736 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:066737 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:356738 };
6739
[email protected]31a2bfe2010-02-09 08:03:396740 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6741 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076742 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:356743
[email protected]8ddf8322012-02-23 18:08:066744 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076745 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:356746
[email protected]49639fa2011-12-20 23:22:416747 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:356748
[email protected]49639fa2011-12-20 23:22:416749 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:356750 EXPECT_EQ(ERR_IO_PENDING, rv);
6751
6752 rv = callback.WaitForResult();
6753 EXPECT_EQ(OK, rv);
6754
[email protected]029c83b62013-01-24 05:28:206755 LoadTimingInfo load_timing_info;
6756 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6757 TestLoadTimingNotReusedWithPac(load_timing_info,
6758 CONNECT_TIMING_HAS_SSL_TIMES);
6759
[email protected]e0c27be2009-07-15 13:09:356760 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506761 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:356762
6763 std::string response_text;
6764 rv = ReadTransaction(trans.get(), &response_text);
6765 EXPECT_EQ(OK, rv);
6766 EXPECT_EQ("Payload", response_text);
6767}
6768
[email protected]23e482282013-06-14 16:08:026769TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:206770 HttpRequestInfo request;
6771 request.method = "GET";
6772 request.url = GURL("http://www.google.com/");
6773 request.load_flags = 0;
6774
[email protected]bb88e1d32013-05-03 23:11:076775 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206776 ProxyService::CreateFixed("socks4://myproxy:1080"));
6777 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076778 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:206779
6780 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366781 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076782 CreateSession(&session_deps_)));
[email protected]029c83b62013-01-24 05:28:206783
6784 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
6785 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
6786
6787 MockWrite data_writes[] = {
6788 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
6789 MockWrite("GET / HTTP/1.1\r\n"
6790 "Host: www.google.com\r\n"
6791 "Connection: keep-alive\r\n\r\n")
6792 };
6793
6794 MockRead data_reads[] = {
6795 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
6796 MockRead("HTTP/1.0 200 OK\r\n"),
6797 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
6798 MockRead("Payload"),
6799 MockRead(SYNCHRONOUS, OK)
6800 };
6801
6802 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6803 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076804 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:206805
6806 TestCompletionCallback callback;
6807
6808 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6809 EXPECT_EQ(ERR_IO_PENDING, rv);
6810
6811 rv = callback.WaitForResult();
6812 EXPECT_EQ(OK, rv);
6813
6814 const HttpResponseInfo* response = trans->GetResponseInfo();
6815 ASSERT_TRUE(response != NULL);
6816
6817 LoadTimingInfo load_timing_info;
6818 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6819 TestLoadTimingNotReused(load_timing_info,
6820 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6821
6822 std::string response_text;
6823 rv = ReadTransaction(trans.get(), &response_text);
6824 EXPECT_EQ(OK, rv);
6825 EXPECT_EQ("Payload", response_text);
6826}
6827
[email protected]23e482282013-06-14 16:08:026828TEST_P(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:276829 HttpRequestInfo request;
6830 request.method = "GET";
6831 request.url = GURL("http://www.google.com/");
6832 request.load_flags = 0;
6833
[email protected]bb88e1d32013-05-03 23:11:076834 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206835 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
6836 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076837 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:356838
6839 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366840 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076841 CreateSession(&session_deps_)));
[email protected]e0c27be2009-07-15 13:09:356842
[email protected]e0c27be2009-07-15 13:09:356843 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
6844 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:376845 const char kSOCKS5OkRequest[] = {
6846 0x05, // Version
6847 0x01, // Command (CONNECT)
6848 0x00, // Reserved.
6849 0x03, // Address type (DOMAINNAME).
6850 0x0E, // Length of domain (14)
6851 // Domain string:
6852 'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
6853 0x00, 0x50, // 16-bit port (80)
6854 };
[email protected]e0c27be2009-07-15 13:09:356855 const char kSOCKS5OkResponse[] =
6856 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
6857
6858 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:066859 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
6860 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
[email protected]e0c27be2009-07-15 13:09:356861 MockWrite("GET / HTTP/1.1\r\n"
6862 "Host: www.google.com\r\n"
6863 "Connection: keep-alive\r\n\r\n")
6864 };
6865
6866 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:016867 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
6868 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:356869 MockRead("HTTP/1.0 200 OK\r\n"),
6870 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
6871 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:066872 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:356873 };
6874
[email protected]31a2bfe2010-02-09 08:03:396875 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6876 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076877 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:356878
[email protected]49639fa2011-12-20 23:22:416879 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:356880
[email protected]49639fa2011-12-20 23:22:416881 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:356882 EXPECT_EQ(ERR_IO_PENDING, rv);
6883
6884 rv = callback.WaitForResult();
6885 EXPECT_EQ(OK, rv);
6886
6887 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506888 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:356889
[email protected]029c83b62013-01-24 05:28:206890 LoadTimingInfo load_timing_info;
6891 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6892 TestLoadTimingNotReusedWithPac(load_timing_info,
6893 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6894
[email protected]e0c27be2009-07-15 13:09:356895 std::string response_text;
6896 rv = ReadTransaction(trans.get(), &response_text);
6897 EXPECT_EQ(OK, rv);
6898 EXPECT_EQ("Payload", response_text);
6899}
6900
[email protected]23e482282013-06-14 16:08:026901TEST_P(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:276902 HttpRequestInfo request;
6903 request.method = "GET";
6904 request.url = GURL("https://www.google.com/");
6905 request.load_flags = 0;
6906
[email protected]bb88e1d32013-05-03 23:11:076907 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206908 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
6909 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076910 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:356911
6912 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366913 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076914 CreateSession(&session_deps_)));
[email protected]e0c27be2009-07-15 13:09:356915
[email protected]e0c27be2009-07-15 13:09:356916 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
6917 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:376918 const unsigned char kSOCKS5OkRequest[] = {
6919 0x05, // Version
6920 0x01, // Command (CONNECT)
6921 0x00, // Reserved.
6922 0x03, // Address type (DOMAINNAME).
6923 0x0E, // Length of domain (14)
6924 // Domain string:
6925 'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
6926 0x01, 0xBB, // 16-bit port (443)
6927 };
6928
[email protected]e0c27be2009-07-15 13:09:356929 const char kSOCKS5OkResponse[] =
6930 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
6931
6932 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:066933 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
6934 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
[email protected]e0c27be2009-07-15 13:09:356935 arraysize(kSOCKS5OkRequest)),
6936 MockWrite("GET / HTTP/1.1\r\n"
6937 "Host: www.google.com\r\n"
6938 "Connection: keep-alive\r\n\r\n")
6939 };
6940
6941 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:016942 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
6943 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:026944 MockRead("HTTP/1.0 200 OK\r\n"),
6945 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
6946 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:066947 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:026948 };
6949
[email protected]31a2bfe2010-02-09 08:03:396950 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6951 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076952 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:026953
[email protected]8ddf8322012-02-23 18:08:066954 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076955 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:026956
[email protected]49639fa2011-12-20 23:22:416957 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:026958
[email protected]49639fa2011-12-20 23:22:416959 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:026960 EXPECT_EQ(ERR_IO_PENDING, rv);
6961
6962 rv = callback.WaitForResult();
6963 EXPECT_EQ(OK, rv);
6964
6965 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506966 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:026967
[email protected]029c83b62013-01-24 05:28:206968 LoadTimingInfo load_timing_info;
6969 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6970 TestLoadTimingNotReusedWithPac(load_timing_info,
6971 CONNECT_TIMING_HAS_SSL_TIMES);
6972
[email protected]3cd17242009-06-23 02:59:026973 std::string response_text;
6974 rv = ReadTransaction(trans.get(), &response_text);
6975 EXPECT_EQ(OK, rv);
6976 EXPECT_EQ("Payload", response_text);
6977}
6978
[email protected]448d4ca52012-03-04 04:12:236979namespace {
6980
[email protected]04e5be32009-06-26 20:00:316981// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:066982
6983struct GroupNameTest {
6984 std::string proxy_server;
6985 std::string url;
6986 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:186987 bool ssl;
[email protected]2d731a32010-04-29 01:04:066988};
6989
6990scoped_refptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]8a0fc822013-06-27 20:52:436991 NextProto next_proto,
[email protected]bb88e1d32013-05-03 23:11:076992 SpdySessionDependencies* session_deps_) {
6993 scoped_refptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:066994
[email protected]30d4c022013-07-18 22:58:166995 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:536996 session->http_server_properties();
6997 http_server_properties->SetAlternateProtocol(
[email protected]2d731a32010-04-29 01:04:066998 HostPortPair("host.with.alternate", 80), 443,
[email protected]8a0fc822013-06-27 20:52:436999 AlternateProtocolFromNextProto(next_proto));
[email protected]2d731a32010-04-29 01:04:067000
7001 return session;
7002}
7003
7004int GroupNameTransactionHelper(
7005 const std::string& url,
7006 const scoped_refptr<HttpNetworkSession>& session) {
[email protected]2d731a32010-04-29 01:04:067007 HttpRequestInfo request;
7008 request.method = "GET";
7009 request.url = GURL(url);
7010 request.load_flags = 0;
7011
[email protected]262eec82013-03-19 21:01:367012 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507013 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277014
[email protected]49639fa2011-12-20 23:22:417015 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:067016
7017 // We do not complete this request, the dtor will clean the transaction up.
[email protected]49639fa2011-12-20 23:22:417018 return trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d731a32010-04-29 01:04:067019}
7020
[email protected]448d4ca52012-03-04 04:12:237021} // namespace
7022
[email protected]23e482282013-06-14 16:08:027023TEST_P(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:067024 const GroupNameTest tests[] = {
[email protected]04e5be32009-06-26 20:00:317025 {
[email protected]2d731a32010-04-29 01:04:067026 "", // unused
[email protected]04e5be32009-06-26 20:00:317027 "http://www.google.com/direct",
[email protected]2ff8b312010-04-26 22:20:547028 "www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:187029 false,
[email protected]2ff8b312010-04-26 22:20:547030 },
7031 {
[email protected]2d731a32010-04-29 01:04:067032 "", // unused
[email protected]2ff8b312010-04-26 22:20:547033 "http://[2001:1418:13:1::25]/direct",
7034 "[2001:1418:13:1::25]:80",
[email protected]e60e47a2010-07-14 03:37:187035 false,
[email protected]04e5be32009-06-26 20:00:317036 },
[email protected]04e5be32009-06-26 20:00:317037
7038 // SSL Tests
7039 {
[email protected]2d731a32010-04-29 01:04:067040 "", // unused
[email protected]04e5be32009-06-26 20:00:317041 "https://www.google.com/direct_ssl",
[email protected]0e88ad602010-05-04 23:47:027042 "ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:187043 true,
[email protected]04e5be32009-06-26 20:00:317044 },
7045 {
[email protected]2d731a32010-04-29 01:04:067046 "", // unused
7047 "https://[2001:1418:13:1::25]/direct",
[email protected]0e88ad602010-05-04 23:47:027048 "ssl/[2001:1418:13:1::25]:443",
[email protected]e60e47a2010-07-14 03:37:187049 true,
[email protected]04e5be32009-06-26 20:00:317050 },
7051 {
[email protected]2d731a32010-04-29 01:04:067052 "", // unused
[email protected]2ff8b312010-04-26 22:20:547053 "http://host.with.alternate/direct",
[email protected]0e88ad602010-05-04 23:47:027054 "ssl/host.with.alternate:443",
[email protected]e60e47a2010-07-14 03:37:187055 true,
[email protected]2ff8b312010-04-26 22:20:547056 },
[email protected]2d731a32010-04-29 01:04:067057 };
[email protected]2ff8b312010-04-26 22:20:547058
[email protected]8e6441ca2010-08-19 05:56:387059 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]2d731a32010-04-29 01:04:067060
7061 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:077062 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:027063 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:067064 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:437065 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:067066
7067 HttpNetworkSessionPeer peer(session);
[email protected]ab739042011-04-07 15:22:287068 CaptureGroupNameTransportSocketPool* transport_conn_pool =
7069 new CaptureGroupNameTransportSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:137070 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347071 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:027072 MockClientSocketPoolManager* mock_pool_manager =
7073 new MockClientSocketPoolManager;
7074 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
7075 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
7076 peer.SetClientSocketPoolManager(mock_pool_manager);
[email protected]2d731a32010-04-29 01:04:067077
7078 EXPECT_EQ(ERR_IO_PENDING,
7079 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:187080 if (tests[i].ssl)
7081 EXPECT_EQ(tests[i].expected_group_name,
7082 ssl_conn_pool->last_group_name_received());
7083 else
7084 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:287085 transport_conn_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:067086 }
7087
[email protected]2d731a32010-04-29 01:04:067088}
7089
[email protected]23e482282013-06-14 16:08:027090TEST_P(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:067091 const GroupNameTest tests[] = {
7092 {
7093 "http_proxy",
7094 "http://www.google.com/http_proxy_normal",
7095 "www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:187096 false,
[email protected]2d731a32010-04-29 01:04:067097 },
7098
7099 // SSL Tests
7100 {
7101 "http_proxy",
7102 "https://www.google.com/http_connect_ssl",
[email protected]0e88ad602010-05-04 23:47:027103 "ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:187104 true,
[email protected]2d731a32010-04-29 01:04:067105 },
[email protected]af3490e2010-10-16 21:02:297106
[email protected]9faeded92010-04-29 20:03:057107 {
7108 "http_proxy",
7109 "http://host.with.alternate/direct",
[email protected]0e88ad602010-05-04 23:47:027110 "ssl/host.with.alternate:443",
[email protected]e60e47a2010-07-14 03:37:187111 true,
[email protected]9faeded92010-04-29 20:03:057112 },
[email protected]45499252013-01-23 17:12:567113
7114 {
7115 "http_proxy",
7116 "ftp://ftp.google.com/http_proxy_normal",
7117 "ftp/ftp.google.com:21",
7118 false,
7119 },
[email protected]2d731a32010-04-29 01:04:067120 };
7121
[email protected]8e6441ca2010-08-19 05:56:387122 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]2d731a32010-04-29 01:04:067123
7124 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:077125 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:027126 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:067127 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:437128 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:067129
7130 HttpNetworkSessionPeer peer(session);
7131
[email protected]e60e47a2010-07-14 03:37:187132 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:137133 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:347134 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:137135 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347136 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:027137
7138 MockClientSocketPoolManager* mock_pool_manager =
7139 new MockClientSocketPoolManager;
7140 mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool);
7141 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
7142 peer.SetClientSocketPoolManager(mock_pool_manager);
[email protected]2d731a32010-04-29 01:04:067143
7144 EXPECT_EQ(ERR_IO_PENDING,
7145 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:187146 if (tests[i].ssl)
7147 EXPECT_EQ(tests[i].expected_group_name,
7148 ssl_conn_pool->last_group_name_received());
7149 else
7150 EXPECT_EQ(tests[i].expected_group_name,
7151 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:067152 }
[email protected]2d731a32010-04-29 01:04:067153}
7154
[email protected]23e482282013-06-14 16:08:027155TEST_P(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:067156 const GroupNameTest tests[] = {
7157 {
7158 "socks4://socks_proxy:1080",
7159 "http://www.google.com/socks4_direct",
7160 "socks4/www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:187161 false,
[email protected]2d731a32010-04-29 01:04:067162 },
7163 {
7164 "socks5://socks_proxy:1080",
7165 "http://www.google.com/socks5_direct",
7166 "socks5/www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:187167 false,
[email protected]2d731a32010-04-29 01:04:067168 },
7169
7170 // SSL Tests
7171 {
7172 "socks4://socks_proxy:1080",
7173 "https://www.google.com/socks4_ssl",
[email protected]0e88ad602010-05-04 23:47:027174 "socks4/ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:187175 true,
[email protected]2d731a32010-04-29 01:04:067176 },
7177 {
7178 "socks5://socks_proxy:1080",
7179 "https://www.google.com/socks5_ssl",
[email protected]0e88ad602010-05-04 23:47:027180 "socks5/ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:187181 true,
[email protected]2d731a32010-04-29 01:04:067182 },
[email protected]af3490e2010-10-16 21:02:297183
[email protected]9faeded92010-04-29 20:03:057184 {
7185 "socks4://socks_proxy:1080",
7186 "http://host.with.alternate/direct",
[email protected]0e88ad602010-05-04 23:47:027187 "socks4/ssl/host.with.alternate:443",
[email protected]e60e47a2010-07-14 03:37:187188 true,
[email protected]9faeded92010-04-29 20:03:057189 },
[email protected]04e5be32009-06-26 20:00:317190 };
7191
[email protected]8e6441ca2010-08-19 05:56:387192 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]2ff8b312010-04-26 22:20:547193
[email protected]04e5be32009-06-26 20:00:317194 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:077195 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:027196 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:067197 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:437198 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]8b114dd72011-03-25 05:33:027199
[email protected]2d731a32010-04-29 01:04:067200 HttpNetworkSessionPeer peer(session);
[email protected]04e5be32009-06-26 20:00:317201
[email protected]e60e47a2010-07-14 03:37:187202 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:137203 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347204 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:137205 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347206 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:027207
7208 MockClientSocketPoolManager* mock_pool_manager =
7209 new MockClientSocketPoolManager;
7210 mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_conn_pool);
7211 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
7212 peer.SetClientSocketPoolManager(mock_pool_manager);
[email protected]04e5be32009-06-26 20:00:317213
[email protected]262eec82013-03-19 21:01:367214 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507215 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]04e5be32009-06-26 20:00:317216
[email protected]2d731a32010-04-29 01:04:067217 EXPECT_EQ(ERR_IO_PENDING,
7218 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:187219 if (tests[i].ssl)
7220 EXPECT_EQ(tests[i].expected_group_name,
7221 ssl_conn_pool->last_group_name_received());
7222 else
7223 EXPECT_EQ(tests[i].expected_group_name,
7224 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:317225 }
7226}
7227
[email protected]23e482282013-06-14 16:08:027228TEST_P(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:277229 HttpRequestInfo request;
7230 request.method = "GET";
7231 request.url = GURL("http://www.google.com/");
7232
[email protected]bb88e1d32013-05-03 23:11:077233 session_deps_.proxy_service.reset(
[email protected]81cdfcd2010-10-16 00:49:007234 ProxyService::CreateFixed("myproxy:70;foobar:80"));
[email protected]b59ff372009-07-15 22:04:327235
[email protected]69719062010-01-05 20:09:217236 // This simulates failure resolving all hostnames; that means we will fail
7237 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:077238 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:327239
[email protected]9172a982009-06-06 00:30:257240 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:367241 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:077242 CreateSession(&session_deps_)));
[email protected]9172a982009-06-06 00:30:257243
[email protected]49639fa2011-12-20 23:22:417244 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:257245
[email protected]49639fa2011-12-20 23:22:417246 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9172a982009-06-06 00:30:257247 EXPECT_EQ(ERR_IO_PENDING, rv);
7248
[email protected]9172a982009-06-06 00:30:257249 rv = callback.WaitForResult();
[email protected]f7fccee2010-09-16 20:53:017250 EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
[email protected]9172a982009-06-06 00:30:257251}
7252
[email protected]685af592010-05-11 19:31:247253// Base test to make sure that when the load flags for a request specify to
7254// bypass the cache, the DNS cache is not used.
[email protected]23e482282013-06-14 16:08:027255void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
[email protected]bb88e1d32013-05-03 23:11:077256 int load_flags) {
[email protected]cb9bf6ca2011-01-28 13:15:277257 // Issue a request, asking to bypass the cache(s).
7258 HttpRequestInfo request;
7259 request.method = "GET";
7260 request.load_flags = load_flags;
7261 request.url = GURL("http://www.google.com/");
7262
[email protected]a2c2fb92009-07-18 07:31:047263 // Select a host resolver that does caching.
[email protected]bb88e1d32013-05-03 23:11:077264 session_deps_.host_resolver.reset(new MockCachingHostResolver);
[email protected]b59ff372009-07-15 22:04:327265
[email protected]262eec82013-03-19 21:01:367266 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:077267 CreateSession(&session_deps_)));
[email protected]3b9cca42009-06-16 01:08:287268
[email protected]6e78dfb2011-07-28 21:34:477269 // Warm up the host cache so it has an entry for "www.google.com".
[email protected]3b9cca42009-06-16 01:08:287270 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:297271 TestCompletionCallback callback;
[email protected]bb88e1d32013-05-03 23:11:077272 int rv = session_deps_.host_resolver->Resolve(
[email protected]930cc742010-09-15 22:54:107273 HostResolver::RequestInfo(HostPortPair("www.google.com", 80)), &addrlist,
[email protected]aa22b242011-11-16 18:58:297274 callback.callback(), NULL, BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:477275 EXPECT_EQ(ERR_IO_PENDING, rv);
7276 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:287277 EXPECT_EQ(OK, rv);
7278
7279 // Verify that it was added to host cache, by doing a subsequent async lookup
7280 // and confirming it completes synchronously.
[email protected]bb88e1d32013-05-03 23:11:077281 rv = session_deps_.host_resolver->Resolve(
[email protected]930cc742010-09-15 22:54:107282 HostResolver::RequestInfo(HostPortPair("www.google.com", 80)), &addrlist,
[email protected]aa22b242011-11-16 18:58:297283 callback.callback(), NULL, BoundNetLog());
[email protected]b59ff372009-07-15 22:04:327284 ASSERT_EQ(OK, rv);
[email protected]3b9cca42009-06-16 01:08:287285
7286 // Inject a failure the next time that "www.google.com" is resolved. This way
7287 // we can tell if the next lookup hit the cache, or the "network".
7288 // (cache --> success, "network" --> failure).
[email protected]bb88e1d32013-05-03 23:11:077289 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.google.com");
[email protected]3b9cca42009-06-16 01:08:287290
7291 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
7292 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:067293 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
[email protected]31a2bfe2010-02-09 08:03:397294 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077295 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:287296
[email protected]3b9cca42009-06-16 01:08:287297 // Run the request.
[email protected]49639fa2011-12-20 23:22:417298 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3b9cca42009-06-16 01:08:287299 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:417300 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:287301
7302 // If we bypassed the cache, we would have gotten a failure while resolving
7303 // "www.google.com".
7304 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
7305}
7306
[email protected]685af592010-05-11 19:31:247307// There are multiple load flags that should trigger the host cache bypass.
7308// Test each in isolation:
[email protected]23e482282013-06-14 16:08:027309TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
[email protected]685af592010-05-11 19:31:247310 BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
7311}
7312
[email protected]23e482282013-06-14 16:08:027313TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
[email protected]685af592010-05-11 19:31:247314 BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
7315}
7316
[email protected]23e482282013-06-14 16:08:027317TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
[email protected]685af592010-05-11 19:31:247318 BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
7319}
7320
[email protected]0877e3d2009-10-17 22:29:577321// Make sure we can handle an error when writing the request.
[email protected]23e482282013-06-14 16:08:027322TEST_P(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]bb88e1d32013-05-03 23:11:077323 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:577324
7325 HttpRequestInfo request;
7326 request.method = "GET";
7327 request.url = GURL("http://www.foo.com/");
7328 request.load_flags = 0;
7329
7330 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:067331 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:577332 };
[email protected]31a2bfe2010-02-09 08:03:397333 StaticSocketDataProvider data(NULL, 0,
7334 write_failure, arraysize(write_failure));
[email protected]bb88e1d32013-05-03 23:11:077335 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]0877e3d2009-10-17 22:29:577336
[email protected]49639fa2011-12-20 23:22:417337 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:577338
7339 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:367340 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:077341 CreateSession(&session_deps_)));
[email protected]0877e3d2009-10-17 22:29:577342
[email protected]49639fa2011-12-20 23:22:417343 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:577344 EXPECT_EQ(ERR_IO_PENDING, rv);
7345
7346 rv = callback.WaitForResult();
7347 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
7348}
7349
7350// Check that a connection closed after the start of the headers finishes ok.
[email protected]23e482282013-06-14 16:08:027351TEST_P(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]bb88e1d32013-05-03 23:11:077352 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:577353
7354 HttpRequestInfo request;
7355 request.method = "GET";
7356 request.url = GURL("http://www.foo.com/");
7357 request.load_flags = 0;
7358
7359 MockRead data_reads[] = {
7360 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:067361 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:577362 };
7363
[email protected]31a2bfe2010-02-09 08:03:397364 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077365 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]0877e3d2009-10-17 22:29:577366
[email protected]49639fa2011-12-20 23:22:417367 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:577368
7369 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:367370 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:077371 CreateSession(&session_deps_)));
[email protected]0877e3d2009-10-17 22:29:577372
[email protected]49639fa2011-12-20 23:22:417373 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:577374 EXPECT_EQ(ERR_IO_PENDING, rv);
7375
7376 rv = callback.WaitForResult();
7377 EXPECT_EQ(OK, rv);
7378
7379 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507380 ASSERT_TRUE(response != NULL);
[email protected]0877e3d2009-10-17 22:29:577381
[email protected]90499482013-06-01 00:39:507382 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]0877e3d2009-10-17 22:29:577383 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
7384
7385 std::string response_data;
7386 rv = ReadTransaction(trans.get(), &response_data);
7387 EXPECT_EQ(OK, rv);
7388 EXPECT_EQ("", response_data);
7389}
7390
7391// Make sure that a dropped connection while draining the body for auth
7392// restart does the right thing.
[email protected]23e482282013-06-14 16:08:027393TEST_P(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]bb88e1d32013-05-03 23:11:077394 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:577395
7396 HttpRequestInfo request;
7397 request.method = "GET";
7398 request.url = GURL("http://www.google.com/");
7399 request.load_flags = 0;
7400
7401 MockWrite data_writes1[] = {
7402 MockWrite("GET / HTTP/1.1\r\n"
7403 "Host: www.google.com\r\n"
7404 "Connection: keep-alive\r\n\r\n"),
7405 };
7406
7407 MockRead data_reads1[] = {
7408 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
7409 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7410 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7411 MockRead("Content-Length: 14\r\n\r\n"),
7412 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:067413 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:577414 };
7415
[email protected]31a2bfe2010-02-09 08:03:397416 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7417 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:077418 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:577419
7420 // After calling trans->RestartWithAuth(), this is the request we should
7421 // be issuing -- the final header line contains the credentials.
7422 MockWrite data_writes2[] = {
7423 MockWrite("GET / HTTP/1.1\r\n"
7424 "Host: www.google.com\r\n"
7425 "Connection: keep-alive\r\n"
7426 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
7427 };
7428
7429 // Lastly, the server responds with the actual content.
7430 MockRead data_reads2[] = {
7431 MockRead("HTTP/1.1 200 OK\r\n"),
7432 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7433 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067434 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:577435 };
7436
[email protected]31a2bfe2010-02-09 08:03:397437 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7438 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077439 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]0877e3d2009-10-17 22:29:577440
[email protected]49639fa2011-12-20 23:22:417441 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:577442
[email protected]262eec82013-03-19 21:01:367443 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507444 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:507445
[email protected]49639fa2011-12-20 23:22:417446 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:577447 EXPECT_EQ(ERR_IO_PENDING, rv);
7448
7449 rv = callback1.WaitForResult();
7450 EXPECT_EQ(OK, rv);
7451
7452 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507453 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:047454 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:577455
[email protected]49639fa2011-12-20 23:22:417456 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:577457
[email protected]49639fa2011-12-20 23:22:417458 rv = trans->RestartWithAuth(
7459 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]0877e3d2009-10-17 22:29:577460 EXPECT_EQ(ERR_IO_PENDING, rv);
7461
7462 rv = callback2.WaitForResult();
7463 EXPECT_EQ(OK, rv);
7464
7465 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507466 ASSERT_TRUE(response != NULL);
[email protected]0877e3d2009-10-17 22:29:577467 EXPECT_TRUE(response->auth_challenge.get() == NULL);
7468 EXPECT_EQ(100, response->headers->GetContentLength());
7469}
7470
7471// Test HTTPS connections going through a proxy that sends extra data.
[email protected]23e482282013-06-14 16:08:027472TEST_P(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
[email protected]bb88e1d32013-05-03 23:11:077473 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]0877e3d2009-10-17 22:29:577474
7475 HttpRequestInfo request;
7476 request.method = "GET";
7477 request.url = GURL("https://www.google.com/");
7478 request.load_flags = 0;
7479
7480 MockRead proxy_reads[] = {
7481 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:067482 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:577483 };
7484
[email protected]31a2bfe2010-02-09 08:03:397485 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
[email protected]8ddf8322012-02-23 18:08:067486 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:577487
[email protected]bb88e1d32013-05-03 23:11:077488 session_deps_.socket_factory->AddSocketDataProvider(&data);
7489 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:577490
[email protected]49639fa2011-12-20 23:22:417491 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:577492
[email protected]bb88e1d32013-05-03 23:11:077493 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:577494
7495 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:367496 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:077497 CreateSession(&session_deps_)));
[email protected]0877e3d2009-10-17 22:29:577498
[email protected]49639fa2011-12-20 23:22:417499 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:577500 EXPECT_EQ(ERR_IO_PENDING, rv);
7501
7502 rv = callback.WaitForResult();
7503 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
7504}
7505
[email protected]23e482282013-06-14 16:08:027506TEST_P(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:467507 HttpRequestInfo request;
7508 request.method = "GET";
7509 request.url = GURL("http://www.google.com/");
7510 request.load_flags = 0;
7511
[email protected]cb9bf6ca2011-01-28 13:15:277512 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:367513 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:077514 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:277515
[email protected]e22e1362009-11-23 21:31:127516 MockRead data_reads[] = {
7517 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067518 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:127519 };
[email protected]9492e4a2010-02-24 00:58:467520
7521 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077522 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:467523
[email protected]49639fa2011-12-20 23:22:417524 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:467525
[email protected]49639fa2011-12-20 23:22:417526 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9492e4a2010-02-24 00:58:467527 EXPECT_EQ(ERR_IO_PENDING, rv);
7528
7529 EXPECT_EQ(OK, callback.WaitForResult());
7530
7531 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507532 ASSERT_TRUE(response != NULL);
[email protected]9492e4a2010-02-24 00:58:467533
[email protected]90499482013-06-01 00:39:507534 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]9492e4a2010-02-24 00:58:467535 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
7536
7537 std::string response_data;
7538 rv = ReadTransaction(trans.get(), &response_data);
[email protected]5543cbb2012-04-20 16:35:237539 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
[email protected]e22e1362009-11-23 21:31:127540}
7541
[email protected]23e482282013-06-14 16:08:027542TEST_P(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:157543 base::FilePath temp_file_path;
[email protected]95d88ffe2010-02-04 21:25:337544 ASSERT_TRUE(file_util::CreateTemporaryFile(&temp_file_path));
7545 const uint64 kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:217546 UploadFileElementReader::ScopedOverridingContentLengthForTests
7547 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:337548
[email protected]b2d26cfd2012-12-11 10:36:067549 ScopedVector<UploadElementReader> element_readers;
7550 element_readers.push_back(
[email protected]cadac622013-06-11 16:46:367551 new UploadFileElementReader(base::MessageLoopProxy::current().get(),
7552 temp_file_path,
7553 0,
7554 kuint64max,
7555 base::Time()));
[email protected]b2d26cfd2012-12-11 10:36:067556 UploadDataStream upload_data_stream(&element_readers, 0);
[email protected]329b68b2012-11-14 17:54:277557
7558 HttpRequestInfo request;
7559 request.method = "POST";
7560 request.url = GURL("http://www.google.com/upload");
7561 request.upload_data_stream = &upload_data_stream;
7562 request.load_flags = 0;
7563
[email protected]329b68b2012-11-14 17:54:277564 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:367565 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:077566 CreateSession(&session_deps_)));
[email protected]95d88ffe2010-02-04 21:25:337567
7568 MockRead data_reads[] = {
7569 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
7570 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:067571 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:337572 };
[email protected]31a2bfe2010-02-09 08:03:397573 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077574 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:337575
[email protected]49639fa2011-12-20 23:22:417576 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:337577
[email protected]49639fa2011-12-20 23:22:417578 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]95d88ffe2010-02-04 21:25:337579 EXPECT_EQ(ERR_IO_PENDING, rv);
7580
7581 rv = callback.WaitForResult();
7582 EXPECT_EQ(OK, rv);
7583
7584 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507585 ASSERT_TRUE(response != NULL);
[email protected]95d88ffe2010-02-04 21:25:337586
[email protected]90499482013-06-01 00:39:507587 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]95d88ffe2010-02-04 21:25:337588 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
7589
7590 std::string response_data;
7591 rv = ReadTransaction(trans.get(), &response_data);
7592 EXPECT_EQ(OK, rv);
7593 EXPECT_EQ("hello world", response_data);
7594
[email protected]dd3aa792013-07-16 19:10:237595 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:337596}
7597
[email protected]23e482282013-06-14 16:08:027598TEST_P(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:157599 base::FilePath temp_file;
[email protected]6624b4622010-03-29 19:58:367600 ASSERT_TRUE(file_util::CreateTemporaryFile(&temp_file));
7601 std::string temp_file_content("Unreadable file.");
7602 ASSERT_TRUE(file_util::WriteFile(temp_file, temp_file_content.c_str(),
7603 temp_file_content.length()));
7604 ASSERT_TRUE(file_util::MakeFileUnreadable(temp_file));
7605
[email protected]b2d26cfd2012-12-11 10:36:067606 ScopedVector<UploadElementReader> element_readers;
7607 element_readers.push_back(
[email protected]cadac622013-06-11 16:46:367608 new UploadFileElementReader(base::MessageLoopProxy::current().get(),
7609 temp_file,
7610 0,
7611 kuint64max,
7612 base::Time()));
[email protected]b2d26cfd2012-12-11 10:36:067613 UploadDataStream upload_data_stream(&element_readers, 0);
[email protected]329b68b2012-11-14 17:54:277614
7615 HttpRequestInfo request;
7616 request.method = "POST";
7617 request.url = GURL("http://www.google.com/upload");
7618 request.upload_data_stream = &upload_data_stream;
7619 request.load_flags = 0;
7620
7621 // If we try to upload an unreadable file, the network stack should report
7622 // the file size as zero and upload zero bytes for that file.
[email protected]329b68b2012-11-14 17:54:277623 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:367624 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:077625 CreateSession(&session_deps_)));
[email protected]6624b4622010-03-29 19:58:367626
7627 MockRead data_reads[] = {
7628 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067629 MockRead(SYNCHRONOUS, OK),
[email protected]6624b4622010-03-29 19:58:367630 };
7631 MockWrite data_writes[] = {
7632 MockWrite("POST /upload HTTP/1.1\r\n"
7633 "Host: www.google.com\r\n"
7634 "Connection: keep-alive\r\n"
7635 "Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067636 MockWrite(SYNCHRONOUS, OK),
[email protected]6624b4622010-03-29 19:58:367637 };
7638 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
7639 arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077640 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:367641
[email protected]49639fa2011-12-20 23:22:417642 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:367643
[email protected]49639fa2011-12-20 23:22:417644 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]6624b4622010-03-29 19:58:367645 EXPECT_EQ(ERR_IO_PENDING, rv);
7646
7647 rv = callback.WaitForResult();
7648 EXPECT_EQ(OK, rv);
7649
7650 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507651 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:507652 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]6624b4622010-03-29 19:58:367653 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
7654
[email protected]dd3aa792013-07-16 19:10:237655 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:367656}
7657
[email protected]23e482282013-06-14 16:08:027658TEST_P(HttpNetworkTransactionTest, UnreadableUploadFileAfterAuthRestart) {
[email protected]6cdfd7f2013-02-08 20:40:157659 base::FilePath temp_file;
[email protected]6624b4622010-03-29 19:58:367660 ASSERT_TRUE(file_util::CreateTemporaryFile(&temp_file));
7661 std::string temp_file_contents("Unreadable file.");
7662 std::string unreadable_contents(temp_file_contents.length(), '\0');
7663 ASSERT_TRUE(file_util::WriteFile(temp_file, temp_file_contents.c_str(),
7664 temp_file_contents.length()));
7665
[email protected]b2d26cfd2012-12-11 10:36:067666 ScopedVector<UploadElementReader> element_readers;
7667 element_readers.push_back(
[email protected]cadac622013-06-11 16:46:367668 new UploadFileElementReader(base::MessageLoopProxy::current().get(),
7669 temp_file,
7670 0,
7671 kuint64max,
7672 base::Time()));
[email protected]b2d26cfd2012-12-11 10:36:067673 UploadDataStream upload_data_stream(&element_readers, 0);
[email protected]329b68b2012-11-14 17:54:277674
7675 HttpRequestInfo request;
7676 request.method = "POST";
7677 request.url = GURL("http://www.google.com/upload");
7678 request.upload_data_stream = &upload_data_stream;
7679 request.load_flags = 0;
7680
[email protected]329b68b2012-11-14 17:54:277681 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:367682 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:077683 CreateSession(&session_deps_)));
[email protected]6624b4622010-03-29 19:58:367684
7685 MockRead data_reads[] = {
7686 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
7687 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7688 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
7689
7690 MockRead("HTTP/1.1 200 OK\r\n"),
7691 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067692 MockRead(SYNCHRONOUS, OK),
[email protected]6624b4622010-03-29 19:58:367693 };
7694 MockWrite data_writes[] = {
7695 MockWrite("POST /upload HTTP/1.1\r\n"
7696 "Host: www.google.com\r\n"
7697 "Connection: keep-alive\r\n"
7698 "Content-Length: 16\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067699 MockWrite(SYNCHRONOUS, temp_file_contents.c_str()),
[email protected]6624b4622010-03-29 19:58:367700
7701 MockWrite("POST /upload HTTP/1.1\r\n"
7702 "Host: www.google.com\r\n"
7703 "Connection: keep-alive\r\n"
[email protected]d98961652012-09-11 20:27:217704 "Content-Length: 0\r\n"
[email protected]6624b4622010-03-29 19:58:367705 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067706 MockWrite(SYNCHRONOUS, unreadable_contents.c_str(),
7707 temp_file_contents.length()),
7708 MockWrite(SYNCHRONOUS, OK),
[email protected]6624b4622010-03-29 19:58:367709 };
7710 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
7711 arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077712 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:367713
[email protected]49639fa2011-12-20 23:22:417714 TestCompletionCallback callback1;
[email protected]6624b4622010-03-29 19:58:367715
[email protected]49639fa2011-12-20 23:22:417716 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]6624b4622010-03-29 19:58:367717 EXPECT_EQ(ERR_IO_PENDING, rv);
7718
7719 rv = callback1.WaitForResult();
7720 EXPECT_EQ(OK, rv);
7721
7722 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:047723 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:507724 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]6624b4622010-03-29 19:58:367725 EXPECT_EQ("HTTP/1.1 401 Unauthorized", response->headers->GetStatusLine());
[email protected]79cb5c12011-09-12 13:12:047726 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]6624b4622010-03-29 19:58:367727
7728 // Now make the file unreadable and try again.
7729 ASSERT_TRUE(file_util::MakeFileUnreadable(temp_file));
7730
[email protected]49639fa2011-12-20 23:22:417731 TestCompletionCallback callback2;
[email protected]6624b4622010-03-29 19:58:367732
[email protected]49639fa2011-12-20 23:22:417733 rv = trans->RestartWithAuth(
7734 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]6624b4622010-03-29 19:58:367735 EXPECT_EQ(ERR_IO_PENDING, rv);
7736
7737 rv = callback2.WaitForResult();
7738 EXPECT_EQ(OK, rv);
7739
7740 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507741 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:507742 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]6624b4622010-03-29 19:58:367743 EXPECT_TRUE(response->auth_challenge.get() == NULL);
7744 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7745
[email protected]dd3aa792013-07-16 19:10:237746 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:367747}
7748
[email protected]aeefc9e82010-02-19 16:18:277749// Tests that changes to Auth realms are treated like auth rejections.
[email protected]23e482282013-06-14 16:08:027750TEST_P(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:277751
7752 HttpRequestInfo request;
7753 request.method = "GET";
7754 request.url = GURL("http://www.google.com/");
7755 request.load_flags = 0;
7756
7757 // First transaction will request a resource and receive a Basic challenge
7758 // with realm="first_realm".
7759 MockWrite data_writes1[] = {
7760 MockWrite("GET / HTTP/1.1\r\n"
7761 "Host: www.google.com\r\n"
7762 "Connection: keep-alive\r\n"
7763 "\r\n"),
7764 };
7765 MockRead data_reads1[] = {
7766 MockRead("HTTP/1.1 401 Unauthorized\r\n"
7767 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
7768 "\r\n"),
7769 };
7770
7771 // After calling trans->RestartWithAuth(), provide an Authentication header
7772 // for first_realm. The server will reject and provide a challenge with
7773 // second_realm.
7774 MockWrite data_writes2[] = {
7775 MockWrite("GET / HTTP/1.1\r\n"
7776 "Host: www.google.com\r\n"
7777 "Connection: keep-alive\r\n"
7778 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
7779 "\r\n"),
7780 };
7781 MockRead data_reads2[] = {
7782 MockRead("HTTP/1.1 401 Unauthorized\r\n"
7783 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
7784 "\r\n"),
7785 };
7786
7787 // This again fails, and goes back to first_realm. Make sure that the
7788 // entry is removed from cache.
7789 MockWrite data_writes3[] = {
7790 MockWrite("GET / HTTP/1.1\r\n"
7791 "Host: www.google.com\r\n"
7792 "Connection: keep-alive\r\n"
7793 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
7794 "\r\n"),
7795 };
7796 MockRead data_reads3[] = {
7797 MockRead("HTTP/1.1 401 Unauthorized\r\n"
7798 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
7799 "\r\n"),
7800 };
7801
7802 // Try one last time (with the correct password) and get the resource.
7803 MockWrite data_writes4[] = {
7804 MockWrite("GET / HTTP/1.1\r\n"
7805 "Host: www.google.com\r\n"
7806 "Connection: keep-alive\r\n"
7807 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
7808 "\r\n"),
7809 };
7810 MockRead data_reads4[] = {
7811 MockRead("HTTP/1.1 200 OK\r\n"
7812 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:507813 "Content-Length: 5\r\n"
7814 "\r\n"
7815 "hello"),
[email protected]aeefc9e82010-02-19 16:18:277816 };
7817
7818 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7819 data_writes1, arraysize(data_writes1));
7820 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7821 data_writes2, arraysize(data_writes2));
7822 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
7823 data_writes3, arraysize(data_writes3));
7824 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
7825 data_writes4, arraysize(data_writes4));
[email protected]bb88e1d32013-05-03 23:11:077826 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7827 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7828 session_deps_.socket_factory->AddSocketDataProvider(&data3);
7829 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:277830
[email protected]49639fa2011-12-20 23:22:417831 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:277832
[email protected]0b0bf032010-09-21 18:08:507833 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:367834 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:077835 CreateSession(&session_deps_)));
[email protected]0b0bf032010-09-21 18:08:507836
[email protected]aeefc9e82010-02-19 16:18:277837 // Issue the first request with Authorize headers. There should be a
7838 // password prompt for first_realm waiting to be filled in after the
7839 // transaction completes.
[email protected]49639fa2011-12-20 23:22:417840 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]aeefc9e82010-02-19 16:18:277841 EXPECT_EQ(ERR_IO_PENDING, rv);
7842 rv = callback1.WaitForResult();
7843 EXPECT_EQ(OK, rv);
7844 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507845 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:047846 const AuthChallengeInfo* challenge = response->auth_challenge.get();
7847 ASSERT_FALSE(challenge == NULL);
7848 EXPECT_FALSE(challenge->is_proxy);
7849 EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
7850 EXPECT_EQ("first_realm", challenge->realm);
7851 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:277852
7853 // Issue the second request with an incorrect password. There should be a
7854 // password prompt for second_realm waiting to be filled in after the
7855 // transaction completes.
[email protected]49639fa2011-12-20 23:22:417856 TestCompletionCallback callback2;
7857 rv = trans->RestartWithAuth(
7858 AuthCredentials(kFirst, kBaz), callback2.callback());
[email protected]aeefc9e82010-02-19 16:18:277859 EXPECT_EQ(ERR_IO_PENDING, rv);
7860 rv = callback2.WaitForResult();
7861 EXPECT_EQ(OK, rv);
7862 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507863 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:047864 challenge = response->auth_challenge.get();
7865 ASSERT_FALSE(challenge == NULL);
7866 EXPECT_FALSE(challenge->is_proxy);
7867 EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
7868 EXPECT_EQ("second_realm", challenge->realm);
7869 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:277870
7871 // Issue the third request with another incorrect password. There should be
7872 // a password prompt for first_realm waiting to be filled in. If the password
7873 // prompt is not present, it indicates that the HttpAuthCacheEntry for
7874 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:417875 TestCompletionCallback callback3;
7876 rv = trans->RestartWithAuth(
7877 AuthCredentials(kSecond, kFou), callback3.callback());
[email protected]aeefc9e82010-02-19 16:18:277878 EXPECT_EQ(ERR_IO_PENDING, rv);
7879 rv = callback3.WaitForResult();
7880 EXPECT_EQ(OK, rv);
7881 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507882 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:047883 challenge = response->auth_challenge.get();
7884 ASSERT_FALSE(challenge == NULL);
7885 EXPECT_FALSE(challenge->is_proxy);
7886 EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
7887 EXPECT_EQ("first_realm", challenge->realm);
7888 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:277889
7890 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:417891 TestCompletionCallback callback4;
7892 rv = trans->RestartWithAuth(
7893 AuthCredentials(kFirst, kBar), callback4.callback());
[email protected]aeefc9e82010-02-19 16:18:277894 EXPECT_EQ(ERR_IO_PENDING, rv);
7895 rv = callback4.WaitForResult();
7896 EXPECT_EQ(OK, rv);
7897 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507898 ASSERT_TRUE(response != NULL);
[email protected]aeefc9e82010-02-19 16:18:277899 EXPECT_TRUE(response->auth_challenge.get() == NULL);
7900}
7901
[email protected]23e482282013-06-14 16:08:027902TEST_P(HttpNetworkTransactionTest, HonorAlternateProtocolHeader) {
[email protected]ecf96e52012-03-03 00:43:037903 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]448d4ca52012-03-04 04:12:237904 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]a2cb8122010-03-10 17:22:427905
[email protected]8a0fc822013-06-27 20:52:437906 std::string alternate_protocol_http_header =
7907 GetAlternateProtocolHttpHeader();
7908
[email protected]564b4912010-03-09 16:30:427909 MockRead data_reads[] = {
7910 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:437911 MockRead(alternate_protocol_http_header.c_str()),
[email protected]564b4912010-03-09 16:30:427912 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:067913 MockRead(SYNCHRONOUS, OK),
[email protected]564b4912010-03-09 16:30:427914 };
7915
7916 HttpRequestInfo request;
7917 request.method = "GET";
7918 request.url = GURL("http://www.google.com/");
7919 request.load_flags = 0;
7920
7921 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
7922
[email protected]bb88e1d32013-05-03 23:11:077923 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]564b4912010-03-09 16:30:427924
[email protected]49639fa2011-12-20 23:22:417925 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:427926
[email protected]bb88e1d32013-05-03 23:11:077927 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:367928 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507929 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]564b4912010-03-09 16:30:427930
[email protected]49639fa2011-12-20 23:22:417931 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:427932 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]9e743cd2010-03-16 07:03:537933
[email protected]2fbaecf22010-07-22 22:20:357934 HostPortPair http_host_port_pair("www.google.com", 80);
[email protected]17291a022011-10-10 07:32:537935 const HttpServerProperties& http_server_properties =
7936 *session->http_server_properties();
[email protected]564b4912010-03-09 16:30:427937 EXPECT_FALSE(
[email protected]17291a022011-10-10 07:32:537938 http_server_properties.HasAlternateProtocol(http_host_port_pair));
[email protected]564b4912010-03-09 16:30:427939
7940 EXPECT_EQ(OK, callback.WaitForResult());
7941
7942 const HttpResponseInfo* response = trans->GetResponseInfo();
7943 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:507944 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:427945 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:537946 EXPECT_FALSE(response->was_fetched_via_spdy);
7947 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]564b4912010-03-09 16:30:427948
7949 std::string response_data;
7950 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
7951 EXPECT_EQ("hello world", response_data);
7952
[email protected]17291a022011-10-10 07:32:537953 ASSERT_TRUE(http_server_properties.HasAlternateProtocol(http_host_port_pair));
7954 const PortAlternateProtocolPair alternate =
7955 http_server_properties.GetAlternateProtocol(http_host_port_pair);
7956 PortAlternateProtocolPair expected_alternate;
[email protected]564b4912010-03-09 16:30:427957 expected_alternate.port = 443;
[email protected]8a0fc822013-06-27 20:52:437958 expected_alternate.protocol = AlternateProtocolFromNextProto(GetParam());
[email protected]564b4912010-03-09 16:30:427959 EXPECT_TRUE(expected_alternate.Equals(alternate));
7960}
7961
[email protected]23e482282013-06-14 16:08:027962TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:237963 MarkBrokenAlternateProtocolAndFallback) {
[email protected]8e6441ca2010-08-19 05:56:387964 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]564b4912010-03-09 16:30:427965
7966 HttpRequestInfo request;
7967 request.method = "GET";
7968 request.url = GURL("http://www.google.com/");
7969 request.load_flags = 0;
7970
[email protected]d973e99a2012-02-17 21:02:367971 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:427972 StaticSocketDataProvider first_data;
7973 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:077974 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]564b4912010-03-09 16:30:427975
7976 MockRead data_reads[] = {
7977 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
7978 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:067979 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:427980 };
7981 StaticSocketDataProvider second_data(
7982 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077983 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:427984
[email protected]bb88e1d32013-05-03 23:11:077985 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:427986
[email protected]30d4c022013-07-18 22:58:167987 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:537988 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:117989 // Port must be < 1024, or the header will be ignored (since initial port was
7990 // port 80 (another restricted port).
[email protected]17291a022011-10-10 07:32:537991 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:117992 HostPortPair::FromURL(request.url),
7993 666 /* port is ignored by MockConnect anyway */,
[email protected]8a0fc822013-06-27 20:52:437994 AlternateProtocolFromNextProto(GetParam()));
[email protected]564b4912010-03-09 16:30:427995
[email protected]262eec82013-03-19 21:01:367996 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507997 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:417998 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:427999
[email protected]49639fa2011-12-20 23:22:418000 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:428001 EXPECT_EQ(ERR_IO_PENDING, rv);
8002 EXPECT_EQ(OK, callback.WaitForResult());
8003
8004 const HttpResponseInfo* response = trans->GetResponseInfo();
8005 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508006 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:428007 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8008
8009 std::string response_data;
8010 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8011 EXPECT_EQ("hello world", response_data);
8012
[email protected]17291a022011-10-10 07:32:538013 ASSERT_TRUE(http_server_properties->HasAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118014 HostPortPair::FromURL(request.url)));
[email protected]17291a022011-10-10 07:32:538015 const PortAlternateProtocolPair alternate =
8016 http_server_properties->GetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118017 HostPortPair::FromURL(request.url));
[email protected]17291a022011-10-10 07:32:538018 EXPECT_EQ(ALTERNATE_PROTOCOL_BROKEN, alternate.protocol);
[email protected]564b4912010-03-09 16:30:428019}
8020
[email protected]23e482282013-06-14 16:08:028021TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238022 AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:118023 // Ensure that we're not allowed to redirect traffic via an alternate
8024 // protocol to an unrestricted (port >= 1024) when the original traffic was
8025 // on a restricted port (port < 1024). Ensure that we can redirect in all
8026 // other cases.
8027 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]3912662a32011-10-04 00:51:118028
8029 HttpRequestInfo restricted_port_request;
8030 restricted_port_request.method = "GET";
8031 restricted_port_request.url = GURL("http://www.google.com:1023/");
8032 restricted_port_request.load_flags = 0;
8033
[email protected]d973e99a2012-02-17 21:02:368034 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118035 StaticSocketDataProvider first_data;
8036 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078037 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118038
8039 MockRead data_reads[] = {
8040 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8041 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068042 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118043 };
8044 StaticSocketDataProvider second_data(
8045 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078046 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118047
[email protected]bb88e1d32013-05-03 23:11:078048 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118049
[email protected]30d4c022013-07-18 22:58:168050 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538051 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118052 const int kUnrestrictedAlternatePort = 1024;
[email protected]17291a022011-10-10 07:32:538053 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118054 HostPortPair::FromURL(restricted_port_request.url),
8055 kUnrestrictedAlternatePort,
[email protected]8a0fc822013-06-27 20:52:438056 AlternateProtocolFromNextProto(GetParam()));
[email protected]3912662a32011-10-04 00:51:118057
[email protected]262eec82013-03-19 21:01:368058 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508059 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418060 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118061
[email protected]49639fa2011-12-20 23:22:418062 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:368063 &restricted_port_request,
8064 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118065 EXPECT_EQ(ERR_IO_PENDING, rv);
8066 // Invalid change to unrestricted port should fail.
8067 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.WaitForResult());
[email protected]c54c6962013-02-01 04:53:198068}
[email protected]3912662a32011-10-04 00:51:118069
[email protected]23e482282013-06-14 16:08:028070TEST_P(HttpNetworkTransactionTest,
[email protected]c54c6962013-02-01 04:53:198071 AlternateProtocolPortRestrictedPermitted) {
8072 // Ensure that we're allowed to redirect traffic via an alternate
8073 // protocol to an unrestricted (port >= 1024) when the original traffic was
8074 // on a restricted port (port < 1024) if we set
8075 // enable_user_alternate_protocol_ports.
8076
8077 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]bb88e1d32013-05-03 23:11:078078 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:198079
8080 HttpRequestInfo restricted_port_request;
8081 restricted_port_request.method = "GET";
8082 restricted_port_request.url = GURL("http://www.google.com:1023/");
8083 restricted_port_request.load_flags = 0;
8084
8085 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
8086 StaticSocketDataProvider first_data;
8087 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078088 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:198089
8090 MockRead data_reads[] = {
8091 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8092 MockRead("hello world"),
8093 MockRead(ASYNC, OK),
8094 };
8095 StaticSocketDataProvider second_data(
8096 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078097 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]c54c6962013-02-01 04:53:198098
[email protected]bb88e1d32013-05-03 23:11:078099 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:198100
[email protected]30d4c022013-07-18 22:58:168101 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]c54c6962013-02-01 04:53:198102 session->http_server_properties();
8103 const int kUnrestrictedAlternatePort = 1024;
8104 http_server_properties->SetAlternateProtocol(
8105 HostPortPair::FromURL(restricted_port_request.url),
8106 kUnrestrictedAlternatePort,
[email protected]8a0fc822013-06-27 20:52:438107 AlternateProtocolFromNextProto(GetParam()));
[email protected]c54c6962013-02-01 04:53:198108
[email protected]262eec82013-03-19 21:01:368109 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508110 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]c54c6962013-02-01 04:53:198111 TestCompletionCallback callback;
8112
8113 EXPECT_EQ(ERR_IO_PENDING, trans->Start(
[email protected]262eec82013-03-19 21:01:368114 &restricted_port_request,
8115 callback.callback(), BoundNetLog()));
[email protected]c54c6962013-02-01 04:53:198116 // Change to unrestricted port should succeed.
8117 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:118118}
8119
[email protected]23e482282013-06-14 16:08:028120TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238121 AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:118122 // Ensure that we're not allowed to redirect traffic via an alternate
8123 // protocol to an unrestricted (port >= 1024) when the original traffic was
8124 // on a restricted port (port < 1024). Ensure that we can redirect in all
8125 // other cases.
8126 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]3912662a32011-10-04 00:51:118127
8128 HttpRequestInfo restricted_port_request;
8129 restricted_port_request.method = "GET";
8130 restricted_port_request.url = GURL("http://www.google.com:1023/");
8131 restricted_port_request.load_flags = 0;
8132
[email protected]d973e99a2012-02-17 21:02:368133 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118134 StaticSocketDataProvider first_data;
8135 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078136 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118137
8138 MockRead data_reads[] = {
8139 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8140 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068141 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118142 };
8143 StaticSocketDataProvider second_data(
8144 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078145 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118146
[email protected]bb88e1d32013-05-03 23:11:078147 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118148
[email protected]30d4c022013-07-18 22:58:168149 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538150 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118151 const int kRestrictedAlternatePort = 80;
[email protected]17291a022011-10-10 07:32:538152 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118153 HostPortPair::FromURL(restricted_port_request.url),
8154 kRestrictedAlternatePort,
[email protected]8a0fc822013-06-27 20:52:438155 AlternateProtocolFromNextProto(GetParam()));
[email protected]3912662a32011-10-04 00:51:118156
[email protected]262eec82013-03-19 21:01:368157 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508158 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418159 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118160
[email protected]49639fa2011-12-20 23:22:418161 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:368162 &restricted_port_request,
8163 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118164 EXPECT_EQ(ERR_IO_PENDING, rv);
8165 // Valid change to restricted port should pass.
8166 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:118167}
8168
[email protected]23e482282013-06-14 16:08:028169TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238170 AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:118171 // Ensure that we're not allowed to redirect traffic via an alternate
8172 // protocol to an unrestricted (port >= 1024) when the original traffic was
8173 // on a restricted port (port < 1024). Ensure that we can redirect in all
8174 // other cases.
8175 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]3912662a32011-10-04 00:51:118176
8177 HttpRequestInfo unrestricted_port_request;
8178 unrestricted_port_request.method = "GET";
8179 unrestricted_port_request.url = GURL("http://www.google.com:1024/");
8180 unrestricted_port_request.load_flags = 0;
8181
[email protected]d973e99a2012-02-17 21:02:368182 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118183 StaticSocketDataProvider first_data;
8184 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078185 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118186
8187 MockRead data_reads[] = {
8188 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8189 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068190 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118191 };
8192 StaticSocketDataProvider second_data(
8193 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078194 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118195
[email protected]bb88e1d32013-05-03 23:11:078196 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118197
[email protected]30d4c022013-07-18 22:58:168198 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538199 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118200 const int kRestrictedAlternatePort = 80;
[email protected]17291a022011-10-10 07:32:538201 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118202 HostPortPair::FromURL(unrestricted_port_request.url),
8203 kRestrictedAlternatePort,
[email protected]8a0fc822013-06-27 20:52:438204 AlternateProtocolFromNextProto(GetParam()));
[email protected]3912662a32011-10-04 00:51:118205
[email protected]262eec82013-03-19 21:01:368206 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508207 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418208 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118209
[email protected]49639fa2011-12-20 23:22:418210 int rv = trans->Start(
8211 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118212 EXPECT_EQ(ERR_IO_PENDING, rv);
8213 // Valid change to restricted port should pass.
8214 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:118215}
8216
[email protected]23e482282013-06-14 16:08:028217TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238218 AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:118219 // Ensure that we're not allowed to redirect traffic via an alternate
8220 // protocol to an unrestricted (port >= 1024) when the original traffic was
8221 // on a restricted port (port < 1024). Ensure that we can redirect in all
8222 // other cases.
8223 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]3912662a32011-10-04 00:51:118224
8225 HttpRequestInfo unrestricted_port_request;
8226 unrestricted_port_request.method = "GET";
8227 unrestricted_port_request.url = GURL("http://www.google.com:1024/");
8228 unrestricted_port_request.load_flags = 0;
8229
[email protected]d973e99a2012-02-17 21:02:368230 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118231 StaticSocketDataProvider first_data;
8232 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078233 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118234
8235 MockRead data_reads[] = {
8236 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8237 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068238 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118239 };
8240 StaticSocketDataProvider second_data(
8241 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078242 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118243
[email protected]bb88e1d32013-05-03 23:11:078244 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118245
[email protected]30d4c022013-07-18 22:58:168246 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538247 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118248 const int kUnrestrictedAlternatePort = 1024;
[email protected]17291a022011-10-10 07:32:538249 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118250 HostPortPair::FromURL(unrestricted_port_request.url),
8251 kUnrestrictedAlternatePort,
[email protected]8a0fc822013-06-27 20:52:438252 AlternateProtocolFromNextProto(GetParam()));
[email protected]3912662a32011-10-04 00:51:118253
[email protected]262eec82013-03-19 21:01:368254 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508255 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418256 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118257
[email protected]49639fa2011-12-20 23:22:418258 int rv = trans->Start(
8259 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118260 EXPECT_EQ(ERR_IO_PENDING, rv);
8261 // Valid change to an unrestricted port should pass.
8262 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:118263}
8264
[email protected]23e482282013-06-14 16:08:028265TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238266 AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:028267 // Ensure that we're not allowed to redirect traffic via an alternate
8268 // protocol to an unsafe port, and that we resume the second
8269 // HttpStreamFactoryImpl::Job once the alternate protocol request fails.
8270 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]eb6234e2012-01-19 01:50:028271
8272 HttpRequestInfo request;
8273 request.method = "GET";
8274 request.url = GURL("http://www.google.com/");
8275 request.load_flags = 0;
8276
8277 // The alternate protocol request will error out before we attempt to connect,
8278 // so only the standard HTTP request will try to connect.
8279 MockRead data_reads[] = {
8280 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8281 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068282 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:028283 };
8284 StaticSocketDataProvider data(
8285 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078286 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:028287
[email protected]bb88e1d32013-05-03 23:11:078288 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:028289
[email protected]30d4c022013-07-18 22:58:168290 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]eb6234e2012-01-19 01:50:028291 session->http_server_properties();
8292 const int kUnsafePort = 7;
8293 http_server_properties->SetAlternateProtocol(
8294 HostPortPair::FromURL(request.url),
8295 kUnsafePort,
[email protected]8a0fc822013-06-27 20:52:438296 AlternateProtocolFromNextProto(GetParam()));
[email protected]eb6234e2012-01-19 01:50:028297
[email protected]262eec82013-03-19 21:01:368298 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508299 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]eb6234e2012-01-19 01:50:028300 TestCompletionCallback callback;
8301
8302 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8303 EXPECT_EQ(ERR_IO_PENDING, rv);
8304 // The HTTP request should succeed.
8305 EXPECT_EQ(OK, callback.WaitForResult());
8306
8307 // Disable alternate protocol before the asserts.
8308 HttpStreamFactory::set_use_alternate_protocols(false);
8309
8310 const HttpResponseInfo* response = trans->GetResponseInfo();
8311 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508312 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]eb6234e2012-01-19 01:50:028313 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8314
8315 std::string response_data;
8316 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8317 EXPECT_EQ("hello world", response_data);
8318}
8319
[email protected]23e482282013-06-14 16:08:028320TEST_P(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]8e6441ca2010-08-19 05:56:388321 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:038322 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]2ff8b312010-04-26 22:20:548323
8324 HttpRequestInfo request;
8325 request.method = "GET";
8326 request.url = GURL("http://www.google.com/");
8327 request.load_flags = 0;
8328
[email protected]8a0fc822013-06-27 20:52:438329 std::string alternate_protocol_http_header =
8330 GetAlternateProtocolHttpHeader();
8331
[email protected]2ff8b312010-04-26 22:20:548332 MockRead data_reads[] = {
8333 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438334 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2ff8b312010-04-26 22:20:548335 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:178336 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
8337 MockRead(ASYNC, OK)
[email protected]2ff8b312010-04-26 22:20:548338 };
8339
8340 StaticSocketDataProvider first_transaction(
8341 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078342 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:548343
[email protected]8ddf8322012-02-23 18:08:068344 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:028345 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:078346 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:548347
[email protected]cdf8f7e72013-05-23 10:56:468348 scoped_ptr<SpdyFrame> req(
8349 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]e7f75092010-07-01 22:39:138350 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
[email protected]2ff8b312010-04-26 22:20:548351
[email protected]23e482282013-06-14 16:08:028352 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
8353 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:548354 MockRead spdy_reads[] = {
[email protected]e7f75092010-07-01 22:39:138355 CreateMockRead(*resp),
8356 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:068357 MockRead(ASYNC, 0, 0),
[email protected]2ff8b312010-04-26 22:20:548358 };
8359
[email protected]dd54bd82012-07-19 23:44:578360 DelayedSocketData spdy_data(
8361 1, // wait for one write to finish before reading.
8362 spdy_reads, arraysize(spdy_reads),
8363 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078364 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:548365
[email protected]d973e99a2012-02-17 21:02:368366 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:558367 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
8368 NULL, 0, NULL, 0);
8369 hanging_non_alternate_protocol_socket.set_connect_data(
8370 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:078371 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:558372 &hanging_non_alternate_protocol_socket);
8373
[email protected]49639fa2011-12-20 23:22:418374 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:548375
[email protected]bb88e1d32013-05-03 23:11:078376 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:368377 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508378 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:548379
[email protected]49639fa2011-12-20 23:22:418380 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:548381 EXPECT_EQ(ERR_IO_PENDING, rv);
8382 EXPECT_EQ(OK, callback.WaitForResult());
8383
8384 const HttpResponseInfo* response = trans->GetResponseInfo();
8385 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508386 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:548387 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8388
8389 std::string response_data;
8390 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8391 EXPECT_EQ("hello world", response_data);
8392
[email protected]90499482013-06-01 00:39:508393 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:548394
[email protected]49639fa2011-12-20 23:22:418395 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:548396 EXPECT_EQ(ERR_IO_PENDING, rv);
8397 EXPECT_EQ(OK, callback.WaitForResult());
8398
8399 response = trans->GetResponseInfo();
8400 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508401 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:548402 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:538403 EXPECT_TRUE(response->was_fetched_via_spdy);
8404 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:548405
8406 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8407 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:548408}
8409
[email protected]23e482282013-06-14 16:08:028410TEST_P(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]2d6728692011-03-12 01:39:558411 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:038412 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]2d6728692011-03-12 01:39:558413
8414 HttpRequestInfo request;
8415 request.method = "GET";
8416 request.url = GURL("http://www.google.com/");
8417 request.load_flags = 0;
8418
[email protected]8a0fc822013-06-27 20:52:438419 std::string alternate_protocol_http_header =
8420 GetAlternateProtocolHttpHeader();
8421
[email protected]2d6728692011-03-12 01:39:558422 MockRead data_reads[] = {
8423 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438424 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2d6728692011-03-12 01:39:558425 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:178426 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:068427 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:558428 };
8429
8430 StaticSocketDataProvider first_transaction(
8431 data_reads, arraysize(data_reads), NULL, 0);
8432 // Socket 1 is the HTTP transaction with the Alternate-Protocol header.
[email protected]bb88e1d32013-05-03 23:11:078433 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:558434
[email protected]d973e99a2012-02-17 21:02:368435 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:558436 StaticSocketDataProvider hanging_socket(
8437 NULL, 0, NULL, 0);
8438 hanging_socket.set_connect_data(never_finishing_connect);
8439 // Socket 2 and 3 are the hanging Alternate-Protocol and
8440 // non-Alternate-Protocol jobs from the 2nd transaction.
[email protected]bb88e1d32013-05-03 23:11:078441 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
8442 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
[email protected]2d6728692011-03-12 01:39:558443
[email protected]8ddf8322012-02-23 18:08:068444 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:028445 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:078446 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:558447
[email protected]cdf8f7e72013-05-23 10:56:468448 scoped_ptr<SpdyFrame> req1(
8449 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
8450 scoped_ptr<SpdyFrame> req2(
8451 spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
[email protected]2d6728692011-03-12 01:39:558452 MockWrite spdy_writes[] = {
8453 CreateMockWrite(*req1),
8454 CreateMockWrite(*req2),
8455 };
[email protected]23e482282013-06-14 16:08:028456 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
8457 scoped_ptr<SpdyFrame> data1(spdy_util_.ConstructSpdyBodyFrame(1, true));
8458 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
8459 scoped_ptr<SpdyFrame> data2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]2d6728692011-03-12 01:39:558460 MockRead spdy_reads[] = {
8461 CreateMockRead(*resp1),
8462 CreateMockRead(*data1),
8463 CreateMockRead(*resp2),
8464 CreateMockRead(*data2),
[email protected]8ddf8322012-02-23 18:08:068465 MockRead(ASYNC, 0, 0),
[email protected]2d6728692011-03-12 01:39:558466 };
8467
[email protected]dd54bd82012-07-19 23:44:578468 DelayedSocketData spdy_data(
8469 2, // wait for writes to finish before reading.
8470 spdy_reads, arraysize(spdy_reads),
8471 spdy_writes, arraysize(spdy_writes));
[email protected]2d6728692011-03-12 01:39:558472 // Socket 4 is the successful Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:078473 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:558474
8475 // Socket 5 is the unsuccessful non-Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:078476 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
[email protected]2d6728692011-03-12 01:39:558477
[email protected]bb88e1d32013-05-03 23:11:078478 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:418479 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:508480 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:558481
[email protected]49639fa2011-12-20 23:22:418482 int rv = trans1.Start(&request, callback1.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:558483 EXPECT_EQ(ERR_IO_PENDING, rv);
8484 EXPECT_EQ(OK, callback1.WaitForResult());
8485
8486 const HttpResponseInfo* response = trans1.GetResponseInfo();
8487 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508488 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:558489 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8490
8491 std::string response_data;
8492 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
8493 EXPECT_EQ("hello world", response_data);
8494
[email protected]49639fa2011-12-20 23:22:418495 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:508496 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:418497 rv = trans2.Start(&request, callback2.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:558498 EXPECT_EQ(ERR_IO_PENDING, rv);
8499
[email protected]49639fa2011-12-20 23:22:418500 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:508501 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:418502 rv = trans3.Start(&request, callback3.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:558503 EXPECT_EQ(ERR_IO_PENDING, rv);
8504
8505 EXPECT_EQ(OK, callback2.WaitForResult());
8506 EXPECT_EQ(OK, callback3.WaitForResult());
8507
8508 response = trans2.GetResponseInfo();
8509 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508510 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:558511 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8512 EXPECT_TRUE(response->was_fetched_via_spdy);
8513 EXPECT_TRUE(response->was_npn_negotiated);
8514 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
8515 EXPECT_EQ("hello!", response_data);
8516
8517 response = trans3.GetResponseInfo();
8518 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508519 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:558520 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8521 EXPECT_TRUE(response->was_fetched_via_spdy);
8522 EXPECT_TRUE(response->was_npn_negotiated);
8523 ASSERT_EQ(OK, ReadTransaction(&trans3, &response_data));
8524 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:558525}
8526
[email protected]23e482282013-06-14 16:08:028527TEST_P(HttpNetworkTransactionTest, StallAlternateProtocolForNpnSpdy) {
[email protected]2d6728692011-03-12 01:39:558528 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:038529 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]2d6728692011-03-12 01:39:558530
8531 HttpRequestInfo request;
8532 request.method = "GET";
8533 request.url = GURL("http://www.google.com/");
8534 request.load_flags = 0;
8535
[email protected]8a0fc822013-06-27 20:52:438536 std::string alternate_protocol_http_header =
8537 GetAlternateProtocolHttpHeader();
8538
[email protected]2d6728692011-03-12 01:39:558539 MockRead data_reads[] = {
8540 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438541 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2d6728692011-03-12 01:39:558542 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:178543 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:068544 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:558545 };
8546
8547 StaticSocketDataProvider first_transaction(
8548 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078549 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:558550
[email protected]8ddf8322012-02-23 18:08:068551 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:028552 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:078553 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:558554
[email protected]d973e99a2012-02-17 21:02:368555 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:558556 StaticSocketDataProvider hanging_alternate_protocol_socket(
8557 NULL, 0, NULL, 0);
8558 hanging_alternate_protocol_socket.set_connect_data(
8559 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:078560 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:558561 &hanging_alternate_protocol_socket);
8562
8563 // 2nd request is just a copy of the first one, over HTTP again.
[email protected]bb88e1d32013-05-03 23:11:078564 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:558565
[email protected]49639fa2011-12-20 23:22:418566 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:558567
[email protected]bb88e1d32013-05-03 23:11:078568 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:368569 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508570 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:558571
[email protected]49639fa2011-12-20 23:22:418572 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:558573 EXPECT_EQ(ERR_IO_PENDING, rv);
8574 EXPECT_EQ(OK, callback.WaitForResult());
8575
8576 const HttpResponseInfo* response = trans->GetResponseInfo();
8577 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508578 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:558579 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8580
8581 std::string response_data;
8582 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8583 EXPECT_EQ("hello world", response_data);
8584
[email protected]90499482013-06-01 00:39:508585 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:558586
[email protected]49639fa2011-12-20 23:22:418587 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:558588 EXPECT_EQ(ERR_IO_PENDING, rv);
8589 EXPECT_EQ(OK, callback.WaitForResult());
8590
8591 response = trans->GetResponseInfo();
8592 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508593 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:558594 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8595 EXPECT_FALSE(response->was_fetched_via_spdy);
8596 EXPECT_FALSE(response->was_npn_negotiated);
8597
8598 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8599 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:558600}
8601
[email protected]631f1322010-04-30 17:59:118602class CapturingProxyResolver : public ProxyResolver {
8603 public:
8604 CapturingProxyResolver() : ProxyResolver(false /* expects_pac_bytes */) {}
8605 virtual ~CapturingProxyResolver() {}
8606
8607 virtual int GetProxyForURL(const GURL& url,
8608 ProxyInfo* results,
[email protected]235786812011-12-20 02:15:318609 const CompletionCallback& callback,
[email protected]631f1322010-04-30 17:59:118610 RequestHandle* request,
[email protected]46fadfd2013-02-06 09:40:168611 const BoundNetLog& net_log) OVERRIDE {
[email protected]fae7669f2010-08-02 21:49:408612 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
8613 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:428614 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:118615 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:428616 return OK;
[email protected]631f1322010-04-30 17:59:118617 }
8618
[email protected]46fadfd2013-02-06 09:40:168619 virtual void CancelRequest(RequestHandle request) OVERRIDE {
[email protected]631f1322010-04-30 17:59:118620 NOTREACHED();
8621 }
8622
[email protected]f2c971f2011-11-08 00:33:178623 virtual LoadState GetLoadState(RequestHandle request) const OVERRIDE {
8624 NOTREACHED();
8625 return LOAD_STATE_IDLE;
8626 }
8627
[email protected]46fadfd2013-02-06 09:40:168628 virtual void CancelSetPacScript() OVERRIDE {
[email protected]1e605472010-12-16 21:41:408629 NOTREACHED();
8630 }
8631
[email protected]24476402010-07-20 20:55:178632 virtual int SetPacScript(const scoped_refptr<ProxyResolverScriptData>&,
[email protected]46fadfd2013-02-06 09:40:168633 const CompletionCallback& /*callback*/) OVERRIDE {
[email protected]d911f1b2010-05-05 22:39:428634 return OK;
[email protected]631f1322010-04-30 17:59:118635 }
8636
[email protected]24476402010-07-20 20:55:178637 const std::vector<GURL>& resolved() const { return resolved_; }
8638
8639 private:
[email protected]631f1322010-04-30 17:59:118640 std::vector<GURL> resolved_;
8641
8642 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
8643};
8644
[email protected]23e482282013-06-14 16:08:028645TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238646 UseAlternateProtocolForTunneledNpnSpdy) {
[email protected]8e6441ca2010-08-19 05:56:388647 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:038648 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]631f1322010-04-30 17:59:118649
8650 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:428651 proxy_config.set_auto_detect(true);
8652 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:118653
[email protected]631f1322010-04-30 17:59:118654 CapturingProxyResolver* capturing_proxy_resolver =
8655 new CapturingProxyResolver();
[email protected]bb88e1d32013-05-03 23:11:078656 session_deps_.proxy_service.reset(new ProxyService(
[email protected]66761b952010-06-25 21:30:388657 new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver,
8658 NULL));
[email protected]029c83b62013-01-24 05:28:208659 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078660 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:118661
8662 HttpRequestInfo request;
8663 request.method = "GET";
8664 request.url = GURL("http://www.google.com/");
8665 request.load_flags = 0;
8666
[email protected]8a0fc822013-06-27 20:52:438667 std::string alternate_protocol_http_header =
8668 GetAlternateProtocolHttpHeader();
8669
[email protected]631f1322010-04-30 17:59:118670 MockRead data_reads[] = {
8671 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438672 MockRead(alternate_protocol_http_header.c_str()),
[email protected]631f1322010-04-30 17:59:118673 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:178674 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:068675 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:118676 };
8677
8678 StaticSocketDataProvider first_transaction(
8679 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078680 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]631f1322010-04-30 17:59:118681
[email protected]8ddf8322012-02-23 18:08:068682 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:028683 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:078684 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]631f1322010-04-30 17:59:118685
[email protected]cdf8f7e72013-05-23 10:56:468686 scoped_ptr<SpdyFrame> req(
8687 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]631f1322010-04-30 17:59:118688 MockWrite spdy_writes[] = {
8689 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
8690 "Host: www.google.com\r\n"
[email protected]d911f1b2010-05-05 22:39:428691 "Proxy-Connection: keep-alive\r\n\r\n"), // 0
[email protected]cdf8f7e72013-05-23 10:56:468692 CreateMockWrite(*req), // 3
[email protected]631f1322010-04-30 17:59:118693 };
8694
[email protected]d911f1b2010-05-05 22:39:428695 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
8696
[email protected]23e482282013-06-14 16:08:028697 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
8698 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]631f1322010-04-30 17:59:118699 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:068700 MockRead(ASYNC, kCONNECTResponse, arraysize(kCONNECTResponse) - 1, 1), // 1
[email protected]e7f75092010-07-01 22:39:138701 CreateMockRead(*resp.get(), 4), // 2, 4
8702 CreateMockRead(*data.get(), 4), // 5
[email protected]8ddf8322012-02-23 18:08:068703 MockRead(ASYNC, 0, 0, 4), // 6
[email protected]631f1322010-04-30 17:59:118704 };
8705
[email protected]dd54bd82012-07-19 23:44:578706 OrderedSocketData spdy_data(
8707 spdy_reads, arraysize(spdy_reads),
8708 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078709 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:118710
[email protected]d973e99a2012-02-17 21:02:368711 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:558712 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
8713 NULL, 0, NULL, 0);
8714 hanging_non_alternate_protocol_socket.set_connect_data(
8715 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:078716 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:558717 &hanging_non_alternate_protocol_socket);
8718
[email protected]49639fa2011-12-20 23:22:418719 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:118720
[email protected]bb88e1d32013-05-03 23:11:078721 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:368722 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508723 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:118724
[email protected]49639fa2011-12-20 23:22:418725 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:118726 EXPECT_EQ(ERR_IO_PENDING, rv);
8727 EXPECT_EQ(OK, callback.WaitForResult());
8728
8729 const HttpResponseInfo* response = trans->GetResponseInfo();
8730 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508731 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]631f1322010-04-30 17:59:118732 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:538733 EXPECT_FALSE(response->was_fetched_via_spdy);
8734 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:118735
8736 std::string response_data;
8737 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8738 EXPECT_EQ("hello world", response_data);
8739
[email protected]90499482013-06-01 00:39:508740 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:118741
[email protected]49639fa2011-12-20 23:22:418742 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:118743 EXPECT_EQ(ERR_IO_PENDING, rv);
8744 EXPECT_EQ(OK, callback.WaitForResult());
8745
8746 response = trans->GetResponseInfo();
8747 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508748 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]631f1322010-04-30 17:59:118749 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:538750 EXPECT_TRUE(response->was_fetched_via_spdy);
8751 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:118752
8753 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8754 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:558755 ASSERT_EQ(3u, capturing_proxy_resolver->resolved().size());
[email protected]d911f1b2010-05-05 22:39:428756 EXPECT_EQ("http://www.google.com/",
[email protected]631f1322010-04-30 17:59:118757 capturing_proxy_resolver->resolved()[0].spec());
[email protected]d911f1b2010-05-05 22:39:428758 EXPECT_EQ("https://www.google.com/",
8759 capturing_proxy_resolver->resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:118760
[email protected]029c83b62013-01-24 05:28:208761 LoadTimingInfo load_timing_info;
8762 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8763 TestLoadTimingNotReusedWithPac(load_timing_info,
8764 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:118765}
[email protected]631f1322010-04-30 17:59:118766
[email protected]23e482282013-06-14 16:08:028767TEST_P(HttpNetworkTransactionTest,
[email protected]2ff8b312010-04-26 22:20:548768 UseAlternateProtocolForNpnSpdyWithExistingSpdySession) {
[email protected]8e6441ca2010-08-19 05:56:388769 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:038770 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]2ff8b312010-04-26 22:20:548771
8772 HttpRequestInfo request;
8773 request.method = "GET";
8774 request.url = GURL("http://www.google.com/");
8775 request.load_flags = 0;
8776
[email protected]8a0fc822013-06-27 20:52:438777 std::string alternate_protocol_http_header =
8778 GetAlternateProtocolHttpHeader();
8779
[email protected]2ff8b312010-04-26 22:20:548780 MockRead data_reads[] = {
8781 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438782 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2ff8b312010-04-26 22:20:548783 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068784 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:548785 };
8786
8787 StaticSocketDataProvider first_transaction(
8788 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078789 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:548790
[email protected]8ddf8322012-02-23 18:08:068791 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:028792 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:078793 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:548794
[email protected]cdf8f7e72013-05-23 10:56:468795 scoped_ptr<SpdyFrame> req(
8796 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]e7f75092010-07-01 22:39:138797 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
[email protected]2ff8b312010-04-26 22:20:548798
[email protected]23e482282013-06-14 16:08:028799 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
8800 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:548801 MockRead spdy_reads[] = {
[email protected]e7f75092010-07-01 22:39:138802 CreateMockRead(*resp),
8803 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:068804 MockRead(ASYNC, 0, 0),
[email protected]2ff8b312010-04-26 22:20:548805 };
8806
[email protected]dd54bd82012-07-19 23:44:578807 DelayedSocketData spdy_data(
8808 1, // wait for one write to finish before reading.
8809 spdy_reads, arraysize(spdy_reads),
8810 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078811 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:548812
[email protected]83039bb2011-12-09 18:43:558813 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:548814
[email protected]bb88e1d32013-05-03 23:11:078815 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:548816
[email protected]262eec82013-03-19 21:01:368817 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508818 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:548819
[email protected]49639fa2011-12-20 23:22:418820 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:548821 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:418822 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:548823
8824 const HttpResponseInfo* response = trans->GetResponseInfo();
8825 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508826 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:548827 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8828
8829 std::string response_data;
8830 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8831 EXPECT_EQ("hello world", response_data);
8832
8833 // Set up an initial SpdySession in the pool to reuse.
[email protected]02b0c342010-09-25 21:09:388834 HostPortPair host_port_pair("www.google.com", 443);
[email protected]e6d017652013-05-17 18:01:408835 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
8836 kPrivacyModeDisabled);
[email protected]795cbf82013-07-22 09:37:278837 base::WeakPtr<SpdySession> spdy_session =
[email protected]41d64e82013-07-03 22:44:268838 CreateSecureSpdySession(session, key, BoundNetLog());
[email protected]02b0c342010-09-25 21:09:388839
[email protected]90499482013-06-01 00:39:508840 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:548841
[email protected]49639fa2011-12-20 23:22:418842 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:548843 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:418844 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:548845
8846 response = trans->GetResponseInfo();
8847 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508848 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:548849 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:538850 EXPECT_TRUE(response->was_fetched_via_spdy);
8851 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:548852
8853 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8854 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:428855}
8856
[email protected]044de0642010-06-17 10:42:158857// GenerateAuthToken is a mighty big test.
8858// It tests all permutation of GenerateAuthToken behavior:
8859// - Synchronous and Asynchronous completion.
8860// - OK or error on completion.
8861// - Direct connection, non-authenticating proxy, and authenticating proxy.
8862// - HTTP or HTTPS backend (to include proxy tunneling).
8863// - Non-authenticating and authenticating backend.
8864//
[email protected]fe3b7dc2012-02-03 19:52:098865// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:158866// problems generating an auth token for an authenticating proxy, we don't
8867// need to test all permutations of the backend server).
8868//
8869// The test proceeds by going over each of the configuration cases, and
8870// potentially running up to three rounds in each of the tests. The TestConfig
8871// specifies both the configuration for the test as well as the expectations
8872// for the results.
[email protected]23e482282013-06-14 16:08:028873TEST_P(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:508874 static const char kServer[] = "http://www.example.com";
8875 static const char kSecureServer[] = "https://www.example.com";
8876 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:158877 const int kAuthErr = ERR_INVALID_AUTH_CREDENTIALS;
8878
8879 enum AuthTiming {
8880 AUTH_NONE,
8881 AUTH_SYNC,
8882 AUTH_ASYNC,
8883 };
8884
8885 const MockWrite kGet(
8886 "GET / HTTP/1.1\r\n"
8887 "Host: www.example.com\r\n"
8888 "Connection: keep-alive\r\n\r\n");
8889 const MockWrite kGetProxy(
8890 "GET http://www.example.com/ HTTP/1.1\r\n"
8891 "Host: www.example.com\r\n"
8892 "Proxy-Connection: keep-alive\r\n\r\n");
8893 const MockWrite kGetAuth(
8894 "GET / HTTP/1.1\r\n"
8895 "Host: www.example.com\r\n"
8896 "Connection: keep-alive\r\n"
8897 "Authorization: auth_token\r\n\r\n");
8898 const MockWrite kGetProxyAuth(
8899 "GET http://www.example.com/ HTTP/1.1\r\n"
8900 "Host: www.example.com\r\n"
8901 "Proxy-Connection: keep-alive\r\n"
8902 "Proxy-Authorization: auth_token\r\n\r\n");
8903 const MockWrite kGetAuthThroughProxy(
8904 "GET http://www.example.com/ HTTP/1.1\r\n"
8905 "Host: www.example.com\r\n"
8906 "Proxy-Connection: keep-alive\r\n"
8907 "Authorization: auth_token\r\n\r\n");
8908 const MockWrite kGetAuthWithProxyAuth(
8909 "GET http://www.example.com/ HTTP/1.1\r\n"
8910 "Host: www.example.com\r\n"
8911 "Proxy-Connection: keep-alive\r\n"
8912 "Proxy-Authorization: auth_token\r\n"
8913 "Authorization: auth_token\r\n\r\n");
8914 const MockWrite kConnect(
8915 "CONNECT www.example.com:443 HTTP/1.1\r\n"
8916 "Host: www.example.com\r\n"
8917 "Proxy-Connection: keep-alive\r\n\r\n");
8918 const MockWrite kConnectProxyAuth(
8919 "CONNECT www.example.com:443 HTTP/1.1\r\n"
8920 "Host: www.example.com\r\n"
8921 "Proxy-Connection: keep-alive\r\n"
8922 "Proxy-Authorization: auth_token\r\n\r\n");
8923
8924 const MockRead kSuccess(
8925 "HTTP/1.1 200 OK\r\n"
8926 "Content-Type: text/html; charset=iso-8859-1\r\n"
8927 "Content-Length: 3\r\n\r\n"
8928 "Yes");
8929 const MockRead kFailure(
8930 "Should not be called.");
8931 const MockRead kServerChallenge(
8932 "HTTP/1.1 401 Unauthorized\r\n"
8933 "WWW-Authenticate: Mock realm=server\r\n"
8934 "Content-Type: text/html; charset=iso-8859-1\r\n"
8935 "Content-Length: 14\r\n\r\n"
8936 "Unauthorized\r\n");
8937 const MockRead kProxyChallenge(
8938 "HTTP/1.1 407 Unauthorized\r\n"
8939 "Proxy-Authenticate: Mock realm=proxy\r\n"
8940 "Proxy-Connection: close\r\n"
8941 "Content-Type: text/html; charset=iso-8859-1\r\n"
8942 "Content-Length: 14\r\n\r\n"
8943 "Unauthorized\r\n");
8944 const MockRead kProxyConnected(
8945 "HTTP/1.1 200 Connection Established\r\n\r\n");
8946
8947 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
8948 // no constructors, but the C++ compiler on Windows warns about
8949 // unspecified data in compound literals. So, moved to using constructors,
8950 // and TestRound's created with the default constructor should not be used.
8951 struct TestRound {
8952 TestRound()
8953 : expected_rv(ERR_UNEXPECTED),
8954 extra_write(NULL),
8955 extra_read(NULL) {
8956 }
8957 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
8958 int expected_rv_arg)
8959 : write(write_arg),
8960 read(read_arg),
8961 expected_rv(expected_rv_arg),
8962 extra_write(NULL),
8963 extra_read(NULL) {
8964 }
8965 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
8966 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:018967 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:158968 : write(write_arg),
8969 read(read_arg),
8970 expected_rv(expected_rv_arg),
8971 extra_write(extra_write_arg),
8972 extra_read(extra_read_arg) {
8973 }
8974 MockWrite write;
8975 MockRead read;
8976 int expected_rv;
8977 const MockWrite* extra_write;
8978 const MockRead* extra_read;
8979 };
8980
8981 static const int kNoSSL = 500;
8982
8983 struct TestConfig {
8984 const char* proxy_url;
8985 AuthTiming proxy_auth_timing;
8986 int proxy_auth_rv;
8987 const char* server_url;
8988 AuthTiming server_auth_timing;
8989 int server_auth_rv;
8990 int num_auth_rounds;
8991 int first_ssl_round;
8992 TestRound rounds[3];
8993 } test_configs[] = {
8994 // Non-authenticating HTTP server with a direct connection.
8995 { NULL, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
8996 { TestRound(kGet, kSuccess, OK)}},
8997 // Authenticating HTTP server with a direct connection.
8998 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
8999 { TestRound(kGet, kServerChallenge, OK),
9000 TestRound(kGetAuth, kSuccess, OK)}},
9001 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
9002 { TestRound(kGet, kServerChallenge, OK),
9003 TestRound(kGetAuth, kFailure, kAuthErr)}},
9004 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
9005 { TestRound(kGet, kServerChallenge, OK),
9006 TestRound(kGetAuth, kSuccess, OK)}},
9007 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
9008 { TestRound(kGet, kServerChallenge, OK),
9009 TestRound(kGetAuth, kFailure, kAuthErr)}},
9010 // Non-authenticating HTTP server through a non-authenticating proxy.
9011 { kProxy, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
9012 { TestRound(kGetProxy, kSuccess, OK)}},
9013 // Authenticating HTTP server through a non-authenticating proxy.
9014 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
9015 { TestRound(kGetProxy, kServerChallenge, OK),
9016 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
9017 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
9018 { TestRound(kGetProxy, kServerChallenge, OK),
9019 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
9020 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
9021 { TestRound(kGetProxy, kServerChallenge, OK),
9022 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
9023 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
9024 { TestRound(kGetProxy, kServerChallenge, OK),
9025 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
9026 // Non-authenticating HTTP server through an authenticating proxy.
9027 { kProxy, AUTH_SYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
9028 { TestRound(kGetProxy, kProxyChallenge, OK),
9029 TestRound(kGetProxyAuth, kSuccess, OK)}},
9030 { kProxy, AUTH_SYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
9031 { TestRound(kGetProxy, kProxyChallenge, OK),
9032 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
9033 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
9034 { TestRound(kGetProxy, kProxyChallenge, OK),
9035 TestRound(kGetProxyAuth, kSuccess, OK)}},
9036 { kProxy, AUTH_ASYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
9037 { TestRound(kGetProxy, kProxyChallenge, OK),
9038 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
9039 // Authenticating HTTP server through an authenticating proxy.
9040 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
9041 { TestRound(kGetProxy, kProxyChallenge, OK),
9042 TestRound(kGetProxyAuth, kServerChallenge, OK),
9043 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9044 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
9045 { TestRound(kGetProxy, kProxyChallenge, OK),
9046 TestRound(kGetProxyAuth, kServerChallenge, OK),
9047 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9048 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
9049 { TestRound(kGetProxy, kProxyChallenge, OK),
9050 TestRound(kGetProxyAuth, kServerChallenge, OK),
9051 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9052 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
9053 { TestRound(kGetProxy, kProxyChallenge, OK),
9054 TestRound(kGetProxyAuth, kServerChallenge, OK),
9055 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9056 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
9057 { TestRound(kGetProxy, kProxyChallenge, OK),
9058 TestRound(kGetProxyAuth, kServerChallenge, OK),
9059 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9060 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
9061 { TestRound(kGetProxy, kProxyChallenge, OK),
9062 TestRound(kGetProxyAuth, kServerChallenge, OK),
9063 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9064 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
9065 { TestRound(kGetProxy, kProxyChallenge, OK),
9066 TestRound(kGetProxyAuth, kServerChallenge, OK),
9067 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9068 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
9069 { TestRound(kGetProxy, kProxyChallenge, OK),
9070 TestRound(kGetProxyAuth, kServerChallenge, OK),
9071 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9072 // Non-authenticating HTTPS server with a direct connection.
9073 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
9074 { TestRound(kGet, kSuccess, OK)}},
9075 // Authenticating HTTPS server with a direct connection.
9076 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
9077 { TestRound(kGet, kServerChallenge, OK),
9078 TestRound(kGetAuth, kSuccess, OK)}},
9079 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
9080 { TestRound(kGet, kServerChallenge, OK),
9081 TestRound(kGetAuth, kFailure, kAuthErr)}},
9082 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
9083 { TestRound(kGet, kServerChallenge, OK),
9084 TestRound(kGetAuth, kSuccess, OK)}},
9085 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
9086 { TestRound(kGet, kServerChallenge, OK),
9087 TestRound(kGetAuth, kFailure, kAuthErr)}},
9088 // Non-authenticating HTTPS server with a non-authenticating proxy.
9089 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
9090 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
9091 // Authenticating HTTPS server through a non-authenticating proxy.
9092 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
9093 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9094 TestRound(kGetAuth, kSuccess, OK)}},
9095 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
9096 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9097 TestRound(kGetAuth, kFailure, kAuthErr)}},
9098 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
9099 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9100 TestRound(kGetAuth, kSuccess, OK)}},
9101 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
9102 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9103 TestRound(kGetAuth, kFailure, kAuthErr)}},
9104 // Non-Authenticating HTTPS server through an authenticating proxy.
9105 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
9106 { TestRound(kConnect, kProxyChallenge, OK),
9107 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
9108 { kProxy, AUTH_SYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
9109 { TestRound(kConnect, kProxyChallenge, OK),
9110 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
9111 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
9112 { TestRound(kConnect, kProxyChallenge, OK),
9113 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
9114 { kProxy, AUTH_ASYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
9115 { TestRound(kConnect, kProxyChallenge, OK),
9116 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
9117 // Authenticating HTTPS server through an authenticating proxy.
9118 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
9119 { TestRound(kConnect, kProxyChallenge, OK),
9120 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9121 &kGet, &kServerChallenge),
9122 TestRound(kGetAuth, kSuccess, OK)}},
9123 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
9124 { TestRound(kConnect, kProxyChallenge, OK),
9125 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9126 &kGet, &kServerChallenge),
9127 TestRound(kGetAuth, kFailure, kAuthErr)}},
9128 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
9129 { TestRound(kConnect, kProxyChallenge, OK),
9130 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9131 &kGet, &kServerChallenge),
9132 TestRound(kGetAuth, kSuccess, OK)}},
9133 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
9134 { TestRound(kConnect, kProxyChallenge, OK),
9135 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9136 &kGet, &kServerChallenge),
9137 TestRound(kGetAuth, kFailure, kAuthErr)}},
9138 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
9139 { TestRound(kConnect, kProxyChallenge, OK),
9140 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9141 &kGet, &kServerChallenge),
9142 TestRound(kGetAuth, kSuccess, OK)}},
9143 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
9144 { TestRound(kConnect, kProxyChallenge, OK),
9145 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9146 &kGet, &kServerChallenge),
9147 TestRound(kGetAuth, kFailure, kAuthErr)}},
9148 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
9149 { TestRound(kConnect, kProxyChallenge, OK),
9150 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9151 &kGet, &kServerChallenge),
9152 TestRound(kGetAuth, kSuccess, OK)}},
9153 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
9154 { TestRound(kConnect, kProxyChallenge, OK),
9155 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9156 &kGet, &kServerChallenge),
9157 TestRound(kGetAuth, kFailure, kAuthErr)}},
9158 };
9159
[email protected]044de0642010-06-17 10:42:159160 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_configs); ++i) {
[email protected]2d01c262011-08-11 23:07:089161 HttpAuthHandlerMock::Factory* auth_factory(
9162 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:079163 session_deps_.http_auth_handler_factory.reset(auth_factory);
[email protected]044de0642010-06-17 10:42:159164 const TestConfig& test_config = test_configs[i];
[email protected]65d34382010-07-01 18:12:269165
9166 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:159167 if (test_config.proxy_auth_timing != AUTH_NONE) {
[email protected]2d01c262011-08-11 23:07:089168 for (int n = 0; n < 2; n++) {
9169 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
9170 std::string auth_challenge = "Mock realm=proxy";
9171 GURL origin(test_config.proxy_url);
9172 HttpAuth::ChallengeTokenizer tokenizer(auth_challenge.begin(),
9173 auth_challenge.end());
9174 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
9175 origin, BoundNetLog());
9176 auth_handler->SetGenerateExpectation(
9177 test_config.proxy_auth_timing == AUTH_ASYNC,
9178 test_config.proxy_auth_rv);
9179 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
9180 }
[email protected]044de0642010-06-17 10:42:159181 }
9182 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:009183 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:159184 std::string auth_challenge = "Mock realm=server";
9185 GURL origin(test_config.server_url);
9186 HttpAuth::ChallengeTokenizer tokenizer(auth_challenge.begin(),
9187 auth_challenge.end());
9188 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
9189 origin, BoundNetLog());
9190 auth_handler->SetGenerateExpectation(
9191 test_config.server_auth_timing == AUTH_ASYNC,
9192 test_config.server_auth_rv);
[email protected]2d01c262011-08-11 23:07:089193 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:159194 }
9195 if (test_config.proxy_url) {
[email protected]bb88e1d32013-05-03 23:11:079196 session_deps_.proxy_service.reset(
[email protected]6104ea5d2011-04-27 21:37:129197 ProxyService::CreateFixed(test_config.proxy_url));
[email protected]044de0642010-06-17 10:42:159198 } else {
[email protected]bb88e1d32013-05-03 23:11:079199 session_deps_.proxy_service.reset(ProxyService::CreateDirect());
[email protected]044de0642010-06-17 10:42:159200 }
9201
9202 HttpRequestInfo request;
9203 request.method = "GET";
9204 request.url = GURL(test_config.server_url);
9205 request.load_flags = 0;
9206
[email protected]bb88e1d32013-05-03 23:11:079207 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369208 HttpNetworkTransaction trans(
[email protected]bb88e1d32013-05-03 23:11:079209 DEFAULT_PRIORITY, CreateSession(&session_deps_));
[email protected]044de0642010-06-17 10:42:159210
9211 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
9212 const TestRound& read_write_round = test_config.rounds[round];
9213
9214 // Set up expected reads and writes.
9215 MockRead reads[2];
9216 reads[0] = read_write_round.read;
9217 size_t length_reads = 1;
9218 if (read_write_round.extra_read) {
9219 reads[1] = *read_write_round.extra_read;
9220 length_reads = 2;
9221 }
9222
9223 MockWrite writes[2];
9224 writes[0] = read_write_round.write;
9225 size_t length_writes = 1;
9226 if (read_write_round.extra_write) {
9227 writes[1] = *read_write_round.extra_write;
9228 length_writes = 2;
9229 }
9230 StaticSocketDataProvider data_provider(
9231 reads, length_reads, writes, length_writes);
[email protected]bb88e1d32013-05-03 23:11:079232 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]044de0642010-06-17 10:42:159233
9234 // Add an SSL sequence if necessary.
[email protected]8ddf8322012-02-23 18:08:069235 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
[email protected]044de0642010-06-17 10:42:159236 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:079237 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:159238 &ssl_socket_data_provider);
9239
9240 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:419241 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:159242 int rv;
9243 if (round == 0) {
[email protected]49639fa2011-12-20 23:22:419244 rv = trans.Start(&request, callback.callback(), BoundNetLog());
[email protected]044de0642010-06-17 10:42:159245 } else {
[email protected]49639fa2011-12-20 23:22:419246 rv = trans.RestartWithAuth(
9247 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:159248 }
9249 if (rv == ERR_IO_PENDING)
9250 rv = callback.WaitForResult();
9251
9252 // Compare results with expected data.
9253 EXPECT_EQ(read_write_round.expected_rv, rv);
[email protected]0b0bf032010-09-21 18:08:509254 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]044de0642010-06-17 10:42:159255 if (read_write_round.expected_rv == OK) {
[email protected]fe2255a2011-09-20 19:37:509256 ASSERT_TRUE(response != NULL);
[email protected]044de0642010-06-17 10:42:159257 } else {
9258 EXPECT_TRUE(response == NULL);
9259 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
9260 continue;
9261 }
9262 if (round + 1 < test_config.num_auth_rounds) {
9263 EXPECT_FALSE(response->auth_challenge.get() == NULL);
9264 } else {
9265 EXPECT_TRUE(response->auth_challenge.get() == NULL);
9266 }
9267 }
[email protected]e5ae96a2010-04-14 20:12:459268 }
9269}
9270
[email protected]23e482282013-06-14 16:08:029271TEST_P(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:149272 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:149273 HttpAuthHandlerMock::Factory* auth_factory(
9274 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:079275 session_deps_.http_auth_handler_factory.reset(auth_factory);
9276 session_deps_.proxy_service.reset(ProxyService::CreateDirect());
9277 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
9278 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:149279
9280 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
9281 auth_handler->set_connection_based(true);
9282 std::string auth_challenge = "Mock realm=server";
9283 GURL origin("http://www.example.com");
9284 HttpAuth::ChallengeTokenizer tokenizer(auth_challenge.begin(),
9285 auth_challenge.end());
9286 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
9287 origin, BoundNetLog());
[email protected]2d01c262011-08-11 23:07:089288 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:149289
[email protected]c871bce92010-07-15 21:51:149290 int rv = OK;
9291 const HttpResponseInfo* response = NULL;
9292 HttpRequestInfo request;
9293 request.method = "GET";
9294 request.url = origin;
9295 request.load_flags = 0;
[email protected]cb9bf6ca2011-01-28 13:15:279296
[email protected]bb88e1d32013-05-03 23:11:079297 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:109298
9299 // Use a TCP Socket Pool with only one connection per group. This is used
9300 // to validate that the TCP socket is not released to the pool between
9301 // each round of multi-round authentication.
9302 HttpNetworkSessionPeer session_peer(session);
[email protected]ab739042011-04-07 15:22:289303 ClientSocketPoolHistograms transport_pool_histograms("SmallTCP");
9304 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:109305 50, // Max sockets for pool
9306 1, // Max sockets per group
[email protected]ab739042011-04-07 15:22:289307 &transport_pool_histograms,
[email protected]bb88e1d32013-05-03 23:11:079308 session_deps_.host_resolver.get(),
9309 session_deps_.socket_factory.get(),
9310 session_deps_.net_log);
[email protected]a42dbd142011-11-17 16:42:029311 MockClientSocketPoolManager* mock_pool_manager =
9312 new MockClientSocketPoolManager;
9313 mock_pool_manager->SetTransportSocketPool(transport_pool);
9314 session_peer.SetClientSocketPoolManager(mock_pool_manager);
[email protected]7ef4cbbb2011-02-06 11:19:109315
[email protected]262eec82013-03-19 21:01:369316 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509317 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419318 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:149319
9320 const MockWrite kGet(
9321 "GET / HTTP/1.1\r\n"
9322 "Host: www.example.com\r\n"
9323 "Connection: keep-alive\r\n\r\n");
9324 const MockWrite kGetAuth(
9325 "GET / HTTP/1.1\r\n"
9326 "Host: www.example.com\r\n"
9327 "Connection: keep-alive\r\n"
9328 "Authorization: auth_token\r\n\r\n");
9329
9330 const MockRead kServerChallenge(
9331 "HTTP/1.1 401 Unauthorized\r\n"
9332 "WWW-Authenticate: Mock realm=server\r\n"
9333 "Content-Type: text/html; charset=iso-8859-1\r\n"
9334 "Content-Length: 14\r\n\r\n"
9335 "Unauthorized\r\n");
9336 const MockRead kSuccess(
9337 "HTTP/1.1 200 OK\r\n"
9338 "Content-Type: text/html; charset=iso-8859-1\r\n"
9339 "Content-Length: 3\r\n\r\n"
9340 "Yes");
9341
9342 MockWrite writes[] = {
9343 // First round
9344 kGet,
9345 // Second round
9346 kGetAuth,
9347 // Third round
9348 kGetAuth,
[email protected]eca50e122010-09-11 14:03:309349 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:109350 kGetAuth,
9351 // Competing request
9352 kGet,
[email protected]c871bce92010-07-15 21:51:149353 };
9354 MockRead reads[] = {
9355 // First round
9356 kServerChallenge,
9357 // Second round
9358 kServerChallenge,
9359 // Third round
[email protected]eca50e122010-09-11 14:03:309360 kServerChallenge,
9361 // Fourth round
[email protected]c871bce92010-07-15 21:51:149362 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:109363 // Competing response
9364 kSuccess,
[email protected]c871bce92010-07-15 21:51:149365 };
9366 StaticSocketDataProvider data_provider(reads, arraysize(reads),
9367 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:079368 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:149369
[email protected]7ef4cbbb2011-02-06 11:19:109370 const char* const kSocketGroup = "www.example.com:80";
9371
9372 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:149373 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:419374 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]c871bce92010-07-15 21:51:149375 if (rv == ERR_IO_PENDING)
9376 rv = callback.WaitForResult();
9377 EXPECT_EQ(OK, rv);
9378 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509379 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:149380 EXPECT_FALSE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:289381 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:149382
[email protected]7ef4cbbb2011-02-06 11:19:109383 // In between rounds, another request comes in for the same domain.
9384 // It should not be able to grab the TCP socket that trans has already
9385 // claimed.
9386 scoped_ptr<HttpTransaction> trans_compete(
[email protected]90499482013-06-01 00:39:509387 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419388 TestCompletionCallback callback_compete;
9389 rv = trans_compete->Start(
9390 &request, callback_compete.callback(), BoundNetLog());
[email protected]7ef4cbbb2011-02-06 11:19:109391 EXPECT_EQ(ERR_IO_PENDING, rv);
9392 // callback_compete.WaitForResult at this point would stall forever,
9393 // since the HttpNetworkTransaction does not release the request back to
9394 // the pool until after authentication completes.
9395
9396 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:149397 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:419398 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:149399 if (rv == ERR_IO_PENDING)
9400 rv = callback.WaitForResult();
9401 EXPECT_EQ(OK, rv);
9402 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509403 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:149404 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:289405 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:149406
[email protected]7ef4cbbb2011-02-06 11:19:109407 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:149408 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:419409 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:149410 if (rv == ERR_IO_PENDING)
9411 rv = callback.WaitForResult();
9412 EXPECT_EQ(OK, rv);
9413 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509414 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:149415 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:289416 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]eca50e122010-09-11 14:03:309417
[email protected]7ef4cbbb2011-02-06 11:19:109418 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:309419 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:419420 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:309421 if (rv == ERR_IO_PENDING)
9422 rv = callback.WaitForResult();
9423 EXPECT_EQ(OK, rv);
9424 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509425 ASSERT_TRUE(response != NULL);
[email protected]eca50e122010-09-11 14:03:309426 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:289427 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:109428
9429 // Read the body since the fourth round was successful. This will also
9430 // release the socket back to the pool.
9431 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
[email protected]90499482013-06-01 00:39:509432 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:109433 if (rv == ERR_IO_PENDING)
9434 rv = callback.WaitForResult();
9435 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:509436 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:109437 EXPECT_EQ(0, rv);
9438 // There are still 0 idle sockets, since the trans_compete transaction
9439 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:289440 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:109441
9442 // The competing request can now finish. Wait for the headers and then
9443 // read the body.
9444 rv = callback_compete.WaitForResult();
9445 EXPECT_EQ(OK, rv);
[email protected]90499482013-06-01 00:39:509446 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:109447 if (rv == ERR_IO_PENDING)
9448 rv = callback.WaitForResult();
9449 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:509450 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:109451 EXPECT_EQ(0, rv);
9452
9453 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:289454 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:149455}
9456
[email protected]65041fa2010-05-21 06:56:539457// This tests the case that a request is issued via http instead of spdy after
9458// npn is negotiated.
[email protected]23e482282013-06-14 16:08:029459TEST_P(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]8e6441ca2010-08-19 05:56:389460 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]0ce3af82013-07-22 16:17:169461 std::vector<NextProto> next_protos;
9462 next_protos.push_back(kProtoHTTP11);
9463 HttpStreamFactory::SetNextProtos(next_protos);
[email protected]65041fa2010-05-21 06:56:539464 HttpRequestInfo request;
9465 request.method = "GET";
9466 request.url = GURL("https://www.google.com/");
9467 request.load_flags = 0;
9468
9469 MockWrite data_writes[] = {
9470 MockWrite("GET / HTTP/1.1\r\n"
9471 "Host: www.google.com\r\n"
9472 "Connection: keep-alive\r\n\r\n"),
9473 };
9474
[email protected]8a0fc822013-06-27 20:52:439475 std::string alternate_protocol_http_header =
9476 GetAlternateProtocolHttpHeader();
9477
[email protected]65041fa2010-05-21 06:56:539478 MockRead data_reads[] = {
9479 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439480 MockRead(alternate_protocol_http_header.c_str()),
[email protected]65041fa2010-05-21 06:56:539481 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069482 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:539483 };
9484
[email protected]8ddf8322012-02-23 18:08:069485 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]65041fa2010-05-21 06:56:539486 ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
9487 ssl.next_proto = "http/1.1";
[email protected]8e3c78cb2012-03-31 03:58:469488 ssl.protocol_negotiated = kProtoHTTP11;
[email protected]65041fa2010-05-21 06:56:539489
[email protected]bb88e1d32013-05-03 23:11:079490 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:539491
9492 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9493 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079494 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:539495
[email protected]49639fa2011-12-20 23:22:419496 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:539497
[email protected]bb88e1d32013-05-03 23:11:079498 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369499 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509500 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]65041fa2010-05-21 06:56:539501
[email protected]49639fa2011-12-20 23:22:419502 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]65041fa2010-05-21 06:56:539503
9504 EXPECT_EQ(ERR_IO_PENDING, rv);
9505 EXPECT_EQ(OK, callback.WaitForResult());
9506
9507 const HttpResponseInfo* response = trans->GetResponseInfo();
9508 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509509 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]65041fa2010-05-21 06:56:539510 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9511
9512 std::string response_data;
9513 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9514 EXPECT_EQ("hello world", response_data);
9515
9516 EXPECT_FALSE(response->was_fetched_via_spdy);
9517 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]65041fa2010-05-21 06:56:539518}
[email protected]26ef6582010-06-24 02:30:479519
[email protected]23e482282013-06-14 16:08:029520TEST_P(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:479521 // Simulate the SSL handshake completing with an NPN negotiation
9522 // followed by an immediate server closing of the socket.
9523 // Fix crash: http://crbug.com/46369
[email protected]8e6441ca2010-08-19 05:56:389524 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:039525 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]26ef6582010-06-24 02:30:479526
9527 HttpRequestInfo request;
9528 request.method = "GET";
9529 request.url = GURL("https://www.google.com/");
9530 request.load_flags = 0;
9531
[email protected]8ddf8322012-02-23 18:08:069532 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029533 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:079534 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:479535
[email protected]cdf8f7e72013-05-23 10:56:469536 scoped_ptr<SpdyFrame> req(
9537 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]e7f75092010-07-01 22:39:139538 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
[email protected]26ef6582010-06-24 02:30:479539
9540 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:069541 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:479542 };
9543
[email protected]dd54bd82012-07-19 23:44:579544 DelayedSocketData spdy_data(
9545 0, // don't wait in this case, immediate hangup.
9546 spdy_reads, arraysize(spdy_reads),
9547 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079548 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:479549
[email protected]49639fa2011-12-20 23:22:419550 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:479551
[email protected]bb88e1d32013-05-03 23:11:079552 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369553 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509554 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]26ef6582010-06-24 02:30:479555
[email protected]49639fa2011-12-20 23:22:419556 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]26ef6582010-06-24 02:30:479557 EXPECT_EQ(ERR_IO_PENDING, rv);
9558 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult());
[email protected]26ef6582010-06-24 02:30:479559}
[email protected]65d34382010-07-01 18:12:269560
[email protected]795cbf82013-07-22 09:37:279561// A subclass of HttpAuthHandlerMock that records the request URL when
9562// it gets it. This is needed since the auth handler may get destroyed
9563// before we get a chance to query it.
9564class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
9565 public:
9566 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
9567
9568 virtual ~UrlRecordingHttpAuthHandlerMock() {}
9569
9570 protected:
9571 virtual int GenerateAuthTokenImpl(const AuthCredentials* credentials,
9572 const HttpRequestInfo* request,
9573 const CompletionCallback& callback,
9574 std::string* auth_token) OVERRIDE {
9575 *url_ = request->url;
9576 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
9577 credentials, request, callback, auth_token);
9578 }
9579
9580 private:
9581 GURL* url_;
9582};
9583
[email protected]23e482282013-06-14 16:08:029584TEST_P(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) {
[email protected]f45c1ee2010-08-03 00:54:309585 // This test ensures that the URL passed into the proxy is upgraded
9586 // to https when doing an Alternate Protocol upgrade.
[email protected]8e6441ca2010-08-19 05:56:389587 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]8a0fc822013-06-27 20:52:439588 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]f45c1ee2010-08-03 00:54:309589
[email protected]bb88e1d32013-05-03 23:11:079590 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:209591 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
9592 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079593 session_deps_.net_log = &net_log;
[email protected]795cbf82013-07-22 09:37:279594 GURL request_url;
9595 {
9596 HttpAuthHandlerMock::Factory* auth_factory =
9597 new HttpAuthHandlerMock::Factory();
9598 UrlRecordingHttpAuthHandlerMock* auth_handler =
9599 new UrlRecordingHttpAuthHandlerMock(&request_url);
9600 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
9601 auth_factory->set_do_init_from_challenge(true);
9602 session_deps_.http_auth_handler_factory.reset(auth_factory);
9603 }
[email protected]f45c1ee2010-08-03 00:54:309604
9605 HttpRequestInfo request;
9606 request.method = "GET";
9607 request.url = GURL("http://www.google.com");
9608 request.load_flags = 0;
9609
9610 // First round goes unauthenticated through the proxy.
9611 MockWrite data_writes_1[] = {
9612 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
9613 "Host: www.google.com\r\n"
9614 "Proxy-Connection: keep-alive\r\n"
9615 "\r\n"),
9616 };
9617 MockRead data_reads_1[] = {
[email protected]8ddf8322012-02-23 18:08:069618 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]f45c1ee2010-08-03 00:54:309619 MockRead("HTTP/1.1 200 OK\r\n"
[email protected]448d4ca52012-03-04 04:12:239620 "Alternate-Protocol: 443:npn-spdy/2\r\n"
[email protected]f45c1ee2010-08-03 00:54:309621 "Proxy-Connection: close\r\n"
9622 "\r\n"),
9623 };
9624 StaticSocketDataProvider data_1(data_reads_1, arraysize(data_reads_1),
9625 data_writes_1, arraysize(data_writes_1));
9626
9627 // Second round tries to tunnel to www.google.com due to the
9628 // Alternate-Protocol announcement in the first round. It fails due
9629 // to a proxy authentication challenge.
[email protected]394816e92010-08-03 07:38:599630 // After the failure, a tunnel is established to www.google.com using
9631 // Proxy-Authorization headers. There is then a SPDY request round.
9632 //
[email protected]fe3b7dc2012-02-03 19:52:099633 // NOTE: Despite the "Proxy-Connection: Close", these are done on the
9634 // same MockTCPClientSocket since the underlying HttpNetworkClientSocket
9635 // does a Disconnect and Connect on the same socket, rather than trying
9636 // to obtain a new one.
9637 //
[email protected]394816e92010-08-03 07:38:599638 // NOTE: Originally, the proxy response to the second CONNECT request
9639 // simply returned another 407 so the unit test could skip the SSL connection
9640 // establishment and SPDY framing issues. Alas, the
9641 // retry-http-when-alternate-protocol fails logic kicks in, which was more
[email protected]f45c1ee2010-08-03 00:54:309642 // complicated to set up expectations for than the SPDY session.
[email protected]394816e92010-08-03 07:38:599643
[email protected]cdf8f7e72013-05-23 10:56:469644 scoped_ptr<SpdyFrame> req(
9645 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]23e482282013-06-14 16:08:029646 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9647 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]f45c1ee2010-08-03 00:54:309648
[email protected]394816e92010-08-03 07:38:599649 MockWrite data_writes_2[] = {
9650 // First connection attempt without Proxy-Authorization.
9651 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
9652 "Host: www.google.com\r\n"
9653 "Proxy-Connection: keep-alive\r\n"
9654 "\r\n"),
9655
9656 // Second connection attempt with Proxy-Authorization.
[email protected]f45c1ee2010-08-03 00:54:309657 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
9658 "Host: www.google.com\r\n"
9659 "Proxy-Connection: keep-alive\r\n"
9660 "Proxy-Authorization: auth_token\r\n"
9661 "\r\n"),
[email protected]f45c1ee2010-08-03 00:54:309662
[email protected]394816e92010-08-03 07:38:599663 // SPDY request
9664 CreateMockWrite(*req),
[email protected]f45c1ee2010-08-03 00:54:309665 };
[email protected]394816e92010-08-03 07:38:599666 const char kRejectConnectResponse[] = ("HTTP/1.1 407 Unauthorized\r\n"
9667 "Proxy-Authenticate: Mock\r\n"
9668 "Proxy-Connection: close\r\n"
9669 "\r\n");
9670 const char kAcceptConnectResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
9671 MockRead data_reads_2[] = {
9672 // First connection attempt fails
[email protected]8ddf8322012-02-23 18:08:069673 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ, 1),
9674 MockRead(ASYNC, kRejectConnectResponse,
[email protected]394816e92010-08-03 07:38:599675 arraysize(kRejectConnectResponse) - 1, 1),
9676
9677 // Second connection attempt passes
[email protected]8ddf8322012-02-23 18:08:069678 MockRead(ASYNC, kAcceptConnectResponse,
[email protected]fe3b7dc2012-02-03 19:52:099679 arraysize(kAcceptConnectResponse) -1, 4),
[email protected]394816e92010-08-03 07:38:599680
9681 // SPDY response
[email protected]fe3b7dc2012-02-03 19:52:099682 CreateMockRead(*resp.get(), 6),
9683 CreateMockRead(*data.get(), 6),
[email protected]8ddf8322012-02-23 18:08:069684 MockRead(ASYNC, 0, 0, 6),
[email protected]394816e92010-08-03 07:38:599685 };
[email protected]dd54bd82012-07-19 23:44:579686 OrderedSocketData data_2(
9687 data_reads_2, arraysize(data_reads_2),
9688 data_writes_2, arraysize(data_writes_2));
[email protected]f45c1ee2010-08-03 00:54:309689
[email protected]8ddf8322012-02-23 18:08:069690 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029691 ssl.SetNextProto(GetParam());
[email protected]f45c1ee2010-08-03 00:54:309692
[email protected]d973e99a2012-02-17 21:02:369693 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559694 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
9695 NULL, 0, NULL, 0);
9696 hanging_non_alternate_protocol_socket.set_connect_data(
9697 never_finishing_connect);
9698
[email protected]bb88e1d32013-05-03 23:11:079699 session_deps_.socket_factory->AddSocketDataProvider(&data_1);
9700 session_deps_.socket_factory->AddSocketDataProvider(&data_2);
9701 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9702 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:559703 &hanging_non_alternate_protocol_socket);
[email protected]bb88e1d32013-05-03 23:11:079704 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f45c1ee2010-08-03 00:54:309705
9706 // First round should work and provide the Alternate-Protocol state.
[email protected]49639fa2011-12-20 23:22:419707 TestCompletionCallback callback_1;
[email protected]262eec82013-03-19 21:01:369708 scoped_ptr<HttpTransaction> trans_1(
[email protected]90499482013-06-01 00:39:509709 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419710 int rv = trans_1->Start(&request, callback_1.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:309711 EXPECT_EQ(ERR_IO_PENDING, rv);
9712 EXPECT_EQ(OK, callback_1.WaitForResult());
9713
9714 // Second round should attempt a tunnel connect and get an auth challenge.
[email protected]49639fa2011-12-20 23:22:419715 TestCompletionCallback callback_2;
[email protected]262eec82013-03-19 21:01:369716 scoped_ptr<HttpTransaction> trans_2(
[email protected]90499482013-06-01 00:39:509717 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419718 rv = trans_2->Start(&request, callback_2.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:309719 EXPECT_EQ(ERR_IO_PENDING, rv);
9720 EXPECT_EQ(OK, callback_2.WaitForResult());
9721 const HttpResponseInfo* response = trans_2->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509722 ASSERT_TRUE(response != NULL);
[email protected]f45c1ee2010-08-03 00:54:309723 ASSERT_FALSE(response->auth_challenge.get() == NULL);
9724
9725 // Restart with auth. Tunnel should work and response received.
[email protected]49639fa2011-12-20 23:22:419726 TestCompletionCallback callback_3;
9727 rv = trans_2->RestartWithAuth(
9728 AuthCredentials(kFoo, kBar), callback_3.callback());
[email protected]f45c1ee2010-08-03 00:54:309729 EXPECT_EQ(ERR_IO_PENDING, rv);
9730 EXPECT_EQ(OK, callback_3.WaitForResult());
9731
9732 // After all that work, these two lines (or actually, just the scheme) are
9733 // what this test is all about. Make sure it happens correctly.
[email protected]f45c1ee2010-08-03 00:54:309734 EXPECT_EQ("https", request_url.scheme());
9735 EXPECT_EQ("www.google.com", request_url.host());
9736
[email protected]029c83b62013-01-24 05:28:209737 LoadTimingInfo load_timing_info;
9738 EXPECT_TRUE(trans_2->GetLoadTimingInfo(&load_timing_info));
9739 TestLoadTimingNotReusedWithPac(load_timing_info,
9740 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]8e6441ca2010-08-19 05:56:389741}
9742
9743// Test that if we cancel the transaction as the connection is completing, that
9744// everything tears down correctly.
[email protected]23e482282013-06-14 16:08:029745TEST_P(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:389746 // Setup everything about the connection to complete synchronously, so that
9747 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
9748 // for is the callback from the HttpStreamRequest.
9749 // Then cancel the transaction.
9750 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:369751 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:389752 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:069753 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
9754 MockRead(SYNCHRONOUS, "hello world"),
9755 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:389756 };
9757
[email protected]8e6441ca2010-08-19 05:56:389758 HttpRequestInfo request;
9759 request.method = "GET";
9760 request.url = GURL("http://www.google.com/");
9761 request.load_flags = 0;
9762
[email protected]bb88e1d32013-05-03 23:11:079763 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]cb9bf6ca2011-01-28 13:15:279764 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:369765 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:079766 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:279767
[email protected]8e6441ca2010-08-19 05:56:389768 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
9769 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079770 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:389771
[email protected]49639fa2011-12-20 23:22:419772 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:389773
[email protected]333bdf62012-06-08 22:57:299774 CapturingBoundNetLog log;
[email protected]49639fa2011-12-20 23:22:419775 int rv = trans->Start(&request, callback.callback(), log.bound());
[email protected]8e6441ca2010-08-19 05:56:389776 EXPECT_EQ(ERR_IO_PENDING, rv);
9777 trans.reset(); // Cancel the transaction here.
9778
[email protected]2da659e2013-05-23 20:51:349779 base::MessageLoop::current()->RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:309780}
9781
[email protected]76a505b2010-08-25 06:23:009782// Test a basic GET request through a proxy.
[email protected]23e482282013-06-14 16:08:029783TEST_P(HttpNetworkTransactionTest, ProxyGet) {
[email protected]bb88e1d32013-05-03 23:11:079784 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:209785 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
[email protected]333bdf62012-06-08 22:57:299786 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:079787 session_deps_.net_log = log.bound().net_log();
9788 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:009789
[email protected]76a505b2010-08-25 06:23:009790 HttpRequestInfo request;
9791 request.method = "GET";
9792 request.url = GURL("http://www.google.com/");
9793
9794 MockWrite data_writes1[] = {
9795 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
9796 "Host: www.google.com\r\n"
9797 "Proxy-Connection: keep-alive\r\n\r\n"),
9798 };
9799
9800 MockRead data_reads1[] = {
9801 MockRead("HTTP/1.1 200 OK\r\n"),
9802 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9803 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069804 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:009805 };
9806
9807 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
9808 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:079809 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:009810
[email protected]49639fa2011-12-20 23:22:419811 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:009812
[email protected]262eec82013-03-19 21:01:369813 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509814 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:509815
[email protected]49639fa2011-12-20 23:22:419816 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:009817 EXPECT_EQ(ERR_IO_PENDING, rv);
9818
9819 rv = callback1.WaitForResult();
9820 EXPECT_EQ(OK, rv);
9821
9822 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509823 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:009824
9825 EXPECT_TRUE(response->headers->IsKeepAlive());
9826 EXPECT_EQ(200, response->headers->response_code());
9827 EXPECT_EQ(100, response->headers->GetContentLength());
9828 EXPECT_TRUE(response->was_fetched_via_proxy);
9829 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:209830
9831 LoadTimingInfo load_timing_info;
9832 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
9833 TestLoadTimingNotReusedWithPac(load_timing_info,
9834 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:009835}
9836
9837// Test a basic HTTPS GET request through a proxy.
[email protected]23e482282013-06-14 16:08:029838TEST_P(HttpNetworkTransactionTest, ProxyTunnelGet) {
[email protected]bb88e1d32013-05-03 23:11:079839 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:209840 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
[email protected]333bdf62012-06-08 22:57:299841 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:079842 session_deps_.net_log = log.bound().net_log();
9843 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:009844
[email protected]76a505b2010-08-25 06:23:009845 HttpRequestInfo request;
9846 request.method = "GET";
9847 request.url = GURL("https://www.google.com/");
9848
9849 // Since we have proxy, should try to establish tunnel.
9850 MockWrite data_writes1[] = {
9851 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
9852 "Host: www.google.com\r\n"
9853 "Proxy-Connection: keep-alive\r\n\r\n"),
9854
9855 MockWrite("GET / HTTP/1.1\r\n"
9856 "Host: www.google.com\r\n"
9857 "Connection: keep-alive\r\n\r\n"),
9858 };
9859
9860 MockRead data_reads1[] = {
9861 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
9862
9863 MockRead("HTTP/1.1 200 OK\r\n"),
9864 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9865 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069866 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:009867 };
9868
9869 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
9870 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:079871 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:069872 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:079873 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:009874
[email protected]49639fa2011-12-20 23:22:419875 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:009876
[email protected]262eec82013-03-19 21:01:369877 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509878 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:509879
[email protected]49639fa2011-12-20 23:22:419880 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:009881 EXPECT_EQ(ERR_IO_PENDING, rv);
9882
9883 rv = callback1.WaitForResult();
9884 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:579885 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:409886 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:009887 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:409888 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:009889 NetLog::PHASE_NONE);
9890 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:409891 entries, pos,
[email protected]76a505b2010-08-25 06:23:009892 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
9893 NetLog::PHASE_NONE);
9894
9895 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509896 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:009897
9898 EXPECT_TRUE(response->headers->IsKeepAlive());
9899 EXPECT_EQ(200, response->headers->response_code());
9900 EXPECT_EQ(100, response->headers->GetContentLength());
9901 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
9902 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]029c83b62013-01-24 05:28:209903
9904 LoadTimingInfo load_timing_info;
9905 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
9906 TestLoadTimingNotReusedWithPac(load_timing_info,
9907 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:009908}
9909
9910// Test a basic HTTPS GET request through a proxy, but the server hangs up
9911// while establishing the tunnel.
[email protected]23e482282013-06-14 16:08:029912TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
[email protected]bb88e1d32013-05-03 23:11:079913 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]333bdf62012-06-08 22:57:299914 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:079915 session_deps_.net_log = log.bound().net_log();
9916 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:009917
[email protected]76a505b2010-08-25 06:23:009918 HttpRequestInfo request;
9919 request.method = "GET";
9920 request.url = GURL("https://www.google.com/");
9921
9922 // Since we have proxy, should try to establish tunnel.
9923 MockWrite data_writes1[] = {
9924 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
9925 "Host: www.google.com\r\n"
9926 "Proxy-Connection: keep-alive\r\n\r\n"),
9927
9928 MockWrite("GET / HTTP/1.1\r\n"
9929 "Host: www.google.com\r\n"
9930 "Connection: keep-alive\r\n\r\n"),
9931 };
9932
9933 MockRead data_reads1[] = {
[email protected]8ddf8322012-02-23 18:08:069934 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:009935 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069936 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:009937 };
9938
9939 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
9940 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:079941 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:069942 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:079943 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:009944
[email protected]49639fa2011-12-20 23:22:419945 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:009946
[email protected]262eec82013-03-19 21:01:369947 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509948 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:509949
[email protected]49639fa2011-12-20 23:22:419950 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:009951 EXPECT_EQ(ERR_IO_PENDING, rv);
9952
9953 rv = callback1.WaitForResult();
9954 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
[email protected]f3da152d2012-06-02 01:00:579955 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:409956 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:009957 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:409958 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:009959 NetLog::PHASE_NONE);
9960 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:409961 entries, pos,
[email protected]76a505b2010-08-25 06:23:009962 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
9963 NetLog::PHASE_NONE);
9964}
9965
[email protected]749eefa82010-09-13 22:14:039966// Test for crbug.com/55424.
[email protected]23e482282013-06-14 16:08:029967TEST_P(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
[email protected]cdf8f7e72013-05-23 10:56:469968 scoped_ptr<SpdyFrame> req(
9969 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
[email protected]749eefa82010-09-13 22:14:039970 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
9971
[email protected]23e482282013-06-14 16:08:029972 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9973 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]749eefa82010-09-13 22:14:039974 MockRead spdy_reads[] = {
9975 CreateMockRead(*resp),
9976 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:069977 MockRead(ASYNC, 0, 0),
[email protected]749eefa82010-09-13 22:14:039978 };
9979
[email protected]dd54bd82012-07-19 23:44:579980 DelayedSocketData spdy_data(
9981 1, // wait for one write to finish before reading.
9982 spdy_reads, arraysize(spdy_reads),
9983 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079984 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:039985
[email protected]8ddf8322012-02-23 18:08:069986 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029987 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:079988 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:039989
[email protected]bb88e1d32013-05-03 23:11:079990 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:039991
9992 // Set up an initial SpdySession in the pool to reuse.
[email protected]02b0c342010-09-25 21:09:389993 HostPortPair host_port_pair("www.google.com", 443);
[email protected]e6d017652013-05-17 18:01:409994 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
9995 kPrivacyModeDisabled);
[email protected]795cbf82013-07-22 09:37:279996 base::WeakPtr<SpdySession> spdy_session =
[email protected]41d64e82013-07-03 22:44:269997 CreateInsecureSpdySession(session, key, BoundNetLog());
[email protected]749eefa82010-09-13 22:14:039998
9999 HttpRequestInfo request;
10000 request.method = "GET";
10001 request.url = GURL("https://www.google.com/");
10002 request.load_flags = 0;
10003
10004 // This is the important line that marks this as a preconnect.
10005 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
10006
[email protected]262eec82013-03-19 21:01:3610007 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010008 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]749eefa82010-09-13 22:14:0310009
[email protected]41d64e82013-07-03 22:44:2610010 TestCompletionCallback callback;
[email protected]49639fa2011-12-20 23:22:4110011 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0310012 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110013 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]749eefa82010-09-13 22:14:0310014}
10015
[email protected]73b8dd222010-11-11 19:55:2410016// Given a net error, cause that error to be returned from the first Write()
10017// call and verify that the HttpTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0210018void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0710019 int error, IoMode mode) {
[email protected]cb9bf6ca2011-01-28 13:15:2710020 net::HttpRequestInfo request_info;
10021 request_info.url = GURL("https://www.example.com/");
10022 request_info.method = "GET";
10023 request_info.load_flags = net::LOAD_NORMAL;
10024
[email protected]8ddf8322012-02-23 18:08:0610025 SSLSocketDataProvider ssl_data(mode, OK);
[email protected]73b8dd222010-11-11 19:55:2410026 net::MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:0610027 net::MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2410028 };
10029 net::StaticSocketDataProvider data(NULL, 0,
10030 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0710031 session_deps_.socket_factory->AddSocketDataProvider(&data);
10032 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2410033
[email protected]bb88e1d32013-05-03 23:11:0710034 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610035 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010036 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]73b8dd222010-11-11 19:55:2410037
[email protected]49639fa2011-12-20 23:22:4110038 TestCompletionCallback callback;
10039 int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
[email protected]73b8dd222010-11-11 19:55:2410040 if (rv == net::ERR_IO_PENDING)
10041 rv = callback.WaitForResult();
10042 ASSERT_EQ(error, rv);
10043}
10044
[email protected]23e482282013-06-14 16:08:0210045TEST_P(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2410046 // Just check a grab bag of cert errors.
10047 static const int kErrors[] = {
10048 ERR_CERT_COMMON_NAME_INVALID,
10049 ERR_CERT_AUTHORITY_INVALID,
10050 ERR_CERT_DATE_INVALID,
10051 };
10052 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0610053 CheckErrorIsPassedBack(kErrors[i], ASYNC);
10054 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2410055 }
10056}
10057
[email protected]bd0b6772011-01-11 19:59:3010058// Ensure that a client certificate is removed from the SSL client auth
10059// cache when:
10060// 1) No proxy is involved.
10061// 2) TLS False Start is disabled.
10062// 3) The initial TLS handshake requests a client certificate.
10063// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0210064TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310065 ClientAuthCertCache_Direct_NoFalseStart) {
[email protected]cb9bf6ca2011-01-28 13:15:2710066 net::HttpRequestInfo request_info;
10067 request_info.url = GURL("https://www.example.com/");
10068 request_info.method = "GET";
10069 request_info.load_flags = net::LOAD_NORMAL;
10070
[email protected]bd0b6772011-01-11 19:59:3010071 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
10072 cert_request->host_and_port = "www.example.com:443";
10073
10074 // [ssl_]data1 contains the data for the first SSL handshake. When a
10075 // CertificateRequest is received for the first time, the handshake will
10076 // be aborted to allow the caller to provide a certificate.
[email protected]8ddf8322012-02-23 18:08:0610077 SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3010078 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710079 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
[email protected]bd0b6772011-01-11 19:59:3010080 net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710081 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3010082
10083 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
10084 // False Start is not being used, the result of the SSL handshake will be
10085 // returned as part of the SSLClientSocket::Connect() call. This test
10086 // matches the result of a server sending a handshake_failure alert,
10087 // rather than a Finished message, because it requires a client
10088 // certificate and none was supplied.
[email protected]8ddf8322012-02-23 18:08:0610089 SSLSocketDataProvider ssl_data2(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3010090 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710091 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
[email protected]bd0b6772011-01-11 19:59:3010092 net::StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710093 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3010094
10095 // [ssl_]data3 contains the data for the third SSL handshake. When a
10096 // connection to a server fails during an SSL handshake,
[email protected]80c75f682012-05-26 16:22:1710097 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
10098 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3010099 // of the HttpNetworkTransaction. Because this test failure is due to
10100 // requiring a client certificate, this fallback handshake should also
10101 // fail.
[email protected]8ddf8322012-02-23 18:08:0610102 SSLSocketDataProvider ssl_data3(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3010103 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710104 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
[email protected]bd0b6772011-01-11 19:59:3010105 net::StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710106 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3010107
[email protected]80c75f682012-05-26 16:22:1710108 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
10109 // connection to a server fails during an SSL handshake,
10110 // HttpNetworkTransaction will attempt to fallback to SSLv3 if the previous
10111 // connection was attempted with TLSv1. This is transparent to the caller
10112 // of the HttpNetworkTransaction. Because this test failure is due to
10113 // requiring a client certificate, this fallback handshake should also
10114 // fail.
10115 SSLSocketDataProvider ssl_data4(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
10116 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710117 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
[email protected]80c75f682012-05-26 16:22:1710118 net::StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710119 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1710120
[email protected]7799de12013-05-30 05:52:5110121 // Need one more if TLSv1.2 is enabled.
10122 SSLSocketDataProvider ssl_data5(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
10123 ssl_data5.cert_request_info = cert_request.get();
10124 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
10125 net::StaticSocketDataProvider data5(NULL, 0, NULL, 0);
10126 session_deps_.socket_factory->AddSocketDataProvider(&data5);
10127
[email protected]bb88e1d32013-05-03 23:11:0710128 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610129 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010130 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3010131
[email protected]bd0b6772011-01-11 19:59:3010132 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4110133 TestCompletionCallback callback;
10134 int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
[email protected]bd0b6772011-01-11 19:59:3010135 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10136
10137 // Complete the SSL handshake, which should abort due to requiring a
10138 // client certificate.
10139 rv = callback.WaitForResult();
10140 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
10141
10142 // Indicate that no certificate should be supplied. From the perspective
10143 // of SSLClientCertCache, NULL is just as meaningful as a real
10144 // certificate, so this is the same as supply a
10145 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4110146 rv = trans->RestartWithCertificate(NULL, callback.callback());
[email protected]bd0b6772011-01-11 19:59:3010147 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10148
10149 // Ensure the certificate was added to the client auth cache before
10150 // allowing the connection to continue restarting.
10151 scoped_refptr<X509Certificate> client_cert;
10152 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
10153 &client_cert));
10154 ASSERT_EQ(NULL, client_cert.get());
10155
10156 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1710157 // then consume ssl_data3 and ssl_data4, both of which should also fail.
10158 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3010159 rv = callback.WaitForResult();
10160 ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
10161
10162 // Ensure that the client certificate is removed from the cache on a
10163 // handshake failure.
10164 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
10165 &client_cert));
10166}
10167
10168// Ensure that a client certificate is removed from the SSL client auth
10169// cache when:
10170// 1) No proxy is involved.
10171// 2) TLS False Start is enabled.
10172// 3) The initial TLS handshake requests a client certificate.
10173// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0210174TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310175 ClientAuthCertCache_Direct_FalseStart) {
[email protected]cb9bf6ca2011-01-28 13:15:2710176 net::HttpRequestInfo request_info;
10177 request_info.url = GURL("https://www.example.com/");
10178 request_info.method = "GET";
10179 request_info.load_flags = net::LOAD_NORMAL;
10180
[email protected]bd0b6772011-01-11 19:59:3010181 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
10182 cert_request->host_and_port = "www.example.com:443";
10183
10184 // When TLS False Start is used, SSLClientSocket::Connect() calls will
10185 // return successfully after reading up to the peer's Certificate message.
10186 // This is to allow the caller to call SSLClientSocket::Write(), which can
10187 // enqueue application data to be sent in the same packet as the
10188 // ChangeCipherSpec and Finished messages.
10189 // The actual handshake will be finished when SSLClientSocket::Read() is
10190 // called, which expects to process the peer's ChangeCipherSpec and
10191 // Finished messages. If there was an error negotiating with the peer,
10192 // such as due to the peer requiring a client certificate when none was
10193 // supplied, the alert sent by the peer won't be processed until Read() is
10194 // called.
10195
10196 // Like the non-False Start case, when a client certificate is requested by
10197 // the peer, the handshake is aborted during the Connect() call.
10198 // [ssl_]data1 represents the initial SSL handshake with the peer.
[email protected]8ddf8322012-02-23 18:08:0610199 SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3010200 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710201 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
[email protected]bd0b6772011-01-11 19:59:3010202 net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710203 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3010204
10205 // When a client certificate is supplied, Connect() will not be aborted
10206 // when the peer requests the certificate. Instead, the handshake will
10207 // artificially succeed, allowing the caller to write the HTTP request to
10208 // the socket. The handshake messages are not processed until Read() is
10209 // called, which then detects that the handshake was aborted, due to the
10210 // peer sending a handshake_failure because it requires a client
10211 // certificate.
[email protected]8ddf8322012-02-23 18:08:0610212 SSLSocketDataProvider ssl_data2(ASYNC, net::OK);
[email protected]bd0b6772011-01-11 19:59:3010213 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710214 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
[email protected]bd0b6772011-01-11 19:59:3010215 net::MockRead data2_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0610216 net::MockRead(ASYNC /* async */, net::ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3010217 };
10218 net::StaticSocketDataProvider data2(
10219 data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710220 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3010221
10222 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1710223 // the data for the SSL handshake once the TLSv1.1 connection falls back to
10224 // TLSv1. It has the same behaviour as [ssl_]data2.
[email protected]8ddf8322012-02-23 18:08:0610225 SSLSocketDataProvider ssl_data3(ASYNC, net::OK);
[email protected]bd0b6772011-01-11 19:59:3010226 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710227 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
[email protected]bd0b6772011-01-11 19:59:3010228 net::StaticSocketDataProvider data3(
10229 data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710230 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3010231
[email protected]80c75f682012-05-26 16:22:1710232 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
10233 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
10234 SSLSocketDataProvider ssl_data4(ASYNC, net::OK);
10235 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710236 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
[email protected]80c75f682012-05-26 16:22:1710237 net::StaticSocketDataProvider data4(
10238 data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710239 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1710240
[email protected]7799de12013-05-30 05:52:5110241 // Need one more if TLSv1.2 is enabled.
10242 SSLSocketDataProvider ssl_data5(ASYNC, net::OK);
10243 ssl_data5.cert_request_info = cert_request.get();
10244 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
10245 net::StaticSocketDataProvider data5(
10246 data2_reads, arraysize(data2_reads), NULL, 0);
10247 session_deps_.socket_factory->AddSocketDataProvider(&data5);
10248
[email protected]bb88e1d32013-05-03 23:11:0710249 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610250 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010251 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3010252
[email protected]bd0b6772011-01-11 19:59:3010253 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4110254 TestCompletionCallback callback;
10255 int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
[email protected]bd0b6772011-01-11 19:59:3010256 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10257
10258 // Complete the SSL handshake, which should abort due to requiring a
10259 // client certificate.
10260 rv = callback.WaitForResult();
10261 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
10262
10263 // Indicate that no certificate should be supplied. From the perspective
10264 // of SSLClientCertCache, NULL is just as meaningful as a real
10265 // certificate, so this is the same as supply a
10266 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4110267 rv = trans->RestartWithCertificate(NULL, callback.callback());
[email protected]bd0b6772011-01-11 19:59:3010268 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10269
10270 // Ensure the certificate was added to the client auth cache before
10271 // allowing the connection to continue restarting.
10272 scoped_refptr<X509Certificate> client_cert;
10273 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
10274 &client_cert));
10275 ASSERT_EQ(NULL, client_cert.get());
10276
[email protected]bd0b6772011-01-11 19:59:3010277 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1710278 // then consume ssl_data3 and ssl_data4, both of which should also fail.
10279 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3010280 rv = callback.WaitForResult();
10281 ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
10282
10283 // Ensure that the client certificate is removed from the cache on a
10284 // handshake failure.
10285 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
10286 &client_cert));
10287}
10288
[email protected]8c405132011-01-11 22:03:1810289// Ensure that a client certificate is removed from the SSL client auth
10290// cache when:
10291// 1) An HTTPS proxy is involved.
10292// 3) The HTTPS proxy requests a client certificate.
10293// 4) The client supplies an invalid/unacceptable certificate for the
10294// proxy.
10295// The test is repeated twice, first for connecting to an HTTPS endpoint,
10296// then for connecting to an HTTP endpoint.
[email protected]23e482282013-06-14 16:08:0210297TEST_P(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
[email protected]bb88e1d32013-05-03 23:11:0710298 session_deps_.proxy_service.reset(
[email protected]8c405132011-01-11 22:03:1810299 ProxyService::CreateFixed("https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:2910300 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710301 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1810302
10303 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
10304 cert_request->host_and_port = "proxy:70";
10305
10306 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
10307 // [ssl_]data[1-3]. Rather than represending the endpoint
10308 // (www.example.com:443), they represent failures with the HTTPS proxy
10309 // (proxy:70).
[email protected]8ddf8322012-02-23 18:08:0610310 SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1810311 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710312 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
[email protected]8c405132011-01-11 22:03:1810313 net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710314 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1810315
[email protected]8ddf8322012-02-23 18:08:0610316 SSLSocketDataProvider ssl_data2(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1810317 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710318 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
[email protected]8c405132011-01-11 22:03:1810319 net::StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710320 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1810321
[email protected]80c75f682012-05-26 16:22:1710322 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
10323#if 0
[email protected]8ddf8322012-02-23 18:08:0610324 SSLSocketDataProvider ssl_data3(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1810325 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710326 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
[email protected]8c405132011-01-11 22:03:1810327 net::StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710328 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1710329#endif
[email protected]8c405132011-01-11 22:03:1810330
10331 net::HttpRequestInfo requests[2];
10332 requests[0].url = GURL("https://www.example.com/");
10333 requests[0].method = "GET";
10334 requests[0].load_flags = net::LOAD_NORMAL;
10335
10336 requests[1].url = GURL("http://www.example.com/");
10337 requests[1].method = "GET";
10338 requests[1].load_flags = net::LOAD_NORMAL;
10339
10340 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0710341 session_deps_.socket_factory->ResetNextMockIndexes();
10342 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c405132011-01-11 22:03:1810343 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5010344 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c405132011-01-11 22:03:1810345
10346 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4110347 TestCompletionCallback callback;
10348 int rv = trans->Start(
10349 &requests[i], callback.callback(), net::BoundNetLog());
[email protected]8c405132011-01-11 22:03:1810350 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10351
10352 // Complete the SSL handshake, which should abort due to requiring a
10353 // client certificate.
10354 rv = callback.WaitForResult();
10355 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
10356
10357 // Indicate that no certificate should be supplied. From the perspective
10358 // of SSLClientCertCache, NULL is just as meaningful as a real
10359 // certificate, so this is the same as supply a
10360 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4110361 rv = trans->RestartWithCertificate(NULL, callback.callback());
[email protected]8c405132011-01-11 22:03:1810362 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10363
10364 // Ensure the certificate was added to the client auth cache before
10365 // allowing the connection to continue restarting.
10366 scoped_refptr<X509Certificate> client_cert;
10367 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup("proxy:70",
10368 &client_cert));
10369 ASSERT_EQ(NULL, client_cert.get());
10370 // Ensure the certificate was NOT cached for the endpoint. This only
10371 // applies to HTTPS requests, but is fine to check for HTTP requests.
10372 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
10373 &client_cert));
10374
10375 // Restart the handshake. This will consume ssl_data2, which fails, and
10376 // then consume ssl_data3, which should also fail. The result code is
10377 // checked against what ssl_data3 should return.
10378 rv = callback.WaitForResult();
10379 ASSERT_EQ(net::ERR_PROXY_CONNECTION_FAILED, rv);
10380
10381 // Now that the new handshake has failed, ensure that the client
10382 // certificate was removed from the client auth cache.
10383 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("proxy:70",
10384 &client_cert));
10385 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
10386 &client_cert));
10387 }
10388}
10389
[email protected]23e482282013-06-14 16:08:0210390// Unlike TEST/TEST_F, which are macros that expand to further macros,
10391// TEST_P is a macro that expands directly to code that stringizes the
10392// arguments. As a result, macros passed as parameters (such as prefix
10393// or test_case_name) will not be expanded by the preprocessor. To
10394// work around this, indirect the macro for TEST_P, so that the
10395// pre-processor will expand macros such as MAYBE_test_name before
10396// instantiating the test.
10397#define WRAPPED_TEST_P(test_case_name, test_name) \
10398 TEST_P(test_case_name, test_name)
10399
[email protected]45b170822012-05-04 21:18:1410400// Times out on Win7 dbg(2) bot. http://crbug.com/124776
10401#if defined(OS_WIN)
10402#define MAYBE_UseIPConnectionPooling DISABLED_UseIPConnectionPooling
10403#else
10404#define MAYBE_UseIPConnectionPooling UseIPConnectionPooling
10405#endif
[email protected]23e482282013-06-14 16:08:0210406WRAPPED_TEST_P(HttpNetworkTransactionTest, MAYBE_UseIPConnectionPooling) {
[email protected]e3ceb682011-06-28 23:55:4610407 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:0310408 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]e3ceb682011-06-28 23:55:4610409
10410 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0710411 session_deps_.host_resolver.reset(new MockCachingHostResolver());
10412 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2610413 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
10414 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4610415
[email protected]8ddf8322012-02-23 18:08:0610416 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210417 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710418 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4610419
[email protected]cdf8f7e72013-05-23 10:56:4610420 scoped_ptr<SpdyFrame> host1_req(
10421 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
10422 scoped_ptr<SpdyFrame> host2_req(
10423 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4610424 MockWrite spdy_writes[] = {
10425 CreateMockWrite(*host1_req, 1),
10426 CreateMockWrite(*host2_req, 4),
10427 };
[email protected]23e482282013-06-14 16:08:0210428 scoped_ptr<SpdyFrame> host1_resp(
10429 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10430 scoped_ptr<SpdyFrame> host1_resp_body(
10431 spdy_util_.ConstructSpdyBodyFrame(1, true));
10432 scoped_ptr<SpdyFrame> host2_resp(
10433 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
10434 scoped_ptr<SpdyFrame> host2_resp_body(
10435 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4610436 MockRead spdy_reads[] = {
10437 CreateMockRead(*host1_resp, 2),
10438 CreateMockRead(*host1_resp_body, 3),
10439 CreateMockRead(*host2_resp, 5),
10440 CreateMockRead(*host2_resp_body, 6),
[email protected]8ddf8322012-02-23 18:08:0610441 MockRead(ASYNC, 0, 7),
[email protected]e3ceb682011-06-28 23:55:4610442 };
10443
[email protected]d2b5f092012-06-08 23:55:0210444 IPAddressNumber ip;
10445 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
10446 IPEndPoint peer_addr = IPEndPoint(ip, 443);
10447 MockConnect connect(ASYNC, OK, peer_addr);
[email protected]dd54bd82012-07-19 23:44:5710448 OrderedSocketData spdy_data(
10449 connect,
10450 spdy_reads, arraysize(spdy_reads),
10451 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710452 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4610453
[email protected]aa22b242011-11-16 18:58:2910454 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4610455 HttpRequestInfo request1;
10456 request1.method = "GET";
10457 request1.url = GURL("https://www.google.com/");
10458 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010459 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4610460
[email protected]49639fa2011-12-20 23:22:4110461 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4610462 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110463 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4610464
10465 const HttpResponseInfo* response = trans1.GetResponseInfo();
10466 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010467 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4610468 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10469
10470 std::string response_data;
10471 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
10472 EXPECT_EQ("hello!", response_data);
10473
10474 // Preload www.gmail.com into HostCache.
10475 HostPortPair host_port("www.gmail.com", 443);
10476 HostResolver::RequestInfo resolve_info(host_port);
10477 AddressList ignored;
[email protected]bb88e1d32013-05-03 23:11:0710478 rv = session_deps_.host_resolver->Resolve(resolve_info, &ignored,
[email protected]c6bf8152012-12-02 07:43:3410479 callback.callback(), NULL,
10480 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4710481 EXPECT_EQ(ERR_IO_PENDING, rv);
10482 rv = callback.WaitForResult();
10483 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4610484
10485 HttpRequestInfo request2;
10486 request2.method = "GET";
10487 request2.url = GURL("https://www.gmail.com/");
10488 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010489 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4610490
[email protected]49639fa2011-12-20 23:22:4110491 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4610492 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110493 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4610494
10495 response = trans2.GetResponseInfo();
10496 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010497 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4610498 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10499 EXPECT_TRUE(response->was_fetched_via_spdy);
10500 EXPECT_TRUE(response->was_npn_negotiated);
10501 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
10502 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4610503}
[email protected]45b170822012-05-04 21:18:1410504#undef MAYBE_UseIPConnectionPooling
[email protected]e3ceb682011-06-28 23:55:4610505
[email protected]23e482282013-06-14 16:08:0210506TEST_P(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d2b5f092012-06-08 23:55:0210507 HttpStreamFactory::set_use_alternate_protocols(true);
10508 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
10509
10510 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0710511 session_deps_.host_resolver.reset(new MockCachingHostResolver());
10512 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0210513 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
10514 pool_peer.DisableDomainAuthenticationVerification();
10515
10516 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210517 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710518 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]d2b5f092012-06-08 23:55:0210519
[email protected]cdf8f7e72013-05-23 10:56:4610520 scoped_ptr<SpdyFrame> host1_req(
10521 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
10522 scoped_ptr<SpdyFrame> host2_req(
10523 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0210524 MockWrite spdy_writes[] = {
10525 CreateMockWrite(*host1_req, 1),
10526 CreateMockWrite(*host2_req, 4),
10527 };
[email protected]23e482282013-06-14 16:08:0210528 scoped_ptr<SpdyFrame> host1_resp(
10529 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10530 scoped_ptr<SpdyFrame> host1_resp_body(
10531 spdy_util_.ConstructSpdyBodyFrame(1, true));
10532 scoped_ptr<SpdyFrame> host2_resp(
10533 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
10534 scoped_ptr<SpdyFrame> host2_resp_body(
10535 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0210536 MockRead spdy_reads[] = {
10537 CreateMockRead(*host1_resp, 2),
10538 CreateMockRead(*host1_resp_body, 3),
10539 CreateMockRead(*host2_resp, 5),
10540 CreateMockRead(*host2_resp_body, 6),
10541 MockRead(ASYNC, 0, 7),
10542 };
10543
10544 IPAddressNumber ip;
10545 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
10546 IPEndPoint peer_addr = IPEndPoint(ip, 443);
10547 MockConnect connect(ASYNC, OK, peer_addr);
[email protected]dd54bd82012-07-19 23:44:5710548 OrderedSocketData spdy_data(
10549 connect,
10550 spdy_reads, arraysize(spdy_reads),
10551 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710552 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0210553
10554 TestCompletionCallback callback;
10555 HttpRequestInfo request1;
10556 request1.method = "GET";
10557 request1.url = GURL("https://www.google.com/");
10558 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010559 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0210560
10561 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
10562 EXPECT_EQ(ERR_IO_PENDING, rv);
10563 EXPECT_EQ(OK, callback.WaitForResult());
10564
10565 const HttpResponseInfo* response = trans1.GetResponseInfo();
10566 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010567 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d2b5f092012-06-08 23:55:0210568 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10569
10570 std::string response_data;
10571 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
10572 EXPECT_EQ("hello!", response_data);
10573
10574 HttpRequestInfo request2;
10575 request2.method = "GET";
10576 request2.url = GURL("https://www.gmail.com/");
10577 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010578 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0210579
10580 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
10581 EXPECT_EQ(ERR_IO_PENDING, rv);
10582 EXPECT_EQ(OK, callback.WaitForResult());
10583
10584 response = trans2.GetResponseInfo();
10585 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010586 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d2b5f092012-06-08 23:55:0210587 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10588 EXPECT_TRUE(response->was_fetched_via_spdy);
10589 EXPECT_TRUE(response->was_npn_negotiated);
10590 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
10591 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0210592}
10593
[email protected]e3ceb682011-06-28 23:55:4610594class OneTimeCachingHostResolver : public net::HostResolver {
10595 public:
10596 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
10597 : host_port_(host_port) {}
10598 virtual ~OneTimeCachingHostResolver() {}
10599
10600 RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); }
10601
10602 // HostResolver methods:
10603 virtual int Resolve(const RequestInfo& info,
10604 AddressList* addresses,
[email protected]aa22b242011-11-16 18:58:2910605 const CompletionCallback& callback,
[email protected]e3ceb682011-06-28 23:55:4610606 RequestHandle* out_req,
[email protected]95a214c2011-08-04 21:50:4010607 const BoundNetLog& net_log) OVERRIDE {
10608 return host_resolver_.Resolve(
[email protected]e3ceb682011-06-28 23:55:4610609 info, addresses, callback, out_req, net_log);
[email protected]95a214c2011-08-04 21:50:4010610 }
10611
10612 virtual int ResolveFromCache(const RequestInfo& info,
10613 AddressList* addresses,
10614 const BoundNetLog& net_log) OVERRIDE {
10615 int rv = host_resolver_.ResolveFromCache(info, addresses, net_log);
10616 if (rv == OK && info.host_port_pair().Equals(host_port_))
[email protected]98e1cd012011-11-08 15:33:0910617 host_resolver_.GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4610618 return rv;
10619 }
10620
[email protected]95a214c2011-08-04 21:50:4010621 virtual void CancelRequest(RequestHandle req) OVERRIDE {
[email protected]e3ceb682011-06-28 23:55:4610622 host_resolver_.CancelRequest(req);
10623 }
10624
[email protected]46da33be2011-07-19 21:58:0410625 MockCachingHostResolver* GetMockHostResolver() {
10626 return &host_resolver_;
10627 }
10628
[email protected]e3ceb682011-06-28 23:55:4610629 private:
10630 MockCachingHostResolver host_resolver_;
10631 const HostPortPair host_port_;
10632};
10633
[email protected]45b170822012-05-04 21:18:1410634// Times out on Win7 dbg(2) bot. http://crbug.com/124776
10635#if defined(OS_WIN)
[email protected]bb88e1d32013-05-03 23:11:0710636#define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \
10637 DISABLED_UseIPConnectionPoolingWithHostCacheExpiration
[email protected]45b170822012-05-04 21:18:1410638#else
[email protected]bb88e1d32013-05-03 23:11:0710639#define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \
10640 UseIPConnectionPoolingWithHostCacheExpiration
[email protected]45b170822012-05-04 21:18:1410641#endif
[email protected]23e482282013-06-14 16:08:0210642WRAPPED_TEST_P(HttpNetworkTransactionTest,
10643 MAYBE_UseIPConnectionPoolingWithHostCacheExpiration) {
[email protected]23e482282013-06-14 16:08:0210644// Times out on Win7 dbg(2) bot. http://crbug.com/124776 . (MAYBE_
10645// prefix doesn't work with parametrized tests).
10646#if defined(OS_WIN)
10647 return;
10648#endif
10649
[email protected]e3ceb682011-06-28 23:55:4610650 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:0310651 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]e3ceb682011-06-28 23:55:4610652
10653 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
[email protected]e3ceb682011-06-28 23:55:4610654 OneTimeCachingHostResolver host_resolver(HostPortPair("www.gmail.com", 443));
[email protected]c6bf8152012-12-02 07:43:3410655 HttpNetworkSession::Params params =
[email protected]bb88e1d32013-05-03 23:11:0710656 SpdySessionDependencies::CreateSessionParams(&session_deps_);
[email protected]e3ceb682011-06-28 23:55:4610657 params.host_resolver = &host_resolver;
[email protected]bb88e1d32013-05-03 23:11:0710658 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2610659 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
10660 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4610661
[email protected]8ddf8322012-02-23 18:08:0610662 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210663 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710664 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4610665
[email protected]cdf8f7e72013-05-23 10:56:4610666 scoped_ptr<SpdyFrame> host1_req(
10667 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
10668 scoped_ptr<SpdyFrame> host2_req(
10669 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4610670 MockWrite spdy_writes[] = {
10671 CreateMockWrite(*host1_req, 1),
10672 CreateMockWrite(*host2_req, 4),
10673 };
[email protected]23e482282013-06-14 16:08:0210674 scoped_ptr<SpdyFrame> host1_resp(
10675 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10676 scoped_ptr<SpdyFrame> host1_resp_body(
10677 spdy_util_.ConstructSpdyBodyFrame(1, true));
10678 scoped_ptr<SpdyFrame> host2_resp(
10679 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
10680 scoped_ptr<SpdyFrame> host2_resp_body(
10681 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4610682 MockRead spdy_reads[] = {
10683 CreateMockRead(*host1_resp, 2),
10684 CreateMockRead(*host1_resp_body, 3),
10685 CreateMockRead(*host2_resp, 5),
10686 CreateMockRead(*host2_resp_body, 6),
[email protected]8ddf8322012-02-23 18:08:0610687 MockRead(ASYNC, 0, 7),
[email protected]e3ceb682011-06-28 23:55:4610688 };
10689
[email protected]d2b5f092012-06-08 23:55:0210690 IPAddressNumber ip;
10691 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
10692 IPEndPoint peer_addr = IPEndPoint(ip, 443);
10693 MockConnect connect(ASYNC, OK, peer_addr);
[email protected]dd54bd82012-07-19 23:44:5710694 OrderedSocketData spdy_data(
10695 connect,
10696 spdy_reads, arraysize(spdy_reads),
10697 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710698 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4610699
[email protected]aa22b242011-11-16 18:58:2910700 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4610701 HttpRequestInfo request1;
10702 request1.method = "GET";
10703 request1.url = GURL("https://www.google.com/");
10704 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010705 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4610706
[email protected]49639fa2011-12-20 23:22:4110707 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4610708 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110709 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4610710
10711 const HttpResponseInfo* response = trans1.GetResponseInfo();
10712 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010713 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4610714 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10715
10716 std::string response_data;
10717 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
10718 EXPECT_EQ("hello!", response_data);
10719
10720 // Preload cache entries into HostCache.
10721 HostResolver::RequestInfo resolve_info(HostPortPair("www.gmail.com", 443));
10722 AddressList ignored;
[email protected]c6bf8152012-12-02 07:43:3410723 rv = host_resolver.Resolve(resolve_info, &ignored, callback.callback(),
10724 NULL, BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4710725 EXPECT_EQ(ERR_IO_PENDING, rv);
10726 rv = callback.WaitForResult();
10727 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4610728
10729 HttpRequestInfo request2;
10730 request2.method = "GET";
10731 request2.url = GURL("https://www.gmail.com/");
10732 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010733 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4610734
[email protected]49639fa2011-12-20 23:22:4110735 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4610736 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110737 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4610738
10739 response = trans2.GetResponseInfo();
10740 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010741 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4610742 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10743 EXPECT_TRUE(response->was_fetched_via_spdy);
10744 EXPECT_TRUE(response->was_npn_negotiated);
10745 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
10746 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4610747}
[email protected]45b170822012-05-04 21:18:1410748#undef MAYBE_UseIPConnectionPoolingWithHostCacheExpiration
[email protected]e3ceb682011-06-28 23:55:4610749
[email protected]23e482282013-06-14 16:08:0210750TEST_P(HttpNetworkTransactionTest, ReadPipelineEvictionFallback) {
[email protected]5a60c8b2011-10-19 20:14:2910751 MockRead data_reads1[] = {
[email protected]8ddf8322012-02-23 18:08:0610752 MockRead(SYNCHRONOUS, ERR_PIPELINE_EVICTION),
[email protected]5a60c8b2011-10-19 20:14:2910753 };
10754 MockRead data_reads2[] = {
10755 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
10756 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610757 MockRead(SYNCHRONOUS, OK),
[email protected]5a60c8b2011-10-19 20:14:2910758 };
10759 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), NULL, 0);
10760 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), NULL, 0);
10761 StaticSocketDataProvider* data[] = { &data1, &data2 };
10762
10763 SimpleGetHelperResult out = SimpleGetHelperForData(data, arraysize(data));
10764
10765 EXPECT_EQ(OK, out.rv);
10766 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
10767 EXPECT_EQ("hello world", out.response_data);
10768}
10769
[email protected]23e482282013-06-14 16:08:0210770TEST_P(HttpNetworkTransactionTest, SendPipelineEvictionFallback) {
[email protected]5a60c8b2011-10-19 20:14:2910771 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:0610772 MockWrite(SYNCHRONOUS, ERR_PIPELINE_EVICTION),
[email protected]5a60c8b2011-10-19 20:14:2910773 };
10774 MockWrite data_writes2[] = {
10775 MockWrite("GET / HTTP/1.1\r\n"
10776 "Host: www.google.com\r\n"
10777 "Connection: keep-alive\r\n\r\n"),
10778 };
10779 MockRead data_reads2[] = {
10780 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
10781 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610782 MockRead(SYNCHRONOUS, OK),
[email protected]5a60c8b2011-10-19 20:14:2910783 };
10784 StaticSocketDataProvider data1(NULL, 0,
10785 data_writes1, arraysize(data_writes1));
10786 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
10787 data_writes2, arraysize(data_writes2));
10788 StaticSocketDataProvider* data[] = { &data1, &data2 };
10789
10790 SimpleGetHelperResult out = SimpleGetHelperForData(data, arraysize(data));
10791
10792 EXPECT_EQ(OK, out.rv);
10793 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
10794 EXPECT_EQ("hello world", out.response_data);
10795}
10796
[email protected]23e482282013-06-14 16:08:0210797TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
[email protected]8450d722012-07-02 19:14:0410798 const std::string https_url = "https://www.google.com/";
10799 const std::string http_url = "http://www.google.com:443/";
10800
10801 // SPDY GET for HTTPS URL
[email protected]cdf8f7e72013-05-23 10:56:4610802 scoped_ptr<SpdyFrame> req1(
10803 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0410804
10805 MockWrite writes1[] = {
10806 CreateMockWrite(*req1, 0),
10807 };
10808
[email protected]23e482282013-06-14 16:08:0210809 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10810 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8450d722012-07-02 19:14:0410811 MockRead reads1[] = {
10812 CreateMockRead(*resp1, 1),
10813 CreateMockRead(*body1, 2),
10814 MockRead(ASYNC, ERR_IO_PENDING, 3)
10815 };
10816
[email protected]dd54bd82012-07-19 23:44:5710817 DelayedSocketData data1(
10818 1, reads1, arraysize(reads1),
10819 writes1, arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0410820 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5710821 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0410822
10823 // HTTP GET for the HTTP URL
10824 MockWrite writes2[] = {
10825 MockWrite(ASYNC, 4,
10826 "GET / HTTP/1.1\r\n"
10827 "Host: www.google.com:443\r\n"
10828 "Connection: keep-alive\r\n\r\n"),
10829 };
10830
10831 MockRead reads2[] = {
10832 MockRead(ASYNC, 5, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
10833 MockRead(ASYNC, 6, "hello"),
10834 MockRead(ASYNC, 7, OK),
10835 };
10836
[email protected]dd54bd82012-07-19 23:44:5710837 DelayedSocketData data2(
10838 1, reads2, arraysize(reads2),
10839 writes2, arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0410840
[email protected]8450d722012-07-02 19:14:0410841 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210842 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710843 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10844 session_deps_.socket_factory->AddSocketDataProvider(&data1);
10845 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0410846
[email protected]bb88e1d32013-05-03 23:11:0710847 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0410848
10849 // Start the first transaction to set up the SpdySession
10850 HttpRequestInfo request1;
10851 request1.method = "GET";
10852 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0410853 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010854 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0410855 TestCompletionCallback callback1;
10856 EXPECT_EQ(ERR_IO_PENDING,
10857 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3410858 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0410859
10860 EXPECT_EQ(OK, callback1.WaitForResult());
10861 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
10862
10863 // Now, start the HTTP request
10864 HttpRequestInfo request2;
10865 request2.method = "GET";
10866 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0410867 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010868 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0410869 TestCompletionCallback callback2;
10870 EXPECT_EQ(ERR_IO_PENDING,
10871 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3410872 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0410873
10874 EXPECT_EQ(OK, callback2.WaitForResult());
10875 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
10876}
10877
[email protected]23e482282013-06-14 16:08:0210878TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
[email protected]8450d722012-07-02 19:14:0410879 const std::string https_url = "https://www.google.com/";
10880 const std::string http_url = "http://www.google.com:443/";
10881
10882 // SPDY GET for HTTPS URL (through CONNECT tunnel)
[email protected]fba2dbde2013-05-24 16:09:0110883 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1));
[email protected]cdf8f7e72013-05-23 10:56:4610884 scoped_ptr<SpdyFrame> req1(
10885 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0410886
10887 // SPDY GET for HTTP URL (through the proxy, but not the tunnel)
[email protected]23e482282013-06-14 16:08:0210888 scoped_ptr<SpdyFrame> wrapped_req1(
10889 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]8450d722012-07-02 19:14:0410890 const char* const headers[] = {
[email protected]23e482282013-06-14 16:08:0210891 spdy_util_.GetMethodKey(), "GET",
10892 spdy_util_.GetPathKey(), spdy_util_.is_spdy2() ? http_url.c_str() : "/",
10893 spdy_util_.GetHostKey(), "www.google.com:443",
10894 spdy_util_.GetSchemeKey(), "http",
10895 spdy_util_.GetVersionKey(), "HTTP/1.1"
[email protected]8450d722012-07-02 19:14:0410896 };
[email protected]4bd46222013-05-14 19:32:2310897 scoped_ptr<SpdyFrame> req2(spdy_util_.ConstructSpdyControlFrame(
10898 NULL, 0, false, 3, MEDIUM, SYN_STREAM, CONTROL_FLAG_FIN,
10899 headers, arraysize(headers), 0));
[email protected]8450d722012-07-02 19:14:0410900
10901 MockWrite writes1[] = {
10902 CreateMockWrite(*connect, 0),
10903 CreateMockWrite(*wrapped_req1, 2),
10904 CreateMockWrite(*req2, 5),
10905 };
10906
[email protected]23e482282013-06-14 16:08:0210907 scoped_ptr<SpdyFrame> conn_resp(
10908 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10909 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10910 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
10911 scoped_ptr<SpdyFrame> wrapped_resp1(
10912 spdy_util_.ConstructWrappedSpdyFrame(resp1, 1));
10913 scoped_ptr<SpdyFrame> wrapped_body1(
10914 spdy_util_.ConstructWrappedSpdyFrame(body1, 1));
10915 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
10916 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]8450d722012-07-02 19:14:0410917 MockRead reads1[] = {
10918 CreateMockRead(*conn_resp, 1),
10919 CreateMockRead(*wrapped_resp1, 3),
10920 CreateMockRead(*wrapped_body1, 4),
10921 CreateMockRead(*resp2, 6),
10922 CreateMockRead(*body2, 7),
10923 MockRead(ASYNC, ERR_IO_PENDING, 8)
10924 };
10925
[email protected]dd54bd82012-07-19 23:44:5710926 DeterministicSocketData data1(reads1, arraysize(reads1),
10927 writes1, arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0410928 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5710929 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0410930
[email protected]bb88e1d32013-05-03 23:11:0710931 session_deps_.proxy_service.reset(
[email protected]f6c63db52013-02-02 00:35:2210932 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
10933 CapturingNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710934 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0410935 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
[email protected]23e482282013-06-14 16:08:0210936 ssl1.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710937 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0410938 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
[email protected]23e482282013-06-14 16:08:0210939 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710940 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
10941 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0410942
10943 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0710944 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]8450d722012-07-02 19:14:0410945
10946 // Start the first transaction to set up the SpdySession
10947 HttpRequestInfo request1;
10948 request1.method = "GET";
10949 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0410950 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010951 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0410952 TestCompletionCallback callback1;
10953 EXPECT_EQ(ERR_IO_PENDING,
10954 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3410955 base::MessageLoop::current()->RunUntilIdle();
[email protected]dd54bd82012-07-19 23:44:5710956 data1.RunFor(4);
[email protected]8450d722012-07-02 19:14:0410957
10958 EXPECT_EQ(OK, callback1.WaitForResult());
10959 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
10960
[email protected]f6c63db52013-02-02 00:35:2210961 LoadTimingInfo load_timing_info1;
10962 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
10963 TestLoadTimingNotReusedWithPac(load_timing_info1,
10964 CONNECT_TIMING_HAS_SSL_TIMES);
10965
[email protected]8450d722012-07-02 19:14:0410966 // Now, start the HTTP request
10967 HttpRequestInfo request2;
10968 request2.method = "GET";
10969 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0410970 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010971 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0410972 TestCompletionCallback callback2;
10973 EXPECT_EQ(ERR_IO_PENDING,
10974 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3410975 base::MessageLoop::current()->RunUntilIdle();
[email protected]dd54bd82012-07-19 23:44:5710976 data1.RunFor(3);
[email protected]8450d722012-07-02 19:14:0410977
10978 EXPECT_EQ(OK, callback2.WaitForResult());
10979 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2210980
10981 LoadTimingInfo load_timing_info2;
10982 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
10983 // The established SPDY sessions is considered reused by the HTTP request.
10984 TestLoadTimingReusedWithPac(load_timing_info2);
10985 // HTTP requests over a SPDY session should have a different connection
10986 // socket_log_id than requests over a tunnel.
10987 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0410988}
10989
[email protected]23e482282013-06-14 16:08:0210990TEST_P(HttpNetworkTransactionTest, UseSpdySessionForHttpWhenForced) {
[email protected]8450d722012-07-02 19:14:0410991 HttpStreamFactory::set_force_spdy_always(true);
10992 const std::string https_url = "https://www.google.com/";
10993 const std::string http_url = "http://www.google.com:443/";
10994
10995 // SPDY GET for HTTPS URL
[email protected]cdf8f7e72013-05-23 10:56:4610996 scoped_ptr<SpdyFrame> req1(
10997 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0410998 // SPDY GET for the HTTP URL
[email protected]cdf8f7e72013-05-23 10:56:4610999 scoped_ptr<SpdyFrame> req2(
11000 spdy_util_.ConstructSpdyGet(http_url.c_str(), false, 3, MEDIUM));
[email protected]8450d722012-07-02 19:14:0411001
11002 MockWrite writes[] = {
11003 CreateMockWrite(*req1, 1),
11004 CreateMockWrite(*req2, 4),
11005 };
11006
[email protected]23e482282013-06-14 16:08:0211007 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11008 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
11009 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11010 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]8450d722012-07-02 19:14:0411011 MockRead reads[] = {
11012 CreateMockRead(*resp1, 2),
11013 CreateMockRead(*body1, 3),
11014 CreateMockRead(*resp2, 5),
11015 CreateMockRead(*body2, 6),
11016 MockRead(ASYNC, ERR_IO_PENDING, 7)
11017 };
11018
[email protected]dd54bd82012-07-19 23:44:5711019 OrderedSocketData data(reads, arraysize(reads),
11020 writes, arraysize(writes));
[email protected]8450d722012-07-02 19:14:0411021
[email protected]8450d722012-07-02 19:14:0411022 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211023 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711024 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11025 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8450d722012-07-02 19:14:0411026
[email protected]bb88e1d32013-05-03 23:11:0711027 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0411028
11029 // Start the first transaction to set up the SpdySession
11030 HttpRequestInfo request1;
11031 request1.method = "GET";
11032 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0411033 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011034 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0411035 TestCompletionCallback callback1;
11036 EXPECT_EQ(ERR_IO_PENDING,
11037 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411038 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411039
11040 EXPECT_EQ(OK, callback1.WaitForResult());
11041 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11042
11043 // Now, start the HTTP request
11044 HttpRequestInfo request2;
11045 request2.method = "GET";
11046 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0411047 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011048 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0411049 TestCompletionCallback callback2;
11050 EXPECT_EQ(ERR_IO_PENDING,
11051 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411052 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411053
11054 EXPECT_EQ(OK, callback2.WaitForResult());
11055 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11056}
11057
[email protected]2d88e7d2012-07-19 17:55:1711058// Test that in the case where we have a SPDY session to a SPDY proxy
11059// that we do not pool other origins that resolve to the same IP when
11060// the certificate does not match the new origin.
11061// http://crbug.com/134690
[email protected]23e482282013-06-14 16:08:0211062TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
[email protected]2d88e7d2012-07-19 17:55:1711063 const std::string url1 = "http://www.google.com/";
11064 const std::string url2 = "https://mail.google.com/";
11065 const std::string ip_addr = "1.2.3.4";
11066
11067 // SPDY GET for HTTP URL (through SPDY proxy)
[email protected]23e482282013-06-14 16:08:0211068 scoped_ptr<SpdyHeaderBlock> headers(
11069 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/"));
[email protected]4bd46222013-05-14 19:32:2311070 scoped_ptr<SpdyFrame> req1(spdy_util_.ConstructSpdyControlFrame(
[email protected]23e482282013-06-14 16:08:0211071 headers.Pass(), false, 1, LOWEST, SYN_STREAM, CONTROL_FLAG_FIN, 0));
[email protected]2d88e7d2012-07-19 17:55:1711072
11073 MockWrite writes1[] = {
11074 CreateMockWrite(*req1, 0),
11075 };
11076
[email protected]23e482282013-06-14 16:08:0211077 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11078 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1711079 MockRead reads1[] = {
11080 CreateMockRead(*resp1, 1),
11081 CreateMockRead(*body1, 2),
11082 MockRead(ASYNC, OK, 3) // EOF
11083 };
11084
11085 scoped_ptr<DeterministicSocketData> data1(
11086 new DeterministicSocketData(reads1, arraysize(reads1),
11087 writes1, arraysize(writes1)));
11088 IPAddressNumber ip;
11089 ASSERT_TRUE(ParseIPLiteralToNumber(ip_addr, &ip));
11090 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11091 MockConnect connect_data1(ASYNC, OK, peer_addr);
11092 data1->set_connect_data(connect_data1);
11093
11094 // SPDY GET for HTTPS URL (direct)
[email protected]cdf8f7e72013-05-23 10:56:4611095 scoped_ptr<SpdyFrame> req2(
11096 spdy_util_.ConstructSpdyGet(url2.c_str(), false, 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1711097
11098 MockWrite writes2[] = {
11099 CreateMockWrite(*req2, 0),
11100 };
11101
[email protected]23e482282013-06-14 16:08:0211102 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11103 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1711104 MockRead reads2[] = {
11105 CreateMockRead(*resp2, 1),
11106 CreateMockRead(*body2, 2),
11107 MockRead(ASYNC, OK, 3) // EOF
11108 };
11109
11110 scoped_ptr<DeterministicSocketData> data2(
11111 new DeterministicSocketData(reads2, arraysize(reads2),
11112 writes2, arraysize(writes2)));
11113 MockConnect connect_data2(ASYNC, OK);
11114 data2->set_connect_data(connect_data2);
11115
11116 // Set up a proxy config that sends HTTP requests to a proxy, and
11117 // all others direct.
11118 ProxyConfig proxy_config;
11119 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
11120 CapturingProxyResolver* capturing_proxy_resolver =
11121 new CapturingProxyResolver();
[email protected]bb88e1d32013-05-03 23:11:0711122 session_deps_.proxy_service.reset(new ProxyService(
[email protected]2d88e7d2012-07-19 17:55:1711123 new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver,
11124 NULL));
11125
11126 // Load a valid cert. Note, that this does not need to
11127 // be valid for proxy because the MockSSLClientSocket does
11128 // not actually verify it. But SpdySession will use this
11129 // to see if it is valid for the new origin
[email protected]6cdfd7f2013-02-08 20:40:1511130 base::FilePath certs_dir = GetTestCertsDirectory();
[email protected]2d88e7d2012-07-19 17:55:1711131 scoped_refptr<X509Certificate> server_cert(
11132 ImportCertFromFile(certs_dir, "ok_cert.pem"));
11133 ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert);
11134
11135 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
[email protected]23e482282013-06-14 16:08:0211136 ssl1.SetNextProto(GetParam());
[email protected]2d88e7d2012-07-19 17:55:1711137 ssl1.cert = server_cert;
[email protected]bb88e1d32013-05-03 23:11:0711138 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
11139 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11140 data1.get());
[email protected]2d88e7d2012-07-19 17:55:1711141
11142 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
[email protected]23e482282013-06-14 16:08:0211143 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711144 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11145 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11146 data2.get());
[email protected]2d88e7d2012-07-19 17:55:1711147
[email protected]bb88e1d32013-05-03 23:11:0711148 session_deps_.host_resolver.reset(new MockCachingHostResolver());
11149 session_deps_.host_resolver->rules()->AddRule("mail.google.com", ip_addr);
11150 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1711151
11152 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0711153 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]2d88e7d2012-07-19 17:55:1711154
11155 // Start the first transaction to set up the SpdySession
11156 HttpRequestInfo request1;
11157 request1.method = "GET";
11158 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1711159 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011160 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1711161 TestCompletionCallback callback1;
11162 ASSERT_EQ(ERR_IO_PENDING,
11163 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
11164 data1->RunFor(3);
11165
11166 ASSERT_TRUE(callback1.have_result());
11167 EXPECT_EQ(OK, callback1.WaitForResult());
11168 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11169
11170 // Now, start the HTTP request
11171 HttpRequestInfo request2;
11172 request2.method = "GET";
11173 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1711174 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011175 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1711176 TestCompletionCallback callback2;
11177 EXPECT_EQ(ERR_IO_PENDING,
11178 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411179 base::MessageLoop::current()->RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1711180 data2->RunFor(3);
11181
11182 ASSERT_TRUE(callback2.have_result());
11183 EXPECT_EQ(OK, callback2.WaitForResult());
11184 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11185}
11186
[email protected]85f97342013-04-17 06:12:2411187// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
11188// error) in SPDY session, removes the socket from pool and closes the SPDY
11189// session. Verify that new url's from the same HttpNetworkSession (and a new
11190// SpdySession) do work. http://crbug.com/224701
[email protected]23e482282013-06-14 16:08:0211191TEST_P(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
[email protected]85f97342013-04-17 06:12:2411192 const std::string https_url = "https://www.google.com/";
11193
11194 MockRead reads1[] = {
11195 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
11196 };
11197
11198 scoped_ptr<DeterministicSocketData> data1(
11199 new DeterministicSocketData(reads1, arraysize(reads1), NULL, 0));
11200 data1->SetStop(1);
11201
[email protected]cdf8f7e72013-05-23 10:56:4611202 scoped_ptr<SpdyFrame> req2(
11203 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2411204 MockWrite writes2[] = {
11205 CreateMockWrite(*req2, 0),
11206 };
11207
[email protected]23e482282013-06-14 16:08:0211208 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11209 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]85f97342013-04-17 06:12:2411210 MockRead reads2[] = {
11211 CreateMockRead(*resp2, 1),
11212 CreateMockRead(*body2, 2),
11213 MockRead(ASYNC, OK, 3) // EOF
11214 };
11215
11216 scoped_ptr<DeterministicSocketData> data2(
11217 new DeterministicSocketData(reads2, arraysize(reads2),
11218 writes2, arraysize(writes2)));
11219
[email protected]85f97342013-04-17 06:12:2411220 SSLSocketDataProvider ssl1(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211221 ssl1.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711222 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
11223 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11224 data1.get());
[email protected]85f97342013-04-17 06:12:2411225
11226 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211227 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711228 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11229 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11230 data2.get());
[email protected]85f97342013-04-17 06:12:2411231
11232 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0711233 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]85f97342013-04-17 06:12:2411234
11235 // Start the first transaction to set up the SpdySession and verify that
11236 // connection was closed.
11237 HttpRequestInfo request1;
11238 request1.method = "GET";
11239 request1.url = GURL(https_url);
11240 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011241 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2411242 TestCompletionCallback callback1;
11243 EXPECT_EQ(ERR_IO_PENDING,
11244 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411245 base::MessageLoop::current()->RunUntilIdle();
[email protected]85f97342013-04-17 06:12:2411246 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback1.WaitForResult());
11247
11248 // Now, start the second request and make sure it succeeds.
11249 HttpRequestInfo request2;
11250 request2.method = "GET";
11251 request2.url = GURL(https_url);
11252 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011253 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2411254 TestCompletionCallback callback2;
11255 EXPECT_EQ(ERR_IO_PENDING,
11256 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411257 base::MessageLoop::current()->RunUntilIdle();
[email protected]85f97342013-04-17 06:12:2411258 data2->RunFor(3);
11259
11260 ASSERT_TRUE(callback2.have_result());
11261 EXPECT_EQ(OK, callback2.WaitForResult());
11262 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11263}
11264
[email protected]23e482282013-06-14 16:08:0211265TEST_P(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]483fa202013-05-14 01:07:0311266 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
11267 ClientSocketPoolManager::set_max_sockets_per_group(
11268 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
11269 ClientSocketPoolManager::set_max_sockets_per_pool(
11270 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
11271
11272 // Use two different hosts with different IPs so they don't get pooled.
11273 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
11274 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
11275 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11276
11277 SSLSocketDataProvider ssl1(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211278 ssl1.SetNextProto(GetParam());
[email protected]483fa202013-05-14 01:07:0311279 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211280 ssl2.SetNextProto(GetParam());
[email protected]483fa202013-05-14 01:07:0311281 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
11282 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
11283
[email protected]cdf8f7e72013-05-23 10:56:4611284 scoped_ptr<SpdyFrame> host1_req(spdy_util_.ConstructSpdyGet(
[email protected]483fa202013-05-14 01:07:0311285 "https://www.a.com", false, 1, DEFAULT_PRIORITY));
11286 MockWrite spdy1_writes[] = {
11287 CreateMockWrite(*host1_req, 1),
11288 };
[email protected]23e482282013-06-14 16:08:0211289 scoped_ptr<SpdyFrame> host1_resp(
11290 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11291 scoped_ptr<SpdyFrame> host1_resp_body(
11292 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0311293 MockRead spdy1_reads[] = {
11294 CreateMockRead(*host1_resp, 2),
11295 CreateMockRead(*host1_resp_body, 3),
11296 MockRead(ASYNC, ERR_IO_PENDING, 4),
11297 };
11298
11299 scoped_ptr<OrderedSocketData> spdy1_data(
11300 new OrderedSocketData(
11301 spdy1_reads, arraysize(spdy1_reads),
11302 spdy1_writes, arraysize(spdy1_writes)));
11303 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
11304
[email protected]cdf8f7e72013-05-23 10:56:4611305 scoped_ptr<SpdyFrame> host2_req(spdy_util_.ConstructSpdyGet(
[email protected]483fa202013-05-14 01:07:0311306 "https://www.b.com", false, 1, DEFAULT_PRIORITY));
11307 MockWrite spdy2_writes[] = {
11308 CreateMockWrite(*host2_req, 1),
11309 };
[email protected]23e482282013-06-14 16:08:0211310 scoped_ptr<SpdyFrame> host2_resp(
11311 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11312 scoped_ptr<SpdyFrame> host2_resp_body(
11313 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0311314 MockRead spdy2_reads[] = {
11315 CreateMockRead(*host2_resp, 2),
11316 CreateMockRead(*host2_resp_body, 3),
11317 MockRead(ASYNC, ERR_IO_PENDING, 4),
11318 };
11319
11320 scoped_ptr<OrderedSocketData> spdy2_data(
11321 new OrderedSocketData(
11322 spdy2_reads, arraysize(spdy2_reads),
11323 spdy2_writes, arraysize(spdy2_writes)));
11324 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
11325
11326 MockWrite http_write[] = {
11327 MockWrite("GET / HTTP/1.1\r\n"
11328 "Host: www.a.com\r\n"
11329 "Connection: keep-alive\r\n\r\n"),
11330 };
11331
11332 MockRead http_read[] = {
11333 MockRead("HTTP/1.1 200 OK\r\n"),
11334 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11335 MockRead("Content-Length: 6\r\n\r\n"),
11336 MockRead("hello!"),
11337 };
11338 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
11339 http_write, arraysize(http_write));
11340 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
11341
11342 HostPortPair host_port_pair_a("www.a.com", 443);
[email protected]e6d017652013-05-17 18:01:4011343 SpdySessionKey spdy_session_key_a(
11344 host_port_pair_a, ProxyServer::Direct(), kPrivacyModeDisabled);
[email protected]483fa202013-05-14 01:07:0311345 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611346 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0311347
11348 TestCompletionCallback callback;
11349 HttpRequestInfo request1;
11350 request1.method = "GET";
11351 request1.url = GURL("https://www.a.com/");
11352 request1.load_flags = 0;
11353 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5011354 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0311355
11356 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
11357 EXPECT_EQ(ERR_IO_PENDING, rv);
11358 EXPECT_EQ(OK, callback.WaitForResult());
11359
11360 const HttpResponseInfo* response = trans->GetResponseInfo();
11361 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011362 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0311363 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11364 EXPECT_TRUE(response->was_fetched_via_spdy);
11365 EXPECT_TRUE(response->was_npn_negotiated);
11366
11367 std::string response_data;
11368 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11369 EXPECT_EQ("hello!", response_data);
11370 trans.reset();
11371 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2611372 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0311373
11374 HostPortPair host_port_pair_b("www.b.com", 443);
[email protected]e6d017652013-05-17 18:01:4011375 SpdySessionKey spdy_session_key_b(
11376 host_port_pair_b, ProxyServer::Direct(), kPrivacyModeDisabled);
[email protected]483fa202013-05-14 01:07:0311377 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611378 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0311379 HttpRequestInfo request2;
11380 request2.method = "GET";
11381 request2.url = GURL("https://www.b.com/");
11382 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011383 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0311384
11385 rv = trans->Start(&request2, callback.callback(), BoundNetLog());
11386 EXPECT_EQ(ERR_IO_PENDING, rv);
11387 EXPECT_EQ(OK, callback.WaitForResult());
11388
11389 response = trans->GetResponseInfo();
11390 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011391 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0311392 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11393 EXPECT_TRUE(response->was_fetched_via_spdy);
11394 EXPECT_TRUE(response->was_npn_negotiated);
11395 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11396 EXPECT_EQ("hello!", response_data);
11397 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611398 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0311399 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2611400 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0311401
11402 HostPortPair host_port_pair_a1("www.a.com", 80);
[email protected]e6d017652013-05-17 18:01:4011403 SpdySessionKey spdy_session_key_a1(
11404 host_port_pair_a1, ProxyServer::Direct(), kPrivacyModeDisabled);
[email protected]483fa202013-05-14 01:07:0311405 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611406 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0311407 HttpRequestInfo request3;
11408 request3.method = "GET";
11409 request3.url = GURL("http://www.a.com/");
11410 request3.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011411 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0311412
11413 rv = trans->Start(&request3, callback.callback(), BoundNetLog());
11414 EXPECT_EQ(ERR_IO_PENDING, rv);
11415 EXPECT_EQ(OK, callback.WaitForResult());
11416
11417 response = trans->GetResponseInfo();
11418 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011419 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0311420 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11421 EXPECT_FALSE(response->was_fetched_via_spdy);
11422 EXPECT_FALSE(response->was_npn_negotiated);
11423 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11424 EXPECT_EQ("hello!", response_data);
11425 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611426 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0311427 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2611428 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0311429}
11430
[email protected]79e1fd62013-06-20 06:50:0411431TEST_P(HttpNetworkTransactionTest, HttpSyncConnectError) {
11432 HttpRequestInfo request;
11433 request.method = "GET";
11434 request.url = GURL("http://www.google.com/");
11435 request.load_flags = 0;
11436
11437 scoped_ptr<HttpTransaction> trans(
11438 new HttpNetworkTransaction(DEFAULT_PRIORITY,
11439 CreateSession(&session_deps_)));
11440
11441 MockConnect mock_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
11442 StaticSocketDataProvider data;
11443 data.set_connect_data(mock_connect);
11444 session_deps_.socket_factory->AddSocketDataProvider(&data);
11445
11446 TestCompletionCallback callback;
11447
11448 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11449 EXPECT_EQ(ERR_IO_PENDING, rv);
11450
11451 rv = callback.WaitForResult();
11452 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
11453
11454 EXPECT_EQ(NULL, trans->GetResponseInfo());
11455
11456 // We don't care whether this succeeds or fails, but it shouldn't crash.
11457 HttpRequestHeaders request_headers;
11458 trans->GetFullRequestHeaders(&request_headers);
11459}
11460
11461TEST_P(HttpNetworkTransactionTest, HttpAsyncConnectError) {
11462 HttpRequestInfo request;
11463 request.method = "GET";
11464 request.url = GURL("http://www.google.com/");
11465 request.load_flags = 0;
11466
11467 scoped_ptr<HttpTransaction> trans(
11468 new HttpNetworkTransaction(DEFAULT_PRIORITY,
11469 CreateSession(&session_deps_)));
11470
11471 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11472 StaticSocketDataProvider data;
11473 data.set_connect_data(mock_connect);
11474 session_deps_.socket_factory->AddSocketDataProvider(&data);
11475
11476 TestCompletionCallback callback;
11477
11478 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11479 EXPECT_EQ(ERR_IO_PENDING, rv);
11480
11481 rv = callback.WaitForResult();
11482 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
11483
11484 EXPECT_EQ(NULL, trans->GetResponseInfo());
11485
11486 // We don't care whether this succeeds or fails, but it shouldn't crash.
11487 HttpRequestHeaders request_headers;
11488 trans->GetFullRequestHeaders(&request_headers);
11489}
11490
11491TEST_P(HttpNetworkTransactionTest, HttpSyncWriteError) {
11492 HttpRequestInfo request;
11493 request.method = "GET";
11494 request.url = GURL("http://www.google.com/");
11495 request.load_flags = 0;
11496
11497 scoped_ptr<HttpTransaction> trans(
11498 new HttpNetworkTransaction(DEFAULT_PRIORITY,
11499 CreateSession(&session_deps_)));
11500
11501 MockWrite data_writes[] = {
11502 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
11503 };
11504 MockRead data_reads[] = {
11505 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
11506 };
11507
11508 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11509 data_writes, arraysize(data_writes));
11510 session_deps_.socket_factory->AddSocketDataProvider(&data);
11511
11512 TestCompletionCallback callback;
11513
11514 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11515 EXPECT_EQ(ERR_IO_PENDING, rv);
11516
11517 rv = callback.WaitForResult();
11518 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
11519
11520 EXPECT_EQ(NULL, trans->GetResponseInfo());
11521
11522 HttpRequestHeaders request_headers;
11523 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
11524 EXPECT_TRUE(request_headers.HasHeader("Host"));
11525}
11526
11527TEST_P(HttpNetworkTransactionTest, HttpAsyncWriteError) {
11528 HttpRequestInfo request;
11529 request.method = "GET";
11530 request.url = GURL("http://www.google.com/");
11531 request.load_flags = 0;
11532
11533 scoped_ptr<HttpTransaction> trans(
11534 new HttpNetworkTransaction(DEFAULT_PRIORITY,
11535 CreateSession(&session_deps_)));
11536
11537 MockWrite data_writes[] = {
11538 MockWrite(ASYNC, ERR_CONNECTION_RESET),
11539 };
11540 MockRead data_reads[] = {
11541 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
11542 };
11543
11544 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11545 data_writes, arraysize(data_writes));
11546 session_deps_.socket_factory->AddSocketDataProvider(&data);
11547
11548 TestCompletionCallback callback;
11549
11550 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11551 EXPECT_EQ(ERR_IO_PENDING, rv);
11552
11553 rv = callback.WaitForResult();
11554 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
11555
11556 EXPECT_EQ(NULL, trans->GetResponseInfo());
11557
11558 HttpRequestHeaders request_headers;
11559 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
11560 EXPECT_TRUE(request_headers.HasHeader("Host"));
11561}
11562
11563TEST_P(HttpNetworkTransactionTest, HttpSyncReadError) {
11564 HttpRequestInfo request;
11565 request.method = "GET";
11566 request.url = GURL("http://www.google.com/");
11567 request.load_flags = 0;
11568
11569 scoped_ptr<HttpTransaction> trans(
11570 new HttpNetworkTransaction(DEFAULT_PRIORITY,
11571 CreateSession(&session_deps_)));
11572
11573 MockWrite data_writes[] = {
11574 MockWrite("GET / HTTP/1.1\r\n"
11575 "Host: www.google.com\r\n"
11576 "Connection: keep-alive\r\n\r\n"),
11577 };
11578 MockRead data_reads[] = {
11579 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
11580 };
11581
11582 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11583 data_writes, arraysize(data_writes));
11584 session_deps_.socket_factory->AddSocketDataProvider(&data);
11585
11586 TestCompletionCallback callback;
11587
11588 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11589 EXPECT_EQ(ERR_IO_PENDING, rv);
11590
11591 rv = callback.WaitForResult();
11592 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
11593
11594 EXPECT_EQ(NULL, trans->GetResponseInfo());
11595
11596 HttpRequestHeaders request_headers;
11597 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
11598 EXPECT_TRUE(request_headers.HasHeader("Host"));
11599}
11600
11601TEST_P(HttpNetworkTransactionTest, HttpAsyncReadError) {
11602 HttpRequestInfo request;
11603 request.method = "GET";
11604 request.url = GURL("http://www.google.com/");
11605 request.load_flags = 0;
11606
11607 scoped_ptr<HttpTransaction> trans(
11608 new HttpNetworkTransaction(DEFAULT_PRIORITY,
11609 CreateSession(&session_deps_)));
11610
11611 MockWrite data_writes[] = {
11612 MockWrite("GET / HTTP/1.1\r\n"
11613 "Host: www.google.com\r\n"
11614 "Connection: keep-alive\r\n\r\n"),
11615 };
11616 MockRead data_reads[] = {
11617 MockRead(ASYNC, ERR_CONNECTION_RESET),
11618 };
11619
11620 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11621 data_writes, arraysize(data_writes));
11622 session_deps_.socket_factory->AddSocketDataProvider(&data);
11623
11624 TestCompletionCallback callback;
11625
11626 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11627 EXPECT_EQ(ERR_IO_PENDING, rv);
11628
11629 rv = callback.WaitForResult();
11630 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
11631
11632 EXPECT_EQ(NULL, trans->GetResponseInfo());
11633
11634 HttpRequestHeaders request_headers;
11635 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
11636 EXPECT_TRUE(request_headers.HasHeader("Host"));
11637}
11638
11639TEST_P(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
11640 HttpRequestInfo request;
11641 request.method = "GET";
11642 request.url = GURL("http://www.google.com/");
11643 request.load_flags = 0;
11644 request.extra_headers.SetHeader("X-Foo", "bar");
11645
11646 scoped_ptr<HttpTransaction> trans(
11647 new HttpNetworkTransaction(DEFAULT_PRIORITY,
11648 CreateSession(&session_deps_)));
11649
11650 MockWrite data_writes[] = {
11651 MockWrite("GET / HTTP/1.1\r\n"
11652 "Host: www.google.com\r\n"
11653 "Connection: keep-alive\r\n"
11654 "X-Foo: bar\r\n\r\n"),
11655 };
11656 MockRead data_reads[] = {
11657 MockRead("HTTP/1.1 200 OK\r\n"
11658 "Content-Length: 5\r\n\r\n"
11659 "hello"),
11660 MockRead(ASYNC, ERR_UNEXPECTED),
11661 };
11662
11663 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11664 data_writes, arraysize(data_writes));
11665 session_deps_.socket_factory->AddSocketDataProvider(&data);
11666
11667 TestCompletionCallback callback;
11668
11669 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11670 EXPECT_EQ(ERR_IO_PENDING, rv);
11671
11672 rv = callback.WaitForResult();
11673 EXPECT_EQ(OK, rv);
11674
11675 HttpRequestHeaders request_headers;
11676 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
11677 std::string foo;
11678 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
11679 EXPECT_EQ("bar", foo);
11680}
11681
[email protected]89ceba9a2009-03-21 03:46:0611682} // namespace net