blob: d0daf3f69c9f752e39c50522d289a478452e10e1 [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"
initial.commit586acc5fe2008-07-26 22:42:5266
67//-----------------------------------------------------------------------------
68
[email protected]13c8a092010-07-29 06:15:4469namespace {
70
[email protected]42cba2fb2013-03-29 19:58:5771const base::string16 kBar(ASCIIToUTF16("bar"));
72const base::string16 kBar2(ASCIIToUTF16("bar2"));
73const base::string16 kBar3(ASCIIToUTF16("bar3"));
74const base::string16 kBaz(ASCIIToUTF16("baz"));
75const base::string16 kFirst(ASCIIToUTF16("first"));
76const base::string16 kFoo(ASCIIToUTF16("foo"));
77const base::string16 kFoo2(ASCIIToUTF16("foo2"));
78const base::string16 kFoo3(ASCIIToUTF16("foo3"));
79const base::string16 kFou(ASCIIToUTF16("fou"));
80const base::string16 kSecond(ASCIIToUTF16("second"));
81const base::string16 kTestingNTLM(ASCIIToUTF16("testing-ntlm"));
82const base::string16 kWrongPassword(ASCIIToUTF16("wrongpassword"));
[email protected]13c8a092010-07-29 06:15:4483
[email protected]5285d972011-10-18 18:56:3484// MakeNextProtos is a utility function that returns a vector of std::strings
85// from its arguments. Don't forget to terminate the argument list with a NULL.
86std::vector<std::string> MakeNextProtos(const char* a, ...) {
87 std::vector<std::string> ret;
88 ret.push_back(a);
89
90 va_list args;
91 va_start(args, a);
92
93 for (;;) {
94 const char* value = va_arg(args, const char*);
95 if (value == NULL)
96 break;
97 ret.push_back(value);
98 }
99 va_end(args);
100
101 return ret;
102}
103
[email protected]e5c026642012-03-17 00:14:02104int GetIdleSocketCountInTransportSocketPool(net::HttpNetworkSession* session) {
105 return session->GetTransportSocketPool(
106 net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IdleSocketCount();
107}
108
109int GetIdleSocketCountInSSLSocketPool(net::HttpNetworkSession* session) {
110 return session->GetSSLSocketPool(
111 net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IdleSocketCount();
112}
113
[email protected]f3da152d2012-06-02 01:00:57114// Takes in a Value created from a NetLogHttpResponseParameter, and returns
115// a JSONified list of headers as a single string. Uses single quotes instead
116// of double quotes for easier comparison. Returns false on failure.
[email protected]ea5ef4c2013-06-13 22:50:27117bool GetHeaders(base::DictionaryValue* params, std::string* headers) {
[email protected]f3da152d2012-06-02 01:00:57118 if (!params)
119 return false;
[email protected]ea5ef4c2013-06-13 22:50:27120 base::ListValue* header_list;
[email protected]f3da152d2012-06-02 01:00:57121 if (!params->GetList("headers", &header_list))
122 return false;
123 std::string double_quote_headers;
124 base::JSONWriter::Write(header_list, &double_quote_headers);
125 ReplaceChars(double_quote_headers, "\"", "'", headers);
126 return true;
127}
128
[email protected]029c83b62013-01-24 05:28:20129// Tests LoadTimingInfo in the case a socket is reused and no PAC script is
130// used.
131void TestLoadTimingReused(const net::LoadTimingInfo& load_timing_info) {
132 EXPECT_TRUE(load_timing_info.socket_reused);
[email protected]58e32bb2013-01-21 18:23:25133 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
134
[email protected]029c83b62013-01-24 05:28:20135 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
136 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
137
138 net::ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
139 EXPECT_FALSE(load_timing_info.send_start.is_null());
[email protected]58e32bb2013-01-21 18:23:25140
141 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]58e32bb2013-01-21 18:23:25142
[email protected]3b23a222013-05-15 21:33:25143 // Set at a higher level.
[email protected]58e32bb2013-01-21 18:23:25144 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
145 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25146 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25147}
148
[email protected]029c83b62013-01-24 05:28:20149// Tests LoadTimingInfo in the case a new socket is used and no PAC script is
150// used.
[email protected]58e32bb2013-01-21 18:23:25151void TestLoadTimingNotReused(const net::LoadTimingInfo& load_timing_info,
152 int connect_timing_flags) {
[email protected]029c83b62013-01-24 05:28:20153 EXPECT_FALSE(load_timing_info.socket_reused);
154 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
155
156 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
157 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
158
159 net::ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
[email protected]3b23a222013-05-15 21:33:25160 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20161 EXPECT_LE(load_timing_info.connect_timing.connect_end,
162 load_timing_info.send_start);
163
164 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20165
[email protected]3b23a222013-05-15 21:33:25166 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20167 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
168 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25169 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20170}
171
172// Tests LoadTimingInfo in the case a socket is reused and a PAC script is
173// used.
174void TestLoadTimingReusedWithPac(const net::LoadTimingInfo& load_timing_info) {
175 EXPECT_TRUE(load_timing_info.socket_reused);
176 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
177
178 net::ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
179
180 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
181 EXPECT_LE(load_timing_info.proxy_resolve_start,
182 load_timing_info.proxy_resolve_end);
183 EXPECT_LE(load_timing_info.proxy_resolve_end,
184 load_timing_info.send_start);
185 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20186
[email protected]3b23a222013-05-15 21:33:25187 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20188 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
189 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25190 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20191}
192
193// Tests LoadTimingInfo in the case a new socket is used and a PAC script is
194// used.
195void TestLoadTimingNotReusedWithPac(const net::LoadTimingInfo& load_timing_info,
196 int connect_timing_flags) {
197 EXPECT_FALSE(load_timing_info.socket_reused);
198 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
199
200 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
201 EXPECT_LE(load_timing_info.proxy_resolve_start,
202 load_timing_info.proxy_resolve_end);
203 EXPECT_LE(load_timing_info.proxy_resolve_end,
204 load_timing_info.connect_timing.connect_start);
205 net::ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
206 connect_timing_flags);
207 EXPECT_LE(load_timing_info.connect_timing.connect_end,
208 load_timing_info.send_start);
209
210 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20211
[email protected]3b23a222013-05-15 21:33:25212 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20213 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
214 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25215 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25216}
217
[email protected]13c8a092010-07-29 06:15:44218} // namespace
219
[email protected]89ceba9a2009-03-21 03:46:06220namespace net {
221
[email protected]448d4ca52012-03-04 04:12:23222namespace {
223
[email protected]c6bf8152012-12-02 07:43:34224HttpNetworkSession* CreateSession(SpdySessionDependencies* session_deps) {
225 return SpdySessionDependencies::SpdyCreateSession(session_deps);
[email protected]e8d536192008-10-17 22:21:14226}
227
[email protected]448d4ca52012-03-04 04:12:23228} // namespace
229
[email protected]23e482282013-06-14 16:08:02230class HttpNetworkTransactionTest
231 : public PlatformTest,
232 public ::testing::WithParamInterface<NextProto> {
[email protected]483fa202013-05-14 01:07:03233 public:
[email protected]23e482282013-06-14 16:08:02234 virtual ~HttpNetworkTransactionTest() {
[email protected]483fa202013-05-14 01:07:03235 // Important to restore the per-pool limit first, since the pool limit must
236 // always be greater than group limit, and the tests reduce both limits.
237 ClientSocketPoolManager::set_max_sockets_per_pool(
238 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
239 ClientSocketPoolManager::set_max_sockets_per_group(
240 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
241 }
242
[email protected]e3ceb682011-06-28 23:55:46243 protected:
[email protected]23e482282013-06-14 16:08:02244 HttpNetworkTransactionTest()
245 : spdy_util_(GetParam()),
246 session_deps_(GetParam()),
[email protected]483fa202013-05-14 01:07:03247 old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
248 HttpNetworkSession::NORMAL_SOCKET_POOL)),
249 old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
250 HttpNetworkSession::NORMAL_SOCKET_POOL)) {
251 }
[email protected]bb88e1d32013-05-03 23:11:07252
[email protected]e3ceb682011-06-28 23:55:46253 struct SimpleGetHelperResult {
254 int rv;
255 std::string status_line;
256 std::string response_data;
[email protected]58e32bb2013-01-21 18:23:25257 LoadTimingInfo load_timing_info;
[email protected]e3ceb682011-06-28 23:55:46258 };
259
[email protected]2ff8b312010-04-26 22:20:54260 virtual void SetUp() {
[email protected]0b0bf032010-09-21 18:08:50261 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:34262 base::MessageLoop::current()->RunUntilIdle();
[email protected]2ff8b312010-04-26 22:20:54263 }
264
[email protected]0e75a732008-10-16 20:36:09265 virtual void TearDown() {
[email protected]0b0bf032010-09-21 18:08:50266 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:34267 base::MessageLoop::current()->RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09268 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:34269 base::MessageLoop::current()->RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09270 PlatformTest::TearDown();
[email protected]0b0bf032010-09-21 18:08:50271 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:34272 base::MessageLoop::current()->RunUntilIdle();
[email protected]c54c6962013-02-01 04:53:19273 HttpStreamFactory::set_use_alternate_protocols(false);
274 HttpStreamFactory::SetNextProtos(std::vector<std::string>());
[email protected]0e75a732008-10-16 20:36:09275 }
276
[email protected]8a0fc822013-06-27 20:52:43277 // This is the expected return from a current server advertising SPDY.
278 std::string GetAlternateProtocolHttpHeader() {
279 return
280 std::string("Alternate-Protocol: 443:") +
281 AlternateProtocolToString(AlternateProtocolFromNextProto(GetParam())) +
282 "\r\n\r\n";
283 }
284
[email protected]202965992011-12-07 23:04:51285 // Either |write_failure| specifies a write failure or |read_failure|
286 // specifies a read failure when using a reused socket. In either case, the
287 // failure should cause the network transaction to resend the request, and the
288 // other argument should be NULL.
289 void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
290 const MockRead* read_failure);
initial.commit586acc5fe2008-07-26 22:42:52291
[email protected]5a60c8b2011-10-19 20:14:29292 SimpleGetHelperResult SimpleGetHelperForData(StaticSocketDataProvider* data[],
293 size_t data_count) {
[email protected]ff007e162009-05-23 09:13:15294 SimpleGetHelperResult out;
initial.commit586acc5fe2008-07-26 22:42:52295
[email protected]ff007e162009-05-23 09:13:15296 HttpRequestInfo request;
297 request.method = "GET";
298 request.url = GURL("http://www.google.com/");
299 request.load_flags = 0;
initial.commit586acc5fe2008-07-26 22:42:52300
[email protected]58e32bb2013-01-21 18:23:25301 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:07302 session_deps_.net_log = log.bound().net_log();
[email protected]cb9bf6ca2011-01-28 13:15:27303 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:36304 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:07305 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:27306
[email protected]5a60c8b2011-10-19 20:14:29307 for (size_t i = 0; i < data_count; ++i) {
[email protected]bb88e1d32013-05-03 23:11:07308 session_deps_.socket_factory->AddSocketDataProvider(data[i]);
[email protected]5a60c8b2011-10-19 20:14:29309 }
initial.commit586acc5fe2008-07-26 22:42:52310
[email protected]49639fa2011-12-20 23:22:41311 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52312
[email protected]3deb9a52010-11-11 00:24:40313 EXPECT_TRUE(log.bound().IsLoggingAllEvents());
[email protected]49639fa2011-12-20 23:22:41314 int rv = trans->Start(&request, callback.callback(), log.bound());
[email protected]ff007e162009-05-23 09:13:15315 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:52316
[email protected]ff007e162009-05-23 09:13:15317 out.rv = callback.WaitForResult();
[email protected]58e32bb2013-01-21 18:23:25318
319 // Even in the failure cases that use this function, connections are always
320 // successfully established before the error.
321 EXPECT_TRUE(trans->GetLoadTimingInfo(&out.load_timing_info));
322 TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
323
[email protected]ff007e162009-05-23 09:13:15324 if (out.rv != OK)
325 return out;
326
327 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50328 // Can't use ASSERT_* inside helper functions like this, so
329 // return an error.
[email protected]90499482013-06-01 00:39:50330 if (response == NULL || response->headers.get() == NULL) {
[email protected]fe2255a2011-09-20 19:37:50331 out.rv = ERR_UNEXPECTED;
332 return out;
333 }
[email protected]ff007e162009-05-23 09:13:15334 out.status_line = response->headers->GetStatusLine();
335
[email protected]80a09a82012-11-16 17:40:06336 EXPECT_EQ("127.0.0.1", response->socket_address.host());
337 EXPECT_EQ(80, response->socket_address.port());
[email protected]6d81b482011-02-22 19:47:19338
[email protected]ff007e162009-05-23 09:13:15339 rv = ReadTransaction(trans.get(), &out.response_data);
340 EXPECT_EQ(OK, rv);
[email protected]b2fcd0e2010-12-01 15:19:40341
[email protected]f3da152d2012-06-02 01:00:57342 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:40343 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:39344 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:40345 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
[email protected]169d0012010-05-10 23:20:12346 NetLog::PHASE_NONE);
[email protected]dbb83db2010-05-11 18:13:39347 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:40348 entries, pos,
[email protected]dbb83db2010-05-11 18:13:39349 NetLog::TYPE_HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
350 NetLog::PHASE_NONE);
[email protected]ff007e162009-05-23 09:13:15351
[email protected]f3da152d2012-06-02 01:00:57352 std::string line;
353 EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
354 EXPECT_EQ("GET / HTTP/1.1\r\n", line);
355
[email protected]79e1fd62013-06-20 06:50:04356 HttpRequestHeaders request_headers;
357 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
358 std::string value;
359 EXPECT_TRUE(request_headers.GetHeader("Host", &value));
360 EXPECT_EQ("www.google.com", value);
361 EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
362 EXPECT_EQ("keep-alive", value);
363
364 std::string response_headers;
365 EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
366 EXPECT_EQ("['Host: www.google.com','Connection: keep-alive']",
367 response_headers);
[email protected]3deb9a52010-11-11 00:24:40368
[email protected]aecfbf22008-10-16 02:02:47369 return out;
[email protected]ff007e162009-05-23 09:13:15370 }
initial.commit586acc5fe2008-07-26 22:42:52371
[email protected]5a60c8b2011-10-19 20:14:29372 SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[],
373 size_t reads_count) {
374 StaticSocketDataProvider reads(data_reads, reads_count, NULL, 0);
375 StaticSocketDataProvider* data[] = { &reads };
376 return SimpleGetHelperForData(data, 1);
377 }
378
[email protected]ff007e162009-05-23 09:13:15379 void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
380 int expected_status);
initial.commit586acc5fe2008-07-26 22:42:52381
[email protected]ff007e162009-05-23 09:13:15382 void ConnectStatusHelper(const MockRead& status);
[email protected]bb88e1d32013-05-03 23:11:07383
384 void BypassHostCacheOnRefreshHelper(int load_flags);
385
386 void CheckErrorIsPassedBack(int error, IoMode mode);
387
[email protected]4bd46222013-05-14 19:32:23388 SpdyTestUtil spdy_util_;
[email protected]bb88e1d32013-05-03 23:11:07389 SpdySessionDependencies session_deps_;
[email protected]483fa202013-05-14 01:07:03390
391 // Original socket limits. Some tests set these. Safest to always restore
392 // them once each test has been run.
393 int old_max_group_sockets_;
394 int old_max_pool_sockets_;
[email protected]ff007e162009-05-23 09:13:15395};
[email protected]231d5a32008-09-13 00:45:27396
[email protected]23e482282013-06-14 16:08:02397INSTANTIATE_TEST_CASE_P(
398 NextProto,
399 HttpNetworkTransactionTest,
400 testing::Values(kProtoSPDY2, kProtoSPDY3, kProtoSPDY31, kProtoSPDY4a2));
401
[email protected]448d4ca52012-03-04 04:12:23402namespace {
403
[email protected]15a5ccf82008-10-23 19:57:43404// Fill |str| with a long header list that consumes >= |size| bytes.
405void FillLargeHeadersString(std::string* str, int size) {
[email protected]4ddaf2502008-10-23 18:26:19406 const char* row =
407 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
408 const int sizeof_row = strlen(row);
409 const int num_rows = static_cast<int>(
410 ceil(static_cast<float>(size) / sizeof_row));
411 const int sizeof_data = num_rows * sizeof_row;
412 DCHECK(sizeof_data >= size);
[email protected]15a5ccf82008-10-23 19:57:43413 str->reserve(sizeof_data);
[email protected]372d34a2008-11-05 21:30:51414
[email protected]4ddaf2502008-10-23 18:26:19415 for (int i = 0; i < num_rows; ++i)
[email protected]15a5ccf82008-10-23 19:57:43416 str->append(row, sizeof_row);
[email protected]4ddaf2502008-10-23 18:26:19417}
418
[email protected]385a4672009-03-11 22:21:29419// Alternative functions that eliminate randomness and dependency on the local
420// host name so that the generated NTLM messages are reproducible.
[email protected]fe2bc6a2009-03-23 16:52:20421void MockGenerateRandom1(uint8* output, size_t n) {
[email protected]385a4672009-03-11 22:21:29422 static const uint8 bytes[] = {
423 0x55, 0x29, 0x66, 0x26, 0x6b, 0x9c, 0x73, 0x54
424 };
425 static size_t current_byte = 0;
426 for (size_t i = 0; i < n; ++i) {
427 output[i] = bytes[current_byte++];
428 current_byte %= arraysize(bytes);
429 }
430}
431
[email protected]fe2bc6a2009-03-23 16:52:20432void MockGenerateRandom2(uint8* output, size_t n) {
[email protected]385a4672009-03-11 22:21:29433 static const uint8 bytes[] = {
434 0x96, 0x79, 0x85, 0xe7, 0x49, 0x93, 0x70, 0xa1,
435 0x4e, 0xe7, 0x87, 0x45, 0x31, 0x5b, 0xd3, 0x1f
436 };
437 static size_t current_byte = 0;
438 for (size_t i = 0; i < n; ++i) {
439 output[i] = bytes[current_byte++];
440 current_byte %= arraysize(bytes);
441 }
442}
443
[email protected]fe2bc6a2009-03-23 16:52:20444std::string MockGetHostName() {
445 return "WTC-WIN7";
[email protected]385a4672009-03-11 22:21:29446}
447
[email protected]e60e47a2010-07-14 03:37:18448template<typename ParentPool>
449class CaptureGroupNameSocketPool : public ParentPool {
[email protected]04e5be32009-06-26 20:00:31450 public:
[email protected]9e1bdd32011-02-03 21:48:34451 CaptureGroupNameSocketPool(HostResolver* host_resolver,
452 CertVerifier* cert_verifier);
[email protected]e60e47a2010-07-14 03:37:18453
[email protected]d80a4322009-08-14 07:07:49454 const std::string last_group_name_received() const {
455 return last_group_name_;
456 }
457
[email protected]684970b2009-08-14 04:54:46458 virtual int RequestSocket(const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49459 const void* socket_params,
[email protected]ac790b42009-12-02 04:31:31460 RequestPriority priority,
[email protected]04e5be32009-06-26 20:00:31461 ClientSocketHandle* handle,
[email protected]49639fa2011-12-20 23:22:41462 const CompletionCallback& callback,
[email protected]9e743cd2010-03-16 07:03:53463 const BoundNetLog& net_log) {
[email protected]04e5be32009-06-26 20:00:31464 last_group_name_ = group_name;
465 return ERR_IO_PENDING;
466 }
[email protected]04e5be32009-06-26 20:00:31467 virtual void CancelRequest(const std::string& group_name,
[email protected]05ea9ff2010-07-15 19:08:21468 ClientSocketHandle* handle) {}
[email protected]04e5be32009-06-26 20:00:31469 virtual void ReleaseSocket(const std::string& group_name,
[email protected]3268023f2011-05-05 00:08:10470 StreamSocket* socket,
[email protected]9f95c692011-02-11 19:20:19471 int id) {}
[email protected]04e5be32009-06-26 20:00:31472 virtual void CloseIdleSockets() {}
[email protected]04e5be32009-06-26 20:00:31473 virtual int IdleSocketCount() const {
474 return 0;
475 }
476 virtual int IdleSocketCountInGroup(const std::string& group_name) const {
477 return 0;
478 }
479 virtual LoadState GetLoadState(const std::string& group_name,
480 const ClientSocketHandle* handle) const {
481 return LOAD_STATE_IDLE;
482 }
[email protected]a796bcec2010-03-22 17:17:26483 virtual base::TimeDelta ConnectionTimeout() const {
484 return base::TimeDelta();
485 }
[email protected]d80a4322009-08-14 07:07:49486
487 private:
[email protected]04e5be32009-06-26 20:00:31488 std::string last_group_name_;
489};
490
[email protected]ab739042011-04-07 15:22:28491typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
492CaptureGroupNameTransportSocketPool;
[email protected]e772db3f2010-07-12 18:11:13493typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
494CaptureGroupNameHttpProxySocketPool;
[email protected]2d731a32010-04-29 01:04:06495typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
[email protected]2227c692010-05-04 15:36:11496CaptureGroupNameSOCKSSocketPool;
[email protected]e60e47a2010-07-14 03:37:18497typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
498CaptureGroupNameSSLSocketPool;
499
500template<typename ParentPool>
501CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34502 HostResolver* host_resolver,
503 CertVerifier* /* cert_verifier */)
504 : ParentPool(0, 0, NULL, host_resolver, NULL, NULL) {}
[email protected]e60e47a2010-07-14 03:37:18505
506template<>
[email protected]2df19bb2010-08-25 20:13:46507CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34508 HostResolver* host_resolver,
509 CertVerifier* /* cert_verifier */)
510 : HttpProxyClientSocketPool(0, 0, NULL, host_resolver, NULL, NULL, NULL) {}
[email protected]2df19bb2010-08-25 20:13:46511
[email protected]007b3f82013-04-09 08:46:45512template <>
[email protected]e60e47a2010-07-14 03:37:18513CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34514 HostResolver* host_resolver,
515 CertVerifier* cert_verifier)
[email protected]007b3f82013-04-09 08:46:45516 : SSLClientSocketPool(0,
517 0,
518 NULL,
519 host_resolver,
520 cert_verifier,
521 NULL,
522 NULL,
523 std::string(),
524 NULL,
525 NULL,
526 NULL,
527 NULL,
528 NULL,
529 NULL) {}
[email protected]2227c692010-05-04 15:36:11530
[email protected]231d5a32008-09-13 00:45:27531//-----------------------------------------------------------------------------
532
[email protected]79cb5c12011-09-12 13:12:04533// Helper functions for validating that AuthChallengeInfo's are correctly
534// configured for common cases.
535bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
536 if (!auth_challenge)
537 return false;
538 EXPECT_FALSE(auth_challenge->is_proxy);
539 EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString());
540 EXPECT_EQ("MyRealm1", auth_challenge->realm);
541 EXPECT_EQ("basic", auth_challenge->scheme);
542 return true;
543}
544
545bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
546 if (!auth_challenge)
547 return false;
548 EXPECT_TRUE(auth_challenge->is_proxy);
549 EXPECT_EQ("myproxy:70", auth_challenge->challenger.ToString());
550 EXPECT_EQ("MyRealm1", auth_challenge->realm);
551 EXPECT_EQ("basic", auth_challenge->scheme);
552 return true;
553}
554
555bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
556 if (!auth_challenge)
557 return false;
558 EXPECT_FALSE(auth_challenge->is_proxy);
559 EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString());
560 EXPECT_EQ("digestive", auth_challenge->realm);
561 EXPECT_EQ("digest", auth_challenge->scheme);
562 return true;
563}
564
565bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
566 if (!auth_challenge)
567 return false;
568 EXPECT_FALSE(auth_challenge->is_proxy);
569 EXPECT_EQ("172.22.68.17:80", auth_challenge->challenger.ToString());
570 EXPECT_EQ(std::string(), auth_challenge->realm);
571 EXPECT_EQ("ntlm", auth_challenge->scheme);
572 return true;
573}
574
[email protected]448d4ca52012-03-04 04:12:23575} // namespace
576
[email protected]23e482282013-06-14 16:08:02577TEST_P(HttpNetworkTransactionTest, Basic) {
[email protected]d207a5f2009-06-04 05:28:40578 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:36579 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:07580 CreateSession(&session_deps_)));
[email protected]231d5a32008-09-13 00:45:27581}
582
[email protected]23e482282013-06-14 16:08:02583TEST_P(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27584 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35585 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
586 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06587 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27588 };
[email protected]31a2bfe2010-02-09 08:03:39589 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
590 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42591 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27592 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
593 EXPECT_EQ("hello world", out.response_data);
594}
595
596// Response with no status line.
[email protected]23e482282013-06-14 16:08:02597TEST_P(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27598 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35599 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06600 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27601 };
[email protected]31a2bfe2010-02-09 08:03:39602 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
603 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42604 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27605 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
606 EXPECT_EQ("hello world", out.response_data);
607}
608
609// Allow up to 4 bytes of junk to precede status line.
[email protected]23e482282013-06-14 16:08:02610TEST_P(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27611 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35612 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06613 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27614 };
[email protected]31a2bfe2010-02-09 08:03:39615 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
616 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42617 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27618 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
619 EXPECT_EQ("DATA", out.response_data);
620}
621
622// Allow up to 4 bytes of junk to precede status line.
[email protected]23e482282013-06-14 16:08:02623TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27624 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35625 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06626 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27627 };
[email protected]31a2bfe2010-02-09 08:03:39628 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
629 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42630 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27631 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
632 EXPECT_EQ("DATA", out.response_data);
633}
634
635// Beyond 4 bytes of slop and it should fail to find a status line.
[email protected]23e482282013-06-14 16:08:02636TEST_P(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27637 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35638 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06639 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27640 };
[email protected]31a2bfe2010-02-09 08:03:39641 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
642 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42643 EXPECT_EQ(OK, out.rv);
[email protected]3d2a59b2008-09-26 19:44:25644 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
645 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
[email protected]231d5a32008-09-13 00:45:27646}
647
648// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
[email protected]23e482282013-06-14 16:08:02649TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27650 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35651 MockRead("\n"),
652 MockRead("\n"),
653 MockRead("Q"),
654 MockRead("J"),
655 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06656 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27657 };
[email protected]31a2bfe2010-02-09 08:03:39658 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
659 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42660 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27661 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
662 EXPECT_EQ("DATA", out.response_data);
663}
664
665// Close the connection before enough bytes to have a status line.
[email protected]23e482282013-06-14 16:08:02666TEST_P(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:27667 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35668 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:06669 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27670 };
[email protected]31a2bfe2010-02-09 08:03:39671 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
672 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42673 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27674 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
675 EXPECT_EQ("HTT", out.response_data);
initial.commit586acc5fe2008-07-26 22:42:52676}
677
[email protected]f9d44aa2008-09-23 23:57:17678// Simulate a 204 response, lacking a Content-Length header, sent over a
679// persistent connection. The response should still terminate since a 204
680// cannot have a response body.
[email protected]23e482282013-06-14 16:08:02681TEST_P(HttpNetworkTransactionTest, StopsReading204) {
[email protected]f9d44aa2008-09-23 23:57:17682 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35683 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
684 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:06685 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:17686 };
[email protected]31a2bfe2010-02-09 08:03:39687 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
688 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42689 EXPECT_EQ(OK, out.rv);
[email protected]f9d44aa2008-09-23 23:57:17690 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
691 EXPECT_EQ("", out.response_data);
692}
693
[email protected]0877e3d2009-10-17 22:29:57694// A simple request using chunked encoding with some extra data after.
695// (Like might be seen in a pipelined response.)
[email protected]23e482282013-06-14 16:08:02696TEST_P(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]0877e3d2009-10-17 22:29:57697 MockRead data_reads[] = {
698 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
699 MockRead("5\r\nHello\r\n"),
700 MockRead("1\r\n"),
701 MockRead(" \r\n"),
702 MockRead("5\r\nworld\r\n"),
703 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:06704 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:57705 };
[email protected]31a2bfe2010-02-09 08:03:39706 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
707 arraysize(data_reads));
[email protected]0877e3d2009-10-17 22:29:57708 EXPECT_EQ(OK, out.rv);
709 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
710 EXPECT_EQ("Hello world", out.response_data);
711}
712
[email protected]9fe44f52010-09-23 18:36:00713// Next tests deal with http://crbug.com/56344.
714
[email protected]23e482282013-06-14 16:08:02715TEST_P(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00716 MultipleContentLengthHeadersNoTransferEncoding) {
717 MockRead data_reads[] = {
718 MockRead("HTTP/1.1 200 OK\r\n"),
719 MockRead("Content-Length: 10\r\n"),
720 MockRead("Content-Length: 5\r\n\r\n"),
721 };
722 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
723 arraysize(data_reads));
724 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
725}
726
[email protected]23e482282013-06-14 16:08:02727TEST_P(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04728 DuplicateContentLengthHeadersNoTransferEncoding) {
729 MockRead data_reads[] = {
730 MockRead("HTTP/1.1 200 OK\r\n"),
731 MockRead("Content-Length: 5\r\n"),
732 MockRead("Content-Length: 5\r\n\r\n"),
733 MockRead("Hello"),
734 };
735 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
736 arraysize(data_reads));
737 EXPECT_EQ(OK, out.rv);
738 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
739 EXPECT_EQ("Hello", out.response_data);
740}
741
[email protected]23e482282013-06-14 16:08:02742TEST_P(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04743 ComplexContentLengthHeadersNoTransferEncoding) {
744 // More than 2 dupes.
745 {
746 MockRead data_reads[] = {
747 MockRead("HTTP/1.1 200 OK\r\n"),
748 MockRead("Content-Length: 5\r\n"),
749 MockRead("Content-Length: 5\r\n"),
750 MockRead("Content-Length: 5\r\n\r\n"),
751 MockRead("Hello"),
752 };
753 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
754 arraysize(data_reads));
755 EXPECT_EQ(OK, out.rv);
756 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
757 EXPECT_EQ("Hello", out.response_data);
758 }
759 // HTTP/1.0
760 {
761 MockRead data_reads[] = {
762 MockRead("HTTP/1.0 200 OK\r\n"),
763 MockRead("Content-Length: 5\r\n"),
764 MockRead("Content-Length: 5\r\n"),
765 MockRead("Content-Length: 5\r\n\r\n"),
766 MockRead("Hello"),
767 };
768 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
769 arraysize(data_reads));
770 EXPECT_EQ(OK, out.rv);
771 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
772 EXPECT_EQ("Hello", out.response_data);
773 }
774 // 2 dupes and one mismatched.
775 {
776 MockRead data_reads[] = {
777 MockRead("HTTP/1.1 200 OK\r\n"),
778 MockRead("Content-Length: 10\r\n"),
779 MockRead("Content-Length: 10\r\n"),
780 MockRead("Content-Length: 5\r\n\r\n"),
781 };
782 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
783 arraysize(data_reads));
784 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
785 }
786}
787
[email protected]23e482282013-06-14 16:08:02788TEST_P(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00789 MultipleContentLengthHeadersTransferEncoding) {
790 MockRead data_reads[] = {
791 MockRead("HTTP/1.1 200 OK\r\n"),
792 MockRead("Content-Length: 666\r\n"),
793 MockRead("Content-Length: 1337\r\n"),
794 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
795 MockRead("5\r\nHello\r\n"),
796 MockRead("1\r\n"),
797 MockRead(" \r\n"),
798 MockRead("5\r\nworld\r\n"),
799 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:06800 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:00801 };
802 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
803 arraysize(data_reads));
804 EXPECT_EQ(OK, out.rv);
805 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
806 EXPECT_EQ("Hello world", out.response_data);
807}
808
[email protected]1628fe92011-10-04 23:04:55809// Next tests deal with http://crbug.com/98895.
810
811// Checks that a single Content-Disposition header results in no error.
[email protected]23e482282013-06-14 16:08:02812TEST_P(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:55813 MockRead data_reads[] = {
814 MockRead("HTTP/1.1 200 OK\r\n"),
815 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
816 MockRead("Content-Length: 5\r\n\r\n"),
817 MockRead("Hello"),
818 };
819 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
820 arraysize(data_reads));
821 EXPECT_EQ(OK, out.rv);
822 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
823 EXPECT_EQ("Hello", out.response_data);
824}
825
[email protected]54a9c6e52012-03-21 20:10:59826// Checks that two identical Content-Disposition headers result in no error.
[email protected]23e482282013-06-14 16:08:02827TEST_P(HttpNetworkTransactionTest,
[email protected]54a9c6e52012-03-21 20:10:59828 TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:55829 MockRead data_reads[] = {
830 MockRead("HTTP/1.1 200 OK\r\n"),
831 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
832 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
833 MockRead("Content-Length: 5\r\n\r\n"),
834 MockRead("Hello"),
835 };
836 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
837 arraysize(data_reads));
[email protected]54a9c6e52012-03-21 20:10:59838 EXPECT_EQ(OK, out.rv);
839 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
840 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:55841}
842
843// Checks that two distinct Content-Disposition headers result in an error.
[email protected]23e482282013-06-14 16:08:02844TEST_P(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:55845 MockRead data_reads[] = {
846 MockRead("HTTP/1.1 200 OK\r\n"),
847 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
848 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
849 MockRead("Content-Length: 5\r\n\r\n"),
850 MockRead("Hello"),
851 };
852 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
853 arraysize(data_reads));
854 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION, out.rv);
855}
856
[email protected]54a9c6e52012-03-21 20:10:59857// Checks that two identical Location headers result in no error.
858// Also tests Location header behavior.
[email protected]23e482282013-06-14 16:08:02859TEST_P(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:55860 MockRead data_reads[] = {
861 MockRead("HTTP/1.1 302 Redirect\r\n"),
862 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:59863 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:55864 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:06865 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:55866 };
867
868 HttpRequestInfo request;
869 request.method = "GET";
870 request.url = GURL("http://redirect.com/");
871 request.load_flags = 0;
872
[email protected]1628fe92011-10-04 23:04:55873 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:36874 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:07875 CreateSession(&session_deps_)));
[email protected]1628fe92011-10-04 23:04:55876
877 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:07878 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:55879
[email protected]49639fa2011-12-20 23:22:41880 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:55881
[email protected]49639fa2011-12-20 23:22:41882 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1628fe92011-10-04 23:04:55883 EXPECT_EQ(ERR_IO_PENDING, rv);
884
885 EXPECT_EQ(OK, callback.WaitForResult());
886
887 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]90499482013-06-01 00:39:50888 ASSERT_TRUE(response != NULL && response->headers.get() != NULL);
[email protected]1628fe92011-10-04 23:04:55889 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
890 std::string url;
891 EXPECT_TRUE(response->headers->IsRedirect(&url));
892 EXPECT_EQ("http://good.com/", url);
893}
894
[email protected]1628fe92011-10-04 23:04:55895// Checks that two distinct Location headers result in an error.
[email protected]23e482282013-06-14 16:08:02896TEST_P(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:55897 MockRead data_reads[] = {
898 MockRead("HTTP/1.1 302 Redirect\r\n"),
899 MockRead("Location: http://good.com/\r\n"),
900 MockRead("Location: http://evil.com/\r\n"),
901 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:06902 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:55903 };
904 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
905 arraysize(data_reads));
906 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION, out.rv);
907}
908
[email protected]ef0faf2e72009-03-05 23:27:23909// Do a request using the HEAD method. Verify that we don't try to read the
910// message body (since HEAD has none).
[email protected]23e482282013-06-14 16:08:02911TEST_P(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:42912 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:23913 request.method = "HEAD";
914 request.url = GURL("http://www.google.com/");
915 request.load_flags = 0;
916
[email protected]cb9bf6ca2011-01-28 13:15:27917 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:36918 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:07919 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:27920
[email protected]ef0faf2e72009-03-05 23:27:23921 MockWrite data_writes1[] = {
922 MockWrite("HEAD / HTTP/1.1\r\n"
923 "Host: www.google.com\r\n"
924 "Connection: keep-alive\r\n"
925 "Content-Length: 0\r\n\r\n"),
926 };
927 MockRead data_reads1[] = {
928 MockRead("HTTP/1.1 404 Not Found\r\n"),
929 MockRead("Server: Blah\r\n"),
930 MockRead("Content-Length: 1234\r\n\r\n"),
931
932 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:06933 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]ef0faf2e72009-03-05 23:27:23934 };
935
[email protected]31a2bfe2010-02-09 08:03:39936 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
937 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:07938 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:23939
[email protected]49639fa2011-12-20 23:22:41940 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:23941
[email protected]49639fa2011-12-20 23:22:41942 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:42943 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]ef0faf2e72009-03-05 23:27:23944
945 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:42946 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:23947
[email protected]1c773ea12009-04-28 19:58:42948 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50949 ASSERT_TRUE(response != NULL);
[email protected]ef0faf2e72009-03-05 23:27:23950
951 // Check that the headers got parsed.
[email protected]90499482013-06-01 00:39:50952 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]ef0faf2e72009-03-05 23:27:23953 EXPECT_EQ(1234, response->headers->GetContentLength());
954 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
955
956 std::string server_header;
957 void* iter = NULL;
958 bool has_server_header = response->headers->EnumerateHeader(
959 &iter, "Server", &server_header);
960 EXPECT_TRUE(has_server_header);
961 EXPECT_EQ("Blah", server_header);
962
963 // Reading should give EOF right away, since there is no message body
964 // (despite non-zero content-length).
965 std::string response_data;
966 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:42967 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:23968 EXPECT_EQ("", response_data);
969}
970
[email protected]23e482282013-06-14 16:08:02971TEST_P(HttpNetworkTransactionTest, ReuseConnection) {
[email protected]bb88e1d32013-05-03 23:11:07972 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:52973
974 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35975 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
976 MockRead("hello"),
977 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
978 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:06979 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:52980 };
[email protected]31a2bfe2010-02-09 08:03:39981 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:07982 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:52983
[email protected]0b0bf032010-09-21 18:08:50984 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:52985 "hello", "world"
986 };
987
988 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:42989 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:52990 request.method = "GET";
991 request.url = GURL("http://www.google.com/");
992 request.load_flags = 0;
993
[email protected]262eec82013-03-19 21:01:36994 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:50995 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:27996
[email protected]49639fa2011-12-20 23:22:41997 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52998
[email protected]49639fa2011-12-20 23:22:41999 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421000 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521001
1002 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421003 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521004
[email protected]1c773ea12009-04-28 19:58:421005 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501006 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521007
[email protected]90499482013-06-01 00:39:501008 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251009 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521010
1011 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571012 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421013 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251014 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521015 }
1016}
1017
[email protected]23e482282013-06-14 16:08:021018TEST_P(HttpNetworkTransactionTest, Ignores100) {
[email protected]b2d26cfd2012-12-11 10:36:061019 ScopedVector<UploadElementReader> element_readers;
1020 element_readers.push_back(new UploadBytesElementReader("foo", 3));
1021 UploadDataStream upload_data_stream(&element_readers, 0);
[email protected]329b68b2012-11-14 17:54:271022
[email protected]1c773ea12009-04-28 19:58:421023 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521024 request.method = "POST";
1025 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271026 request.upload_data_stream = &upload_data_stream;
initial.commit586acc5fe2008-07-26 22:42:521027 request.load_flags = 0;
1028
[email protected]cb9bf6ca2011-01-28 13:15:271029 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:361030 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:071031 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:271032
initial.commit586acc5fe2008-07-26 22:42:521033 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351034 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1035 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1036 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061037 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521038 };
[email protected]31a2bfe2010-02-09 08:03:391039 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071040 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521041
[email protected]49639fa2011-12-20 23:22:411042 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521043
[email protected]49639fa2011-12-20 23:22:411044 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421045 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521046
1047 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421048 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521049
[email protected]1c773ea12009-04-28 19:58:421050 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501051 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521052
[email protected]90499482013-06-01 00:39:501053 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251054 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521055
1056 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571057 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421058 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251059 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521060}
1061
[email protected]3a2d3662009-03-27 03:49:141062// This test is almost the same as Ignores100 above, but the response contains
1063// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571064// HTTP/1.1 and the two status headers are read in one read.
[email protected]23e482282013-06-14 16:08:021065TEST_P(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421066 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141067 request.method = "GET";
1068 request.url = GURL("http://www.foo.com/");
1069 request.load_flags = 0;
1070
[email protected]cb9bf6ca2011-01-28 13:15:271071 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:361072 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:071073 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:271074
[email protected]3a2d3662009-03-27 03:49:141075 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571076 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1077 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141078 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061079 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141080 };
[email protected]31a2bfe2010-02-09 08:03:391081 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071082 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141083
[email protected]49639fa2011-12-20 23:22:411084 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141085
[email protected]49639fa2011-12-20 23:22:411086 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421087 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3a2d3662009-03-27 03:49:141088
1089 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421090 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:141091
[email protected]1c773ea12009-04-28 19:58:421092 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501093 ASSERT_TRUE(response != NULL);
[email protected]3a2d3662009-03-27 03:49:141094
[email protected]90499482013-06-01 00:39:501095 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3a2d3662009-03-27 03:49:141096 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1097
1098 std::string response_data;
1099 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421100 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:141101 EXPECT_EQ("hello world", response_data);
1102}
1103
[email protected]23e482282013-06-14 16:08:021104TEST_P(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
[email protected]ee9410e72010-01-07 01:42:381105 HttpRequestInfo request;
1106 request.method = "POST";
1107 request.url = GURL("http://www.foo.com/");
1108 request.load_flags = 0;
1109
[email protected]cb9bf6ca2011-01-28 13:15:271110 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:361111 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:071112 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:271113
[email protected]ee9410e72010-01-07 01:42:381114 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061115 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1116 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381117 };
[email protected]31a2bfe2010-02-09 08:03:391118 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071119 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381120
[email protected]49639fa2011-12-20 23:22:411121 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381122
[email protected]49639fa2011-12-20 23:22:411123 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]ee9410e72010-01-07 01:42:381124 EXPECT_EQ(ERR_IO_PENDING, rv);
1125
1126 rv = callback.WaitForResult();
1127 EXPECT_EQ(OK, rv);
1128
1129 std::string response_data;
1130 rv = ReadTransaction(trans.get(), &response_data);
1131 EXPECT_EQ(OK, rv);
1132 EXPECT_EQ("", response_data);
1133}
1134
[email protected]23e482282013-06-14 16:08:021135TEST_P(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381136 HttpRequestInfo request;
1137 request.method = "POST";
1138 request.url = GURL("http://www.foo.com/");
1139 request.load_flags = 0;
1140
[email protected]cb9bf6ca2011-01-28 13:15:271141 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:361142 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:071143 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:271144
[email protected]ee9410e72010-01-07 01:42:381145 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061146 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381147 };
[email protected]31a2bfe2010-02-09 08:03:391148 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071149 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381150
[email protected]49639fa2011-12-20 23:22:411151 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381152
[email protected]49639fa2011-12-20 23:22:411153 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]ee9410e72010-01-07 01:42:381154 EXPECT_EQ(ERR_IO_PENDING, rv);
1155
1156 rv = callback.WaitForResult();
1157 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
1158}
1159
[email protected]23e482282013-06-14 16:08:021160void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511161 const MockWrite* write_failure,
1162 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421163 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521164 request.method = "GET";
1165 request.url = GURL("http://www.foo.com/");
1166 request.load_flags = 0;
1167
[email protected]58e32bb2013-01-21 18:23:251168 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071169 session_deps_.net_log = &net_log;
1170 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271171
[email protected]202965992011-12-07 23:04:511172 // Written data for successfully sending both requests.
1173 MockWrite data1_writes[] = {
1174 MockWrite("GET / HTTP/1.1\r\n"
1175 "Host: www.foo.com\r\n"
1176 "Connection: keep-alive\r\n\r\n"),
1177 MockWrite("GET / HTTP/1.1\r\n"
1178 "Host: www.foo.com\r\n"
1179 "Connection: keep-alive\r\n\r\n")
1180 };
1181
1182 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521183 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351184 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1185 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061186 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521187 };
[email protected]202965992011-12-07 23:04:511188
1189 if (write_failure) {
1190 ASSERT_TRUE(!read_failure);
1191 data1_writes[1] = *write_failure;
1192 } else {
1193 ASSERT_TRUE(read_failure);
1194 data1_reads[2] = *read_failure;
1195 }
1196
1197 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
1198 data1_writes, arraysize(data1_writes));
[email protected]bb88e1d32013-05-03 23:11:071199 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521200
1201 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351202 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1203 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061204 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521205 };
[email protected]31a2bfe2010-02-09 08:03:391206 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071207 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521208
1209 const char* kExpectedResponseData[] = {
1210 "hello", "world"
1211 };
1212
[email protected]58e32bb2013-01-21 18:23:251213 uint32 first_socket_log_id = NetLog::Source::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521214 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411215 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521216
[email protected]262eec82013-03-19 21:01:361217 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501218 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
initial.commit586acc5fe2008-07-26 22:42:521219
[email protected]49639fa2011-12-20 23:22:411220 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421221 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521222
1223 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421224 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521225
[email protected]58e32bb2013-01-21 18:23:251226 LoadTimingInfo load_timing_info;
1227 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1228 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1229 if (i == 0) {
1230 first_socket_log_id = load_timing_info.socket_log_id;
1231 } else {
1232 // The second request should be using a new socket.
1233 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1234 }
1235
[email protected]1c773ea12009-04-28 19:58:421236 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501237 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521238
[email protected]90499482013-06-01 00:39:501239 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251240 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521241
1242 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571243 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421244 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251245 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521246 }
1247}
[email protected]3d2a59b2008-09-26 19:44:251248
[email protected]23e482282013-06-14 16:08:021249TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:231250 KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061251 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]202965992011-12-07 23:04:511252 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1253}
1254
[email protected]23e482282013-06-14 16:08:021255TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061256 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]202965992011-12-07 23:04:511257 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251258}
1259
[email protected]23e482282013-06-14 16:08:021260TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061261 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]202965992011-12-07 23:04:511262 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251263}
1264
[email protected]23e482282013-06-14 16:08:021265TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:421266 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:251267 request.method = "GET";
1268 request.url = GURL("http://www.google.com/");
1269 request.load_flags = 0;
1270
[email protected]cb9bf6ca2011-01-28 13:15:271271 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:361272 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:071273 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:271274
[email protected]3d2a59b2008-09-26 19:44:251275 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061276 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:351277 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1278 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061279 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251280 };
[email protected]31a2bfe2010-02-09 08:03:391281 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071282 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:251283
[email protected]49639fa2011-12-20 23:22:411284 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:251285
[email protected]49639fa2011-12-20 23:22:411286 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421287 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3d2a59b2008-09-26 19:44:251288
1289 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421290 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]3d2a59b2008-09-26 19:44:251291
[email protected]1c773ea12009-04-28 19:58:421292 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]3d2a59b2008-09-26 19:44:251293 EXPECT_TRUE(response == NULL);
[email protected]3d2a59b2008-09-26 19:44:251294}
1295
1296// What do various browsers do when the server closes a non-keepalive
1297// connection without sending any response header or body?
1298//
1299// IE7: error page
1300// Safari 3.1.2 (Windows): error page
1301// Firefox 3.0.1: blank page
1302// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:421303// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1304// Us: error page (EMPTY_RESPONSE)
[email protected]23e482282013-06-14 16:08:021305TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:251306 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061307 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:351308 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1309 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061310 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251311 };
[email protected]31a2bfe2010-02-09 08:03:391312 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1313 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:421314 EXPECT_EQ(ERR_EMPTY_RESPONSE, out.rv);
[email protected]3d2a59b2008-09-26 19:44:251315}
[email protected]038e9a32008-10-08 22:40:161316
[email protected]7a5378b2012-11-04 03:25:171317// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
1318// tests. There was a bug causing HttpNetworkTransaction to hang in the
1319// destructor in such situations.
1320// See http://crbug.com/154712 and http://crbug.com/156609.
[email protected]23e482282013-06-14 16:08:021321TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:171322 HttpRequestInfo request;
1323 request.method = "GET";
1324 request.url = GURL("http://www.google.com/");
1325 request.load_flags = 0;
1326
[email protected]bb88e1d32013-05-03 23:11:071327 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:361328 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501329 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171330
1331 MockRead data_reads[] = {
1332 MockRead("HTTP/1.0 200 OK\r\n"),
1333 MockRead("Connection: keep-alive\r\n"),
1334 MockRead("Content-Length: 100\r\n\r\n"),
1335 MockRead("hello"),
1336 MockRead(SYNCHRONOUS, 0),
1337 };
1338 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071339 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171340
1341 TestCompletionCallback callback;
1342
1343 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1344 EXPECT_EQ(ERR_IO_PENDING, rv);
1345
1346 rv = callback.WaitForResult();
1347 EXPECT_EQ(OK, rv);
1348
1349 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501350 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171351 if (rv == ERR_IO_PENDING)
1352 rv = callback.WaitForResult();
1353 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:501354 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171355 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1356
1357 trans.reset();
[email protected]2da659e2013-05-23 20:51:341358 base::MessageLoop::current()->RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171359 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1360}
1361
[email protected]23e482282013-06-14 16:08:021362TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:171363 HttpRequestInfo request;
1364 request.method = "GET";
1365 request.url = GURL("http://www.google.com/");
1366 request.load_flags = 0;
1367
[email protected]bb88e1d32013-05-03 23:11:071368 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:361369 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501370 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171371
1372 MockRead data_reads[] = {
1373 MockRead("HTTP/1.0 200 OK\r\n"),
1374 MockRead("Connection: keep-alive\r\n"),
1375 MockRead("Content-Length: 100\r\n\r\n"),
1376 MockRead(SYNCHRONOUS, 0),
1377 };
1378 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071379 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171380
1381 TestCompletionCallback callback;
1382
1383 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1384 EXPECT_EQ(ERR_IO_PENDING, rv);
1385
1386 rv = callback.WaitForResult();
1387 EXPECT_EQ(OK, rv);
1388
1389 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501390 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171391 if (rv == ERR_IO_PENDING)
1392 rv = callback.WaitForResult();
1393 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1394
1395 trans.reset();
[email protected]2da659e2013-05-23 20:51:341396 base::MessageLoop::current()->RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171397 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1398}
1399
[email protected]0b0bf032010-09-21 18:08:501400// Test that we correctly reuse a keep-alive connection after not explicitly
1401// reading the body.
[email protected]23e482282013-06-14 16:08:021402TEST_P(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:131403 HttpRequestInfo request;
1404 request.method = "GET";
1405 request.url = GURL("http://www.foo.com/");
1406 request.load_flags = 0;
1407
[email protected]58e32bb2013-01-21 18:23:251408 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071409 session_deps_.net_log = &net_log;
1410 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271411
[email protected]0b0bf032010-09-21 18:08:501412 // Note that because all these reads happen in the same
1413 // StaticSocketDataProvider, it shows that the same socket is being reused for
1414 // all transactions.
[email protected]fc31d6a42010-06-24 18:05:131415 MockRead data1_reads[] = {
[email protected]0b0bf032010-09-21 18:08:501416 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
1417 MockRead("HTTP/1.1 205 Reset Content\r\n\r\n"),
[email protected]fc31d6a42010-06-24 18:05:131418 MockRead("HTTP/1.1 304 Not Modified\r\n\r\n"),
[email protected]0b0bf032010-09-21 18:08:501419 MockRead("HTTP/1.1 302 Found\r\n"
1420 "Content-Length: 0\r\n\r\n"),
1421 MockRead("HTTP/1.1 302 Found\r\n"
1422 "Content-Length: 5\r\n\r\n"
1423 "hello"),
1424 MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1425 "Content-Length: 0\r\n\r\n"),
1426 MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1427 "Content-Length: 5\r\n\r\n"
1428 "hello"),
[email protected]fc31d6a42010-06-24 18:05:131429 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1430 MockRead("hello"),
1431 };
1432 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071433 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]fc31d6a42010-06-24 18:05:131434
1435 MockRead data2_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061436 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]fc31d6a42010-06-24 18:05:131437 };
1438 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071439 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]fc31d6a42010-06-24 18:05:131440
[email protected]0b0bf032010-09-21 18:08:501441 const int kNumUnreadBodies = arraysize(data1_reads) - 2;
1442 std::string response_lines[kNumUnreadBodies];
1443
[email protected]58e32bb2013-01-21 18:23:251444 uint32 first_socket_log_id = NetLog::Source::kInvalidId;
[email protected]0b0bf032010-09-21 18:08:501445 for (size_t i = 0; i < arraysize(data1_reads) - 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411446 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:131447
[email protected]262eec82013-03-19 21:01:361448 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501449 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]fc31d6a42010-06-24 18:05:131450
[email protected]49639fa2011-12-20 23:22:411451 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]fc31d6a42010-06-24 18:05:131452 EXPECT_EQ(ERR_IO_PENDING, rv);
1453
1454 rv = callback.WaitForResult();
1455 EXPECT_EQ(OK, rv);
1456
[email protected]58e32bb2013-01-21 18:23:251457 LoadTimingInfo load_timing_info;
1458 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1459 if (i == 0) {
1460 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1461 first_socket_log_id = load_timing_info.socket_log_id;
1462 } else {
1463 TestLoadTimingReused(load_timing_info);
1464 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
1465 }
1466
[email protected]fc31d6a42010-06-24 18:05:131467 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]0b0bf032010-09-21 18:08:501468 ASSERT_TRUE(response != NULL);
[email protected]fc31d6a42010-06-24 18:05:131469
[email protected]90499482013-06-01 00:39:501470 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]0b0bf032010-09-21 18:08:501471 response_lines[i] = response->headers->GetStatusLine();
1472
1473 // We intentionally don't read the response bodies.
[email protected]fc31d6a42010-06-24 18:05:131474 }
[email protected]0b0bf032010-09-21 18:08:501475
1476 const char* const kStatusLines[] = {
1477 "HTTP/1.1 204 No Content",
1478 "HTTP/1.1 205 Reset Content",
1479 "HTTP/1.1 304 Not Modified",
1480 "HTTP/1.1 302 Found",
1481 "HTTP/1.1 302 Found",
1482 "HTTP/1.1 301 Moved Permanently",
1483 "HTTP/1.1 301 Moved Permanently",
1484 };
1485
1486 COMPILE_ASSERT(kNumUnreadBodies == arraysize(kStatusLines),
1487 forgot_to_update_kStatusLines);
1488
1489 for (int i = 0; i < kNumUnreadBodies; ++i)
1490 EXPECT_EQ(kStatusLines[i], response_lines[i]);
1491
[email protected]49639fa2011-12-20 23:22:411492 TestCompletionCallback callback;
[email protected]262eec82013-03-19 21:01:361493 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501494 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:411495 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0b0bf032010-09-21 18:08:501496 EXPECT_EQ(ERR_IO_PENDING, rv);
1497 rv = callback.WaitForResult();
1498 EXPECT_EQ(OK, rv);
1499 const HttpResponseInfo* response = trans->GetResponseInfo();
1500 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:501501 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]0b0bf032010-09-21 18:08:501502 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1503 std::string response_data;
1504 rv = ReadTransaction(trans.get(), &response_data);
1505 EXPECT_EQ(OK, rv);
1506 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:131507}
1508
[email protected]038e9a32008-10-08 22:40:161509// Test the request-challenge-retry sequence for basic auth.
1510// (basic auth is the easiest to mock, because it has no randomness).
[email protected]23e482282013-06-14 16:08:021511TEST_P(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:421512 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:161513 request.method = "GET";
1514 request.url = GURL("http://www.google.com/");
1515 request.load_flags = 0;
1516
[email protected]58e32bb2013-01-21 18:23:251517 CapturingNetLog log;
[email protected]bb88e1d32013-05-03 23:11:071518 session_deps_.net_log = &log;
[email protected]cb9bf6ca2011-01-28 13:15:271519 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:361520 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:071521 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:271522
[email protected]f9ee6b52008-11-08 06:46:231523 MockWrite data_writes1[] = {
1524 MockWrite("GET / HTTP/1.1\r\n"
1525 "Host: www.google.com\r\n"
1526 "Connection: keep-alive\r\n\r\n"),
1527 };
1528
[email protected]038e9a32008-10-08 22:40:161529 MockRead data_reads1[] = {
1530 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
1531 // Give a couple authenticate options (only the middle one is actually
1532 // supported).
[email protected]22927ad2009-09-21 19:56:191533 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:161534 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1535 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
1536 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1537 // Large content-length -- won't matter, as connection will be reset.
1538 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061539 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:161540 };
1541
1542 // After calling trans->RestartWithAuth(), this is the request we should
1543 // be issuing -- the final header line contains the credentials.
1544 MockWrite data_writes2[] = {
1545 MockWrite("GET / HTTP/1.1\r\n"
1546 "Host: www.google.com\r\n"
1547 "Connection: keep-alive\r\n"
1548 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1549 };
1550
1551 // Lastly, the server responds with the actual content.
1552 MockRead data_reads2[] = {
1553 MockRead("HTTP/1.0 200 OK\r\n"),
1554 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1555 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061556 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:161557 };
1558
[email protected]31a2bfe2010-02-09 08:03:391559 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1560 data_writes1, arraysize(data_writes1));
1561 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1562 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:071563 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1564 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:161565
[email protected]49639fa2011-12-20 23:22:411566 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:161567
[email protected]49639fa2011-12-20 23:22:411568 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421569 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:161570
1571 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421572 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:161573
[email protected]58e32bb2013-01-21 18:23:251574 LoadTimingInfo load_timing_info1;
1575 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
1576 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
1577
[email protected]1c773ea12009-04-28 19:58:421578 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501579 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:041580 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:161581
[email protected]49639fa2011-12-20 23:22:411582 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:161583
[email protected]49639fa2011-12-20 23:22:411584 rv = trans->RestartWithAuth(
1585 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:421586 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:161587
1588 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421589 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:161590
[email protected]58e32bb2013-01-21 18:23:251591 LoadTimingInfo load_timing_info2;
1592 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
1593 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
1594 // The load timing after restart should have a new socket ID, and times after
1595 // those of the first load timing.
1596 EXPECT_LE(load_timing_info1.receive_headers_end,
1597 load_timing_info2.connect_timing.connect_start);
1598 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
1599
[email protected]038e9a32008-10-08 22:40:161600 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501601 ASSERT_TRUE(response != NULL);
[email protected]038e9a32008-10-08 22:40:161602 EXPECT_TRUE(response->auth_challenge.get() == NULL);
1603 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:161604}
1605
[email protected]23e482282013-06-14 16:08:021606TEST_P(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:461607 HttpRequestInfo request;
1608 request.method = "GET";
1609 request.url = GURL("http://www.google.com/");
1610 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
1611
[email protected]cb9bf6ca2011-01-28 13:15:271612 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:361613 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:071614 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:271615
[email protected]861fcd52009-08-26 02:33:461616 MockWrite data_writes[] = {
1617 MockWrite("GET / HTTP/1.1\r\n"
1618 "Host: www.google.com\r\n"
1619 "Connection: keep-alive\r\n\r\n"),
1620 };
1621
1622 MockRead data_reads[] = {
1623 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
1624 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1625 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1626 // Large content-length -- won't matter, as connection will be reset.
1627 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061628 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:461629 };
1630
[email protected]31a2bfe2010-02-09 08:03:391631 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
1632 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:071633 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:411634 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:461635
[email protected]49639fa2011-12-20 23:22:411636 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]861fcd52009-08-26 02:33:461637 EXPECT_EQ(ERR_IO_PENDING, rv);
1638
1639 rv = callback.WaitForResult();
1640 EXPECT_EQ(0, rv);
1641
1642 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501643 ASSERT_TRUE(response != NULL);
[email protected]861fcd52009-08-26 02:33:461644 EXPECT_TRUE(response->auth_challenge.get() == NULL);
1645}
1646
[email protected]2d2697f92009-02-18 21:00:321647// Test the request-challenge-retry sequence for basic auth, over a keep-alive
1648// connection.
[email protected]23e482282013-06-14 16:08:021649TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
[email protected]1c773ea12009-04-28 19:58:421650 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:321651 request.method = "GET";
1652 request.url = GURL("http://www.google.com/");
1653 request.load_flags = 0;
1654
[email protected]58e32bb2013-01-21 18:23:251655 CapturingNetLog log;
[email protected]bb88e1d32013-05-03 23:11:071656 session_deps_.net_log = &log;
1657 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271658
[email protected]2d2697f92009-02-18 21:00:321659 MockWrite data_writes1[] = {
1660 MockWrite("GET / HTTP/1.1\r\n"
1661 "Host: www.google.com\r\n"
1662 "Connection: keep-alive\r\n\r\n"),
1663
1664 // After calling trans->RestartWithAuth(), this is the request we should
1665 // be issuing -- the final header line contains the credentials.
1666 MockWrite("GET / HTTP/1.1\r\n"
1667 "Host: www.google.com\r\n"
1668 "Connection: keep-alive\r\n"
1669 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1670 };
1671
1672 MockRead data_reads1[] = {
1673 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
1674 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1675 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1676 MockRead("Content-Length: 14\r\n\r\n"),
1677 MockRead("Unauthorized\r\n"),
1678
1679 // Lastly, the server responds with the actual content.
1680 MockRead("HTTP/1.1 200 OK\r\n"),
1681 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:501682 MockRead("Content-Length: 5\r\n\r\n"),
1683 MockRead("Hello"),
[email protected]2d2697f92009-02-18 21:00:321684 };
1685
[email protected]2d0a4f92011-05-05 16:38:461686 // If there is a regression where we disconnect a Keep-Alive
1687 // connection during an auth roundtrip, we'll end up reading this.
1688 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:061689 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:461690 };
1691
[email protected]31a2bfe2010-02-09 08:03:391692 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1693 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:461694 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1695 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071696 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1697 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:321698
[email protected]49639fa2011-12-20 23:22:411699 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:321700
[email protected]262eec82013-03-19 21:01:361701 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501702 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:411703 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421704 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:321705
1706 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421707 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:321708
[email protected]58e32bb2013-01-21 18:23:251709 LoadTimingInfo load_timing_info1;
1710 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
1711 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
1712
[email protected]1c773ea12009-04-28 19:58:421713 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501714 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:041715 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:321716
[email protected]49639fa2011-12-20 23:22:411717 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:321718
[email protected]49639fa2011-12-20 23:22:411719 rv = trans->RestartWithAuth(
1720 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:421721 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:321722
1723 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421724 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:321725
[email protected]58e32bb2013-01-21 18:23:251726 LoadTimingInfo load_timing_info2;
1727 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
1728 TestLoadTimingReused(load_timing_info2);
1729 // The load timing after restart should have the same socket ID, and times
1730 // those of the first load timing.
1731 EXPECT_LE(load_timing_info1.receive_headers_end,
1732 load_timing_info2.send_start);
1733 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
1734
[email protected]2d2697f92009-02-18 21:00:321735 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501736 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:321737 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:501738 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:321739}
1740
1741// Test the request-challenge-retry sequence for basic auth, over a keep-alive
1742// connection and with no response body to drain.
[email protected]23e482282013-06-14 16:08:021743TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:421744 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:321745 request.method = "GET";
1746 request.url = GURL("http://www.google.com/");
1747 request.load_flags = 0;
1748
[email protected]bb88e1d32013-05-03 23:11:071749 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271750
[email protected]2d2697f92009-02-18 21:00:321751 MockWrite data_writes1[] = {
1752 MockWrite("GET / HTTP/1.1\r\n"
1753 "Host: www.google.com\r\n"
1754 "Connection: keep-alive\r\n\r\n"),
1755
1756 // After calling trans->RestartWithAuth(), this is the request we should
1757 // be issuing -- the final header line contains the credentials.
1758 MockWrite("GET / HTTP/1.1\r\n"
1759 "Host: www.google.com\r\n"
1760 "Connection: keep-alive\r\n"
1761 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1762 };
1763
[email protected]2d2697f92009-02-18 21:00:321764 MockRead data_reads1[] = {
1765 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
1766 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:311767 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:321768
1769 // Lastly, the server responds with the actual content.
1770 MockRead("HTTP/1.1 200 OK\r\n"),
1771 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:501772 MockRead("Content-Length: 5\r\n\r\n"),
1773 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:321774 };
1775
[email protected]2d0a4f92011-05-05 16:38:461776 // An incorrect reconnect would cause this to be read.
1777 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:061778 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:461779 };
1780
[email protected]31a2bfe2010-02-09 08:03:391781 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1782 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:461783 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1784 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071785 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1786 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:321787
[email protected]49639fa2011-12-20 23:22:411788 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:321789
[email protected]262eec82013-03-19 21:01:361790 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501791 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:411792 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421793 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:321794
1795 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421796 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:321797
[email protected]1c773ea12009-04-28 19:58:421798 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501799 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:041800 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:321801
[email protected]49639fa2011-12-20 23:22:411802 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:321803
[email protected]49639fa2011-12-20 23:22:411804 rv = trans->RestartWithAuth(
1805 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:421806 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:321807
1808 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421809 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:321810
1811 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501812 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:321813 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:501814 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:321815}
1816
1817// Test the request-challenge-retry sequence for basic auth, over a keep-alive
1818// connection and with a large response body to drain.
[email protected]23e482282013-06-14 16:08:021819TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:421820 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:321821 request.method = "GET";
1822 request.url = GURL("http://www.google.com/");
1823 request.load_flags = 0;
1824
[email protected]bb88e1d32013-05-03 23:11:071825 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271826
[email protected]2d2697f92009-02-18 21:00:321827 MockWrite data_writes1[] = {
1828 MockWrite("GET / HTTP/1.1\r\n"
1829 "Host: www.google.com\r\n"
1830 "Connection: keep-alive\r\n\r\n"),
1831
1832 // After calling trans->RestartWithAuth(), this is the request we should
1833 // be issuing -- the final header line contains the credentials.
1834 MockWrite("GET / HTTP/1.1\r\n"
1835 "Host: www.google.com\r\n"
1836 "Connection: keep-alive\r\n"
1837 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1838 };
1839
1840 // Respond with 5 kb of response body.
1841 std::string large_body_string("Unauthorized");
1842 large_body_string.append(5 * 1024, ' ');
1843 large_body_string.append("\r\n");
1844
1845 MockRead data_reads1[] = {
1846 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
1847 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1848 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1849 // 5134 = 12 + 5 * 1024 + 2
1850 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061851 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:321852
1853 // Lastly, the server responds with the actual content.
1854 MockRead("HTTP/1.1 200 OK\r\n"),
1855 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:501856 MockRead("Content-Length: 5\r\n\r\n"),
1857 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:321858 };
1859
[email protected]2d0a4f92011-05-05 16:38:461860 // An incorrect reconnect would cause this to be read.
1861 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:061862 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:461863 };
1864
[email protected]31a2bfe2010-02-09 08:03:391865 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1866 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:461867 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1868 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071869 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1870 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:321871
[email protected]49639fa2011-12-20 23:22:411872 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:321873
[email protected]262eec82013-03-19 21:01:361874 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501875 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:411876 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421877 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:321878
1879 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421880 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:321881
[email protected]1c773ea12009-04-28 19:58:421882 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501883 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:041884 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:321885
[email protected]49639fa2011-12-20 23:22:411886 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:321887
[email protected]49639fa2011-12-20 23:22:411888 rv = trans->RestartWithAuth(
1889 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:421890 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:321891
1892 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421893 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:321894
1895 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501896 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:321897 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:501898 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:321899}
1900
1901// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:311902// connection, but the server gets impatient and closes the connection.
[email protected]23e482282013-06-14 16:08:021903TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:311904 HttpRequestInfo request;
1905 request.method = "GET";
1906 request.url = GURL("http://www.google.com/");
1907 request.load_flags = 0;
1908
[email protected]bb88e1d32013-05-03 23:11:071909 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271910
[email protected]11203f012009-11-12 23:02:311911 MockWrite data_writes1[] = {
1912 MockWrite("GET / HTTP/1.1\r\n"
1913 "Host: www.google.com\r\n"
1914 "Connection: keep-alive\r\n\r\n"),
1915 // This simulates the seemingly successful write to a closed connection
1916 // if the bug is not fixed.
1917 MockWrite("GET / HTTP/1.1\r\n"
1918 "Host: www.google.com\r\n"
1919 "Connection: keep-alive\r\n"
1920 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1921 };
1922
1923 MockRead data_reads1[] = {
1924 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
1925 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1926 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1927 MockRead("Content-Length: 14\r\n\r\n"),
1928 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:061929 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:311930 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:061931 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:311932 };
1933
1934 // After calling trans->RestartWithAuth(), this is the request we should
1935 // be issuing -- the final header line contains the credentials.
1936 MockWrite data_writes2[] = {
1937 MockWrite("GET / HTTP/1.1\r\n"
1938 "Host: www.google.com\r\n"
1939 "Connection: keep-alive\r\n"
1940 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1941 };
1942
1943 // Lastly, the server responds with the actual content.
1944 MockRead data_reads2[] = {
1945 MockRead("HTTP/1.1 200 OK\r\n"),
1946 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:501947 MockRead("Content-Length: 5\r\n\r\n"),
1948 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:311949 };
1950
[email protected]31a2bfe2010-02-09 08:03:391951 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1952 data_writes1, arraysize(data_writes1));
1953 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1954 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:071955 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1956 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:311957
[email protected]49639fa2011-12-20 23:22:411958 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:311959
[email protected]262eec82013-03-19 21:01:361960 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501961 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:411962 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]11203f012009-11-12 23:02:311963 EXPECT_EQ(ERR_IO_PENDING, rv);
1964
1965 rv = callback1.WaitForResult();
1966 EXPECT_EQ(OK, rv);
1967
1968 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501969 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:041970 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:311971
[email protected]49639fa2011-12-20 23:22:411972 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:311973
[email protected]49639fa2011-12-20 23:22:411974 rv = trans->RestartWithAuth(
1975 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]11203f012009-11-12 23:02:311976 EXPECT_EQ(ERR_IO_PENDING, rv);
1977
1978 rv = callback2.WaitForResult();
1979 EXPECT_EQ(OK, rv);
1980
1981 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501982 ASSERT_TRUE(response != NULL);
[email protected]11203f012009-11-12 23:02:311983 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:501984 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:311985}
1986
[email protected]394816e92010-08-03 07:38:591987// Test the request-challenge-retry sequence for basic auth, over a connection
1988// that requires a restart when setting up an SSL tunnel.
[email protected]23e482282013-06-14 16:08:021989TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAlive) {
[email protected]394816e92010-08-03 07:38:591990 HttpRequestInfo request;
1991 request.method = "GET";
1992 request.url = GURL("https://www.google.com/");
1993 // when the no authentication data flag is set.
1994 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
1995
[email protected]cb9bf6ca2011-01-28 13:15:271996 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:071997 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:201998 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
[email protected]333bdf62012-06-08 22:57:291999 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072000 session_deps_.net_log = log.bound().net_log();
2001 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272002
[email protected]394816e92010-08-03 07:38:592003 // Since we have proxy, should try to establish tunnel.
2004 MockWrite data_writes1[] = {
2005 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2006 "Host: www.google.com\r\n"
2007 "Proxy-Connection: keep-alive\r\n\r\n"),
2008
2009 // After calling trans->RestartWithAuth(), this is the request we should
2010 // be issuing -- the final header line contains the credentials.
2011 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2012 "Host: www.google.com\r\n"
2013 "Proxy-Connection: keep-alive\r\n"
2014 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2015
2016 MockWrite("GET / HTTP/1.1\r\n"
2017 "Host: www.google.com\r\n"
2018 "Connection: keep-alive\r\n\r\n"),
2019 };
2020
2021 // The proxy responds to the connect with a 407, using a persistent
2022 // connection.
2023 MockRead data_reads1[] = {
2024 // No credentials.
2025 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2026 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2027 MockRead("Proxy-Connection: close\r\n\r\n"),
2028
2029 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2030
2031 MockRead("HTTP/1.1 200 OK\r\n"),
2032 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502033 MockRead("Content-Length: 5\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062034 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:592035 };
2036
2037 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2038 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072039 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:062040 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072041 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:592042
[email protected]49639fa2011-12-20 23:22:412043 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:592044
[email protected]262eec82013-03-19 21:01:362045 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502046 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:502047
[email protected]49639fa2011-12-20 23:22:412048 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]394816e92010-08-03 07:38:592049 EXPECT_EQ(ERR_IO_PENDING, rv);
2050
2051 rv = callback1.WaitForResult();
2052 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:572053 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:402054 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:592055 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402056 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]394816e92010-08-03 07:38:592057 NetLog::PHASE_NONE);
2058 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402059 entries, pos,
[email protected]394816e92010-08-03 07:38:592060 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2061 NetLog::PHASE_NONE);
2062
2063 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502064 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502065 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]394816e92010-08-03 07:38:592066 EXPECT_EQ(407, response->headers->response_code());
2067 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042068 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:592069
[email protected]029c83b62013-01-24 05:28:202070 LoadTimingInfo load_timing_info;
2071 // CONNECT requests and responses are handled at the connect job level, so
2072 // the transaction does not yet have a connection.
2073 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
2074
[email protected]49639fa2011-12-20 23:22:412075 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:592076
[email protected]49639fa2011-12-20 23:22:412077 rv = trans->RestartWithAuth(
2078 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]394816e92010-08-03 07:38:592079 EXPECT_EQ(ERR_IO_PENDING, rv);
2080
2081 rv = callback2.WaitForResult();
2082 EXPECT_EQ(OK, rv);
2083
2084 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502085 ASSERT_TRUE(response != NULL);
[email protected]394816e92010-08-03 07:38:592086
2087 EXPECT_TRUE(response->headers->IsKeepAlive());
2088 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:502089 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:592090 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2091
2092 // The password prompt info should not be set.
2093 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502094
[email protected]029c83b62013-01-24 05:28:202095 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2096 TestLoadTimingNotReusedWithPac(load_timing_info,
2097 CONNECT_TIMING_HAS_SSL_TIMES);
2098
[email protected]0b0bf032010-09-21 18:08:502099 trans.reset();
[email protected]102e27c2011-02-23 01:01:312100 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:592101}
2102
[email protected]11203f012009-11-12 23:02:312103// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]2d2697f92009-02-18 21:00:322104// proxy connection, when setting up an SSL tunnel.
[email protected]23e482282013-06-14 16:08:022105TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAlive) {
[email protected]cb9bf6ca2011-01-28 13:15:272106 HttpRequestInfo request;
2107 request.method = "GET";
2108 request.url = GURL("https://www.google.com/");
2109 // Ensure that proxy authentication is attempted even
2110 // when the no authentication data flag is set.
2111 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
2112
[email protected]2d2697f92009-02-18 21:00:322113 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072114 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]333bdf62012-06-08 22:57:292115 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072116 session_deps_.net_log = log.bound().net_log();
2117 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:322118
[email protected]262eec82013-03-19 21:01:362119 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502120 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d2697f92009-02-18 21:00:322121
[email protected]2d2697f92009-02-18 21:00:322122 // Since we have proxy, should try to establish tunnel.
2123 MockWrite data_writes1[] = {
2124 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:452125 "Host: www.google.com\r\n"
2126 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322127
2128 // After calling trans->RestartWithAuth(), this is the request we should
2129 // be issuing -- the final header line contains the credentials.
2130 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2131 "Host: www.google.com\r\n"
[email protected]e44de5d2009-06-05 20:12:452132 "Proxy-Connection: keep-alive\r\n"
[email protected]2d2697f92009-02-18 21:00:322133 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
2134 };
2135
2136 // The proxy responds to the connect with a 407, using a persistent
2137 // connection.
2138 MockRead data_reads1[] = {
2139 // No credentials.
2140 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2141 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2142 MockRead("Content-Length: 10\r\n\r\n"),
2143 MockRead("0123456789"),
2144
2145 // Wrong credentials (wrong password).
2146 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2147 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2148 MockRead("Content-Length: 10\r\n\r\n"),
2149 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:062150 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]2d2697f92009-02-18 21:00:322151 };
2152
[email protected]31a2bfe2010-02-09 08:03:392153 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2154 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072155 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d2697f92009-02-18 21:00:322156
[email protected]49639fa2011-12-20 23:22:412157 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322158
[email protected]49639fa2011-12-20 23:22:412159 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]1c773ea12009-04-28 19:58:422160 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322161
2162 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422163 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:572164 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:402165 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:392166 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402167 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]dbb83db2010-05-11 18:13:392168 NetLog::PHASE_NONE);
2169 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402170 entries, pos,
[email protected]dbb83db2010-05-11 18:13:392171 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2172 NetLog::PHASE_NONE);
[email protected]2d2697f92009-02-18 21:00:322173
[email protected]1c773ea12009-04-28 19:58:422174 const HttpResponseInfo* 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]2d2697f92009-02-18 21:00:322182
[email protected]49639fa2011-12-20 23:22:412183 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322184
2185 // Wrong password (should be "bar").
[email protected]49639fa2011-12-20 23:22:412186 rv = trans->RestartWithAuth(
2187 AuthCredentials(kFoo, kBaz), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422188 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322189
2190 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422191 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322192
2193 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502194 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502195 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]2d2697f92009-02-18 21:00:322196 EXPECT_TRUE(response->headers->IsKeepAlive());
2197 EXPECT_EQ(407, response->headers->response_code());
2198 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422199 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042200 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]e772db3f2010-07-12 18:11:132201
[email protected]e60e47a2010-07-14 03:37:182202 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
2203 // out of scope.
[email protected]102e27c2011-02-23 01:01:312204 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:322205}
2206
[email protected]a8e9b162009-03-12 00:06:442207// Test that we don't read the response body when we fail to establish a tunnel,
2208// even if the user cancels the proxy's auth attempt.
[email protected]23e482282013-06-14 16:08:022209TEST_P(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:272210 HttpRequestInfo request;
2211 request.method = "GET";
2212 request.url = GURL("https://www.google.com/");
2213 request.load_flags = 0;
2214
[email protected]a8e9b162009-03-12 00:06:442215 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072216 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]a8e9b162009-03-12 00:06:442217
[email protected]bb88e1d32013-05-03 23:11:072218 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:442219
[email protected]262eec82013-03-19 21:01:362220 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502221 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]a8e9b162009-03-12 00:06:442222
[email protected]a8e9b162009-03-12 00:06:442223 // Since we have proxy, should try to establish tunnel.
2224 MockWrite data_writes[] = {
2225 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:452226 "Host: www.google.com\r\n"
2227 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:442228 };
2229
2230 // The proxy responds to the connect with a 407.
2231 MockRead data_reads[] = {
2232 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2233 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2234 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062235 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]a8e9b162009-03-12 00:06:442236 };
2237
[email protected]31a2bfe2010-02-09 08:03:392238 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2239 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072240 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:442241
[email protected]49639fa2011-12-20 23:22:412242 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:442243
[email protected]49639fa2011-12-20 23:22:412244 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422245 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a8e9b162009-03-12 00:06:442246
2247 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422248 EXPECT_EQ(OK, rv);
[email protected]a8e9b162009-03-12 00:06:442249
[email protected]1c773ea12009-04-28 19:58:422250 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502251 ASSERT_TRUE(response != NULL);
[email protected]a8e9b162009-03-12 00:06:442252
2253 EXPECT_TRUE(response->headers->IsKeepAlive());
2254 EXPECT_EQ(407, response->headers->response_code());
2255 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422256 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:442257
2258 std::string response_data;
2259 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:422260 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]e60e47a2010-07-14 03:37:182261
2262 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:312263 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:442264}
2265
[email protected]8fdbcd22010-05-05 02:54:522266// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
2267// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
[email protected]23e482282013-06-14 16:08:022268TEST_P(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:522269 HttpRequestInfo request;
2270 request.method = "GET";
2271 request.url = GURL("http://www.google.com/");
2272 request.load_flags = 0;
2273
[email protected]cb9bf6ca2011-01-28 13:15:272274 // We are using a DIRECT connection (i.e. no proxy) for this session.
[email protected]cb9bf6ca2011-01-28 13:15:272275 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:362276 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:072277 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:272278
[email protected]8fdbcd22010-05-05 02:54:522279 MockWrite data_writes1[] = {
2280 MockWrite("GET / HTTP/1.1\r\n"
2281 "Host: www.google.com\r\n"
2282 "Connection: keep-alive\r\n\r\n"),
2283 };
2284
2285 MockRead data_reads1[] = {
2286 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
2287 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2288 // Large content-length -- won't matter, as connection will be reset.
2289 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062290 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:522291 };
2292
2293 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2294 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072295 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:522296
[email protected]49639fa2011-12-20 23:22:412297 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:522298
[email protected]49639fa2011-12-20 23:22:412299 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]8fdbcd22010-05-05 02:54:522300 EXPECT_EQ(ERR_IO_PENDING, rv);
2301
2302 rv = callback.WaitForResult();
2303 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
2304}
2305
[email protected]7a67a8152010-11-05 18:31:102306// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
2307// through a non-authenticating proxy. The request should fail with
2308// ERR_UNEXPECTED_PROXY_AUTH.
2309// Note that it is impossible to detect if an HTTP server returns a 407 through
2310// a non-authenticating proxy - there is nothing to indicate whether the
2311// response came from the proxy or the server, so it is treated as if the proxy
2312// issued the challenge.
[email protected]23e482282013-06-14 16:08:022313TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:232314 HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:272315 HttpRequestInfo request;
2316 request.method = "GET";
2317 request.url = GURL("https://www.google.com/");
2318
[email protected]bb88e1d32013-05-03 23:11:072319 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]333bdf62012-06-08 22:57:292320 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072321 session_deps_.net_log = log.bound().net_log();
2322 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:102323
[email protected]7a67a8152010-11-05 18:31:102324 // Since we have proxy, should try to establish tunnel.
2325 MockWrite data_writes1[] = {
2326 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2327 "Host: www.google.com\r\n"
2328 "Proxy-Connection: keep-alive\r\n\r\n"),
2329
2330 MockWrite("GET / HTTP/1.1\r\n"
2331 "Host: www.google.com\r\n"
2332 "Connection: keep-alive\r\n\r\n"),
2333 };
2334
2335 MockRead data_reads1[] = {
2336 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2337
2338 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
2339 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2340 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:062341 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:102342 };
2343
2344 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2345 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072346 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:062347 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072348 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:102349
[email protected]49639fa2011-12-20 23:22:412350 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:102351
[email protected]262eec82013-03-19 21:01:362352 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502353 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a67a8152010-11-05 18:31:102354
[email protected]49639fa2011-12-20 23:22:412355 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7a67a8152010-11-05 18:31:102356 EXPECT_EQ(ERR_IO_PENDING, rv);
2357
2358 rv = callback1.WaitForResult();
2359 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
[email protected]f3da152d2012-06-02 01:00:572360 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:402361 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:102362 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402363 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]7a67a8152010-11-05 18:31:102364 NetLog::PHASE_NONE);
2365 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402366 entries, pos,
[email protected]7a67a8152010-11-05 18:31:102367 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2368 NetLog::PHASE_NONE);
2369}
[email protected]2df19bb2010-08-25 20:13:462370
[email protected]029c83b62013-01-24 05:28:202371// Test the load timing for HTTPS requests with an HTTP proxy.
[email protected]23e482282013-06-14 16:08:022372TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:202373 HttpRequestInfo request1;
2374 request1.method = "GET";
2375 request1.url = GURL("https://www.google.com/1");
2376
2377 HttpRequestInfo request2;
2378 request2.method = "GET";
2379 request2.url = GURL("https://www.google.com/2");
2380
2381 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072382 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:202383 ProxyService::CreateFixed("PROXY myproxy:70"));
2384 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072385 session_deps_.net_log = log.bound().net_log();
2386 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:202387
2388 // Since we have proxy, should try to establish tunnel.
2389 MockWrite data_writes1[] = {
2390 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2391 "Host: www.google.com\r\n"
2392 "Proxy-Connection: keep-alive\r\n\r\n"),
2393
2394 MockWrite("GET /1 HTTP/1.1\r\n"
2395 "Host: www.google.com\r\n"
2396 "Connection: keep-alive\r\n\r\n"),
2397
2398 MockWrite("GET /2 HTTP/1.1\r\n"
2399 "Host: www.google.com\r\n"
2400 "Connection: keep-alive\r\n\r\n"),
2401 };
2402
2403 // The proxy responds to the connect with a 407, using a persistent
2404 // connection.
2405 MockRead data_reads1[] = {
2406 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2407
2408 MockRead("HTTP/1.1 200 OK\r\n"),
2409 MockRead("Content-Length: 1\r\n\r\n"),
2410 MockRead(SYNCHRONOUS, "1"),
2411
2412 MockRead("HTTP/1.1 200 OK\r\n"),
2413 MockRead("Content-Length: 2\r\n\r\n"),
2414 MockRead(SYNCHRONOUS, "22"),
2415 };
2416
2417 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2418 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072419 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:202420 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072421 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:202422
2423 TestCompletionCallback callback1;
[email protected]262eec82013-03-19 21:01:362424 scoped_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:502425 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:202426
2427 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
2428 EXPECT_EQ(ERR_IO_PENDING, rv);
2429
2430 rv = callback1.WaitForResult();
2431 EXPECT_EQ(OK, rv);
2432
2433 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2434 ASSERT_TRUE(response1 != NULL);
[email protected]90499482013-06-01 00:39:502435 ASSERT_TRUE(response1->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:202436 EXPECT_EQ(1, response1->headers->GetContentLength());
2437
2438 LoadTimingInfo load_timing_info1;
2439 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
2440 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
2441
2442 trans1.reset();
2443
2444 TestCompletionCallback callback2;
[email protected]262eec82013-03-19 21:01:362445 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:502446 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:202447
2448 rv = trans2->Start(&request2, callback2.callback(), log.bound());
2449 EXPECT_EQ(ERR_IO_PENDING, rv);
2450
2451 rv = callback2.WaitForResult();
2452 EXPECT_EQ(OK, rv);
2453
2454 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2455 ASSERT_TRUE(response2 != NULL);
[email protected]90499482013-06-01 00:39:502456 ASSERT_TRUE(response2->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:202457 EXPECT_EQ(2, response2->headers->GetContentLength());
2458
2459 LoadTimingInfo load_timing_info2;
2460 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
2461 TestLoadTimingReused(load_timing_info2);
2462
2463 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2464
2465 trans2.reset();
2466 session->CloseAllConnections();
2467}
2468
2469// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
[email protected]23e482282013-06-14 16:08:022470TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:202471 HttpRequestInfo request1;
2472 request1.method = "GET";
2473 request1.url = GURL("https://www.google.com/1");
2474
2475 HttpRequestInfo request2;
2476 request2.method = "GET";
2477 request2.url = GURL("https://www.google.com/2");
2478
2479 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072480 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:202481 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
2482 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072483 session_deps_.net_log = log.bound().net_log();
2484 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:202485
2486 // Since we have proxy, should try to establish tunnel.
2487 MockWrite data_writes1[] = {
2488 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
2489 "Host: www.google.com\r\n"
2490 "Proxy-Connection: keep-alive\r\n\r\n"),
2491
2492 MockWrite("GET /1 HTTP/1.1\r\n"
2493 "Host: www.google.com\r\n"
2494 "Connection: keep-alive\r\n\r\n"),
2495
2496 MockWrite("GET /2 HTTP/1.1\r\n"
2497 "Host: www.google.com\r\n"
2498 "Connection: keep-alive\r\n\r\n"),
2499 };
2500
2501 // The proxy responds to the connect with a 407, using a persistent
2502 // connection.
2503 MockRead data_reads1[] = {
2504 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2505
2506 MockRead("HTTP/1.1 200 OK\r\n"),
2507 MockRead("Content-Length: 1\r\n\r\n"),
2508 MockRead(SYNCHRONOUS, "1"),
2509
2510 MockRead("HTTP/1.1 200 OK\r\n"),
2511 MockRead("Content-Length: 2\r\n\r\n"),
2512 MockRead(SYNCHRONOUS, "22"),
2513 };
2514
2515 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2516 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072517 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:202518 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072519 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:202520
2521 TestCompletionCallback callback1;
[email protected]262eec82013-03-19 21:01:362522 scoped_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:502523 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:202524
2525 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
2526 EXPECT_EQ(ERR_IO_PENDING, rv);
2527
2528 rv = callback1.WaitForResult();
2529 EXPECT_EQ(OK, rv);
2530
2531 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2532 ASSERT_TRUE(response1 != NULL);
[email protected]90499482013-06-01 00:39:502533 ASSERT_TRUE(response1->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:202534 EXPECT_EQ(1, response1->headers->GetContentLength());
2535
2536 LoadTimingInfo load_timing_info1;
2537 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
2538 TestLoadTimingNotReusedWithPac(load_timing_info1,
2539 CONNECT_TIMING_HAS_SSL_TIMES);
2540
2541 trans1.reset();
2542
2543 TestCompletionCallback callback2;
[email protected]262eec82013-03-19 21:01:362544 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:502545 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:202546
2547 rv = trans2->Start(&request2, callback2.callback(), log.bound());
2548 EXPECT_EQ(ERR_IO_PENDING, rv);
2549
2550 rv = callback2.WaitForResult();
2551 EXPECT_EQ(OK, rv);
2552
2553 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2554 ASSERT_TRUE(response2 != NULL);
[email protected]90499482013-06-01 00:39:502555 ASSERT_TRUE(response2->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:202556 EXPECT_EQ(2, response2->headers->GetContentLength());
2557
2558 LoadTimingInfo load_timing_info2;
2559 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
2560 TestLoadTimingReusedWithPac(load_timing_info2);
2561
2562 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2563
2564 trans2.reset();
2565 session->CloseAllConnections();
2566}
2567
[email protected]2df19bb2010-08-25 20:13:462568// Test a simple get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:022569TEST_P(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:272570 HttpRequestInfo request;
2571 request.method = "GET";
2572 request.url = GURL("http://www.google.com/");
2573
[email protected]2df19bb2010-08-25 20:13:462574 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:072575 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:112576 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:292577 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072578 session_deps_.net_log = log.bound().net_log();
2579 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:462580
[email protected]2df19bb2010-08-25 20:13:462581 // Since we have proxy, should use full url
2582 MockWrite data_writes1[] = {
2583 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
2584 "Host: www.google.com\r\n"
2585 "Proxy-Connection: keep-alive\r\n\r\n"),
2586 };
2587
2588 MockRead data_reads1[] = {
2589 MockRead("HTTP/1.1 200 OK\r\n"),
2590 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2591 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062592 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:462593 };
2594
2595 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2596 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072597 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:062598 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072599 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:462600
[email protected]49639fa2011-12-20 23:22:412601 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:462602
[email protected]262eec82013-03-19 21:01:362603 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502604 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:502605
[email protected]49639fa2011-12-20 23:22:412606 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:462607 EXPECT_EQ(ERR_IO_PENDING, rv);
2608
2609 rv = callback1.WaitForResult();
2610 EXPECT_EQ(OK, rv);
2611
[email protected]58e32bb2013-01-21 18:23:252612 LoadTimingInfo load_timing_info;
2613 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2614 TestLoadTimingNotReused(load_timing_info,
2615 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
2616
[email protected]2df19bb2010-08-25 20:13:462617 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502618 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:462619
2620 EXPECT_TRUE(response->headers->IsKeepAlive());
2621 EXPECT_EQ(200, response->headers->response_code());
2622 EXPECT_EQ(100, response->headers->GetContentLength());
2623 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2624
2625 // The password prompt info should not be set.
2626 EXPECT_TRUE(response->auth_challenge.get() == NULL);
2627}
2628
[email protected]7642b5ae2010-09-01 20:55:172629// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:022630TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:272631 HttpRequestInfo request;
2632 request.method = "GET";
2633 request.url = GURL("http://www.google.com/");
2634 request.load_flags = 0;
2635
[email protected]7642b5ae2010-09-01 20:55:172636 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:072637 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:112638 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:292639 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072640 session_deps_.net_log = log.bound().net_log();
2641 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:172642
[email protected]7642b5ae2010-09-01 20:55:172643 // fetch http://www.google.com/ via SPDY
[email protected]cdf8f7e72013-05-23 10:56:462644 scoped_ptr<SpdyFrame> req(
2645 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]7642b5ae2010-09-01 20:55:172646 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
2647
[email protected]23e482282013-06-14 16:08:022648 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2649 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:172650 MockRead spdy_reads[] = {
2651 CreateMockRead(*resp),
2652 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:062653 MockRead(ASYNC, 0, 0),
[email protected]7642b5ae2010-09-01 20:55:172654 };
2655
[email protected]dd54bd82012-07-19 23:44:572656 DelayedSocketData spdy_data(
2657 1, // wait for one write to finish before reading.
2658 spdy_reads, arraysize(spdy_reads),
2659 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:072660 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:172661
[email protected]8ddf8322012-02-23 18:08:062662 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:022663 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:072664 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:172665
[email protected]49639fa2011-12-20 23:22:412666 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:172667
[email protected]262eec82013-03-19 21:01:362668 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502669 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:502670
[email protected]49639fa2011-12-20 23:22:412671 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7642b5ae2010-09-01 20:55:172672 EXPECT_EQ(ERR_IO_PENDING, rv);
2673
2674 rv = callback1.WaitForResult();
2675 EXPECT_EQ(OK, rv);
2676
[email protected]58e32bb2013-01-21 18:23:252677 LoadTimingInfo load_timing_info;
2678 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2679 TestLoadTimingNotReused(load_timing_info,
2680 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
2681
[email protected]7642b5ae2010-09-01 20:55:172682 const HttpResponseInfo* response = trans->GetResponseInfo();
2683 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502684 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]7642b5ae2010-09-01 20:55:172685 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2686
2687 std::string response_data;
2688 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:232689 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:172690}
2691
[email protected]dc7bd1c52010-11-12 00:01:132692// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:022693TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:272694 HttpRequestInfo request;
2695 request.method = "GET";
2696 request.url = GURL("http://www.google.com/");
2697 request.load_flags = 0;
2698
[email protected]79cb5c12011-09-12 13:12:042699 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072700 session_deps_.proxy_service.reset(
[email protected]79cb5c12011-09-12 13:12:042701 ProxyService::CreateFixed("https://myproxy:70"));
[email protected]333bdf62012-06-08 22:57:292702 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072703 session_deps_.net_log = log.bound().net_log();
2704 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:132705
[email protected]dc7bd1c52010-11-12 00:01:132706 // The first request will be a bare GET, the second request will be a
2707 // GET with a Proxy-Authorization header.
[email protected]ff98d7f02012-03-22 21:44:192708 scoped_ptr<SpdyFrame> req_get(
[email protected]cdf8f7e72013-05-23 10:56:462709 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]dc7bd1c52010-11-12 00:01:132710 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:462711 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:132712 };
[email protected]ff98d7f02012-03-22 21:44:192713 scoped_ptr<SpdyFrame> req_get_authorization(
[email protected]cdf8f7e72013-05-23 10:56:462714 spdy_util_.ConstructSpdyGet(kExtraAuthorizationHeaders,
2715 arraysize(kExtraAuthorizationHeaders) / 2,
2716 false,
2717 3,
2718 LOWEST,
2719 false));
[email protected]dc7bd1c52010-11-12 00:01:132720 MockWrite spdy_writes[] = {
2721 CreateMockWrite(*req_get, 1),
2722 CreateMockWrite(*req_get_authorization, 4),
2723 };
2724
2725 // The first response is a 407 proxy authentication challenge, and the second
2726 // response will be a 200 response since the second request includes a valid
2727 // Authorization header.
2728 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:462729 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:132730 };
[email protected]ff98d7f02012-03-22 21:44:192731 scoped_ptr<SpdyFrame> resp_authentication(
[email protected]23e482282013-06-14 16:08:022732 spdy_util_.ConstructSpdySynReplyError(
[email protected]dc7bd1c52010-11-12 00:01:132733 "407 Proxy Authentication Required",
2734 kExtraAuthenticationHeaders, arraysize(kExtraAuthenticationHeaders)/2,
2735 1));
[email protected]ff98d7f02012-03-22 21:44:192736 scoped_ptr<SpdyFrame> body_authentication(
[email protected]23e482282013-06-14 16:08:022737 spdy_util_.ConstructSpdyBodyFrame(1, true));
2738 scoped_ptr<SpdyFrame> resp_data(
2739 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
2740 scoped_ptr<SpdyFrame> body_data(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:132741 MockRead spdy_reads[] = {
2742 CreateMockRead(*resp_authentication, 2),
2743 CreateMockRead(*body_authentication, 3),
2744 CreateMockRead(*resp_data, 5),
2745 CreateMockRead(*body_data, 6),
[email protected]8ddf8322012-02-23 18:08:062746 MockRead(ASYNC, 0, 7),
[email protected]dc7bd1c52010-11-12 00:01:132747 };
2748
[email protected]dd54bd82012-07-19 23:44:572749 OrderedSocketData data(
2750 spdy_reads, arraysize(spdy_reads),
2751 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:072752 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:132753
[email protected]8ddf8322012-02-23 18:08:062754 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:022755 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:072756 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:132757
[email protected]49639fa2011-12-20 23:22:412758 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:132759
[email protected]262eec82013-03-19 21:01:362760 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502761 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]dc7bd1c52010-11-12 00:01:132762
[email protected]49639fa2011-12-20 23:22:412763 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]dc7bd1c52010-11-12 00:01:132764 EXPECT_EQ(ERR_IO_PENDING, rv);
2765
2766 rv = callback1.WaitForResult();
2767 EXPECT_EQ(OK, rv);
2768
2769 const HttpResponseInfo* const response = trans->GetResponseInfo();
2770
2771 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502772 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]dc7bd1c52010-11-12 00:01:132773 EXPECT_EQ(407, response->headers->response_code());
2774 EXPECT_TRUE(response->was_fetched_via_spdy);
[email protected]79cb5c12011-09-12 13:12:042775 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:132776
[email protected]49639fa2011-12-20 23:22:412777 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:132778
[email protected]49639fa2011-12-20 23:22:412779 rv = trans->RestartWithAuth(
2780 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]dc7bd1c52010-11-12 00:01:132781 EXPECT_EQ(ERR_IO_PENDING, rv);
2782
2783 rv = callback2.WaitForResult();
2784 EXPECT_EQ(OK, rv);
2785
2786 const HttpResponseInfo* const response_restart = trans->GetResponseInfo();
2787
2788 ASSERT_TRUE(response_restart != NULL);
[email protected]90499482013-06-01 00:39:502789 ASSERT_TRUE(response_restart->headers.get() != NULL);
[email protected]dc7bd1c52010-11-12 00:01:132790 EXPECT_EQ(200, response_restart->headers->response_code());
2791 // The password prompt info should not be set.
2792 EXPECT_TRUE(response_restart->auth_challenge.get() == NULL);
2793}
2794
[email protected]d9da5fe2010-10-13 22:37:162795// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
[email protected]23e482282013-06-14 16:08:022796TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:272797 HttpRequestInfo request;
2798 request.method = "GET";
2799 request.url = GURL("https://www.google.com/");
2800 request.load_flags = 0;
2801
[email protected]d9da5fe2010-10-13 22:37:162802 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:072803 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:112804 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:292805 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072806 session_deps_.net_log = log.bound().net_log();
2807 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:162808
[email protected]262eec82013-03-19 21:01:362809 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502810 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:162811
[email protected]d9da5fe2010-10-13 22:37:162812 // CONNECT to www.google.com:443 via SPDY
[email protected]fba2dbde2013-05-24 16:09:012813 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:162814 // fetch https://www.google.com/ via HTTP
2815
2816 const char get[] = "GET / HTTP/1.1\r\n"
2817 "Host: www.google.com\r\n"
2818 "Connection: keep-alive\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:192819 scoped_ptr<SpdyFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:022820 spdy_util_.ConstructSpdyBodyFrame(1, get, strlen(get), false));
2821 scoped_ptr<SpdyFrame> conn_resp(
2822 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:162823 const char resp[] = "HTTP/1.1 200 OK\r\n"
2824 "Content-Length: 10\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:192825 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:022826 spdy_util_.ConstructSpdyBodyFrame(1, resp, strlen(resp), false));
[email protected]ff98d7f02012-03-22 21:44:192827 scoped_ptr<SpdyFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:022828 spdy_util_.ConstructSpdyBodyFrame(1, "1234567890", 10, false));
[email protected]ff98d7f02012-03-22 21:44:192829 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:202830 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
[email protected]8d2f7012012-02-16 00:08:042831
2832 MockWrite spdy_writes[] = {
2833 CreateMockWrite(*connect, 1),
2834 CreateMockWrite(*wrapped_get, 3),
[email protected]cdf8f7e72013-05-23 10:56:462835 CreateMockWrite(*window_update, 5),
[email protected]8d2f7012012-02-16 00:08:042836 };
2837
[email protected]d9da5fe2010-10-13 22:37:162838 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:062839 CreateMockRead(*conn_resp, 2, ASYNC),
2840 CreateMockRead(*wrapped_get_resp, 4, ASYNC),
2841 CreateMockRead(*wrapped_body, 6, ASYNC),
2842 CreateMockRead(*wrapped_body, 7, ASYNC),
2843 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:162844 };
2845
[email protected]dd54bd82012-07-19 23:44:572846 OrderedSocketData spdy_data(
2847 spdy_reads, arraysize(spdy_reads),
2848 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:072849 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:162850
[email protected]8ddf8322012-02-23 18:08:062851 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:022852 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:072853 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:062854 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]d9da5fe2010-10-13 22:37:162855 ssl2.was_npn_negotiated = false;
[email protected]8e3c78cb2012-03-31 03:58:462856 ssl2.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:072857 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:162858
[email protected]49639fa2011-12-20 23:22:412859 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:162860
[email protected]49639fa2011-12-20 23:22:412861 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:162862 EXPECT_EQ(ERR_IO_PENDING, rv);
2863
2864 rv = callback1.WaitForResult();
2865 EXPECT_EQ(OK, rv);
2866
[email protected]58e32bb2013-01-21 18:23:252867 LoadTimingInfo load_timing_info;
2868 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2869 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
2870
[email protected]d9da5fe2010-10-13 22:37:162871 const HttpResponseInfo* response = trans->GetResponseInfo();
2872 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502873 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d9da5fe2010-10-13 22:37:162874 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2875
2876 std::string response_data;
2877 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
2878 EXPECT_EQ("1234567890", response_data);
2879}
2880
2881// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
[email protected]23e482282013-06-14 16:08:022882TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
[email protected]cb9bf6ca2011-01-28 13:15:272883 HttpRequestInfo request;
2884 request.method = "GET";
2885 request.url = GURL("https://www.google.com/");
2886 request.load_flags = 0;
2887
[email protected]d9da5fe2010-10-13 22:37:162888 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:072889 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:112890 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:292891 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072892 session_deps_.net_log = log.bound().net_log();
2893 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:162894
[email protected]262eec82013-03-19 21:01:362895 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502896 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:162897
[email protected]d9da5fe2010-10-13 22:37:162898 // CONNECT to www.google.com:443 via SPDY
[email protected]fba2dbde2013-05-24 16:09:012899 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:162900 // fetch https://www.google.com/ via SPDY
2901 const char* const kMyUrl = "https://www.google.com/";
[email protected]cdf8f7e72013-05-23 10:56:462902 scoped_ptr<SpdyFrame> get(
2903 spdy_util_.ConstructSpdyGet(kMyUrl, false, 1, LOWEST));
[email protected]23e482282013-06-14 16:08:022904 scoped_ptr<SpdyFrame> wrapped_get(
2905 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
2906 scoped_ptr<SpdyFrame> conn_resp(
2907 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2908 scoped_ptr<SpdyFrame> get_resp(
2909 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]ff98d7f02012-03-22 21:44:192910 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:022911 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
2912 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
2913 scoped_ptr<SpdyFrame> wrapped_body(
2914 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
[email protected]ff98d7f02012-03-22 21:44:192915 scoped_ptr<SpdyFrame> window_update_get_resp(
[email protected]c10b20852013-05-15 21:29:202916 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
[email protected]ff98d7f02012-03-22 21:44:192917 scoped_ptr<SpdyFrame> window_update_body(
[email protected]c10b20852013-05-15 21:29:202918 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body->size()));
[email protected]8d2f7012012-02-16 00:08:042919
2920 MockWrite spdy_writes[] = {
2921 CreateMockWrite(*connect, 1),
2922 CreateMockWrite(*wrapped_get, 3),
2923 CreateMockWrite(*window_update_get_resp, 5),
2924 CreateMockWrite(*window_update_body, 7),
2925 };
2926
[email protected]d9da5fe2010-10-13 22:37:162927 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:062928 CreateMockRead(*conn_resp, 2, ASYNC),
2929 CreateMockRead(*wrapped_get_resp, 4, ASYNC),
2930 CreateMockRead(*wrapped_body, 6, ASYNC),
2931 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:162932 };
2933
[email protected]dd54bd82012-07-19 23:44:572934 OrderedSocketData spdy_data(
2935 spdy_reads, arraysize(spdy_reads),
2936 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:072937 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:162938
[email protected]8ddf8322012-02-23 18:08:062939 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:022940 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:072941 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:062942 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:022943 ssl2.SetNextProto(GetParam());
2944 ssl2.protocol_negotiated = GetParam();
[email protected]bb88e1d32013-05-03 23:11:072945 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:162946
[email protected]49639fa2011-12-20 23:22:412947 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:162948
[email protected]49639fa2011-12-20 23:22:412949 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:162950 EXPECT_EQ(ERR_IO_PENDING, rv);
2951
2952 rv = callback1.WaitForResult();
2953 EXPECT_EQ(OK, rv);
2954
[email protected]58e32bb2013-01-21 18:23:252955 LoadTimingInfo load_timing_info;
2956 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2957 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
2958
[email protected]d9da5fe2010-10-13 22:37:162959 const HttpResponseInfo* response = trans->GetResponseInfo();
2960 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:502961 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d9da5fe2010-10-13 22:37:162962 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2963
2964 std::string response_data;
2965 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:232966 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:162967}
2968
2969// Test a SPDY CONNECT failure through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:022970TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:272971 HttpRequestInfo request;
2972 request.method = "GET";
2973 request.url = GURL("https://www.google.com/");
2974 request.load_flags = 0;
2975
[email protected]d9da5fe2010-10-13 22:37:162976 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:072977 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:112978 "https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:292979 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072980 session_deps_.net_log = log.bound().net_log();
2981 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:162982
[email protected]262eec82013-03-19 21:01:362983 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502984 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:162985
[email protected]d9da5fe2010-10-13 22:37:162986 // CONNECT to www.google.com:443 via SPDY
[email protected]fba2dbde2013-05-24 16:09:012987 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1));
[email protected]c10b20852013-05-15 21:29:202988 scoped_ptr<SpdyFrame> get(
2989 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:162990
2991 MockWrite spdy_writes[] = {
2992 CreateMockWrite(*connect, 1),
2993 CreateMockWrite(*get, 3),
2994 };
2995
[email protected]23e482282013-06-14 16:08:022996 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdySynReplyError(1));
2997 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:162998 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:062999 CreateMockRead(*resp, 2, ASYNC),
3000 MockRead(ASYNC, 0, 4),
[email protected]d9da5fe2010-10-13 22:37:163001 };
3002
[email protected]dd54bd82012-07-19 23:44:573003 OrderedSocketData spdy_data(
3004 spdy_reads, arraysize(spdy_reads),
3005 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073006 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163007
[email protected]8ddf8322012-02-23 18:08:063008 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023009 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073010 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063011 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023012 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073013 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163014
[email protected]49639fa2011-12-20 23:22:413015 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163016
[email protected]49639fa2011-12-20 23:22:413017 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163018 EXPECT_EQ(ERR_IO_PENDING, rv);
3019
3020 rv = callback1.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:173021 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]d9da5fe2010-10-13 22:37:163022
[email protected]4eddbc732012-08-09 05:40:173023 // TODO(ttuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:163024}
3025
[email protected]f6c63db52013-02-02 00:35:223026// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
3027// HTTPS Proxy to different servers.
[email protected]23e482282013-06-14 16:08:023028TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:223029 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
3030 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073031 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:223032 "https://proxy:70"));
3033 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073034 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:223035 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:073036 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:223037
3038 HttpRequestInfo request1;
3039 request1.method = "GET";
3040 request1.url = GURL("https://www.google.com/");
3041 request1.load_flags = 0;
3042
3043 HttpRequestInfo request2;
3044 request2.method = "GET";
3045 request2.url = GURL("https://news.google.com/");
3046 request2.load_flags = 0;
3047
3048 // CONNECT to www.google.com:443 via SPDY.
[email protected]fba2dbde2013-05-24 16:09:013049 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(NULL, 0, 1));
[email protected]23e482282013-06-14 16:08:023050 scoped_ptr<SpdyFrame> conn_resp1(
3051 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:223052
3053 // Fetch https://www.google.com/ via HTTP.
3054 const char get1[] = "GET / HTTP/1.1\r\n"
3055 "Host: www.google.com\r\n"
3056 "Connection: keep-alive\r\n\r\n";
3057 scoped_ptr<SpdyFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:023058 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:223059 const char resp1[] = "HTTP/1.1 200 OK\r\n"
3060 "Content-Length: 1\r\n\r\n";
3061 scoped_ptr<SpdyFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:023062 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
3063 scoped_ptr<SpdyFrame> wrapped_body1(
3064 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
[email protected]f6c63db52013-02-02 00:35:223065 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203066 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:223067
3068 // CONNECT to news.google.com:443 via SPDY.
3069 const char* const kConnectHeaders2[] = {
[email protected]23e482282013-06-14 16:08:023070 spdy_util_.GetMethodKey(), "CONNECT",
3071 spdy_util_.GetPathKey(), "news.google.com:443",
3072 spdy_util_.GetHostKey(), "news.google.com",
3073 spdy_util_.GetVersionKey(), "HTTP/1.1",
[email protected]f6c63db52013-02-02 00:35:223074 };
3075 scoped_ptr<SpdyFrame> connect2(
[email protected]4bd46222013-05-14 19:32:233076 spdy_util_.ConstructSpdyControlFrame(NULL,
3077 0,
3078 /*compressed*/ false,
3079 3,
3080 LOWEST,
3081 SYN_STREAM,
3082 CONTROL_FLAG_NONE,
3083 kConnectHeaders2,
3084 arraysize(kConnectHeaders2),
3085 0));
[email protected]23e482282013-06-14 16:08:023086 scoped_ptr<SpdyFrame> conn_resp2(
3087 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:223088
3089 // Fetch https://news.google.com/ via HTTP.
3090 const char get2[] = "GET / HTTP/1.1\r\n"
3091 "Host: news.google.com\r\n"
3092 "Connection: keep-alive\r\n\r\n";
3093 scoped_ptr<SpdyFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:023094 spdy_util_.ConstructSpdyBodyFrame(3, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:223095 const char resp2[] = "HTTP/1.1 200 OK\r\n"
3096 "Content-Length: 2\r\n\r\n";
3097 scoped_ptr<SpdyFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:023098 spdy_util_.ConstructSpdyBodyFrame(3, resp2, strlen(resp2), false));
[email protected]f6c63db52013-02-02 00:35:223099 scoped_ptr<SpdyFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:023100 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:223101
3102 MockWrite spdy_writes[] = {
3103 CreateMockWrite(*connect1, 0),
3104 CreateMockWrite(*wrapped_get1, 2),
3105 CreateMockWrite(*connect2, 5),
3106 CreateMockWrite(*wrapped_get2, 7),
3107 };
3108
3109 MockRead spdy_reads[] = {
3110 CreateMockRead(*conn_resp1, 1, ASYNC),
3111 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
3112 CreateMockRead(*wrapped_body1, 4, ASYNC),
3113 CreateMockRead(*conn_resp2, 6, ASYNC),
3114 CreateMockRead(*wrapped_get_resp2, 8, ASYNC),
3115 CreateMockRead(*wrapped_body2, 9, ASYNC),
3116 MockRead(ASYNC, 0, 10),
3117 };
3118
3119 DeterministicSocketData spdy_data(
3120 spdy_reads, arraysize(spdy_reads),
3121 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073122 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:223123
3124 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023125 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073126 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:223127 SSLSocketDataProvider ssl2(ASYNC, OK);
3128 ssl2.was_npn_negotiated = false;
3129 ssl2.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:073130 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:223131 SSLSocketDataProvider ssl3(ASYNC, OK);
3132 ssl3.was_npn_negotiated = false;
3133 ssl3.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:073134 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:223135
3136 TestCompletionCallback callback;
3137
[email protected]262eec82013-03-19 21:01:363138 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503139 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223140 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
3141 EXPECT_EQ(ERR_IO_PENDING, rv);
3142 // The first connect and request, each of their responses, and the body.
3143 spdy_data.RunFor(5);
3144
3145 rv = callback.WaitForResult();
3146 EXPECT_EQ(OK, rv);
3147
3148 LoadTimingInfo load_timing_info;
3149 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3150 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3151
3152 const HttpResponseInfo* response = trans->GetResponseInfo();
3153 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503154 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:223155 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3156
3157 std::string response_data;
3158 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
[email protected]90499482013-06-01 00:39:503159 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223160
[email protected]262eec82013-03-19 21:01:363161 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503162 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223163 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
3164 EXPECT_EQ(ERR_IO_PENDING, rv);
3165
3166 // The second connect and request, each of their responses, and the body.
3167 spdy_data.RunFor(5);
3168 rv = callback.WaitForResult();
3169 EXPECT_EQ(OK, rv);
3170
3171 LoadTimingInfo load_timing_info2;
3172 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3173 // Even though the SPDY connection is reused, a new tunnelled connection has
3174 // to be created, so the socket's load timing looks like a fresh connection.
3175 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
3176
3177 // The requests should have different IDs, since they each are using their own
3178 // separate stream.
3179 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
3180
[email protected]90499482013-06-01 00:39:503181 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223182}
3183
3184// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
3185// HTTPS Proxy to the same server.
[email protected]23e482282013-06-14 16:08:023186TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:223187 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
3188 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073189 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:223190 "https://proxy:70"));
3191 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073192 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:223193 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:073194 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:223195
3196 HttpRequestInfo request1;
3197 request1.method = "GET";
3198 request1.url = GURL("https://www.google.com/");
3199 request1.load_flags = 0;
3200
3201 HttpRequestInfo request2;
3202 request2.method = "GET";
3203 request2.url = GURL("https://www.google.com/2");
3204 request2.load_flags = 0;
3205
3206 // CONNECT to www.google.com:443 via SPDY.
[email protected]fba2dbde2013-05-24 16:09:013207 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(NULL, 0, 1));
[email protected]23e482282013-06-14 16:08:023208 scoped_ptr<SpdyFrame> conn_resp1(
3209 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:223210
3211 // Fetch https://www.google.com/ via HTTP.
3212 const char get1[] = "GET / HTTP/1.1\r\n"
3213 "Host: www.google.com\r\n"
3214 "Connection: keep-alive\r\n\r\n";
3215 scoped_ptr<SpdyFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:023216 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:223217 const char resp1[] = "HTTP/1.1 200 OK\r\n"
3218 "Content-Length: 1\r\n\r\n";
3219 scoped_ptr<SpdyFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:023220 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
3221 scoped_ptr<SpdyFrame> wrapped_body1(
3222 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
[email protected]f6c63db52013-02-02 00:35:223223 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203224 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:223225
3226 // Fetch https://www.google.com/2 via HTTP.
3227 const char get2[] = "GET /2 HTTP/1.1\r\n"
3228 "Host: www.google.com\r\n"
3229 "Connection: keep-alive\r\n\r\n";
3230 scoped_ptr<SpdyFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:023231 spdy_util_.ConstructSpdyBodyFrame(1, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:223232 const char resp2[] = "HTTP/1.1 200 OK\r\n"
3233 "Content-Length: 2\r\n\r\n";
3234 scoped_ptr<SpdyFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:023235 spdy_util_.ConstructSpdyBodyFrame(1, resp2, strlen(resp2), false));
[email protected]f6c63db52013-02-02 00:35:223236 scoped_ptr<SpdyFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:023237 spdy_util_.ConstructSpdyBodyFrame(1, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:223238
3239 MockWrite spdy_writes[] = {
3240 CreateMockWrite(*connect1, 0),
3241 CreateMockWrite(*wrapped_get1, 2),
3242 CreateMockWrite(*wrapped_get2, 5),
3243 };
3244
3245 MockRead spdy_reads[] = {
3246 CreateMockRead(*conn_resp1, 1, ASYNC),
3247 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
3248 CreateMockRead(*wrapped_body1, 4, ASYNC),
3249 CreateMockRead(*wrapped_get_resp2, 6, ASYNC),
3250 CreateMockRead(*wrapped_body2, 7, ASYNC),
3251 MockRead(ASYNC, 0, 8),
3252 };
3253
3254 DeterministicSocketData spdy_data(
3255 spdy_reads, arraysize(spdy_reads),
3256 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073257 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:223258
3259 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023260 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073261 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:223262 SSLSocketDataProvider ssl2(ASYNC, OK);
3263 ssl2.was_npn_negotiated = false;
3264 ssl2.protocol_negotiated = kProtoUnknown;
[email protected]bb88e1d32013-05-03 23:11:073265 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:223266
3267 TestCompletionCallback callback;
3268
[email protected]262eec82013-03-19 21:01:363269 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503270 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223271 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
3272 EXPECT_EQ(ERR_IO_PENDING, rv);
3273 // The first connect and request, each of their responses, and the body.
3274 spdy_data.RunFor(5);
3275
3276 rv = callback.WaitForResult();
3277 EXPECT_EQ(OK, rv);
3278
3279 LoadTimingInfo load_timing_info;
3280 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3281 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3282
3283 const HttpResponseInfo* response = trans->GetResponseInfo();
3284 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503285 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:223286 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3287
3288 std::string response_data;
3289 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
[email protected]90499482013-06-01 00:39:503290 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223291 trans.reset();
3292
[email protected]262eec82013-03-19 21:01:363293 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503294 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223295 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
3296 EXPECT_EQ(ERR_IO_PENDING, rv);
3297
3298 // The second request, response, and body. There should not be a second
3299 // connect.
3300 spdy_data.RunFor(3);
3301 rv = callback.WaitForResult();
3302 EXPECT_EQ(OK, rv);
3303
3304 LoadTimingInfo load_timing_info2;
3305 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3306 TestLoadTimingReused(load_timing_info2);
3307
3308 // The requests should have the same ID.
3309 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
3310
[email protected]90499482013-06-01 00:39:503311 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223312}
3313
3314// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
3315// Proxy to different servers.
[email protected]23e482282013-06-14 16:08:023316TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:223317 HttpsProxySpdyLoadTimingTwoHttpRequests) {
3318 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073319 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:223320 "https://proxy:70"));
3321 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073322 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:223323 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:073324 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:223325
3326 HttpRequestInfo request1;
3327 request1.method = "GET";
3328 request1.url = GURL("http://www.google.com/");
3329 request1.load_flags = 0;
3330
3331 HttpRequestInfo request2;
3332 request2.method = "GET";
3333 request2.url = GURL("http://news.google.com/");
3334 request2.load_flags = 0;
3335
3336 // http://www.google.com/
[email protected]23e482282013-06-14 16:08:023337 scoped_ptr<SpdyHeaderBlock> headers(
3338 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/"));
[email protected]4bd46222013-05-14 19:32:233339 scoped_ptr<SpdyFrame> get1(spdy_util_.ConstructSpdyControlFrame(
[email protected]23e482282013-06-14 16:08:023340 headers.Pass(), false, 1, LOWEST, SYN_STREAM, CONTROL_FLAG_FIN, 0));
3341 scoped_ptr<SpdyFrame> get_resp1(
3342 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3343 scoped_ptr<SpdyFrame> body1(
3344 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, true));
[email protected]f6c63db52013-02-02 00:35:223345
3346 // http://news.google.com/
[email protected]23e482282013-06-14 16:08:023347 scoped_ptr<SpdyHeaderBlock> headers2(
3348 spdy_util_.ConstructGetHeaderBlockForProxy("http://news.google.com/"));
[email protected]4bd46222013-05-14 19:32:233349 scoped_ptr<SpdyFrame> get2(spdy_util_.ConstructSpdyControlFrame(
[email protected]23e482282013-06-14 16:08:023350 headers2.Pass(), false, 3, LOWEST, SYN_STREAM, CONTROL_FLAG_FIN, 0));
3351 scoped_ptr<SpdyFrame> get_resp2(
3352 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
3353 scoped_ptr<SpdyFrame> body2(
3354 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, true));
[email protected]f6c63db52013-02-02 00:35:223355
3356 MockWrite spdy_writes[] = {
3357 CreateMockWrite(*get1, 0),
3358 CreateMockWrite(*get2, 3),
3359 };
3360
3361 MockRead spdy_reads[] = {
3362 CreateMockRead(*get_resp1, 1, ASYNC),
3363 CreateMockRead(*body1, 2, ASYNC),
3364 CreateMockRead(*get_resp2, 4, ASYNC),
3365 CreateMockRead(*body2, 5, ASYNC),
3366 MockRead(ASYNC, 0, 6),
3367 };
3368
3369 DeterministicSocketData spdy_data(
3370 spdy_reads, arraysize(spdy_reads),
3371 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073372 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:223373
3374 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023375 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073376 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:223377
3378 TestCompletionCallback callback;
3379
[email protected]262eec82013-03-19 21:01:363380 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503381 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223382 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
3383 EXPECT_EQ(ERR_IO_PENDING, rv);
3384 spdy_data.RunFor(2);
3385
3386 rv = callback.WaitForResult();
3387 EXPECT_EQ(OK, rv);
3388
3389 LoadTimingInfo load_timing_info;
3390 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3391 TestLoadTimingNotReused(load_timing_info,
3392 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3393
3394 const HttpResponseInfo* response = trans->GetResponseInfo();
3395 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503396 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:223397 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3398
3399 std::string response_data;
3400 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
[email protected]90499482013-06-01 00:39:503401 EXPECT_EQ(ERR_IO_PENDING, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223402 spdy_data.RunFor(1);
3403 EXPECT_EQ(1, callback.WaitForResult());
3404 // Delete the first request, so the second one can reuse the socket.
3405 trans.reset();
3406
[email protected]262eec82013-03-19 21:01:363407 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503408 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223409 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
3410 EXPECT_EQ(ERR_IO_PENDING, rv);
3411
3412 spdy_data.RunFor(2);
3413 rv = callback.WaitForResult();
3414 EXPECT_EQ(OK, rv);
3415
3416 LoadTimingInfo load_timing_info2;
3417 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3418 TestLoadTimingReused(load_timing_info2);
3419
3420 // The requests should have the same ID.
3421 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
3422
[email protected]90499482013-06-01 00:39:503423 EXPECT_EQ(ERR_IO_PENDING, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223424 spdy_data.RunFor(1);
3425 EXPECT_EQ(2, callback.WaitForResult());
3426}
3427
[email protected]2df19bb2010-08-25 20:13:463428// Test the challenge-response-retry sequence through an HTTPS Proxy
[email protected]23e482282013-06-14 16:08:023429TEST_P(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:463430 HttpRequestInfo request;
3431 request.method = "GET";
3432 request.url = GURL("http://www.google.com/");
3433 // when the no authentication data flag is set.
3434 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
3435
[email protected]79cb5c12011-09-12 13:12:043436 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073437 session_deps_.proxy_service.reset(
[email protected]79cb5c12011-09-12 13:12:043438 ProxyService::CreateFixed("https://myproxy:70"));
[email protected]333bdf62012-06-08 22:57:293439 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073440 session_deps_.net_log = log.bound().net_log();
3441 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273442
[email protected]2df19bb2010-08-25 20:13:463443 // Since we have proxy, should use full url
3444 MockWrite data_writes1[] = {
3445 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
3446 "Host: www.google.com\r\n"
3447 "Proxy-Connection: keep-alive\r\n\r\n"),
3448
3449 // After calling trans->RestartWithAuth(), this is the request we should
3450 // be issuing -- the final header line contains the credentials.
3451 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
3452 "Host: www.google.com\r\n"
3453 "Proxy-Connection: keep-alive\r\n"
3454 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3455 };
3456
3457 // The proxy responds to the GET with a 407, using a persistent
3458 // connection.
3459 MockRead data_reads1[] = {
3460 // No credentials.
3461 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3462 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3463 MockRead("Proxy-Connection: keep-alive\r\n"),
3464 MockRead("Content-Length: 0\r\n\r\n"),
3465
3466 MockRead("HTTP/1.1 200 OK\r\n"),
3467 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3468 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063469 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:463470 };
3471
3472 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3473 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073474 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063475 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073476 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:463477
[email protected]49639fa2011-12-20 23:22:413478 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:463479
[email protected]262eec82013-03-19 21:01:363480 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503481 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503482
[email protected]49639fa2011-12-20 23:22:413483 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:463484 EXPECT_EQ(ERR_IO_PENDING, rv);
3485
3486 rv = callback1.WaitForResult();
3487 EXPECT_EQ(OK, rv);
3488
[email protected]58e32bb2013-01-21 18:23:253489 LoadTimingInfo load_timing_info;
3490 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3491 TestLoadTimingNotReused(load_timing_info,
3492 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3493
[email protected]2df19bb2010-08-25 20:13:463494 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503495 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503496 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]2df19bb2010-08-25 20:13:463497 EXPECT_EQ(407, response->headers->response_code());
3498 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043499 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:463500
[email protected]49639fa2011-12-20 23:22:413501 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:463502
[email protected]49639fa2011-12-20 23:22:413503 rv = trans->RestartWithAuth(
3504 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]2df19bb2010-08-25 20:13:463505 EXPECT_EQ(ERR_IO_PENDING, rv);
3506
3507 rv = callback2.WaitForResult();
3508 EXPECT_EQ(OK, rv);
3509
[email protected]58e32bb2013-01-21 18:23:253510 load_timing_info = LoadTimingInfo();
3511 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3512 // Retrying with HTTP AUTH is considered to be reusing a socket.
3513 TestLoadTimingReused(load_timing_info);
3514
[email protected]2df19bb2010-08-25 20:13:463515 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503516 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:463517
3518 EXPECT_TRUE(response->headers->IsKeepAlive());
3519 EXPECT_EQ(200, response->headers->response_code());
3520 EXPECT_EQ(100, response->headers->GetContentLength());
3521 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3522
3523 // The password prompt info should not be set.
3524 EXPECT_TRUE(response->auth_challenge.get() == NULL);
3525}
3526
[email protected]23e482282013-06-14 16:08:023527void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:083528 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:423529 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:083530 request.method = "GET";
3531 request.url = GURL("https://www.google.com/");
3532 request.load_flags = 0;
3533
[email protected]cb9bf6ca2011-01-28 13:15:273534 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073535 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]cb9bf6ca2011-01-28 13:15:273536
[email protected]bb88e1d32013-05-03 23:11:073537 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273538
[email protected]c744cf22009-02-27 07:28:083539 // Since we have proxy, should try to establish tunnel.
3540 MockWrite data_writes[] = {
3541 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:453542 "Host: www.google.com\r\n"
3543 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:083544 };
3545
3546 MockRead data_reads[] = {
3547 status,
3548 MockRead("Content-Length: 10\r\n\r\n"),
3549 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:063550 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]c744cf22009-02-27 07:28:083551 };
3552
[email protected]31a2bfe2010-02-09 08:03:393553 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
3554 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:073555 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:083556
[email protected]49639fa2011-12-20 23:22:413557 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:083558
[email protected]262eec82013-03-19 21:01:363559 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503560 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503561
[email protected]49639fa2011-12-20 23:22:413562 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:423563 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]c744cf22009-02-27 07:28:083564
3565 rv = callback.WaitForResult();
3566 EXPECT_EQ(expected_status, rv);
3567}
3568
[email protected]23e482282013-06-14 16:08:023569void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:233570 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:083571 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:423572 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:083573}
3574
[email protected]23e482282013-06-14 16:08:023575TEST_P(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:083576 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
3577}
3578
[email protected]23e482282013-06-14 16:08:023579TEST_P(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:083580 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
3581}
3582
[email protected]23e482282013-06-14 16:08:023583TEST_P(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:083584 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
3585}
3586
[email protected]23e482282013-06-14 16:08:023587TEST_P(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:083588 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
3589}
3590
[email protected]23e482282013-06-14 16:08:023591TEST_P(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:083592 ConnectStatusHelper(
3593 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
3594}
3595
[email protected]23e482282013-06-14 16:08:023596TEST_P(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:083597 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
3598}
3599
[email protected]23e482282013-06-14 16:08:023600TEST_P(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:083601 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
3602}
3603
[email protected]23e482282013-06-14 16:08:023604TEST_P(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:083605 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
3606}
3607
[email protected]23e482282013-06-14 16:08:023608TEST_P(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:083609 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
3610}
3611
[email protected]23e482282013-06-14 16:08:023612TEST_P(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:083613 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
3614}
3615
[email protected]23e482282013-06-14 16:08:023616TEST_P(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:083617 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
3618}
3619
[email protected]23e482282013-06-14 16:08:023620TEST_P(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:083621 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
3622}
3623
[email protected]23e482282013-06-14 16:08:023624TEST_P(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:083625 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
3626}
3627
[email protected]23e482282013-06-14 16:08:023628TEST_P(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:083629 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
3630}
3631
[email protected]23e482282013-06-14 16:08:023632TEST_P(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:083633 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
3634}
3635
[email protected]23e482282013-06-14 16:08:023636TEST_P(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:083637 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
3638}
3639
[email protected]23e482282013-06-14 16:08:023640TEST_P(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:083641 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
3642}
3643
[email protected]23e482282013-06-14 16:08:023644TEST_P(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:083645 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
3646}
3647
[email protected]23e482282013-06-14 16:08:023648TEST_P(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:083649 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
3650}
3651
[email protected]23e482282013-06-14 16:08:023652TEST_P(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:083653 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
3654}
3655
[email protected]23e482282013-06-14 16:08:023656TEST_P(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:083657 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
3658}
3659
[email protected]23e482282013-06-14 16:08:023660TEST_P(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:083661 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
3662}
3663
[email protected]23e482282013-06-14 16:08:023664TEST_P(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:083665 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
3666}
3667
[email protected]23e482282013-06-14 16:08:023668TEST_P(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:083669 ConnectStatusHelperWithExpectedStatus(
3670 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:543671 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:083672}
3673
[email protected]23e482282013-06-14 16:08:023674TEST_P(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:083675 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
3676}
3677
[email protected]23e482282013-06-14 16:08:023678TEST_P(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:083679 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
3680}
3681
[email protected]23e482282013-06-14 16:08:023682TEST_P(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:083683 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
3684}
3685
[email protected]23e482282013-06-14 16:08:023686TEST_P(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:083687 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
3688}
3689
[email protected]23e482282013-06-14 16:08:023690TEST_P(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:083691 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
3692}
3693
[email protected]23e482282013-06-14 16:08:023694TEST_P(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:083695 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
3696}
3697
[email protected]23e482282013-06-14 16:08:023698TEST_P(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:083699 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
3700}
3701
[email protected]23e482282013-06-14 16:08:023702TEST_P(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:083703 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
3704}
3705
[email protected]23e482282013-06-14 16:08:023706TEST_P(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:083707 ConnectStatusHelper(
3708 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
3709}
3710
[email protected]23e482282013-06-14 16:08:023711TEST_P(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:083712 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
3713}
3714
[email protected]23e482282013-06-14 16:08:023715TEST_P(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:083716 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
3717}
3718
[email protected]23e482282013-06-14 16:08:023719TEST_P(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:083720 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
3721}
3722
[email protected]23e482282013-06-14 16:08:023723TEST_P(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:083724 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
3725}
3726
[email protected]23e482282013-06-14 16:08:023727TEST_P(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:083728 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
3729}
3730
[email protected]23e482282013-06-14 16:08:023731TEST_P(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:083732 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
3733}
3734
[email protected]23e482282013-06-14 16:08:023735TEST_P(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:083736 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
3737}
3738
[email protected]038e9a32008-10-08 22:40:163739// Test the flow when both the proxy server AND origin server require
3740// authentication. Again, this uses basic auth for both since that is
3741// the simplest to mock.
[email protected]23e482282013-06-14 16:08:023742TEST_P(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:273743 HttpRequestInfo request;
3744 request.method = "GET";
3745 request.url = GURL("http://www.google.com/");
3746 request.load_flags = 0;
3747
[email protected]bb88e1d32013-05-03 23:11:073748 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]db8f44c2008-12-13 04:52:013749
[email protected]038e9a32008-10-08 22:40:163750 // Configure against proxy server "myproxy:70".
[email protected]262eec82013-03-19 21:01:363751 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:073752 CreateSession(&session_deps_)));
[email protected]038e9a32008-10-08 22:40:163753
[email protected]f9ee6b52008-11-08 06:46:233754 MockWrite data_writes1[] = {
3755 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
3756 "Host: www.google.com\r\n"
3757 "Proxy-Connection: keep-alive\r\n\r\n"),
3758 };
3759
[email protected]038e9a32008-10-08 22:40:163760 MockRead data_reads1[] = {
3761 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
3762 // Give a couple authenticate options (only the middle one is actually
3763 // supported).
[email protected]22927ad2009-09-21 19:56:193764 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:163765 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3766 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
3767 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3768 // Large content-length -- won't matter, as connection will be reset.
3769 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063770 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:163771 };
3772
3773 // After calling trans->RestartWithAuth() the first time, this is the
3774 // request we should be issuing -- the final header line contains the
3775 // proxy's credentials.
3776 MockWrite data_writes2[] = {
3777 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
3778 "Host: www.google.com\r\n"
3779 "Proxy-Connection: keep-alive\r\n"
3780 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3781 };
3782
3783 // Now the proxy server lets the request pass through to origin server.
3784 // The origin server responds with a 401.
3785 MockRead data_reads2[] = {
3786 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
3787 // Note: We are using the same realm-name as the proxy server. This is
3788 // completely valid, as realms are unique across hosts.
3789 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3790 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3791 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063792 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:163793 };
3794
3795 // After calling trans->RestartWithAuth() the second time, we should send
3796 // the credentials for both the proxy and origin server.
3797 MockWrite data_writes3[] = {
3798 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
3799 "Host: www.google.com\r\n"
3800 "Proxy-Connection: keep-alive\r\n"
3801 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
3802 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
3803 };
3804
3805 // Lastly we get the desired content.
3806 MockRead data_reads3[] = {
3807 MockRead("HTTP/1.0 200 OK\r\n"),
3808 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3809 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063810 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:163811 };
3812
[email protected]31a2bfe2010-02-09 08:03:393813 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3814 data_writes1, arraysize(data_writes1));
3815 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3816 data_writes2, arraysize(data_writes2));
3817 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
3818 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:073819 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3820 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3821 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:163822
[email protected]49639fa2011-12-20 23:22:413823 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:163824
[email protected]49639fa2011-12-20 23:22:413825 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:423826 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:163827
3828 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:423829 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:163830
[email protected]1c773ea12009-04-28 19:58:423831 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503832 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:043833 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:163834
[email protected]49639fa2011-12-20 23:22:413835 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:163836
[email protected]49639fa2011-12-20 23:22:413837 rv = trans->RestartWithAuth(
3838 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:423839 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:163840
3841 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:423842 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:163843
3844 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503845 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:043846 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:163847
[email protected]49639fa2011-12-20 23:22:413848 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:163849
[email protected]49639fa2011-12-20 23:22:413850 rv = trans->RestartWithAuth(
3851 AuthCredentials(kFoo2, kBar2), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:423852 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:163853
3854 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:423855 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:163856
3857 response = trans->GetResponseInfo();
3858 EXPECT_TRUE(response->auth_challenge.get() == NULL);
3859 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:163860}
[email protected]4ddaf2502008-10-23 18:26:193861
[email protected]ea9dc9a2009-09-05 00:43:323862// For the NTLM implementation using SSPI, we skip the NTLM tests since we
3863// can't hook into its internals to cause it to generate predictable NTLM
3864// authorization headers.
3865#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:293866// The NTLM authentication unit tests were generated by capturing the HTTP
3867// requests and responses using Fiddler 2 and inspecting the generated random
3868// bytes in the debugger.
3869
3870// Enter the correct password and authenticate successfully.
[email protected]23e482282013-06-14 16:08:023871TEST_P(HttpNetworkTransactionTest, NTLMAuth1) {
[email protected]1c773ea12009-04-28 19:58:423872 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:243873 request.method = "GET";
3874 request.url = GURL("http://172.22.68.17/kids/login.aspx");
3875 request.load_flags = 0;
3876
[email protected]cb9bf6ca2011-01-28 13:15:273877 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
3878 MockGetHostName);
[email protected]bb88e1d32013-05-03 23:11:073879 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273880
[email protected]3f918782009-02-28 01:29:243881 MockWrite data_writes1[] = {
3882 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
3883 "Host: 172.22.68.17\r\n"
3884 "Connection: keep-alive\r\n\r\n"),
3885 };
3886
3887 MockRead data_reads1[] = {
3888 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:043889 // Negotiate and NTLM are often requested together. However, we only want
3890 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
3891 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:243892 MockRead("WWW-Authenticate: NTLM\r\n"),
3893 MockRead("Connection: close\r\n"),
3894 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:363895 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:243896 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:063897 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]3f918782009-02-28 01:29:243898 };
3899
3900 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:223901 // After restarting with a null identity, this is the
[email protected]3f918782009-02-28 01:29:243902 // request we should be issuing -- the final header line contains a Type
3903 // 1 message.
3904 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
3905 "Host: 172.22.68.17\r\n"
3906 "Connection: keep-alive\r\n"
3907 "Authorization: NTLM "
3908 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
3909
3910 // After calling trans->RestartWithAuth(), we should send a Type 3 message
3911 // (the credentials for the origin server). The second request continues
3912 // on the same connection.
3913 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
3914 "Host: 172.22.68.17\r\n"
3915 "Connection: keep-alive\r\n"
[email protected]385a4672009-03-11 22:21:293916 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
3917 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
3918 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
3919 "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
3920 "ahlhx5I=\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:243921 };
3922
3923 MockRead data_reads2[] = {
3924 // The origin server responds with a Type 2 message.
3925 MockRead("HTTP/1.1 401 Access Denied\r\n"),
3926 MockRead("WWW-Authenticate: NTLM "
[email protected]385a4672009-03-11 22:21:293927 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
[email protected]3f918782009-02-28 01:29:243928 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
3929 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
3930 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
3931 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
3932 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
3933 "BtAAAAAAA=\r\n"),
3934 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:363935 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:243936 MockRead("You are not authorized to view this page\r\n"),
3937
3938 // Lastly we get the desired content.
3939 MockRead("HTTP/1.1 200 OK\r\n"),
3940 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
3941 MockRead("Content-Length: 13\r\n\r\n"),
3942 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:063943 MockRead(SYNCHRONOUS, OK),
[email protected]3f918782009-02-28 01:29:243944 };
3945
[email protected]31a2bfe2010-02-09 08:03:393946 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3947 data_writes1, arraysize(data_writes1));
3948 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3949 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:073950 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3951 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:243952
[email protected]49639fa2011-12-20 23:22:413953 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:243954
[email protected]262eec82013-03-19 21:01:363955 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503956 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503957
[email protected]49639fa2011-12-20 23:22:413958 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:423959 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:243960
3961 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:423962 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:243963
[email protected]0757e7702009-03-27 04:00:223964 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
3965
[email protected]1c773ea12009-04-28 19:58:423966 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:043967 ASSERT_FALSE(response == NULL);
3968 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:243969
[email protected]49639fa2011-12-20 23:22:413970 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:253971
[email protected]f3cf9802011-10-28 18:44:583972 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:413973 callback2.callback());
[email protected]10af5fe72011-01-31 16:17:253974 EXPECT_EQ(ERR_IO_PENDING, rv);
3975
3976 rv = callback2.WaitForResult();
3977 EXPECT_EQ(OK, rv);
3978
3979 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
3980
3981 response = trans->GetResponseInfo();
3982 ASSERT_TRUE(response != NULL);
[email protected]10af5fe72011-01-31 16:17:253983 EXPECT_TRUE(response->auth_challenge.get() == NULL);
3984
[email protected]49639fa2011-12-20 23:22:413985 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:243986
[email protected]49639fa2011-12-20 23:22:413987 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:423988 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:243989
[email protected]0757e7702009-03-27 04:00:223990 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:423991 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:243992
3993 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503994 ASSERT_TRUE(response != NULL);
[email protected]3f918782009-02-28 01:29:243995 EXPECT_TRUE(response->auth_challenge.get() == NULL);
3996 EXPECT_EQ(13, response->headers->GetContentLength());
3997}
3998
[email protected]385a4672009-03-11 22:21:293999// Enter a wrong password, and then the correct one.
[email protected]23e482282013-06-14 16:08:024000TEST_P(HttpNetworkTransactionTest, NTLMAuth2) {
[email protected]1c773ea12009-04-28 19:58:424001 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:294002 request.method = "GET";
4003 request.url = GURL("http://172.22.68.17/kids/login.aspx");
4004 request.load_flags = 0;
4005
[email protected]cb9bf6ca2011-01-28 13:15:274006 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
4007 MockGetHostName);
[email protected]bb88e1d32013-05-03 23:11:074008 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274009
[email protected]385a4672009-03-11 22:21:294010 MockWrite data_writes1[] = {
4011 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4012 "Host: 172.22.68.17\r\n"
4013 "Connection: keep-alive\r\n\r\n"),
4014 };
4015
4016 MockRead data_reads1[] = {
4017 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:044018 // Negotiate and NTLM are often requested together. However, we only want
4019 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
4020 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:294021 MockRead("WWW-Authenticate: NTLM\r\n"),
4022 MockRead("Connection: close\r\n"),
4023 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364024 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294025 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064026 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:294027 };
4028
4029 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:224030 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:294031 // request we should be issuing -- the final header line contains a Type
4032 // 1 message.
4033 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4034 "Host: 172.22.68.17\r\n"
4035 "Connection: keep-alive\r\n"
4036 "Authorization: NTLM "
4037 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4038
4039 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4040 // (the credentials for the origin server). The second request continues
4041 // on the same connection.
4042 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4043 "Host: 172.22.68.17\r\n"
4044 "Connection: keep-alive\r\n"
4045 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4046 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4047 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
4048 "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
4049 "4Ww7b7E=\r\n\r\n"),
4050 };
4051
4052 MockRead data_reads2[] = {
4053 // The origin server responds with a Type 2 message.
4054 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4055 MockRead("WWW-Authenticate: NTLM "
4056 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
4057 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4058 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4059 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4060 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4061 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4062 "BtAAAAAAA=\r\n"),
4063 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364064 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294065 MockRead("You are not authorized to view this page\r\n"),
4066
4067 // Wrong password.
4068 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]385a4672009-03-11 22:21:294069 MockRead("WWW-Authenticate: NTLM\r\n"),
4070 MockRead("Connection: close\r\n"),
4071 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364072 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294073 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064074 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:294075 };
4076
4077 MockWrite data_writes3[] = {
[email protected]0757e7702009-03-27 04:00:224078 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:294079 // request we should be issuing -- the final header line contains a Type
4080 // 1 message.
4081 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4082 "Host: 172.22.68.17\r\n"
4083 "Connection: keep-alive\r\n"
4084 "Authorization: NTLM "
4085 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4086
4087 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4088 // (the credentials for the origin server). The second request continues
4089 // on the same connection.
4090 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4091 "Host: 172.22.68.17\r\n"
4092 "Connection: keep-alive\r\n"
4093 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4094 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4095 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
4096 "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
4097 "+4MUm7c=\r\n\r\n"),
4098 };
4099
4100 MockRead data_reads3[] = {
4101 // The origin server responds with a Type 2 message.
4102 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4103 MockRead("WWW-Authenticate: NTLM "
4104 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
4105 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4106 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4107 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4108 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4109 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4110 "BtAAAAAAA=\r\n"),
4111 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364112 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294113 MockRead("You are not authorized to view this page\r\n"),
4114
4115 // Lastly we get the desired content.
4116 MockRead("HTTP/1.1 200 OK\r\n"),
4117 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
4118 MockRead("Content-Length: 13\r\n\r\n"),
4119 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:064120 MockRead(SYNCHRONOUS, OK),
[email protected]385a4672009-03-11 22:21:294121 };
4122
[email protected]31a2bfe2010-02-09 08:03:394123 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4124 data_writes1, arraysize(data_writes1));
4125 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4126 data_writes2, arraysize(data_writes2));
4127 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4128 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:074129 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4130 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4131 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:294132
[email protected]49639fa2011-12-20 23:22:414133 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:294134
[email protected]262eec82013-03-19 21:01:364135 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504136 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504137
[email protected]49639fa2011-12-20 23:22:414138 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424139 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:294140
4141 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424142 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:294143
[email protected]0757e7702009-03-27 04:00:224144 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:294145
[email protected]1c773ea12009-04-28 19:58:424146 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504147 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044148 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:294149
[email protected]49639fa2011-12-20 23:22:414150 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:294151
[email protected]0757e7702009-03-27 04:00:224152 // Enter the wrong password.
[email protected]f3cf9802011-10-28 18:44:584153 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword),
[email protected]49639fa2011-12-20 23:22:414154 callback2.callback());
[email protected]1c773ea12009-04-28 19:58:424155 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:294156
[email protected]10af5fe72011-01-31 16:17:254157 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424158 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:294159
[email protected]0757e7702009-03-27 04:00:224160 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:414161 TestCompletionCallback callback3;
4162 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424163 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]10af5fe72011-01-31 16:17:254164 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424165 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:224166 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4167
4168 response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:044169 ASSERT_FALSE(response == NULL);
4170 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:224171
[email protected]49639fa2011-12-20 23:22:414172 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:224173
4174 // Now enter the right password.
[email protected]f3cf9802011-10-28 18:44:584175 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:414176 callback4.callback());
[email protected]10af5fe72011-01-31 16:17:254177 EXPECT_EQ(ERR_IO_PENDING, rv);
4178
4179 rv = callback4.WaitForResult();
4180 EXPECT_EQ(OK, rv);
4181
4182 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4183
[email protected]49639fa2011-12-20 23:22:414184 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:254185
4186 // One more roundtrip
[email protected]49639fa2011-12-20 23:22:414187 rv = trans->RestartWithAuth(AuthCredentials(), callback5.callback());
[email protected]1c773ea12009-04-28 19:58:424188 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:224189
4190 rv = callback5.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424191 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:224192
[email protected]385a4672009-03-11 22:21:294193 response = trans->GetResponseInfo();
4194 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4195 EXPECT_EQ(13, response->headers->GetContentLength());
4196}
[email protected]ea9dc9a2009-09-05 00:43:324197#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:294198
[email protected]4ddaf2502008-10-23 18:26:194199// Test reading a server response which has only headers, and no body.
4200// After some maximum number of bytes is consumed, the transaction should
4201// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
[email protected]23e482282013-06-14 16:08:024202TEST_P(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:424203 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:194204 request.method = "GET";
4205 request.url = GURL("http://www.google.com/");
4206 request.load_flags = 0;
4207
[email protected]cb9bf6ca2011-01-28 13:15:274208 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:364209 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:074210 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:274211
[email protected]b75b7b2f2009-10-06 00:54:534212 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:434213 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:534214 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:194215
4216 MockRead data_reads[] = {
4217 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:064218 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:194219 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:064220 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:194221 };
[email protected]31a2bfe2010-02-09 08:03:394222 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:074223 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:194224
[email protected]49639fa2011-12-20 23:22:414225 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:194226
[email protected]49639fa2011-12-20 23:22:414227 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424228 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]4ddaf2502008-10-23 18:26:194229
4230 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424231 EXPECT_EQ(ERR_RESPONSE_HEADERS_TOO_BIG, rv);
[email protected]4ddaf2502008-10-23 18:26:194232
[email protected]1c773ea12009-04-28 19:58:424233 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]4ddaf2502008-10-23 18:26:194234 EXPECT_TRUE(response == NULL);
4235}
[email protected]f4e426b2008-11-05 00:24:494236
4237// Make sure that we don't try to reuse a TCPClientSocket when failing to
4238// establish tunnel.
4239// http://code.google.com/p/chromium/issues/detail?id=3772
[email protected]23e482282013-06-14 16:08:024240TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:234241 DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:274242 HttpRequestInfo request;
4243 request.method = "GET";
4244 request.url = GURL("https://www.google.com/");
4245 request.load_flags = 0;
4246
[email protected]f4e426b2008-11-05 00:24:494247 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:074248 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]db8f44c2008-12-13 04:52:014249
[email protected]bb88e1d32013-05-03 23:11:074250 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:494251
[email protected]262eec82013-03-19 21:01:364252 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504253 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f4e426b2008-11-05 00:24:494254
[email protected]f4e426b2008-11-05 00:24:494255 // Since we have proxy, should try to establish tunnel.
4256 MockWrite data_writes1[] = {
4257 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:454258 "Host: www.google.com\r\n"
4259 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:494260 };
4261
[email protected]77848d12008-11-14 00:00:224262 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:494263 // connection. Usually a proxy would return 501 (not implemented),
4264 // or 200 (tunnel established).
4265 MockRead data_reads1[] = {
4266 MockRead("HTTP/1.1 404 Not Found\r\n"),
4267 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064268 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]f4e426b2008-11-05 00:24:494269 };
4270
[email protected]31a2bfe2010-02-09 08:03:394271 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4272 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074273 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:494274
[email protected]49639fa2011-12-20 23:22:414275 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:494276
[email protected]49639fa2011-12-20 23:22:414277 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424278 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f4e426b2008-11-05 00:24:494279
4280 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424281 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]f4e426b2008-11-05 00:24:494282
[email protected]1c773ea12009-04-28 19:58:424283 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]c744cf22009-02-27 07:28:084284 EXPECT_TRUE(response == NULL);
[email protected]f4e426b2008-11-05 00:24:494285
[email protected]b4404c02009-04-10 16:38:524286 // Empty the current queue. This is necessary because idle sockets are
4287 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344288 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:524289
[email protected]f4e426b2008-11-05 00:24:494290 // We now check to make sure the TCPClientSocket was not added back to
4291 // the pool.
[email protected]90499482013-06-01 00:39:504292 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:494293 trans.reset();
[email protected]2da659e2013-05-23 20:51:344294 base::MessageLoop::current()->RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:494295 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:504296 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:494297}
[email protected]372d34a2008-11-05 21:30:514298
[email protected]1b157c02009-04-21 01:55:404299// Make sure that we recycle a socket after reading all of the response body.
[email protected]23e482282013-06-14 16:08:024300TEST_P(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:424301 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:404302 request.method = "GET";
4303 request.url = GURL("http://www.google.com/");
4304 request.load_flags = 0;
4305
[email protected]bb88e1d32013-05-03 23:11:074306 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274307
[email protected]262eec82013-03-19 21:01:364308 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504309 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:274310
[email protected]1b157c02009-04-21 01:55:404311 MockRead data_reads[] = {
4312 // A part of the response body is received with the response headers.
4313 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
4314 // The rest of the response body is received in two parts.
4315 MockRead("lo"),
4316 MockRead(" world"),
4317 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:064318 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:404319 };
4320
[email protected]31a2bfe2010-02-09 08:03:394321 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:074322 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:404323
[email protected]49639fa2011-12-20 23:22:414324 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:404325
[email protected]49639fa2011-12-20 23:22:414326 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424327 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]1b157c02009-04-21 01:55:404328
4329 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424330 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:404331
[email protected]1c773ea12009-04-28 19:58:424332 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504333 ASSERT_TRUE(response != NULL);
[email protected]1b157c02009-04-21 01:55:404334
[email protected]90499482013-06-01 00:39:504335 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]1b157c02009-04-21 01:55:404336 std::string status_line = response->headers->GetStatusLine();
4337 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
4338
[email protected]90499482013-06-01 00:39:504339 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:404340
4341 std::string response_data;
4342 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:424343 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:404344 EXPECT_EQ("hello world", response_data);
4345
4346 // Empty the current queue. This is necessary because idle sockets are
4347 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344348 base::MessageLoop::current()->RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:404349
4350 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504351 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:404352}
4353
[email protected]76a505b2010-08-25 06:23:004354// Make sure that we recycle a SSL socket after reading all of the response
4355// body.
[email protected]23e482282013-06-14 16:08:024356TEST_P(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:004357 HttpRequestInfo request;
4358 request.method = "GET";
4359 request.url = GURL("https://www.google.com/");
4360 request.load_flags = 0;
4361
4362 MockWrite data_writes[] = {
4363 MockWrite("GET / HTTP/1.1\r\n"
4364 "Host: www.google.com\r\n"
4365 "Connection: keep-alive\r\n\r\n"),
4366 };
4367
4368 MockRead data_reads[] = {
4369 MockRead("HTTP/1.1 200 OK\r\n"),
4370 MockRead("Content-Length: 11\r\n\r\n"),
4371 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:064372 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:004373 };
4374
[email protected]8ddf8322012-02-23 18:08:064375 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074376 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:004377
4378 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
4379 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:074380 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:004381
[email protected]49639fa2011-12-20 23:22:414382 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:004383
[email protected]bb88e1d32013-05-03 23:11:074384 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:364385 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504386 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:004387
[email protected]49639fa2011-12-20 23:22:414388 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:004389
4390 EXPECT_EQ(ERR_IO_PENDING, rv);
4391 EXPECT_EQ(OK, callback.WaitForResult());
4392
4393 const HttpResponseInfo* response = trans->GetResponseInfo();
4394 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504395 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:004396 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4397
[email protected]90499482013-06-01 00:39:504398 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004399
4400 std::string response_data;
4401 rv = ReadTransaction(trans.get(), &response_data);
4402 EXPECT_EQ(OK, rv);
4403 EXPECT_EQ("hello world", response_data);
4404
4405 // Empty the current queue. This is necessary because idle sockets are
4406 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344407 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:004408
4409 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504410 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004411}
4412
4413// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
4414// from the pool and make sure that we recover okay.
[email protected]23e482282013-06-14 16:08:024415TEST_P(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:004416 HttpRequestInfo request;
4417 request.method = "GET";
4418 request.url = GURL("https://www.google.com/");
4419 request.load_flags = 0;
4420
4421 MockWrite data_writes[] = {
4422 MockWrite("GET / HTTP/1.1\r\n"
4423 "Host: www.google.com\r\n"
4424 "Connection: keep-alive\r\n\r\n"),
4425 MockWrite("GET / HTTP/1.1\r\n"
4426 "Host: www.google.com\r\n"
4427 "Connection: keep-alive\r\n\r\n"),
4428 };
4429
4430 MockRead data_reads[] = {
4431 MockRead("HTTP/1.1 200 OK\r\n"),
4432 MockRead("Content-Length: 11\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064433 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:004434 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:064435 MockRead(ASYNC, 0, 0) // EOF
[email protected]76a505b2010-08-25 06:23:004436 };
4437
[email protected]8ddf8322012-02-23 18:08:064438 SSLSocketDataProvider ssl(ASYNC, OK);
4439 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074440 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4441 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:004442
4443 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
4444 data_writes, arraysize(data_writes));
4445 StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
4446 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:074447 session_deps_.socket_factory->AddSocketDataProvider(&data);
4448 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:004449
[email protected]49639fa2011-12-20 23:22:414450 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:004451
[email protected]bb88e1d32013-05-03 23:11:074452 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:364453 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504454 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:004455
[email protected]49639fa2011-12-20 23:22:414456 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:004457
4458 EXPECT_EQ(ERR_IO_PENDING, rv);
4459 EXPECT_EQ(OK, callback.WaitForResult());
4460
4461 const HttpResponseInfo* response = trans->GetResponseInfo();
4462 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504463 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:004464 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4465
[email protected]90499482013-06-01 00:39:504466 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004467
4468 std::string response_data;
4469 rv = ReadTransaction(trans.get(), &response_data);
4470 EXPECT_EQ(OK, rv);
4471 EXPECT_EQ("hello world", response_data);
4472
4473 // Empty the current queue. This is necessary because idle sockets are
4474 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344475 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:004476
4477 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504478 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004479
4480 // Now start the second transaction, which should reuse the previous socket.
4481
[email protected]90499482013-06-01 00:39:504482 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:004483
[email protected]49639fa2011-12-20 23:22:414484 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:004485
4486 EXPECT_EQ(ERR_IO_PENDING, rv);
4487 EXPECT_EQ(OK, callback.WaitForResult());
4488
4489 response = trans->GetResponseInfo();
4490 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504491 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:004492 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4493
[email protected]90499482013-06-01 00:39:504494 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004495
4496 rv = ReadTransaction(trans.get(), &response_data);
4497 EXPECT_EQ(OK, rv);
4498 EXPECT_EQ("hello world", response_data);
4499
4500 // Empty the current queue. This is necessary because idle sockets are
4501 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344502 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:004503
4504 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504505 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:004506}
4507
[email protected]b4404c02009-04-10 16:38:524508// Make sure that we recycle a socket after a zero-length response.
4509// http://crbug.com/9880
[email protected]23e482282013-06-14 16:08:024510TEST_P(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:424511 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:524512 request.method = "GET";
4513 request.url = GURL("http://www.google.com/csi?v=3&s=web&action=&"
4514 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
4515 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
4516 "rt=prt.2642,ol.2649,xjs.2951");
4517 request.load_flags = 0;
4518
[email protected]bb88e1d32013-05-03 23:11:074519 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274520
[email protected]262eec82013-03-19 21:01:364521 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504522 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:274523
[email protected]b4404c02009-04-10 16:38:524524 MockRead data_reads[] = {
4525 MockRead("HTTP/1.1 204 No Content\r\n"
4526 "Content-Length: 0\r\n"
4527 "Content-Type: text/html\r\n\r\n"),
4528 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:064529 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:524530 };
4531
[email protected]31a2bfe2010-02-09 08:03:394532 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:074533 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:524534
[email protected]49639fa2011-12-20 23:22:414535 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:524536
[email protected]49639fa2011-12-20 23:22:414537 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424538 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]b4404c02009-04-10 16:38:524539
4540 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424541 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:524542
[email protected]1c773ea12009-04-28 19:58:424543 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504544 ASSERT_TRUE(response != NULL);
[email protected]b4404c02009-04-10 16:38:524545
[email protected]90499482013-06-01 00:39:504546 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]b4404c02009-04-10 16:38:524547 std::string status_line = response->headers->GetStatusLine();
4548 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
4549
[email protected]90499482013-06-01 00:39:504550 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:524551
4552 std::string response_data;
4553 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:424554 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:524555 EXPECT_EQ("", response_data);
4556
4557 // Empty the current queue. This is necessary because idle sockets are
4558 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:344559 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:524560
4561 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:504562 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:524563}
4564
[email protected]23e482282013-06-14 16:08:024565TEST_P(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
[email protected]b2d26cfd2012-12-11 10:36:064566 ScopedVector<UploadElementReader> element_readers;
4567 element_readers.push_back(new UploadBytesElementReader("foo", 3));
4568 UploadDataStream upload_data_stream(&element_readers, 0);
[email protected]329b68b2012-11-14 17:54:274569
[email protected]1c773ea12009-04-28 19:58:424570 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:514571 // Transaction 1: a GET request that succeeds. The socket is recycled
4572 // after use.
4573 request[0].method = "GET";
4574 request[0].url = GURL("http://www.google.com/");
4575 request[0].load_flags = 0;
4576 // Transaction 2: a POST request. Reuses the socket kept alive from
4577 // transaction 1. The first attempts fails when writing the POST data.
4578 // This causes the transaction to retry with a new socket. The second
4579 // attempt succeeds.
4580 request[1].method = "POST";
4581 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:274582 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:514583 request[1].load_flags = 0;
4584
[email protected]bb88e1d32013-05-03 23:11:074585 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:514586
4587 // The first socket is used for transaction 1 and the first attempt of
4588 // transaction 2.
4589
4590 // The response of transaction 1.
4591 MockRead data_reads1[] = {
4592 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
4593 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:064594 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:514595 };
4596 // The mock write results of transaction 1 and the first attempt of
4597 // transaction 2.
4598 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:064599 MockWrite(SYNCHRONOUS, 64), // GET
4600 MockWrite(SYNCHRONOUS, 93), // POST
4601 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:514602 };
[email protected]31a2bfe2010-02-09 08:03:394603 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4604 data_writes1, arraysize(data_writes1));
[email protected]372d34a2008-11-05 21:30:514605
4606 // The second socket is used for the second attempt of transaction 2.
4607
4608 // The response of transaction 2.
4609 MockRead data_reads2[] = {
4610 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
4611 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:064612 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:514613 };
4614 // The mock write results of the second attempt of transaction 2.
4615 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:064616 MockWrite(SYNCHRONOUS, 93), // POST
4617 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:514618 };
[email protected]31a2bfe2010-02-09 08:03:394619 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4620 data_writes2, arraysize(data_writes2));
[email protected]372d34a2008-11-05 21:30:514621
[email protected]bb88e1d32013-05-03 23:11:074622 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4623 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:514624
4625 const char* kExpectedResponseData[] = {
4626 "hello world", "welcome"
4627 };
4628
4629 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:424630 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504631 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]372d34a2008-11-05 21:30:514632
[email protected]49639fa2011-12-20 23:22:414633 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:514634
[email protected]49639fa2011-12-20 23:22:414635 int rv = trans->Start(&request[i], callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424636 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]372d34a2008-11-05 21:30:514637
4638 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424639 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:514640
[email protected]1c773ea12009-04-28 19:58:424641 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504642 ASSERT_TRUE(response != NULL);
[email protected]372d34a2008-11-05 21:30:514643
[email protected]90499482013-06-01 00:39:504644 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]372d34a2008-11-05 21:30:514645 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4646
4647 std::string response_data;
4648 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:424649 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:514650 EXPECT_EQ(kExpectedResponseData[i], response_data);
4651 }
4652}
[email protected]f9ee6b52008-11-08 06:46:234653
4654// Test the request-challenge-retry sequence for basic auth when there is
4655// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:164656// it fails the identity from the URL is used to answer the challenge.
[email protected]23e482282013-06-14 16:08:024657TEST_P(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:424658 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:234659 request.method = "GET";
[email protected]a97cca42009-08-14 01:00:294660 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:414661 request.load_flags = LOAD_NORMAL;
[email protected]a97cca42009-08-14 01:00:294662
[email protected]cb9bf6ca2011-01-28 13:15:274663 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:364664 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:074665 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:274666
[email protected]a97cca42009-08-14 01:00:294667 // The password contains an escaped character -- for this test to pass it
4668 // will need to be unescaped by HttpNetworkTransaction.
4669 EXPECT_EQ("b%40r", request.url.password());
4670
[email protected]f9ee6b52008-11-08 06:46:234671 MockWrite data_writes1[] = {
4672 MockWrite("GET / HTTP/1.1\r\n"
4673 "Host: www.google.com\r\n"
4674 "Connection: keep-alive\r\n\r\n"),
4675 };
4676
4677 MockRead data_reads1[] = {
4678 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4679 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4680 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064681 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:234682 };
4683
[email protected]2262e3a2012-05-22 16:08:164684 // After the challenge above, the transaction will be restarted using the
4685 // identity from the url (foo, b@r) to answer the challenge.
4686 MockWrite data_writes2[] = {
4687 MockWrite("GET / HTTP/1.1\r\n"
4688 "Host: www.google.com\r\n"
4689 "Connection: keep-alive\r\n"
4690 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
4691 };
4692
4693 MockRead data_reads2[] = {
4694 MockRead("HTTP/1.0 200 OK\r\n"),
4695 MockRead("Content-Length: 100\r\n\r\n"),
4696 MockRead(SYNCHRONOUS, OK),
4697 };
4698
[email protected]31a2bfe2010-02-09 08:03:394699 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4700 data_writes1, arraysize(data_writes1));
[email protected]2262e3a2012-05-22 16:08:164701 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4702 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:074703 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4704 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:234705
[email protected]49639fa2011-12-20 23:22:414706 TestCompletionCallback callback1;
[email protected]49639fa2011-12-20 23:22:414707 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424708 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:234709 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424710 EXPECT_EQ(OK, rv);
[email protected]2262e3a2012-05-22 16:08:164711 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4712
4713 TestCompletionCallback callback2;
4714 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
4715 EXPECT_EQ(ERR_IO_PENDING, rv);
4716 rv = callback2.WaitForResult();
4717 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:224718 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4719
[email protected]2262e3a2012-05-22 16:08:164720 const HttpResponseInfo* response = trans->GetResponseInfo();
4721 ASSERT_TRUE(response != NULL);
4722
4723 // There is no challenge info, since the identity in URL worked.
4724 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4725
4726 EXPECT_EQ(100, response->headers->GetContentLength());
4727
4728 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:344729 base::MessageLoop::current()->RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:164730}
4731
4732// Test the request-challenge-retry sequence for basic auth when there is an
4733// incorrect identity in the URL. The identity from the URL should be used only
4734// once.
[email protected]23e482282013-06-14 16:08:024735TEST_P(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:164736 HttpRequestInfo request;
4737 request.method = "GET";
4738 // Note: the URL has a username:password in it. The password "baz" is
4739 // wrong (should be "bar").
4740 request.url = GURL("http://foo:[email protected]/");
4741
4742 request.load_flags = LOAD_NORMAL;
4743
[email protected]2262e3a2012-05-22 16:08:164744 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:364745 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:074746 CreateSession(&session_deps_)));
[email protected]2262e3a2012-05-22 16:08:164747
4748 MockWrite data_writes1[] = {
4749 MockWrite("GET / HTTP/1.1\r\n"
4750 "Host: www.google.com\r\n"
4751 "Connection: keep-alive\r\n\r\n"),
4752 };
4753
4754 MockRead data_reads1[] = {
4755 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4756 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4757 MockRead("Content-Length: 10\r\n\r\n"),
4758 MockRead(SYNCHRONOUS, ERR_FAILED),
4759 };
4760
4761 // After the challenge above, the transaction will be restarted using the
4762 // identity from the url (foo, baz) to answer the challenge.
4763 MockWrite data_writes2[] = {
4764 MockWrite("GET / HTTP/1.1\r\n"
4765 "Host: www.google.com\r\n"
4766 "Connection: keep-alive\r\n"
4767 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
4768 };
4769
4770 MockRead data_reads2[] = {
4771 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4772 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4773 MockRead("Content-Length: 10\r\n\r\n"),
4774 MockRead(SYNCHRONOUS, ERR_FAILED),
4775 };
4776
4777 // After the challenge above, the transaction will be restarted using the
4778 // identity supplied by the user (foo, bar) to answer the challenge.
4779 MockWrite data_writes3[] = {
4780 MockWrite("GET / HTTP/1.1\r\n"
4781 "Host: www.google.com\r\n"
4782 "Connection: keep-alive\r\n"
4783 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
4784 };
4785
4786 MockRead data_reads3[] = {
4787 MockRead("HTTP/1.0 200 OK\r\n"),
4788 MockRead("Content-Length: 100\r\n\r\n"),
4789 MockRead(SYNCHRONOUS, OK),
4790 };
4791
4792 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4793 data_writes1, arraysize(data_writes1));
4794 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4795 data_writes2, arraysize(data_writes2));
4796 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4797 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:074798 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4799 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4800 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:164801
4802 TestCompletionCallback callback1;
4803
4804 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
4805 EXPECT_EQ(ERR_IO_PENDING, rv);
4806
4807 rv = callback1.WaitForResult();
4808 EXPECT_EQ(OK, rv);
4809
4810 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4811 TestCompletionCallback callback2;
4812 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
4813 EXPECT_EQ(ERR_IO_PENDING, rv);
4814 rv = callback2.WaitForResult();
4815 EXPECT_EQ(OK, rv);
4816 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4817
4818 const HttpResponseInfo* response = trans->GetResponseInfo();
4819 ASSERT_TRUE(response != NULL);
4820 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
4821
4822 TestCompletionCallback callback3;
4823 rv = trans->RestartWithAuth(
4824 AuthCredentials(kFoo, kBar), callback3.callback());
4825 EXPECT_EQ(ERR_IO_PENDING, rv);
4826 rv = callback3.WaitForResult();
4827 EXPECT_EQ(OK, rv);
4828 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4829
4830 response = trans->GetResponseInfo();
4831 ASSERT_TRUE(response != NULL);
4832
4833 // There is no challenge info, since the identity worked.
4834 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4835
4836 EXPECT_EQ(100, response->headers->GetContentLength());
4837
[email protected]ea9dc9a2009-09-05 00:43:324838 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:344839 base::MessageLoop::current()->RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:324840}
4841
[email protected]f9ee6b52008-11-08 06:46:234842// Test that previously tried username/passwords for a realm get re-used.
[email protected]23e482282013-06-14 16:08:024843TEST_P(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
[email protected]bb88e1d32013-05-03 23:11:074844 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:234845
4846 // Transaction 1: authenticate (foo, bar) on MyRealm1
4847 {
[email protected]1c773ea12009-04-28 19:58:424848 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:234849 request.method = "GET";
4850 request.url = GURL("http://www.google.com/x/y/z");
4851 request.load_flags = 0;
4852
[email protected]262eec82013-03-19 21:01:364853 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504854 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:274855
[email protected]f9ee6b52008-11-08 06:46:234856 MockWrite data_writes1[] = {
4857 MockWrite("GET /x/y/z HTTP/1.1\r\n"
4858 "Host: www.google.com\r\n"
4859 "Connection: keep-alive\r\n\r\n"),
4860 };
4861
4862 MockRead data_reads1[] = {
4863 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4864 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4865 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064866 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:234867 };
4868
4869 // Resend with authorization (username=foo, password=bar)
4870 MockWrite data_writes2[] = {
4871 MockWrite("GET /x/y/z HTTP/1.1\r\n"
4872 "Host: www.google.com\r\n"
4873 "Connection: keep-alive\r\n"
4874 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
4875 };
4876
4877 // Sever accepts the authorization.
4878 MockRead data_reads2[] = {
4879 MockRead("HTTP/1.0 200 OK\r\n"),
4880 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064881 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:234882 };
4883
[email protected]31a2bfe2010-02-09 08:03:394884 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4885 data_writes1, arraysize(data_writes1));
4886 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4887 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:074888 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4889 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:234890
[email protected]49639fa2011-12-20 23:22:414891 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:234892
[email protected]49639fa2011-12-20 23:22:414893 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424894 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:234895
4896 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424897 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:234898
[email protected]1c773ea12009-04-28 19:58:424899 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504900 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044901 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:234902
[email protected]49639fa2011-12-20 23:22:414903 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:234904
[email protected]49639fa2011-12-20 23:22:414905 rv = trans->RestartWithAuth(
4906 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:424907 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:234908
4909 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424910 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:234911
4912 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504913 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:234914 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4915 EXPECT_EQ(100, response->headers->GetContentLength());
4916 }
4917
4918 // ------------------------------------------------------------------------
4919
4920 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
4921 {
[email protected]1c773ea12009-04-28 19:58:424922 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:234923 request.method = "GET";
4924 // Note that Transaction 1 was at /x/y/z, so this is in the same
4925 // protection space as MyRealm1.
4926 request.url = GURL("http://www.google.com/x/y/a/b");
4927 request.load_flags = 0;
4928
[email protected]262eec82013-03-19 21:01:364929 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504930 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:274931
[email protected]f9ee6b52008-11-08 06:46:234932 MockWrite data_writes1[] = {
4933 MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
4934 "Host: www.google.com\r\n"
4935 "Connection: keep-alive\r\n"
4936 // Send preemptive authorization for MyRealm1
4937 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
4938 };
4939
4940 // The server didn't like the preemptive authorization, and
4941 // challenges us for a different realm (MyRealm2).
4942 MockRead data_reads1[] = {
4943 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4944 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
4945 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064946 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:234947 };
4948
4949 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
4950 MockWrite data_writes2[] = {
4951 MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
4952 "Host: www.google.com\r\n"
4953 "Connection: keep-alive\r\n"
4954 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
4955 };
4956
4957 // Sever accepts the authorization.
4958 MockRead data_reads2[] = {
4959 MockRead("HTTP/1.0 200 OK\r\n"),
4960 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064961 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:234962 };
4963
[email protected]31a2bfe2010-02-09 08:03:394964 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4965 data_writes1, arraysize(data_writes1));
4966 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4967 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:074968 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4969 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:234970
[email protected]49639fa2011-12-20 23:22:414971 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:234972
[email protected]49639fa2011-12-20 23:22:414973 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424974 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:234975
4976 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424977 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:234978
[email protected]1c773ea12009-04-28 19:58:424979 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504980 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044981 ASSERT_TRUE(response->auth_challenge.get());
4982 EXPECT_FALSE(response->auth_challenge->is_proxy);
4983 EXPECT_EQ("www.google.com:80",
4984 response->auth_challenge->challenger.ToString());
4985 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
4986 EXPECT_EQ("basic", response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:234987
[email protected]49639fa2011-12-20 23:22:414988 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:234989
[email protected]49639fa2011-12-20 23:22:414990 rv = trans->RestartWithAuth(
4991 AuthCredentials(kFoo2, kBar2), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:424992 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:234993
4994 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424995 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:234996
4997 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504998 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:234999 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5000 EXPECT_EQ(100, response->headers->GetContentLength());
5001 }
5002
5003 // ------------------------------------------------------------------------
5004
5005 // Transaction 3: Resend a request in MyRealm's protection space --
5006 // succeed with preemptive authorization.
5007 {
[email protected]1c773ea12009-04-28 19:58:425008 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235009 request.method = "GET";
5010 request.url = GURL("http://www.google.com/x/y/z2");
5011 request.load_flags = 0;
5012
[email protected]262eec82013-03-19 21:01:365013 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505014 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275015
[email protected]f9ee6b52008-11-08 06:46:235016 MockWrite data_writes1[] = {
5017 MockWrite("GET /x/y/z2 HTTP/1.1\r\n"
5018 "Host: www.google.com\r\n"
5019 "Connection: keep-alive\r\n"
5020 // The authorization for MyRealm1 gets sent preemptively
5021 // (since the url is in the same protection space)
5022 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5023 };
5024
5025 // Sever accepts the preemptive authorization
5026 MockRead data_reads1[] = {
5027 MockRead("HTTP/1.0 200 OK\r\n"),
5028 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065029 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235030 };
5031
[email protected]31a2bfe2010-02-09 08:03:395032 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5033 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075034 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:235035
[email protected]49639fa2011-12-20 23:22:415036 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235037
[email protected]49639fa2011-12-20 23:22:415038 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425039 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235040
5041 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425042 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235043
[email protected]1c773ea12009-04-28 19:58:425044 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505045 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235046
5047 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5048 EXPECT_EQ(100, response->headers->GetContentLength());
5049 }
5050
5051 // ------------------------------------------------------------------------
5052
5053 // Transaction 4: request another URL in MyRealm (however the
5054 // url is not known to belong to the protection space, so no pre-auth).
5055 {
[email protected]1c773ea12009-04-28 19:58:425056 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235057 request.method = "GET";
5058 request.url = GURL("http://www.google.com/x/1");
5059 request.load_flags = 0;
5060
[email protected]262eec82013-03-19 21:01:365061 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505062 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275063
[email protected]f9ee6b52008-11-08 06:46:235064 MockWrite data_writes1[] = {
5065 MockWrite("GET /x/1 HTTP/1.1\r\n"
5066 "Host: www.google.com\r\n"
5067 "Connection: keep-alive\r\n\r\n"),
5068 };
5069
5070 MockRead data_reads1[] = {
5071 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5072 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5073 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065074 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235075 };
5076
5077 // Resend with authorization from MyRealm's cache.
5078 MockWrite data_writes2[] = {
5079 MockWrite("GET /x/1 HTTP/1.1\r\n"
5080 "Host: www.google.com\r\n"
5081 "Connection: keep-alive\r\n"
5082 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5083 };
5084
5085 // Sever accepts the authorization.
5086 MockRead data_reads2[] = {
5087 MockRead("HTTP/1.0 200 OK\r\n"),
5088 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065089 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235090 };
5091
[email protected]31a2bfe2010-02-09 08:03:395092 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5093 data_writes1, arraysize(data_writes1));
5094 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5095 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075096 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5097 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235098
[email protected]49639fa2011-12-20 23:22:415099 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235100
[email protected]49639fa2011-12-20 23:22:415101 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425102 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235103
5104 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425105 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235106
[email protected]0757e7702009-03-27 04:00:225107 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:415108 TestCompletionCallback callback2;
5109 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425110 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:225111 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425112 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225113 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5114
[email protected]1c773ea12009-04-28 19:58:425115 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505116 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235117 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5118 EXPECT_EQ(100, response->headers->GetContentLength());
5119 }
5120
5121 // ------------------------------------------------------------------------
5122
5123 // Transaction 5: request a URL in MyRealm, but the server rejects the
5124 // cached identity. Should invalidate and re-prompt.
5125 {
[email protected]1c773ea12009-04-28 19:58:425126 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235127 request.method = "GET";
5128 request.url = GURL("http://www.google.com/p/q/t");
5129 request.load_flags = 0;
5130
[email protected]262eec82013-03-19 21:01:365131 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505132 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275133
[email protected]f9ee6b52008-11-08 06:46:235134 MockWrite data_writes1[] = {
5135 MockWrite("GET /p/q/t HTTP/1.1\r\n"
5136 "Host: www.google.com\r\n"
5137 "Connection: keep-alive\r\n\r\n"),
5138 };
5139
5140 MockRead data_reads1[] = {
5141 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5142 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5143 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065144 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235145 };
5146
5147 // Resend with authorization from cache for MyRealm.
5148 MockWrite data_writes2[] = {
5149 MockWrite("GET /p/q/t HTTP/1.1\r\n"
5150 "Host: www.google.com\r\n"
5151 "Connection: keep-alive\r\n"
5152 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5153 };
5154
5155 // Sever rejects the authorization.
5156 MockRead data_reads2[] = {
5157 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5158 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5159 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065160 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235161 };
5162
5163 // At this point we should prompt for new credentials for MyRealm.
5164 // Restart with username=foo3, password=foo4.
5165 MockWrite data_writes3[] = {
5166 MockWrite("GET /p/q/t HTTP/1.1\r\n"
5167 "Host: www.google.com\r\n"
5168 "Connection: keep-alive\r\n"
5169 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
5170 };
5171
5172 // Sever accepts the authorization.
5173 MockRead data_reads3[] = {
5174 MockRead("HTTP/1.0 200 OK\r\n"),
5175 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065176 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235177 };
5178
[email protected]31a2bfe2010-02-09 08:03:395179 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5180 data_writes1, arraysize(data_writes1));
5181 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5182 data_writes2, arraysize(data_writes2));
5183 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5184 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075185 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5186 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5187 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:235188
[email protected]49639fa2011-12-20 23:22:415189 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235190
[email protected]49639fa2011-12-20 23:22:415191 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425192 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235193
5194 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425195 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235196
[email protected]0757e7702009-03-27 04:00:225197 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:415198 TestCompletionCallback callback2;
5199 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425200 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:225201 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425202 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225203 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5204
[email protected]1c773ea12009-04-28 19:58:425205 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505206 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045207 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:235208
[email protected]49639fa2011-12-20 23:22:415209 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:235210
[email protected]49639fa2011-12-20 23:22:415211 rv = trans->RestartWithAuth(
5212 AuthCredentials(kFoo3, kBar3), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:425213 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235214
[email protected]0757e7702009-03-27 04:00:225215 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425216 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235217
5218 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505219 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235220 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5221 EXPECT_EQ(100, response->headers->GetContentLength());
5222 }
5223}
[email protected]89ceba9a2009-03-21 03:46:065224
[email protected]3c32c5f2010-05-18 15:18:125225// Tests that nonce count increments when multiple auth attempts
5226// are started with the same nonce.
[email protected]23e482282013-06-14 16:08:025227TEST_P(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:445228 HttpAuthHandlerDigest::Factory* digest_factory =
5229 new HttpAuthHandlerDigest::Factory();
5230 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
5231 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
5232 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:075233 session_deps_.http_auth_handler_factory.reset(digest_factory);
5234 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:125235
5236 // Transaction 1: authenticate (foo, bar) on MyRealm1
5237 {
[email protected]3c32c5f2010-05-18 15:18:125238 HttpRequestInfo request;
5239 request.method = "GET";
5240 request.url = GURL("http://www.google.com/x/y/z");
5241 request.load_flags = 0;
5242
[email protected]262eec82013-03-19 21:01:365243 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505244 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275245
[email protected]3c32c5f2010-05-18 15:18:125246 MockWrite data_writes1[] = {
5247 MockWrite("GET /x/y/z HTTP/1.1\r\n"
5248 "Host: www.google.com\r\n"
5249 "Connection: keep-alive\r\n\r\n"),
5250 };
5251
5252 MockRead data_reads1[] = {
5253 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5254 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
5255 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065256 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:125257 };
5258
5259 // Resend with authorization (username=foo, password=bar)
5260 MockWrite data_writes2[] = {
5261 MockWrite("GET /x/y/z HTTP/1.1\r\n"
5262 "Host: www.google.com\r\n"
5263 "Connection: keep-alive\r\n"
5264 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
5265 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
5266 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
5267 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
5268 };
5269
5270 // Sever accepts the authorization.
5271 MockRead data_reads2[] = {
5272 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:065273 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:125274 };
5275
5276 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5277 data_writes1, arraysize(data_writes1));
5278 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5279 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075280 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5281 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:125282
[email protected]49639fa2011-12-20 23:22:415283 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:125284
[email protected]49639fa2011-12-20 23:22:415285 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:125286 EXPECT_EQ(ERR_IO_PENDING, rv);
5287
5288 rv = callback1.WaitForResult();
5289 EXPECT_EQ(OK, rv);
5290
5291 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505292 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045293 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:125294
[email protected]49639fa2011-12-20 23:22:415295 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:125296
[email protected]49639fa2011-12-20 23:22:415297 rv = trans->RestartWithAuth(
5298 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]3c32c5f2010-05-18 15:18:125299 EXPECT_EQ(ERR_IO_PENDING, rv);
5300
5301 rv = callback2.WaitForResult();
5302 EXPECT_EQ(OK, rv);
5303
5304 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505305 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:125306 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5307 }
5308
5309 // ------------------------------------------------------------------------
5310
5311 // Transaction 2: Request another resource in digestive's protection space.
5312 // This will preemptively add an Authorization header which should have an
5313 // "nc" value of 2 (as compared to 1 in the first use.
5314 {
[email protected]3c32c5f2010-05-18 15:18:125315 HttpRequestInfo request;
5316 request.method = "GET";
5317 // Note that Transaction 1 was at /x/y/z, so this is in the same
5318 // protection space as digest.
5319 request.url = GURL("http://www.google.com/x/y/a/b");
5320 request.load_flags = 0;
5321
[email protected]262eec82013-03-19 21:01:365322 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505323 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275324
[email protected]3c32c5f2010-05-18 15:18:125325 MockWrite data_writes1[] = {
5326 MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
5327 "Host: www.google.com\r\n"
5328 "Connection: keep-alive\r\n"
5329 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
5330 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
5331 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
5332 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
5333 };
5334
5335 // Sever accepts the authorization.
5336 MockRead data_reads1[] = {
5337 MockRead("HTTP/1.0 200 OK\r\n"),
5338 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065339 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:125340 };
5341
5342 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5343 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075344 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:125345
[email protected]49639fa2011-12-20 23:22:415346 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:125347
[email protected]49639fa2011-12-20 23:22:415348 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:125349 EXPECT_EQ(ERR_IO_PENDING, rv);
5350
5351 rv = callback1.WaitForResult();
5352 EXPECT_EQ(OK, rv);
5353
5354 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505355 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:125356 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5357 }
5358}
5359
[email protected]89ceba9a2009-03-21 03:46:065360// Test the ResetStateForRestart() private method.
[email protected]23e482282013-06-14 16:08:025361TEST_P(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:065362 // Create a transaction (the dependencies aren't important).
[email protected]d207a5f2009-06-04 05:28:405363 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]262eec82013-03-19 21:01:365364 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:075365 CreateSession(&session_deps_)));
[email protected]89ceba9a2009-03-21 03:46:065366
5367 // Setup some state (which we expect ResetStateForRestart() will clear).
[email protected]89ceba9a2009-03-21 03:46:065368 trans->read_buf_ = new IOBuffer(15);
5369 trans->read_buf_len_ = 15;
[email protected]b94f92d2010-10-27 16:45:205370 trans->request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:065371
5372 // Setup state in response_
[email protected]a7e41312009-12-16 23:18:145373 HttpResponseInfo* response = &trans->response_;
[email protected]0877e3d2009-10-17 22:29:575374 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:085375 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:575376 response->response_time = base::Time::Now();
5377 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:065378
5379 { // Setup state for response_.vary_data
5380 HttpRequestInfo request;
5381 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
5382 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:275383 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:435384 request.extra_headers.SetHeader("Foo", "1");
5385 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:505386 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:065387 }
5388
5389 // Cause the above state to be reset.
5390 trans->ResetStateForRestart();
5391
5392 // Verify that the state that needed to be reset, has been reset.
[email protected]9b6fee12009-09-29 18:13:075393 EXPECT_TRUE(trans->read_buf_.get() == NULL);
[email protected]89ceba9a2009-03-21 03:46:065394 EXPECT_EQ(0, trans->read_buf_len_);
[email protected]b94f92d2010-10-27 16:45:205395 EXPECT_TRUE(trans->request_headers_.IsEmpty());
[email protected]0877e3d2009-10-17 22:29:575396 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5397 EXPECT_TRUE(response->headers.get() == NULL);
[email protected]34f40942010-10-04 00:34:045398 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:085399 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:575400 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:065401}
5402
[email protected]bacff652009-03-31 17:50:335403// Test HTTPS connections to a site with a bad certificate
[email protected]23e482282013-06-14 16:08:025404TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:335405 HttpRequestInfo request;
5406 request.method = "GET";
5407 request.url = GURL("https://www.google.com/");
5408 request.load_flags = 0;
5409
[email protected]cb9bf6ca2011-01-28 13:15:275410 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:365411 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:075412 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:275413
[email protected]bacff652009-03-31 17:50:335414 MockWrite data_writes[] = {
5415 MockWrite("GET / HTTP/1.1\r\n"
5416 "Host: www.google.com\r\n"
5417 "Connection: keep-alive\r\n\r\n"),
5418 };
5419
5420 MockRead data_reads[] = {
5421 MockRead("HTTP/1.0 200 OK\r\n"),
5422 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5423 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065424 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:335425 };
5426
[email protected]5ecc992a42009-11-11 01:41:595427 StaticSocketDataProvider ssl_bad_certificate;
[email protected]31a2bfe2010-02-09 08:03:395428 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5429 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:065430 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
5431 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:335432
[email protected]bb88e1d32013-05-03 23:11:075433 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
5434 session_deps_.socket_factory->AddSocketDataProvider(&data);
5435 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
5436 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:335437
[email protected]49639fa2011-12-20 23:22:415438 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:335439
[email protected]49639fa2011-12-20 23:22:415440 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:335441 EXPECT_EQ(ERR_IO_PENDING, rv);
5442
5443 rv = callback.WaitForResult();
5444 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
5445
[email protected]49639fa2011-12-20 23:22:415446 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:335447 EXPECT_EQ(ERR_IO_PENDING, rv);
5448
5449 rv = callback.WaitForResult();
5450 EXPECT_EQ(OK, rv);
5451
5452 const HttpResponseInfo* response = trans->GetResponseInfo();
5453
[email protected]fe2255a2011-09-20 19:37:505454 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:335455 EXPECT_EQ(100, response->headers->GetContentLength());
5456}
5457
5458// Test HTTPS connections to a site with a bad certificate, going through a
5459// proxy
[email protected]23e482282013-06-14 16:08:025460TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
[email protected]bb88e1d32013-05-03 23:11:075461 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]bacff652009-03-31 17:50:335462
5463 HttpRequestInfo request;
5464 request.method = "GET";
5465 request.url = GURL("https://www.google.com/");
5466 request.load_flags = 0;
5467
5468 MockWrite proxy_writes[] = {
5469 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:455470 "Host: www.google.com\r\n"
5471 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:335472 };
5473
5474 MockRead proxy_reads[] = {
5475 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065476 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:335477 };
5478
5479 MockWrite data_writes[] = {
5480 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
[email protected]e44de5d2009-06-05 20:12:455481 "Host: www.google.com\r\n"
5482 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:335483 MockWrite("GET / HTTP/1.1\r\n"
5484 "Host: www.google.com\r\n"
5485 "Connection: keep-alive\r\n\r\n"),
5486 };
5487
5488 MockRead data_reads[] = {
5489 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
5490 MockRead("HTTP/1.0 200 OK\r\n"),
5491 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5492 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065493 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:335494 };
5495
[email protected]31a2bfe2010-02-09 08:03:395496 StaticSocketDataProvider ssl_bad_certificate(
5497 proxy_reads, arraysize(proxy_reads),
5498 proxy_writes, arraysize(proxy_writes));
5499 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5500 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:065501 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
5502 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:335503
[email protected]bb88e1d32013-05-03 23:11:075504 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
5505 session_deps_.socket_factory->AddSocketDataProvider(&data);
5506 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
5507 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:335508
[email protected]49639fa2011-12-20 23:22:415509 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:335510
5511 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:075512 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:335513
[email protected]d207a5f2009-06-04 05:28:405514 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:365515 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:075516 CreateSession(&session_deps_)));
[email protected]bacff652009-03-31 17:50:335517
[email protected]49639fa2011-12-20 23:22:415518 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:335519 EXPECT_EQ(ERR_IO_PENDING, rv);
5520
5521 rv = callback.WaitForResult();
5522 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
5523
[email protected]49639fa2011-12-20 23:22:415524 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:335525 EXPECT_EQ(ERR_IO_PENDING, rv);
5526
5527 rv = callback.WaitForResult();
5528 EXPECT_EQ(OK, rv);
5529
5530 const HttpResponseInfo* response = trans->GetResponseInfo();
5531
[email protected]fe2255a2011-09-20 19:37:505532 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:335533 EXPECT_EQ(100, response->headers->GetContentLength());
5534 }
5535}
5536
[email protected]2df19bb2010-08-25 20:13:465537
5538// Test HTTPS connections to a site, going through an HTTPS proxy
[email protected]23e482282013-06-14 16:08:025539TEST_P(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:075540 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:205541 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
5542 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:075543 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:465544
5545 HttpRequestInfo request;
5546 request.method = "GET";
5547 request.url = GURL("https://www.google.com/");
5548 request.load_flags = 0;
5549
5550 MockWrite data_writes[] = {
5551 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
5552 "Host: www.google.com\r\n"
5553 "Proxy-Connection: keep-alive\r\n\r\n"),
5554 MockWrite("GET / HTTP/1.1\r\n"
5555 "Host: www.google.com\r\n"
5556 "Connection: keep-alive\r\n\r\n"),
5557 };
5558
5559 MockRead data_reads[] = {
5560 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
5561 MockRead("HTTP/1.1 200 OK\r\n"),
5562 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5563 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065564 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:465565 };
5566
5567 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5568 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:065569 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
5570 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:465571
[email protected]bb88e1d32013-05-03 23:11:075572 session_deps_.socket_factory->AddSocketDataProvider(&data);
5573 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
5574 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:465575
[email protected]49639fa2011-12-20 23:22:415576 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:465577
5578 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:365579 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:075580 CreateSession(&session_deps_)));
[email protected]2df19bb2010-08-25 20:13:465581
[email protected]49639fa2011-12-20 23:22:415582 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:465583 EXPECT_EQ(ERR_IO_PENDING, rv);
5584
5585 rv = callback.WaitForResult();
5586 EXPECT_EQ(OK, rv);
5587 const HttpResponseInfo* response = trans->GetResponseInfo();
5588
[email protected]fe2255a2011-09-20 19:37:505589 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:465590
5591 EXPECT_TRUE(response->headers->IsKeepAlive());
5592 EXPECT_EQ(200, response->headers->response_code());
5593 EXPECT_EQ(100, response->headers->GetContentLength());
5594 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:205595
5596 LoadTimingInfo load_timing_info;
5597 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5598 TestLoadTimingNotReusedWithPac(load_timing_info,
5599 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:465600}
5601
[email protected]511f6f52010-12-17 03:58:295602// Test an HTTPS Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:025603TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:075604 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:205605 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
5606 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:075607 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:295608
5609 HttpRequestInfo request;
5610 request.method = "GET";
5611 request.url = GURL("https://www.google.com/");
5612 request.load_flags = 0;
5613
5614 MockWrite data_writes[] = {
5615 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
5616 "Host: www.google.com\r\n"
5617 "Proxy-Connection: keep-alive\r\n\r\n"),
5618 };
5619
5620 MockRead data_reads[] = {
5621 MockRead("HTTP/1.1 302 Redirect\r\n"),
5622 MockRead("Location: http://login.example.com/\r\n"),
5623 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065624 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:295625 };
5626
5627 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5628 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:065629 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:295630
[email protected]bb88e1d32013-05-03 23:11:075631 session_deps_.socket_factory->AddSocketDataProvider(&data);
5632 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:295633
[email protected]49639fa2011-12-20 23:22:415634 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:295635
5636 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:365637 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:075638 CreateSession(&session_deps_)));
[email protected]511f6f52010-12-17 03:58:295639
[email protected]49639fa2011-12-20 23:22:415640 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:295641 EXPECT_EQ(ERR_IO_PENDING, rv);
5642
5643 rv = callback.WaitForResult();
5644 EXPECT_EQ(OK, rv);
5645 const HttpResponseInfo* response = trans->GetResponseInfo();
5646
[email protected]fe2255a2011-09-20 19:37:505647 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:295648
5649 EXPECT_EQ(302, response->headers->response_code());
5650 std::string url;
5651 EXPECT_TRUE(response->headers->IsRedirect(&url));
5652 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:205653
5654 // In the case of redirects from proxies, HttpNetworkTransaction returns
5655 // timing for the proxy connection instead of the connection to the host,
5656 // and no send / receive times.
5657 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
5658 LoadTimingInfo load_timing_info;
5659 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5660
5661 EXPECT_FALSE(load_timing_info.socket_reused);
5662 EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
5663
5664 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
5665 EXPECT_LE(load_timing_info.proxy_resolve_start,
5666 load_timing_info.proxy_resolve_end);
5667 EXPECT_LE(load_timing_info.proxy_resolve_end,
5668 load_timing_info.connect_timing.connect_start);
5669 ExpectConnectTimingHasTimes(
5670 load_timing_info.connect_timing,
5671 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
5672
5673 EXPECT_TRUE(load_timing_info.send_start.is_null());
5674 EXPECT_TRUE(load_timing_info.send_end.is_null());
5675 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:295676}
5677
5678// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:025679TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
[email protected]bb88e1d32013-05-03 23:11:075680 session_deps_.proxy_service.reset(
[email protected]511f6f52010-12-17 03:58:295681 ProxyService::CreateFixed("https://proxy:70"));
5682
5683 HttpRequestInfo request;
5684 request.method = "GET";
5685 request.url = GURL("https://www.google.com/");
5686 request.load_flags = 0;
5687
[email protected]fba2dbde2013-05-24 16:09:015688 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(NULL, 0, 1));
[email protected]c10b20852013-05-15 21:29:205689 scoped_ptr<SpdyFrame> goaway(
5690 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:295691 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:065692 CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
[email protected]57d2dfa2013-06-24 06:04:125693 CreateMockWrite(*goaway.get(), 3, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:295694 };
5695
5696 static const char* const kExtraHeaders[] = {
5697 "location",
5698 "http://login.example.com/",
5699 };
[email protected]ff98d7f02012-03-22 21:44:195700 scoped_ptr<SpdyFrame> resp(
[email protected]23e482282013-06-14 16:08:025701 spdy_util_.ConstructSpdySynReplyError("302 Redirect", kExtraHeaders,
[email protected]511f6f52010-12-17 03:58:295702 arraysize(kExtraHeaders)/2, 1));
5703 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:065704 CreateMockRead(*resp.get(), 1, SYNCHRONOUS),
5705 MockRead(ASYNC, 0, 2), // EOF
[email protected]511f6f52010-12-17 03:58:295706 };
5707
[email protected]dd54bd82012-07-19 23:44:575708 DelayedSocketData data(
5709 1, // wait for one write to finish before reading.
5710 data_reads, arraysize(data_reads),
5711 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:065712 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]23e482282013-06-14 16:08:025713 proxy_ssl.SetNextProto(GetParam());
[email protected]511f6f52010-12-17 03:58:295714
[email protected]bb88e1d32013-05-03 23:11:075715 session_deps_.socket_factory->AddSocketDataProvider(&data);
5716 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:295717
[email protected]49639fa2011-12-20 23:22:415718 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:295719
5720 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:365721 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:075722 CreateSession(&session_deps_)));
[email protected]511f6f52010-12-17 03:58:295723
[email protected]49639fa2011-12-20 23:22:415724 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:295725 EXPECT_EQ(ERR_IO_PENDING, rv);
5726
5727 rv = callback.WaitForResult();
5728 EXPECT_EQ(OK, rv);
5729 const HttpResponseInfo* response = trans->GetResponseInfo();
5730
[email protected]fe2255a2011-09-20 19:37:505731 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:295732
5733 EXPECT_EQ(302, response->headers->response_code());
5734 std::string url;
5735 EXPECT_TRUE(response->headers->IsRedirect(&url));
5736 EXPECT_EQ("http://login.example.com/", url);
5737}
5738
[email protected]4eddbc732012-08-09 05:40:175739// Test that an HTTPS proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:025740TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:175741 ErrorResponseToHttpsConnectViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:075742 session_deps_.proxy_service.reset(
[email protected]511f6f52010-12-17 03:58:295743 ProxyService::CreateFixed("https://proxy:70"));
5744
5745 HttpRequestInfo request;
5746 request.method = "GET";
5747 request.url = GURL("https://www.google.com/");
5748 request.load_flags = 0;
5749
5750 MockWrite data_writes[] = {
5751 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
5752 "Host: www.google.com\r\n"
5753 "Proxy-Connection: keep-alive\r\n\r\n"),
5754 };
5755
5756 MockRead data_reads[] = {
5757 MockRead("HTTP/1.1 404 Not Found\r\n"),
5758 MockRead("Content-Length: 23\r\n\r\n"),
5759 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:065760 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:295761 };
5762
5763 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5764 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:065765 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:295766
[email protected]bb88e1d32013-05-03 23:11:075767 session_deps_.socket_factory->AddSocketDataProvider(&data);
5768 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:295769
[email protected]49639fa2011-12-20 23:22:415770 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:295771
5772 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:365773 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:075774 CreateSession(&session_deps_)));
[email protected]511f6f52010-12-17 03:58:295775
[email protected]49639fa2011-12-20 23:22:415776 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:295777 EXPECT_EQ(ERR_IO_PENDING, rv);
5778
5779 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:175780 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:295781
[email protected]4eddbc732012-08-09 05:40:175782 // TODO(ttuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:295783}
5784
[email protected]4eddbc732012-08-09 05:40:175785// Test that a SPDY proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:025786TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:175787 ErrorResponseToHttpsConnectViaSpdyProxy) {
[email protected]bb88e1d32013-05-03 23:11:075788 session_deps_.proxy_service.reset(
5789 ProxyService::CreateFixed("https://proxy:70"));
[email protected]511f6f52010-12-17 03:58:295790
5791 HttpRequestInfo request;
5792 request.method = "GET";
5793 request.url = GURL("https://www.google.com/");
5794 request.load_flags = 0;
5795
[email protected]fba2dbde2013-05-24 16:09:015796 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(NULL, 0, 1));
[email protected]c10b20852013-05-15 21:29:205797 scoped_ptr<SpdyFrame> rst(
5798 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:295799 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:065800 CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
[email protected]4eddbc732012-08-09 05:40:175801 CreateMockWrite(*rst.get(), 3, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:295802 };
5803
5804 static const char* const kExtraHeaders[] = {
5805 "location",
5806 "http://login.example.com/",
5807 };
[email protected]ff98d7f02012-03-22 21:44:195808 scoped_ptr<SpdyFrame> resp(
[email protected]23e482282013-06-14 16:08:025809 spdy_util_.ConstructSpdySynReplyError("404 Not Found", kExtraHeaders,
[email protected]511f6f52010-12-17 03:58:295810 arraysize(kExtraHeaders)/2, 1));
[email protected]ff98d7f02012-03-22 21:44:195811 scoped_ptr<SpdyFrame> body(
[email protected]23e482282013-06-14 16:08:025812 spdy_util_.ConstructSpdyBodyFrame(
5813 1, "The host does not exist", 23, true));
[email protected]511f6f52010-12-17 03:58:295814 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:065815 CreateMockRead(*resp.get(), 1, SYNCHRONOUS),
5816 CreateMockRead(*body.get(), 2, SYNCHRONOUS),
[email protected]4eddbc732012-08-09 05:40:175817 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:295818 };
5819
[email protected]dd54bd82012-07-19 23:44:575820 DelayedSocketData data(
5821 1, // wait for one write to finish before reading.
5822 data_reads, arraysize(data_reads),
5823 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:065824 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]23e482282013-06-14 16:08:025825 proxy_ssl.SetNextProto(GetParam());
[email protected]511f6f52010-12-17 03:58:295826
[email protected]bb88e1d32013-05-03 23:11:075827 session_deps_.socket_factory->AddSocketDataProvider(&data);
5828 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:295829
[email protected]49639fa2011-12-20 23:22:415830 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:295831
5832 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:365833 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:075834 CreateSession(&session_deps_)));
[email protected]511f6f52010-12-17 03:58:295835
[email protected]49639fa2011-12-20 23:22:415836 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:295837 EXPECT_EQ(ERR_IO_PENDING, rv);
5838
5839 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:175840 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:295841
[email protected]4eddbc732012-08-09 05:40:175842 // TODO(ttuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:295843}
5844
[email protected]0c5fb722012-02-28 11:50:355845// Test the request-challenge-retry sequence for basic auth, through
5846// a SPDY proxy over a single SPDY session.
[email protected]23e482282013-06-14 16:08:025847TEST_P(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:355848 HttpRequestInfo request;
5849 request.method = "GET";
5850 request.url = GURL("https://www.google.com/");
5851 // when the no authentication data flag is set.
5852 request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
5853
5854 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:075855 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:205856 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
[email protected]333bdf62012-06-08 22:57:295857 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075858 session_deps_.net_log = log.bound().net_log();
5859 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:355860
5861 // Since we have proxy, should try to establish tunnel.
[email protected]fba2dbde2013-05-24 16:09:015862 scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyConnect(NULL, 0, 1));
[email protected]c10b20852013-05-15 21:29:205863 scoped_ptr<SpdyFrame> rst(
5864 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]0c5fb722012-02-28 11:50:355865
5866 // After calling trans->RestartWithAuth(), this is the request we should
5867 // be issuing -- the final header line contains the credentials.
5868 const char* const kAuthCredentials[] = {
5869 "proxy-authorization", "Basic Zm9vOmJhcg==",
5870 };
[email protected]fba2dbde2013-05-24 16:09:015871 scoped_ptr<SpdyFrame> connect2(spdy_util_.ConstructSpdyConnect(
5872 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3));
[email protected]0c5fb722012-02-28 11:50:355873 // fetch https://www.google.com/ via HTTP
5874 const char get[] = "GET / HTTP/1.1\r\n"
5875 "Host: www.google.com\r\n"
5876 "Connection: keep-alive\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:195877 scoped_ptr<SpdyFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:025878 spdy_util_.ConstructSpdyBodyFrame(3, get, strlen(get), false));
[email protected]0c5fb722012-02-28 11:50:355879
5880 MockWrite spdy_writes[] = {
[email protected]3d7c43f2012-07-10 21:26:205881 CreateMockWrite(*req, 1, ASYNC),
[email protected]c92f4b4542012-07-26 23:53:215882 CreateMockWrite(*rst, 4, ASYNC),
5883 CreateMockWrite(*connect2, 5),
[email protected]3d7c43f2012-07-10 21:26:205884 CreateMockWrite(*wrapped_get, 8),
[email protected]0c5fb722012-02-28 11:50:355885 };
5886
5887 // The proxy responds to the connect with a 407, using a persistent
5888 // connection.
5889 const char* const kAuthChallenge[] = {
[email protected]23e482282013-06-14 16:08:025890 spdy_util_.GetStatusKey(), "407 Proxy Authentication Required",
5891 spdy_util_.GetVersionKey(), "HTTP/1.1",
[email protected]0c5fb722012-02-28 11:50:355892 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
5893 };
5894
[email protected]ff98d7f02012-03-22 21:44:195895 scoped_ptr<SpdyFrame> conn_auth_resp(
[email protected]4bd46222013-05-14 19:32:235896 spdy_util_.ConstructSpdyControlFrame(NULL,
5897 0,
5898 false,
5899 1,
5900 LOWEST,
5901 SYN_REPLY,
5902 CONTROL_FLAG_NONE,
5903 kAuthChallenge,
5904 arraysize(kAuthChallenge),
5905 0));
[email protected]0c5fb722012-02-28 11:50:355906
[email protected]23e482282013-06-14 16:08:025907 scoped_ptr<SpdyFrame> conn_resp(
5908 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:355909 const char resp[] = "HTTP/1.1 200 OK\r\n"
5910 "Content-Length: 5\r\n\r\n";
5911
[email protected]ff98d7f02012-03-22 21:44:195912 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:025913 spdy_util_.ConstructSpdyBodyFrame(3, resp, strlen(resp), false));
[email protected]ff98d7f02012-03-22 21:44:195914 scoped_ptr<SpdyFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:025915 spdy_util_.ConstructSpdyBodyFrame(3, "hello", 5, false));
[email protected]0c5fb722012-02-28 11:50:355916 MockRead spdy_reads[] = {
[email protected]3d7c43f2012-07-10 21:26:205917 CreateMockRead(*conn_auth_resp, 2, ASYNC),
5918 CreateMockRead(*conn_resp, 6, ASYNC),
5919 CreateMockRead(*wrapped_get_resp, 9, ASYNC),
5920 CreateMockRead(*wrapped_body, 10, ASYNC),
5921 MockRead(ASYNC, OK, 11), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:355922 };
5923
[email protected]dd54bd82012-07-19 23:44:575924 OrderedSocketData spdy_data(
5925 spdy_reads, arraysize(spdy_reads),
5926 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075927 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:355928 // Negotiate SPDY to the proxy
5929 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:025930 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:075931 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:355932 // Vanilla SSL to the server
5933 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075934 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:355935
5936 TestCompletionCallback callback1;
5937
[email protected]262eec82013-03-19 21:01:365938 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505939 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0c5fb722012-02-28 11:50:355940
5941 int rv = trans->Start(&request, callback1.callback(), log.bound());
5942 EXPECT_EQ(ERR_IO_PENDING, rv);
5943
5944 rv = callback1.WaitForResult();
5945 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:575946 net::CapturingNetLog::CapturedEntryList entries;
[email protected]0c5fb722012-02-28 11:50:355947 log.GetEntries(&entries);
5948 size_t pos = ExpectLogContainsSomewhere(
5949 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
5950 NetLog::PHASE_NONE);
5951 ExpectLogContainsSomewhere(
5952 entries, pos,
5953 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
5954 NetLog::PHASE_NONE);
5955
5956 const HttpResponseInfo* response = trans->GetResponseInfo();
5957 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:505958 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]0c5fb722012-02-28 11:50:355959 EXPECT_EQ(407, response->headers->response_code());
5960 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5961 EXPECT_TRUE(response->auth_challenge.get() != NULL);
5962 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
5963
5964 TestCompletionCallback callback2;
5965
5966 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
5967 callback2.callback());
5968 EXPECT_EQ(ERR_IO_PENDING, rv);
5969
5970 rv = callback2.WaitForResult();
5971 EXPECT_EQ(OK, rv);
5972
5973 response = trans->GetResponseInfo();
5974 ASSERT_TRUE(response != NULL);
5975
5976 EXPECT_TRUE(response->headers->IsKeepAlive());
5977 EXPECT_EQ(200, response->headers->response_code());
5978 EXPECT_EQ(5, response->headers->GetContentLength());
5979 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5980
5981 // The password prompt info should not be set.
5982 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5983
[email protected]029c83b62013-01-24 05:28:205984 LoadTimingInfo load_timing_info;
5985 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5986 TestLoadTimingNotReusedWithPac(load_timing_info,
5987 CONNECT_TIMING_HAS_SSL_TIMES);
5988
[email protected]0c5fb722012-02-28 11:50:355989 trans.reset();
5990 session->CloseAllConnections();
5991}
5992
[email protected]7c6f7ba2012-04-03 04:09:295993// Test that an explicitly trusted SPDY proxy can push a resource from an
5994// origin that is different from that of its associated resource.
[email protected]23e482282013-06-14 16:08:025995TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPush) {
[email protected]7c6f7ba2012-04-03 04:09:295996 HttpRequestInfo request;
5997 HttpRequestInfo push_request;
5998
[email protected]7c6f7ba2012-04-03 04:09:295999 request.method = "GET";
6000 request.url = GURL("http://www.google.com/");
6001 push_request.method = "GET";
6002 push_request.url = GURL("http://www.another-origin.com/foo.dat");
6003
[email protected]7c6f7ba2012-04-03 04:09:296004 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076005 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206006 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
[email protected]333bdf62012-06-08 22:57:296007 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076008 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:506009
6010 // Enable cross-origin push.
[email protected]bb88e1d32013-05-03 23:11:076011 session_deps_.trusted_spdy_proxy = "myproxy:70";
[email protected]61b4efc2012-04-27 18:12:506012
[email protected]bb88e1d32013-05-03 23:11:076013 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:296014
[email protected]cdf8f7e72013-05-23 10:56:466015 scoped_ptr<SpdyFrame> stream1_syn(
6016 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]7c6f7ba2012-04-03 04:09:296017
6018 MockWrite spdy_writes[] = {
[email protected]cdf8f7e72013-05-23 10:56:466019 CreateMockWrite(*stream1_syn, 1, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:296020 };
6021
6022 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026023 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:296024
6025 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026026 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:296027
6028 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026029 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
[email protected]7c6f7ba2012-04-03 04:09:296030 0,
6031 2,
6032 1,
6033 "http://www.another-origin.com/foo.dat"));
[email protected]8a0fc822013-06-27 20:52:436034 const char kPushedData[] = "pushed";
6035 scoped_ptr<SpdyFrame> stream2_body(
6036 spdy_util_.ConstructSpdyBodyFrame(
6037 2, kPushedData, strlen(kPushedData), true));
[email protected]7c6f7ba2012-04-03 04:09:296038
6039 MockRead spdy_reads[] = {
6040 CreateMockRead(*stream1_reply, 2, ASYNC),
6041 CreateMockRead(*stream2_syn, 3, ASYNC),
6042 CreateMockRead(*stream1_body, 4, ASYNC),
[email protected]8a0fc822013-06-27 20:52:436043 CreateMockRead(*stream2_body, 5, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:296044 MockRead(ASYNC, ERR_IO_PENDING, 6), // Force a pause
6045 };
6046
[email protected]dd54bd82012-07-19 23:44:576047 OrderedSocketData spdy_data(
6048 spdy_reads, arraysize(spdy_reads),
6049 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:076050 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:296051 // Negotiate SPDY to the proxy
6052 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:026053 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:076054 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:296055
[email protected]262eec82013-03-19 21:01:366056 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506057 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7c6f7ba2012-04-03 04:09:296058 TestCompletionCallback callback;
6059 int rv = trans->Start(&request, callback.callback(), log.bound());
6060 EXPECT_EQ(ERR_IO_PENDING, rv);
6061
6062 rv = callback.WaitForResult();
6063 EXPECT_EQ(OK, rv);
6064 const HttpResponseInfo* response = trans->GetResponseInfo();
6065
[email protected]262eec82013-03-19 21:01:366066 scoped_ptr<HttpTransaction> push_trans(
[email protected]90499482013-06-01 00:39:506067 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
6068 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
[email protected]7c6f7ba2012-04-03 04:09:296069 EXPECT_EQ(ERR_IO_PENDING, rv);
6070
6071 rv = callback.WaitForResult();
6072 EXPECT_EQ(OK, rv);
6073 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
6074
6075 ASSERT_TRUE(response != NULL);
6076 EXPECT_TRUE(response->headers->IsKeepAlive());
6077
6078 EXPECT_EQ(200, response->headers->response_code());
6079 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6080
6081 std::string response_data;
6082 rv = ReadTransaction(trans.get(), &response_data);
6083 EXPECT_EQ(OK, rv);
6084 EXPECT_EQ("hello!", response_data);
6085
[email protected]029c83b62013-01-24 05:28:206086 LoadTimingInfo load_timing_info;
6087 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6088 TestLoadTimingNotReusedWithPac(load_timing_info,
6089 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6090
[email protected]7c6f7ba2012-04-03 04:09:296091 // Verify the pushed stream.
[email protected]90499482013-06-01 00:39:506092 EXPECT_TRUE(push_response->headers.get() != NULL);
[email protected]7c6f7ba2012-04-03 04:09:296093 EXPECT_EQ(200, push_response->headers->response_code());
6094
6095 rv = ReadTransaction(push_trans.get(), &response_data);
6096 EXPECT_EQ(OK, rv);
6097 EXPECT_EQ("pushed", response_data);
6098
[email protected]029c83b62013-01-24 05:28:206099 LoadTimingInfo push_load_timing_info;
6100 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
6101 TestLoadTimingReusedWithPac(push_load_timing_info);
6102 // The transactions should share a socket ID, despite being for different
6103 // origins.
6104 EXPECT_EQ(load_timing_info.socket_log_id,
6105 push_load_timing_info.socket_log_id);
6106
[email protected]7c6f7ba2012-04-03 04:09:296107 trans.reset();
6108 push_trans.reset();
6109 session->CloseAllConnections();
6110}
6111
[email protected]8c843192012-04-05 07:15:006112// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
[email protected]23e482282013-06-14 16:08:026113TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
[email protected]8c843192012-04-05 07:15:006114 HttpRequestInfo request;
6115
6116 request.method = "GET";
6117 request.url = GURL("http://www.google.com/");
6118
[email protected]8c843192012-04-05 07:15:006119 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076120 session_deps_.proxy_service.reset(
[email protected]8c843192012-04-05 07:15:006121 ProxyService::CreateFixed("https://myproxy:70"));
[email protected]333bdf62012-06-08 22:57:296122 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076123 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:506124
6125 // Enable cross-origin push.
[email protected]bb88e1d32013-05-03 23:11:076126 session_deps_.trusted_spdy_proxy = "myproxy:70";
[email protected]61b4efc2012-04-27 18:12:506127
[email protected]bb88e1d32013-05-03 23:11:076128 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:006129
[email protected]cdf8f7e72013-05-23 10:56:466130 scoped_ptr<SpdyFrame> stream1_syn(
6131 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]8c843192012-04-05 07:15:006132
6133 scoped_ptr<SpdyFrame> push_rst(
[email protected]c10b20852013-05-15 21:29:206134 spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:006135
6136 MockWrite spdy_writes[] = {
6137 CreateMockWrite(*stream1_syn, 1, ASYNC),
6138 CreateMockWrite(*push_rst, 4),
6139 };
6140
6141 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026142 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:006143
6144 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026145 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8c843192012-04-05 07:15:006146
6147 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026148 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
[email protected]8c843192012-04-05 07:15:006149 0,
6150 2,
6151 1,
6152 "https://www.another-origin.com/foo.dat"));
6153
6154 MockRead spdy_reads[] = {
6155 CreateMockRead(*stream1_reply, 2, ASYNC),
6156 CreateMockRead(*stream2_syn, 3, ASYNC),
6157 CreateMockRead(*stream1_body, 5, ASYNC),
6158 MockRead(ASYNC, ERR_IO_PENDING, 6), // Force a pause
6159 };
6160
[email protected]dd54bd82012-07-19 23:44:576161 OrderedSocketData spdy_data(
6162 spdy_reads, arraysize(spdy_reads),
6163 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:076164 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:006165 // Negotiate SPDY to the proxy
6166 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:026167 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:076168 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:006169
[email protected]262eec82013-03-19 21:01:366170 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506171 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c843192012-04-05 07:15:006172 TestCompletionCallback callback;
6173 int rv = trans->Start(&request, callback.callback(), log.bound());
6174 EXPECT_EQ(ERR_IO_PENDING, rv);
6175
6176 rv = callback.WaitForResult();
6177 EXPECT_EQ(OK, rv);
6178 const HttpResponseInfo* response = trans->GetResponseInfo();
6179
6180 ASSERT_TRUE(response != NULL);
6181 EXPECT_TRUE(response->headers->IsKeepAlive());
6182
6183 EXPECT_EQ(200, response->headers->response_code());
6184 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6185
6186 std::string response_data;
6187 rv = ReadTransaction(trans.get(), &response_data);
6188 EXPECT_EQ(OK, rv);
6189 EXPECT_EQ("hello!", response_data);
6190
6191 trans.reset();
6192 session->CloseAllConnections();
6193}
6194
[email protected]2df19bb2010-08-25 20:13:466195// Test HTTPS connections to a site with a bad certificate, going through an
6196// HTTPS proxy
[email protected]23e482282013-06-14 16:08:026197TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076198 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:116199 "https://proxy:70"));
[email protected]2df19bb2010-08-25 20:13:466200
6201 HttpRequestInfo request;
6202 request.method = "GET";
6203 request.url = GURL("https://www.google.com/");
6204 request.load_flags = 0;
6205
6206 // Attempt to fetch the URL from a server with a bad cert
6207 MockWrite bad_cert_writes[] = {
6208 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6209 "Host: www.google.com\r\n"
6210 "Proxy-Connection: keep-alive\r\n\r\n"),
6211 };
6212
6213 MockRead bad_cert_reads[] = {
6214 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066215 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:466216 };
6217
6218 // Attempt to fetch the URL with a good cert
6219 MockWrite good_data_writes[] = {
6220 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6221 "Host: www.google.com\r\n"
6222 "Proxy-Connection: keep-alive\r\n\r\n"),
6223 MockWrite("GET / HTTP/1.1\r\n"
6224 "Host: www.google.com\r\n"
6225 "Connection: keep-alive\r\n\r\n"),
6226 };
6227
6228 MockRead good_cert_reads[] = {
6229 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
6230 MockRead("HTTP/1.0 200 OK\r\n"),
6231 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6232 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066233 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:466234 };
6235
6236 StaticSocketDataProvider ssl_bad_certificate(
6237 bad_cert_reads, arraysize(bad_cert_reads),
6238 bad_cert_writes, arraysize(bad_cert_writes));
6239 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
6240 good_data_writes, arraysize(good_data_writes));
[email protected]8ddf8322012-02-23 18:08:066241 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
6242 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:466243
6244 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:076245 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6246 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
6247 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:466248
6249 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:076250 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6251 session_deps_.socket_factory->AddSocketDataProvider(&data);
6252 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:466253
[email protected]49639fa2011-12-20 23:22:416254 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:466255
6256 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366257 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076258 CreateSession(&session_deps_)));
[email protected]2df19bb2010-08-25 20:13:466259
[email protected]49639fa2011-12-20 23:22:416260 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:466261 EXPECT_EQ(ERR_IO_PENDING, rv);
6262
6263 rv = callback.WaitForResult();
6264 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
6265
[email protected]49639fa2011-12-20 23:22:416266 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]2df19bb2010-08-25 20:13:466267 EXPECT_EQ(ERR_IO_PENDING, rv);
6268
6269 rv = callback.WaitForResult();
6270 EXPECT_EQ(OK, rv);
6271
6272 const HttpResponseInfo* response = trans->GetResponseInfo();
6273
[email protected]fe2255a2011-09-20 19:37:506274 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:466275 EXPECT_EQ(100, response->headers->GetContentLength());
6276}
6277
[email protected]23e482282013-06-14 16:08:026278TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:426279 HttpRequestInfo request;
6280 request.method = "GET";
6281 request.url = GURL("http://www.google.com/");
[email protected]8c76ae22010-04-20 22:15:436282 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
6283 "Chromium Ultra Awesome X Edition");
[email protected]1c773ea12009-04-28 19:58:426284
[email protected]cb9bf6ca2011-01-28 13:15:276285 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366286 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076287 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:276288
[email protected]1c773ea12009-04-28 19:58:426289 MockWrite data_writes[] = {
6290 MockWrite("GET / HTTP/1.1\r\n"
6291 "Host: www.google.com\r\n"
6292 "Connection: keep-alive\r\n"
6293 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
6294 };
6295
6296 // Lastly, the server responds with the actual content.
6297 MockRead data_reads[] = {
6298 MockRead("HTTP/1.0 200 OK\r\n"),
6299 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6300 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066301 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426302 };
6303
[email protected]31a2bfe2010-02-09 08:03:396304 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6305 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076306 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426307
[email protected]49639fa2011-12-20 23:22:416308 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426309
[email protected]49639fa2011-12-20 23:22:416310 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426311 EXPECT_EQ(ERR_IO_PENDING, rv);
6312
6313 rv = callback.WaitForResult();
6314 EXPECT_EQ(OK, rv);
6315}
6316
[email protected]23e482282013-06-14 16:08:026317TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:296318 HttpRequestInfo request;
6319 request.method = "GET";
6320 request.url = GURL("https://www.google.com/");
6321 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
6322 "Chromium Ultra Awesome X Edition");
6323
[email protected]bb88e1d32013-05-03 23:11:076324 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]cb9bf6ca2011-01-28 13:15:276325 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366326 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076327 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:276328
[email protected]da81f132010-08-18 23:39:296329 MockWrite data_writes[] = {
6330 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
6331 "Host: www.google.com\r\n"
6332 "Proxy-Connection: keep-alive\r\n"
6333 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
6334 };
6335 MockRead data_reads[] = {
6336 // Return an error, so the transaction stops here (this test isn't
6337 // interested in the rest).
6338 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
6339 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6340 MockRead("Proxy-Connection: close\r\n\r\n"),
6341 };
6342
6343 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6344 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076345 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:296346
[email protected]49639fa2011-12-20 23:22:416347 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:296348
[email protected]49639fa2011-12-20 23:22:416349 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]da81f132010-08-18 23:39:296350 EXPECT_EQ(ERR_IO_PENDING, rv);
6351
6352 rv = callback.WaitForResult();
6353 EXPECT_EQ(OK, rv);
6354}
6355
[email protected]23e482282013-06-14 16:08:026356TEST_P(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:426357 HttpRequestInfo request;
6358 request.method = "GET";
6359 request.url = GURL("http://www.google.com/");
6360 request.load_flags = 0;
[email protected]c10450102011-06-27 09:06:166361 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
6362 "http://the.previous.site.com/");
[email protected]1c773ea12009-04-28 19:58:426363
[email protected]cb9bf6ca2011-01-28 13:15:276364 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366365 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076366 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:276367
[email protected]1c773ea12009-04-28 19:58:426368 MockWrite data_writes[] = {
6369 MockWrite("GET / HTTP/1.1\r\n"
6370 "Host: www.google.com\r\n"
6371 "Connection: keep-alive\r\n"
6372 "Referer: http://the.previous.site.com/\r\n\r\n"),
6373 };
6374
6375 // Lastly, the server responds with the actual content.
6376 MockRead data_reads[] = {
6377 MockRead("HTTP/1.0 200 OK\r\n"),
6378 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6379 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066380 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426381 };
6382
[email protected]31a2bfe2010-02-09 08:03:396383 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6384 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076385 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426386
[email protected]49639fa2011-12-20 23:22:416387 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426388
[email protected]49639fa2011-12-20 23:22:416389 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426390 EXPECT_EQ(ERR_IO_PENDING, rv);
6391
6392 rv = callback.WaitForResult();
6393 EXPECT_EQ(OK, rv);
6394}
6395
[email protected]23e482282013-06-14 16:08:026396TEST_P(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:426397 HttpRequestInfo request;
6398 request.method = "POST";
6399 request.url = GURL("http://www.google.com/");
6400
[email protected]cb9bf6ca2011-01-28 13:15:276401 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366402 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076403 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:276404
[email protected]1c773ea12009-04-28 19:58:426405 MockWrite data_writes[] = {
6406 MockWrite("POST / HTTP/1.1\r\n"
6407 "Host: www.google.com\r\n"
6408 "Connection: keep-alive\r\n"
6409 "Content-Length: 0\r\n\r\n"),
6410 };
6411
6412 // Lastly, the server responds with the actual content.
6413 MockRead data_reads[] = {
6414 MockRead("HTTP/1.0 200 OK\r\n"),
6415 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6416 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066417 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426418 };
6419
[email protected]31a2bfe2010-02-09 08:03:396420 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6421 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076422 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426423
[email protected]49639fa2011-12-20 23:22:416424 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426425
[email protected]49639fa2011-12-20 23:22:416426 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426427 EXPECT_EQ(ERR_IO_PENDING, rv);
6428
6429 rv = callback.WaitForResult();
6430 EXPECT_EQ(OK, rv);
6431}
6432
[email protected]23e482282013-06-14 16:08:026433TEST_P(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:426434 HttpRequestInfo request;
6435 request.method = "PUT";
6436 request.url = GURL("http://www.google.com/");
6437
[email protected]cb9bf6ca2011-01-28 13:15:276438 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366439 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076440 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:276441
[email protected]1c773ea12009-04-28 19:58:426442 MockWrite data_writes[] = {
6443 MockWrite("PUT / HTTP/1.1\r\n"
6444 "Host: www.google.com\r\n"
6445 "Connection: keep-alive\r\n"
6446 "Content-Length: 0\r\n\r\n"),
6447 };
6448
6449 // Lastly, the server responds with the actual content.
6450 MockRead data_reads[] = {
6451 MockRead("HTTP/1.0 200 OK\r\n"),
6452 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6453 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066454 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426455 };
6456
[email protected]31a2bfe2010-02-09 08:03:396457 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6458 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076459 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426460
[email protected]49639fa2011-12-20 23:22:416461 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426462
[email protected]49639fa2011-12-20 23:22:416463 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426464 EXPECT_EQ(ERR_IO_PENDING, rv);
6465
6466 rv = callback.WaitForResult();
6467 EXPECT_EQ(OK, rv);
6468}
6469
[email protected]23e482282013-06-14 16:08:026470TEST_P(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:426471 HttpRequestInfo request;
6472 request.method = "HEAD";
6473 request.url = GURL("http://www.google.com/");
6474
[email protected]cb9bf6ca2011-01-28 13:15:276475 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366476 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076477 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:276478
[email protected]1c773ea12009-04-28 19:58:426479 MockWrite data_writes[] = {
6480 MockWrite("HEAD / HTTP/1.1\r\n"
6481 "Host: www.google.com\r\n"
6482 "Connection: keep-alive\r\n"
6483 "Content-Length: 0\r\n\r\n"),
6484 };
6485
6486 // Lastly, the server responds with the actual content.
6487 MockRead data_reads[] = {
6488 MockRead("HTTP/1.0 200 OK\r\n"),
6489 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6490 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066491 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426492 };
6493
[email protected]31a2bfe2010-02-09 08:03:396494 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6495 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076496 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426497
[email protected]49639fa2011-12-20 23:22:416498 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426499
[email protected]49639fa2011-12-20 23:22:416500 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426501 EXPECT_EQ(ERR_IO_PENDING, rv);
6502
6503 rv = callback.WaitForResult();
6504 EXPECT_EQ(OK, rv);
6505}
6506
[email protected]23e482282013-06-14 16:08:026507TEST_P(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:426508 HttpRequestInfo request;
6509 request.method = "GET";
6510 request.url = GURL("http://www.google.com/");
6511 request.load_flags = LOAD_BYPASS_CACHE;
6512
[email protected]cb9bf6ca2011-01-28 13:15:276513 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366514 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076515 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:276516
[email protected]1c773ea12009-04-28 19:58:426517 MockWrite data_writes[] = {
6518 MockWrite("GET / HTTP/1.1\r\n"
6519 "Host: www.google.com\r\n"
6520 "Connection: keep-alive\r\n"
6521 "Pragma: no-cache\r\n"
6522 "Cache-Control: no-cache\r\n\r\n"),
6523 };
6524
6525 // Lastly, the server responds with the actual content.
6526 MockRead data_reads[] = {
6527 MockRead("HTTP/1.0 200 OK\r\n"),
6528 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6529 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066530 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426531 };
6532
[email protected]31a2bfe2010-02-09 08:03:396533 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6534 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076535 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426536
[email protected]49639fa2011-12-20 23:22:416537 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426538
[email protected]49639fa2011-12-20 23:22:416539 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426540 EXPECT_EQ(ERR_IO_PENDING, rv);
6541
6542 rv = callback.WaitForResult();
6543 EXPECT_EQ(OK, rv);
6544}
6545
[email protected]23e482282013-06-14 16:08:026546TEST_P(HttpNetworkTransactionTest,
[email protected]1c773ea12009-04-28 19:58:426547 BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:426548 HttpRequestInfo request;
6549 request.method = "GET";
6550 request.url = GURL("http://www.google.com/");
6551 request.load_flags = LOAD_VALIDATE_CACHE;
6552
[email protected]cb9bf6ca2011-01-28 13:15:276553 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366554 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076555 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:276556
[email protected]1c773ea12009-04-28 19:58:426557 MockWrite data_writes[] = {
6558 MockWrite("GET / HTTP/1.1\r\n"
6559 "Host: www.google.com\r\n"
6560 "Connection: keep-alive\r\n"
6561 "Cache-Control: max-age=0\r\n\r\n"),
6562 };
6563
6564 // Lastly, the server responds with the actual content.
6565 MockRead data_reads[] = {
6566 MockRead("HTTP/1.0 200 OK\r\n"),
6567 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6568 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066569 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426570 };
6571
[email protected]31a2bfe2010-02-09 08:03:396572 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6573 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076574 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426575
[email protected]49639fa2011-12-20 23:22:416576 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426577
[email protected]49639fa2011-12-20 23:22:416578 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426579 EXPECT_EQ(ERR_IO_PENDING, rv);
6580
6581 rv = callback.WaitForResult();
6582 EXPECT_EQ(OK, rv);
6583}
6584
[email protected]23e482282013-06-14 16:08:026585TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:426586 HttpRequestInfo request;
6587 request.method = "GET";
6588 request.url = GURL("http://www.google.com/");
[email protected]8c76ae22010-04-20 22:15:436589 request.extra_headers.SetHeader("FooHeader", "Bar");
[email protected]1c773ea12009-04-28 19:58:426590
[email protected]cb9bf6ca2011-01-28 13:15:276591 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366592 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076593 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:276594
[email protected]1c773ea12009-04-28 19:58:426595 MockWrite data_writes[] = {
6596 MockWrite("GET / HTTP/1.1\r\n"
6597 "Host: www.google.com\r\n"
6598 "Connection: keep-alive\r\n"
6599 "FooHeader: Bar\r\n\r\n"),
6600 };
6601
6602 // Lastly, the server responds with the actual content.
6603 MockRead data_reads[] = {
6604 MockRead("HTTP/1.0 200 OK\r\n"),
6605 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6606 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066607 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:426608 };
6609
[email protected]31a2bfe2010-02-09 08:03:396610 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6611 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076612 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:426613
[email protected]49639fa2011-12-20 23:22:416614 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:426615
[email protected]49639fa2011-12-20 23:22:416616 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426617 EXPECT_EQ(ERR_IO_PENDING, rv);
6618
6619 rv = callback.WaitForResult();
6620 EXPECT_EQ(OK, rv);
6621}
6622
[email protected]23e482282013-06-14 16:08:026623TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:476624 HttpRequestInfo request;
6625 request.method = "GET";
6626 request.url = GURL("http://www.google.com/");
[email protected]8c76ae22010-04-20 22:15:436627 request.extra_headers.SetHeader("referer", "www.foo.com");
6628 request.extra_headers.SetHeader("hEllo", "Kitty");
6629 request.extra_headers.SetHeader("FoO", "bar");
[email protected]270c6412010-03-29 22:02:476630
[email protected]cb9bf6ca2011-01-28 13:15:276631 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366632 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076633 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:276634
[email protected]270c6412010-03-29 22:02:476635 MockWrite data_writes[] = {
6636 MockWrite("GET / HTTP/1.1\r\n"
6637 "Host: www.google.com\r\n"
6638 "Connection: keep-alive\r\n"
[email protected]c10450102011-06-27 09:06:166639 "referer: www.foo.com\r\n"
[email protected]270c6412010-03-29 22:02:476640 "hEllo: Kitty\r\n"
6641 "FoO: bar\r\n\r\n"),
6642 };
6643
6644 // Lastly, the server responds with the actual content.
6645 MockRead data_reads[] = {
6646 MockRead("HTTP/1.0 200 OK\r\n"),
6647 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6648 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066649 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:476650 };
6651
6652 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6653 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076654 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:476655
[email protected]49639fa2011-12-20 23:22:416656 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:476657
[email protected]49639fa2011-12-20 23:22:416658 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]270c6412010-03-29 22:02:476659 EXPECT_EQ(ERR_IO_PENDING, rv);
6660
6661 rv = callback.WaitForResult();
6662 EXPECT_EQ(OK, rv);
6663}
6664
[email protected]23e482282013-06-14 16:08:026665TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:276666 HttpRequestInfo request;
6667 request.method = "GET";
6668 request.url = GURL("http://www.google.com/");
6669 request.load_flags = 0;
6670
[email protected]bb88e1d32013-05-03 23:11:076671 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206672 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
6673 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076674 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:026675
6676 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366677 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076678 CreateSession(&session_deps_)));
[email protected]3cd17242009-06-23 02:59:026679
[email protected]3cd17242009-06-23 02:59:026680 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
6681 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
6682
6683 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:066684 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
[email protected]3cd17242009-06-23 02:59:026685 MockWrite("GET / HTTP/1.1\r\n"
6686 "Host: www.google.com\r\n"
6687 "Connection: keep-alive\r\n\r\n")
6688 };
6689
6690 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:066691 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:026692 MockRead("HTTP/1.0 200 OK\r\n"),
6693 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
6694 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:066695 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:026696 };
6697
[email protected]31a2bfe2010-02-09 08:03:396698 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6699 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076700 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:026701
[email protected]49639fa2011-12-20 23:22:416702 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:026703
[email protected]49639fa2011-12-20 23:22:416704 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:026705 EXPECT_EQ(ERR_IO_PENDING, rv);
6706
6707 rv = callback.WaitForResult();
6708 EXPECT_EQ(OK, rv);
6709
6710 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506711 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:026712
[email protected]029c83b62013-01-24 05:28:206713 LoadTimingInfo load_timing_info;
6714 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6715 TestLoadTimingNotReusedWithPac(load_timing_info,
6716 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6717
[email protected]3cd17242009-06-23 02:59:026718 std::string response_text;
6719 rv = ReadTransaction(trans.get(), &response_text);
6720 EXPECT_EQ(OK, rv);
6721 EXPECT_EQ("Payload", response_text);
6722}
6723
[email protected]23e482282013-06-14 16:08:026724TEST_P(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:276725 HttpRequestInfo request;
6726 request.method = "GET";
6727 request.url = GURL("https://www.google.com/");
6728 request.load_flags = 0;
6729
[email protected]bb88e1d32013-05-03 23:11:076730 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206731 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
6732 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076733 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:026734
6735 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366736 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076737 CreateSession(&session_deps_)));
[email protected]3cd17242009-06-23 02:59:026738
[email protected]3cd17242009-06-23 02:59:026739 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
6740 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
6741
6742 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:066743 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
[email protected]e0c27be2009-07-15 13:09:356744 arraysize(write_buffer)),
[email protected]3cd17242009-06-23 02:59:026745 MockWrite("GET / HTTP/1.1\r\n"
6746 "Host: www.google.com\r\n"
6747 "Connection: keep-alive\r\n\r\n")
6748 };
6749
6750 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:016751 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
6752 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:356753 MockRead("HTTP/1.0 200 OK\r\n"),
6754 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
6755 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:066756 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:356757 };
6758
[email protected]31a2bfe2010-02-09 08:03:396759 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6760 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076761 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:356762
[email protected]8ddf8322012-02-23 18:08:066763 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076764 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:356765
[email protected]49639fa2011-12-20 23:22:416766 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:356767
[email protected]49639fa2011-12-20 23:22:416768 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:356769 EXPECT_EQ(ERR_IO_PENDING, rv);
6770
6771 rv = callback.WaitForResult();
6772 EXPECT_EQ(OK, rv);
6773
[email protected]029c83b62013-01-24 05:28:206774 LoadTimingInfo load_timing_info;
6775 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6776 TestLoadTimingNotReusedWithPac(load_timing_info,
6777 CONNECT_TIMING_HAS_SSL_TIMES);
6778
[email protected]e0c27be2009-07-15 13:09:356779 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506780 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:356781
6782 std::string response_text;
6783 rv = ReadTransaction(trans.get(), &response_text);
6784 EXPECT_EQ(OK, rv);
6785 EXPECT_EQ("Payload", response_text);
6786}
6787
[email protected]23e482282013-06-14 16:08:026788TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:206789 HttpRequestInfo request;
6790 request.method = "GET";
6791 request.url = GURL("http://www.google.com/");
6792 request.load_flags = 0;
6793
[email protected]bb88e1d32013-05-03 23:11:076794 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206795 ProxyService::CreateFixed("socks4://myproxy:1080"));
6796 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076797 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:206798
6799 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366800 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076801 CreateSession(&session_deps_)));
[email protected]029c83b62013-01-24 05:28:206802
6803 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
6804 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
6805
6806 MockWrite data_writes[] = {
6807 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
6808 MockWrite("GET / HTTP/1.1\r\n"
6809 "Host: www.google.com\r\n"
6810 "Connection: keep-alive\r\n\r\n")
6811 };
6812
6813 MockRead data_reads[] = {
6814 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
6815 MockRead("HTTP/1.0 200 OK\r\n"),
6816 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
6817 MockRead("Payload"),
6818 MockRead(SYNCHRONOUS, OK)
6819 };
6820
6821 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6822 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076823 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:206824
6825 TestCompletionCallback callback;
6826
6827 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6828 EXPECT_EQ(ERR_IO_PENDING, rv);
6829
6830 rv = callback.WaitForResult();
6831 EXPECT_EQ(OK, rv);
6832
6833 const HttpResponseInfo* response = trans->GetResponseInfo();
6834 ASSERT_TRUE(response != NULL);
6835
6836 LoadTimingInfo load_timing_info;
6837 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6838 TestLoadTimingNotReused(load_timing_info,
6839 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6840
6841 std::string response_text;
6842 rv = ReadTransaction(trans.get(), &response_text);
6843 EXPECT_EQ(OK, rv);
6844 EXPECT_EQ("Payload", response_text);
6845}
6846
[email protected]23e482282013-06-14 16:08:026847TEST_P(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:276848 HttpRequestInfo request;
6849 request.method = "GET";
6850 request.url = GURL("http://www.google.com/");
6851 request.load_flags = 0;
6852
[email protected]bb88e1d32013-05-03 23:11:076853 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206854 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
6855 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076856 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:356857
6858 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366859 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076860 CreateSession(&session_deps_)));
[email protected]e0c27be2009-07-15 13:09:356861
[email protected]e0c27be2009-07-15 13:09:356862 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
6863 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:376864 const char kSOCKS5OkRequest[] = {
6865 0x05, // Version
6866 0x01, // Command (CONNECT)
6867 0x00, // Reserved.
6868 0x03, // Address type (DOMAINNAME).
6869 0x0E, // Length of domain (14)
6870 // Domain string:
6871 'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
6872 0x00, 0x50, // 16-bit port (80)
6873 };
[email protected]e0c27be2009-07-15 13:09:356874 const char kSOCKS5OkResponse[] =
6875 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
6876
6877 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:066878 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
6879 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
[email protected]e0c27be2009-07-15 13:09:356880 MockWrite("GET / HTTP/1.1\r\n"
6881 "Host: www.google.com\r\n"
6882 "Connection: keep-alive\r\n\r\n")
6883 };
6884
6885 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:016886 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
6887 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:356888 MockRead("HTTP/1.0 200 OK\r\n"),
6889 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
6890 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:066891 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:356892 };
6893
[email protected]31a2bfe2010-02-09 08:03:396894 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6895 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076896 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:356897
[email protected]49639fa2011-12-20 23:22:416898 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:356899
[email protected]49639fa2011-12-20 23:22:416900 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:356901 EXPECT_EQ(ERR_IO_PENDING, rv);
6902
6903 rv = callback.WaitForResult();
6904 EXPECT_EQ(OK, rv);
6905
6906 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506907 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:356908
[email protected]029c83b62013-01-24 05:28:206909 LoadTimingInfo load_timing_info;
6910 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6911 TestLoadTimingNotReusedWithPac(load_timing_info,
6912 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6913
[email protected]e0c27be2009-07-15 13:09:356914 std::string response_text;
6915 rv = ReadTransaction(trans.get(), &response_text);
6916 EXPECT_EQ(OK, rv);
6917 EXPECT_EQ("Payload", response_text);
6918}
6919
[email protected]23e482282013-06-14 16:08:026920TEST_P(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:276921 HttpRequestInfo request;
6922 request.method = "GET";
6923 request.url = GURL("https://www.google.com/");
6924 request.load_flags = 0;
6925
[email protected]bb88e1d32013-05-03 23:11:076926 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206927 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
6928 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076929 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:356930
6931 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:366932 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:076933 CreateSession(&session_deps_)));
[email protected]e0c27be2009-07-15 13:09:356934
[email protected]e0c27be2009-07-15 13:09:356935 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
6936 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:376937 const unsigned char kSOCKS5OkRequest[] = {
6938 0x05, // Version
6939 0x01, // Command (CONNECT)
6940 0x00, // Reserved.
6941 0x03, // Address type (DOMAINNAME).
6942 0x0E, // Length of domain (14)
6943 // Domain string:
6944 'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
6945 0x01, 0xBB, // 16-bit port (443)
6946 };
6947
[email protected]e0c27be2009-07-15 13:09:356948 const char kSOCKS5OkResponse[] =
6949 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
6950
6951 MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:066952 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
6953 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
[email protected]e0c27be2009-07-15 13:09:356954 arraysize(kSOCKS5OkRequest)),
6955 MockWrite("GET / HTTP/1.1\r\n"
6956 "Host: www.google.com\r\n"
6957 "Connection: keep-alive\r\n\r\n")
6958 };
6959
6960 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:016961 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
6962 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:026963 MockRead("HTTP/1.0 200 OK\r\n"),
6964 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
6965 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:066966 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:026967 };
6968
[email protected]31a2bfe2010-02-09 08:03:396969 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6970 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076971 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:026972
[email protected]8ddf8322012-02-23 18:08:066973 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076974 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:026975
[email protected]49639fa2011-12-20 23:22:416976 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:026977
[email protected]49639fa2011-12-20 23:22:416978 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:026979 EXPECT_EQ(ERR_IO_PENDING, rv);
6980
6981 rv = callback.WaitForResult();
6982 EXPECT_EQ(OK, rv);
6983
6984 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506985 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:026986
[email protected]029c83b62013-01-24 05:28:206987 LoadTimingInfo load_timing_info;
6988 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6989 TestLoadTimingNotReusedWithPac(load_timing_info,
6990 CONNECT_TIMING_HAS_SSL_TIMES);
6991
[email protected]3cd17242009-06-23 02:59:026992 std::string response_text;
6993 rv = ReadTransaction(trans.get(), &response_text);
6994 EXPECT_EQ(OK, rv);
6995 EXPECT_EQ("Payload", response_text);
6996}
6997
[email protected]448d4ca52012-03-04 04:12:236998namespace {
6999
[email protected]04e5be32009-06-26 20:00:317000// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:067001
7002struct GroupNameTest {
7003 std::string proxy_server;
7004 std::string url;
7005 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:187006 bool ssl;
[email protected]2d731a32010-04-29 01:04:067007};
7008
7009scoped_refptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]8a0fc822013-06-27 20:52:437010 NextProto next_proto,
[email protected]bb88e1d32013-05-03 23:11:077011 SpdySessionDependencies* session_deps_) {
7012 scoped_refptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:067013
[email protected]17291a022011-10-10 07:32:537014 HttpServerProperties* http_server_properties =
7015 session->http_server_properties();
7016 http_server_properties->SetAlternateProtocol(
[email protected]2d731a32010-04-29 01:04:067017 HostPortPair("host.with.alternate", 80), 443,
[email protected]8a0fc822013-06-27 20:52:437018 AlternateProtocolFromNextProto(next_proto));
[email protected]2d731a32010-04-29 01:04:067019
7020 return session;
7021}
7022
7023int GroupNameTransactionHelper(
7024 const std::string& url,
7025 const scoped_refptr<HttpNetworkSession>& session) {
[email protected]2d731a32010-04-29 01:04:067026 HttpRequestInfo request;
7027 request.method = "GET";
7028 request.url = GURL(url);
7029 request.load_flags = 0;
7030
[email protected]262eec82013-03-19 21:01:367031 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507032 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277033
[email protected]49639fa2011-12-20 23:22:417034 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:067035
7036 // We do not complete this request, the dtor will clean the transaction up.
[email protected]49639fa2011-12-20 23:22:417037 return trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d731a32010-04-29 01:04:067038}
7039
[email protected]448d4ca52012-03-04 04:12:237040} // namespace
7041
[email protected]23e482282013-06-14 16:08:027042TEST_P(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:067043 const GroupNameTest tests[] = {
[email protected]04e5be32009-06-26 20:00:317044 {
[email protected]2d731a32010-04-29 01:04:067045 "", // unused
[email protected]04e5be32009-06-26 20:00:317046 "http://www.google.com/direct",
[email protected]2ff8b312010-04-26 22:20:547047 "www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:187048 false,
[email protected]2ff8b312010-04-26 22:20:547049 },
7050 {
[email protected]2d731a32010-04-29 01:04:067051 "", // unused
[email protected]2ff8b312010-04-26 22:20:547052 "http://[2001:1418:13:1::25]/direct",
7053 "[2001:1418:13:1::25]:80",
[email protected]e60e47a2010-07-14 03:37:187054 false,
[email protected]04e5be32009-06-26 20:00:317055 },
[email protected]04e5be32009-06-26 20:00:317056
7057 // SSL Tests
7058 {
[email protected]2d731a32010-04-29 01:04:067059 "", // unused
[email protected]04e5be32009-06-26 20:00:317060 "https://www.google.com/direct_ssl",
[email protected]0e88ad602010-05-04 23:47:027061 "ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:187062 true,
[email protected]04e5be32009-06-26 20:00:317063 },
7064 {
[email protected]2d731a32010-04-29 01:04:067065 "", // unused
7066 "https://[2001:1418:13:1::25]/direct",
[email protected]0e88ad602010-05-04 23:47:027067 "ssl/[2001:1418:13:1::25]:443",
[email protected]e60e47a2010-07-14 03:37:187068 true,
[email protected]04e5be32009-06-26 20:00:317069 },
7070 {
[email protected]2d731a32010-04-29 01:04:067071 "", // unused
[email protected]2ff8b312010-04-26 22:20:547072 "http://host.with.alternate/direct",
[email protected]0e88ad602010-05-04 23:47:027073 "ssl/host.with.alternate:443",
[email protected]e60e47a2010-07-14 03:37:187074 true,
[email protected]2ff8b312010-04-26 22:20:547075 },
[email protected]2d731a32010-04-29 01:04:067076 };
[email protected]2ff8b312010-04-26 22:20:547077
[email protected]8e6441ca2010-08-19 05:56:387078 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]2d731a32010-04-29 01:04:067079
7080 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:077081 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:027082 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:067083 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:437084 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:067085
7086 HttpNetworkSessionPeer peer(session);
[email protected]ab739042011-04-07 15:22:287087 CaptureGroupNameTransportSocketPool* transport_conn_pool =
7088 new CaptureGroupNameTransportSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:137089 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347090 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:027091 MockClientSocketPoolManager* mock_pool_manager =
7092 new MockClientSocketPoolManager;
7093 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
7094 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
7095 peer.SetClientSocketPoolManager(mock_pool_manager);
[email protected]2d731a32010-04-29 01:04:067096
7097 EXPECT_EQ(ERR_IO_PENDING,
7098 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:187099 if (tests[i].ssl)
7100 EXPECT_EQ(tests[i].expected_group_name,
7101 ssl_conn_pool->last_group_name_received());
7102 else
7103 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:287104 transport_conn_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:067105 }
7106
[email protected]2d731a32010-04-29 01:04:067107}
7108
[email protected]23e482282013-06-14 16:08:027109TEST_P(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:067110 const GroupNameTest tests[] = {
7111 {
7112 "http_proxy",
7113 "http://www.google.com/http_proxy_normal",
7114 "www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:187115 false,
[email protected]2d731a32010-04-29 01:04:067116 },
7117
7118 // SSL Tests
7119 {
7120 "http_proxy",
7121 "https://www.google.com/http_connect_ssl",
[email protected]0e88ad602010-05-04 23:47:027122 "ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:187123 true,
[email protected]2d731a32010-04-29 01:04:067124 },
[email protected]af3490e2010-10-16 21:02:297125
[email protected]9faeded92010-04-29 20:03:057126 {
7127 "http_proxy",
7128 "http://host.with.alternate/direct",
[email protected]0e88ad602010-05-04 23:47:027129 "ssl/host.with.alternate:443",
[email protected]e60e47a2010-07-14 03:37:187130 true,
[email protected]9faeded92010-04-29 20:03:057131 },
[email protected]45499252013-01-23 17:12:567132
7133 {
7134 "http_proxy",
7135 "ftp://ftp.google.com/http_proxy_normal",
7136 "ftp/ftp.google.com:21",
7137 false,
7138 },
[email protected]2d731a32010-04-29 01:04:067139 };
7140
[email protected]8e6441ca2010-08-19 05:56:387141 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]2d731a32010-04-29 01:04:067142
7143 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:077144 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:027145 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:067146 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:437147 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:067148
7149 HttpNetworkSessionPeer peer(session);
7150
[email protected]e60e47a2010-07-14 03:37:187151 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:137152 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:347153 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:137154 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347155 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:027156
7157 MockClientSocketPoolManager* mock_pool_manager =
7158 new MockClientSocketPoolManager;
7159 mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool);
7160 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
7161 peer.SetClientSocketPoolManager(mock_pool_manager);
[email protected]2d731a32010-04-29 01:04:067162
7163 EXPECT_EQ(ERR_IO_PENDING,
7164 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:187165 if (tests[i].ssl)
7166 EXPECT_EQ(tests[i].expected_group_name,
7167 ssl_conn_pool->last_group_name_received());
7168 else
7169 EXPECT_EQ(tests[i].expected_group_name,
7170 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:067171 }
[email protected]2d731a32010-04-29 01:04:067172}
7173
[email protected]23e482282013-06-14 16:08:027174TEST_P(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:067175 const GroupNameTest tests[] = {
7176 {
7177 "socks4://socks_proxy:1080",
7178 "http://www.google.com/socks4_direct",
7179 "socks4/www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:187180 false,
[email protected]2d731a32010-04-29 01:04:067181 },
7182 {
7183 "socks5://socks_proxy:1080",
7184 "http://www.google.com/socks5_direct",
7185 "socks5/www.google.com:80",
[email protected]e60e47a2010-07-14 03:37:187186 false,
[email protected]2d731a32010-04-29 01:04:067187 },
7188
7189 // SSL Tests
7190 {
7191 "socks4://socks_proxy:1080",
7192 "https://www.google.com/socks4_ssl",
[email protected]0e88ad602010-05-04 23:47:027193 "socks4/ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:187194 true,
[email protected]2d731a32010-04-29 01:04:067195 },
7196 {
7197 "socks5://socks_proxy:1080",
7198 "https://www.google.com/socks5_ssl",
[email protected]0e88ad602010-05-04 23:47:027199 "socks5/ssl/www.google.com:443",
[email protected]e60e47a2010-07-14 03:37:187200 true,
[email protected]2d731a32010-04-29 01:04:067201 },
[email protected]af3490e2010-10-16 21:02:297202
[email protected]9faeded92010-04-29 20:03:057203 {
7204 "socks4://socks_proxy:1080",
7205 "http://host.with.alternate/direct",
[email protected]0e88ad602010-05-04 23:47:027206 "socks4/ssl/host.with.alternate:443",
[email protected]e60e47a2010-07-14 03:37:187207 true,
[email protected]9faeded92010-04-29 20:03:057208 },
[email protected]04e5be32009-06-26 20:00:317209 };
7210
[email protected]8e6441ca2010-08-19 05:56:387211 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]2ff8b312010-04-26 22:20:547212
[email protected]04e5be32009-06-26 20:00:317213 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:077214 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:027215 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:067216 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:437217 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]8b114dd72011-03-25 05:33:027218
[email protected]2d731a32010-04-29 01:04:067219 HttpNetworkSessionPeer peer(session);
[email protected]04e5be32009-06-26 20:00:317220
[email protected]e60e47a2010-07-14 03:37:187221 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:137222 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347223 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:137224 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347225 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:027226
7227 MockClientSocketPoolManager* mock_pool_manager =
7228 new MockClientSocketPoolManager;
7229 mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_conn_pool);
7230 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
7231 peer.SetClientSocketPoolManager(mock_pool_manager);
[email protected]04e5be32009-06-26 20:00:317232
[email protected]262eec82013-03-19 21:01:367233 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507234 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]04e5be32009-06-26 20:00:317235
[email protected]2d731a32010-04-29 01:04:067236 EXPECT_EQ(ERR_IO_PENDING,
7237 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:187238 if (tests[i].ssl)
7239 EXPECT_EQ(tests[i].expected_group_name,
7240 ssl_conn_pool->last_group_name_received());
7241 else
7242 EXPECT_EQ(tests[i].expected_group_name,
7243 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:317244 }
7245}
7246
[email protected]23e482282013-06-14 16:08:027247TEST_P(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:277248 HttpRequestInfo request;
7249 request.method = "GET";
7250 request.url = GURL("http://www.google.com/");
7251
[email protected]bb88e1d32013-05-03 23:11:077252 session_deps_.proxy_service.reset(
[email protected]81cdfcd2010-10-16 00:49:007253 ProxyService::CreateFixed("myproxy:70;foobar:80"));
[email protected]b59ff372009-07-15 22:04:327254
[email protected]69719062010-01-05 20:09:217255 // This simulates failure resolving all hostnames; that means we will fail
7256 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:077257 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:327258
[email protected]9172a982009-06-06 00:30:257259 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:367260 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:077261 CreateSession(&session_deps_)));
[email protected]9172a982009-06-06 00:30:257262
[email protected]49639fa2011-12-20 23:22:417263 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:257264
[email protected]49639fa2011-12-20 23:22:417265 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9172a982009-06-06 00:30:257266 EXPECT_EQ(ERR_IO_PENDING, rv);
7267
[email protected]9172a982009-06-06 00:30:257268 rv = callback.WaitForResult();
[email protected]f7fccee2010-09-16 20:53:017269 EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
[email protected]9172a982009-06-06 00:30:257270}
7271
[email protected]685af592010-05-11 19:31:247272// Base test to make sure that when the load flags for a request specify to
7273// bypass the cache, the DNS cache is not used.
[email protected]23e482282013-06-14 16:08:027274void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
[email protected]bb88e1d32013-05-03 23:11:077275 int load_flags) {
[email protected]cb9bf6ca2011-01-28 13:15:277276 // Issue a request, asking to bypass the cache(s).
7277 HttpRequestInfo request;
7278 request.method = "GET";
7279 request.load_flags = load_flags;
7280 request.url = GURL("http://www.google.com/");
7281
[email protected]a2c2fb92009-07-18 07:31:047282 // Select a host resolver that does caching.
[email protected]bb88e1d32013-05-03 23:11:077283 session_deps_.host_resolver.reset(new MockCachingHostResolver);
[email protected]b59ff372009-07-15 22:04:327284
[email protected]262eec82013-03-19 21:01:367285 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:077286 CreateSession(&session_deps_)));
[email protected]3b9cca42009-06-16 01:08:287287
[email protected]6e78dfb2011-07-28 21:34:477288 // Warm up the host cache so it has an entry for "www.google.com".
[email protected]3b9cca42009-06-16 01:08:287289 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:297290 TestCompletionCallback callback;
[email protected]bb88e1d32013-05-03 23:11:077291 int rv = session_deps_.host_resolver->Resolve(
[email protected]930cc742010-09-15 22:54:107292 HostResolver::RequestInfo(HostPortPair("www.google.com", 80)), &addrlist,
[email protected]aa22b242011-11-16 18:58:297293 callback.callback(), NULL, BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:477294 EXPECT_EQ(ERR_IO_PENDING, rv);
7295 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:287296 EXPECT_EQ(OK, rv);
7297
7298 // Verify that it was added to host cache, by doing a subsequent async lookup
7299 // and confirming it completes synchronously.
[email protected]bb88e1d32013-05-03 23:11:077300 rv = session_deps_.host_resolver->Resolve(
[email protected]930cc742010-09-15 22:54:107301 HostResolver::RequestInfo(HostPortPair("www.google.com", 80)), &addrlist,
[email protected]aa22b242011-11-16 18:58:297302 callback.callback(), NULL, BoundNetLog());
[email protected]b59ff372009-07-15 22:04:327303 ASSERT_EQ(OK, rv);
[email protected]3b9cca42009-06-16 01:08:287304
7305 // Inject a failure the next time that "www.google.com" is resolved. This way
7306 // we can tell if the next lookup hit the cache, or the "network".
7307 // (cache --> success, "network" --> failure).
[email protected]bb88e1d32013-05-03 23:11:077308 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.google.com");
[email protected]3b9cca42009-06-16 01:08:287309
7310 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
7311 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:067312 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
[email protected]31a2bfe2010-02-09 08:03:397313 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077314 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:287315
[email protected]3b9cca42009-06-16 01:08:287316 // Run the request.
[email protected]49639fa2011-12-20 23:22:417317 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3b9cca42009-06-16 01:08:287318 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:417319 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:287320
7321 // If we bypassed the cache, we would have gotten a failure while resolving
7322 // "www.google.com".
7323 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
7324}
7325
[email protected]685af592010-05-11 19:31:247326// There are multiple load flags that should trigger the host cache bypass.
7327// Test each in isolation:
[email protected]23e482282013-06-14 16:08:027328TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
[email protected]685af592010-05-11 19:31:247329 BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
7330}
7331
[email protected]23e482282013-06-14 16:08:027332TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
[email protected]685af592010-05-11 19:31:247333 BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
7334}
7335
[email protected]23e482282013-06-14 16:08:027336TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
[email protected]685af592010-05-11 19:31:247337 BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
7338}
7339
[email protected]0877e3d2009-10-17 22:29:577340// Make sure we can handle an error when writing the request.
[email protected]23e482282013-06-14 16:08:027341TEST_P(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]bb88e1d32013-05-03 23:11:077342 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:577343
7344 HttpRequestInfo request;
7345 request.method = "GET";
7346 request.url = GURL("http://www.foo.com/");
7347 request.load_flags = 0;
7348
7349 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:067350 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:577351 };
[email protected]31a2bfe2010-02-09 08:03:397352 StaticSocketDataProvider data(NULL, 0,
7353 write_failure, arraysize(write_failure));
[email protected]bb88e1d32013-05-03 23:11:077354 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]0877e3d2009-10-17 22:29:577355
[email protected]49639fa2011-12-20 23:22:417356 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:577357
7358 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:367359 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:077360 CreateSession(&session_deps_)));
[email protected]0877e3d2009-10-17 22:29:577361
[email protected]49639fa2011-12-20 23:22:417362 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:577363 EXPECT_EQ(ERR_IO_PENDING, rv);
7364
7365 rv = callback.WaitForResult();
7366 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
7367}
7368
7369// Check that a connection closed after the start of the headers finishes ok.
[email protected]23e482282013-06-14 16:08:027370TEST_P(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]bb88e1d32013-05-03 23:11:077371 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:577372
7373 HttpRequestInfo request;
7374 request.method = "GET";
7375 request.url = GURL("http://www.foo.com/");
7376 request.load_flags = 0;
7377
7378 MockRead data_reads[] = {
7379 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:067380 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:577381 };
7382
[email protected]31a2bfe2010-02-09 08:03:397383 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077384 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]0877e3d2009-10-17 22:29:577385
[email protected]49639fa2011-12-20 23:22:417386 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:577387
7388 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:367389 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:077390 CreateSession(&session_deps_)));
[email protected]0877e3d2009-10-17 22:29:577391
[email protected]49639fa2011-12-20 23:22:417392 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:577393 EXPECT_EQ(ERR_IO_PENDING, rv);
7394
7395 rv = callback.WaitForResult();
7396 EXPECT_EQ(OK, rv);
7397
7398 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507399 ASSERT_TRUE(response != NULL);
[email protected]0877e3d2009-10-17 22:29:577400
[email protected]90499482013-06-01 00:39:507401 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]0877e3d2009-10-17 22:29:577402 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
7403
7404 std::string response_data;
7405 rv = ReadTransaction(trans.get(), &response_data);
7406 EXPECT_EQ(OK, rv);
7407 EXPECT_EQ("", response_data);
7408}
7409
7410// Make sure that a dropped connection while draining the body for auth
7411// restart does the right thing.
[email protected]23e482282013-06-14 16:08:027412TEST_P(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]bb88e1d32013-05-03 23:11:077413 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:577414
7415 HttpRequestInfo request;
7416 request.method = "GET";
7417 request.url = GURL("http://www.google.com/");
7418 request.load_flags = 0;
7419
7420 MockWrite data_writes1[] = {
7421 MockWrite("GET / HTTP/1.1\r\n"
7422 "Host: www.google.com\r\n"
7423 "Connection: keep-alive\r\n\r\n"),
7424 };
7425
7426 MockRead data_reads1[] = {
7427 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
7428 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7429 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7430 MockRead("Content-Length: 14\r\n\r\n"),
7431 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:067432 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:577433 };
7434
[email protected]31a2bfe2010-02-09 08:03:397435 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7436 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:077437 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:577438
7439 // After calling trans->RestartWithAuth(), this is the request we should
7440 // be issuing -- the final header line contains the credentials.
7441 MockWrite data_writes2[] = {
7442 MockWrite("GET / HTTP/1.1\r\n"
7443 "Host: www.google.com\r\n"
7444 "Connection: keep-alive\r\n"
7445 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
7446 };
7447
7448 // Lastly, the server responds with the actual content.
7449 MockRead data_reads2[] = {
7450 MockRead("HTTP/1.1 200 OK\r\n"),
7451 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7452 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067453 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:577454 };
7455
[email protected]31a2bfe2010-02-09 08:03:397456 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7457 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077458 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]0877e3d2009-10-17 22:29:577459
[email protected]49639fa2011-12-20 23:22:417460 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:577461
[email protected]262eec82013-03-19 21:01:367462 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507463 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:507464
[email protected]49639fa2011-12-20 23:22:417465 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:577466 EXPECT_EQ(ERR_IO_PENDING, rv);
7467
7468 rv = callback1.WaitForResult();
7469 EXPECT_EQ(OK, rv);
7470
7471 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507472 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:047473 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:577474
[email protected]49639fa2011-12-20 23:22:417475 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:577476
[email protected]49639fa2011-12-20 23:22:417477 rv = trans->RestartWithAuth(
7478 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]0877e3d2009-10-17 22:29:577479 EXPECT_EQ(ERR_IO_PENDING, rv);
7480
7481 rv = callback2.WaitForResult();
7482 EXPECT_EQ(OK, rv);
7483
7484 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507485 ASSERT_TRUE(response != NULL);
[email protected]0877e3d2009-10-17 22:29:577486 EXPECT_TRUE(response->auth_challenge.get() == NULL);
7487 EXPECT_EQ(100, response->headers->GetContentLength());
7488}
7489
7490// Test HTTPS connections going through a proxy that sends extra data.
[email protected]23e482282013-06-14 16:08:027491TEST_P(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
[email protected]bb88e1d32013-05-03 23:11:077492 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]0877e3d2009-10-17 22:29:577493
7494 HttpRequestInfo request;
7495 request.method = "GET";
7496 request.url = GURL("https://www.google.com/");
7497 request.load_flags = 0;
7498
7499 MockRead proxy_reads[] = {
7500 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:067501 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:577502 };
7503
[email protected]31a2bfe2010-02-09 08:03:397504 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
[email protected]8ddf8322012-02-23 18:08:067505 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:577506
[email protected]bb88e1d32013-05-03 23:11:077507 session_deps_.socket_factory->AddSocketDataProvider(&data);
7508 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:577509
[email protected]49639fa2011-12-20 23:22:417510 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:577511
[email protected]bb88e1d32013-05-03 23:11:077512 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:577513
7514 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:367515 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:077516 CreateSession(&session_deps_)));
[email protected]0877e3d2009-10-17 22:29:577517
[email protected]49639fa2011-12-20 23:22:417518 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:577519 EXPECT_EQ(ERR_IO_PENDING, rv);
7520
7521 rv = callback.WaitForResult();
7522 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
7523}
7524
[email protected]23e482282013-06-14 16:08:027525TEST_P(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:467526 HttpRequestInfo request;
7527 request.method = "GET";
7528 request.url = GURL("http://www.google.com/");
7529 request.load_flags = 0;
7530
[email protected]cb9bf6ca2011-01-28 13:15:277531 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:367532 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:077533 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:277534
[email protected]e22e1362009-11-23 21:31:127535 MockRead data_reads[] = {
7536 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067537 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:127538 };
[email protected]9492e4a2010-02-24 00:58:467539
7540 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077541 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:467542
[email protected]49639fa2011-12-20 23:22:417543 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:467544
[email protected]49639fa2011-12-20 23:22:417545 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9492e4a2010-02-24 00:58:467546 EXPECT_EQ(ERR_IO_PENDING, rv);
7547
7548 EXPECT_EQ(OK, callback.WaitForResult());
7549
7550 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507551 ASSERT_TRUE(response != NULL);
[email protected]9492e4a2010-02-24 00:58:467552
[email protected]90499482013-06-01 00:39:507553 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]9492e4a2010-02-24 00:58:467554 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
7555
7556 std::string response_data;
7557 rv = ReadTransaction(trans.get(), &response_data);
[email protected]5543cbb2012-04-20 16:35:237558 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
[email protected]e22e1362009-11-23 21:31:127559}
7560
[email protected]23e482282013-06-14 16:08:027561TEST_P(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:157562 base::FilePath temp_file_path;
[email protected]95d88ffe2010-02-04 21:25:337563 ASSERT_TRUE(file_util::CreateTemporaryFile(&temp_file_path));
7564 const uint64 kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:217565 UploadFileElementReader::ScopedOverridingContentLengthForTests
7566 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:337567
[email protected]b2d26cfd2012-12-11 10:36:067568 ScopedVector<UploadElementReader> element_readers;
7569 element_readers.push_back(
[email protected]cadac622013-06-11 16:46:367570 new UploadFileElementReader(base::MessageLoopProxy::current().get(),
7571 temp_file_path,
7572 0,
7573 kuint64max,
7574 base::Time()));
[email protected]b2d26cfd2012-12-11 10:36:067575 UploadDataStream upload_data_stream(&element_readers, 0);
[email protected]329b68b2012-11-14 17:54:277576
7577 HttpRequestInfo request;
7578 request.method = "POST";
7579 request.url = GURL("http://www.google.com/upload");
7580 request.upload_data_stream = &upload_data_stream;
7581 request.load_flags = 0;
7582
[email protected]329b68b2012-11-14 17:54:277583 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:367584 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:077585 CreateSession(&session_deps_)));
[email protected]95d88ffe2010-02-04 21:25:337586
7587 MockRead data_reads[] = {
7588 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
7589 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:067590 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:337591 };
[email protected]31a2bfe2010-02-09 08:03:397592 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:077593 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:337594
[email protected]49639fa2011-12-20 23:22:417595 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:337596
[email protected]49639fa2011-12-20 23:22:417597 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]95d88ffe2010-02-04 21:25:337598 EXPECT_EQ(ERR_IO_PENDING, rv);
7599
7600 rv = callback.WaitForResult();
7601 EXPECT_EQ(OK, rv);
7602
7603 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507604 ASSERT_TRUE(response != NULL);
[email protected]95d88ffe2010-02-04 21:25:337605
[email protected]90499482013-06-01 00:39:507606 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]95d88ffe2010-02-04 21:25:337607 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
7608
7609 std::string response_data;
7610 rv = ReadTransaction(trans.get(), &response_data);
7611 EXPECT_EQ(OK, rv);
7612 EXPECT_EQ("hello world", response_data);
7613
7614 file_util::Delete(temp_file_path, false);
7615}
7616
[email protected]23e482282013-06-14 16:08:027617TEST_P(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:157618 base::FilePath temp_file;
[email protected]6624b4622010-03-29 19:58:367619 ASSERT_TRUE(file_util::CreateTemporaryFile(&temp_file));
7620 std::string temp_file_content("Unreadable file.");
7621 ASSERT_TRUE(file_util::WriteFile(temp_file, temp_file_content.c_str(),
7622 temp_file_content.length()));
7623 ASSERT_TRUE(file_util::MakeFileUnreadable(temp_file));
7624
[email protected]b2d26cfd2012-12-11 10:36:067625 ScopedVector<UploadElementReader> element_readers;
7626 element_readers.push_back(
[email protected]cadac622013-06-11 16:46:367627 new UploadFileElementReader(base::MessageLoopProxy::current().get(),
7628 temp_file,
7629 0,
7630 kuint64max,
7631 base::Time()));
[email protected]b2d26cfd2012-12-11 10:36:067632 UploadDataStream upload_data_stream(&element_readers, 0);
[email protected]329b68b2012-11-14 17:54:277633
7634 HttpRequestInfo request;
7635 request.method = "POST";
7636 request.url = GURL("http://www.google.com/upload");
7637 request.upload_data_stream = &upload_data_stream;
7638 request.load_flags = 0;
7639
7640 // If we try to upload an unreadable file, the network stack should report
7641 // the file size as zero and upload zero bytes for that file.
[email protected]329b68b2012-11-14 17:54:277642 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:367643 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:077644 CreateSession(&session_deps_)));
[email protected]6624b4622010-03-29 19:58:367645
7646 MockRead data_reads[] = {
7647 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067648 MockRead(SYNCHRONOUS, OK),
[email protected]6624b4622010-03-29 19:58:367649 };
7650 MockWrite data_writes[] = {
7651 MockWrite("POST /upload HTTP/1.1\r\n"
7652 "Host: www.google.com\r\n"
7653 "Connection: keep-alive\r\n"
7654 "Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067655 MockWrite(SYNCHRONOUS, OK),
[email protected]6624b4622010-03-29 19:58:367656 };
7657 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
7658 arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077659 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:367660
[email protected]49639fa2011-12-20 23:22:417661 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:367662
[email protected]49639fa2011-12-20 23:22:417663 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]6624b4622010-03-29 19:58:367664 EXPECT_EQ(ERR_IO_PENDING, rv);
7665
7666 rv = callback.WaitForResult();
7667 EXPECT_EQ(OK, rv);
7668
7669 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507670 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:507671 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]6624b4622010-03-29 19:58:367672 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
7673
7674 file_util::Delete(temp_file, false);
7675}
7676
[email protected]23e482282013-06-14 16:08:027677TEST_P(HttpNetworkTransactionTest, UnreadableUploadFileAfterAuthRestart) {
[email protected]6cdfd7f2013-02-08 20:40:157678 base::FilePath temp_file;
[email protected]6624b4622010-03-29 19:58:367679 ASSERT_TRUE(file_util::CreateTemporaryFile(&temp_file));
7680 std::string temp_file_contents("Unreadable file.");
7681 std::string unreadable_contents(temp_file_contents.length(), '\0');
7682 ASSERT_TRUE(file_util::WriteFile(temp_file, temp_file_contents.c_str(),
7683 temp_file_contents.length()));
7684
[email protected]b2d26cfd2012-12-11 10:36:067685 ScopedVector<UploadElementReader> element_readers;
7686 element_readers.push_back(
[email protected]cadac622013-06-11 16:46:367687 new UploadFileElementReader(base::MessageLoopProxy::current().get(),
7688 temp_file,
7689 0,
7690 kuint64max,
7691 base::Time()));
[email protected]b2d26cfd2012-12-11 10:36:067692 UploadDataStream upload_data_stream(&element_readers, 0);
[email protected]329b68b2012-11-14 17:54:277693
7694 HttpRequestInfo request;
7695 request.method = "POST";
7696 request.url = GURL("http://www.google.com/upload");
7697 request.upload_data_stream = &upload_data_stream;
7698 request.load_flags = 0;
7699
[email protected]329b68b2012-11-14 17:54:277700 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:367701 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:077702 CreateSession(&session_deps_)));
[email protected]6624b4622010-03-29 19:58:367703
7704 MockRead data_reads[] = {
7705 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
7706 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7707 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
7708
7709 MockRead("HTTP/1.1 200 OK\r\n"),
7710 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067711 MockRead(SYNCHRONOUS, OK),
[email protected]6624b4622010-03-29 19:58:367712 };
7713 MockWrite data_writes[] = {
7714 MockWrite("POST /upload HTTP/1.1\r\n"
7715 "Host: www.google.com\r\n"
7716 "Connection: keep-alive\r\n"
7717 "Content-Length: 16\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067718 MockWrite(SYNCHRONOUS, temp_file_contents.c_str()),
[email protected]6624b4622010-03-29 19:58:367719
7720 MockWrite("POST /upload HTTP/1.1\r\n"
7721 "Host: www.google.com\r\n"
7722 "Connection: keep-alive\r\n"
[email protected]d98961652012-09-11 20:27:217723 "Content-Length: 0\r\n"
[email protected]6624b4622010-03-29 19:58:367724 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067725 MockWrite(SYNCHRONOUS, unreadable_contents.c_str(),
7726 temp_file_contents.length()),
7727 MockWrite(SYNCHRONOUS, OK),
[email protected]6624b4622010-03-29 19:58:367728 };
7729 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
7730 arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077731 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:367732
[email protected]49639fa2011-12-20 23:22:417733 TestCompletionCallback callback1;
[email protected]6624b4622010-03-29 19:58:367734
[email protected]49639fa2011-12-20 23:22:417735 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]6624b4622010-03-29 19:58:367736 EXPECT_EQ(ERR_IO_PENDING, rv);
7737
7738 rv = callback1.WaitForResult();
7739 EXPECT_EQ(OK, rv);
7740
7741 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:047742 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:507743 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]6624b4622010-03-29 19:58:367744 EXPECT_EQ("HTTP/1.1 401 Unauthorized", response->headers->GetStatusLine());
[email protected]79cb5c12011-09-12 13:12:047745 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]6624b4622010-03-29 19:58:367746
7747 // Now make the file unreadable and try again.
7748 ASSERT_TRUE(file_util::MakeFileUnreadable(temp_file));
7749
[email protected]49639fa2011-12-20 23:22:417750 TestCompletionCallback callback2;
[email protected]6624b4622010-03-29 19:58:367751
[email protected]49639fa2011-12-20 23:22:417752 rv = trans->RestartWithAuth(
7753 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]6624b4622010-03-29 19:58:367754 EXPECT_EQ(ERR_IO_PENDING, rv);
7755
7756 rv = callback2.WaitForResult();
7757 EXPECT_EQ(OK, rv);
7758
7759 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507760 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:507761 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]6624b4622010-03-29 19:58:367762 EXPECT_TRUE(response->auth_challenge.get() == NULL);
7763 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7764
7765 file_util::Delete(temp_file, false);
7766}
7767
[email protected]aeefc9e82010-02-19 16:18:277768// Tests that changes to Auth realms are treated like auth rejections.
[email protected]23e482282013-06-14 16:08:027769TEST_P(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:277770
7771 HttpRequestInfo request;
7772 request.method = "GET";
7773 request.url = GURL("http://www.google.com/");
7774 request.load_flags = 0;
7775
7776 // First transaction will request a resource and receive a Basic challenge
7777 // with realm="first_realm".
7778 MockWrite data_writes1[] = {
7779 MockWrite("GET / HTTP/1.1\r\n"
7780 "Host: www.google.com\r\n"
7781 "Connection: keep-alive\r\n"
7782 "\r\n"),
7783 };
7784 MockRead data_reads1[] = {
7785 MockRead("HTTP/1.1 401 Unauthorized\r\n"
7786 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
7787 "\r\n"),
7788 };
7789
7790 // After calling trans->RestartWithAuth(), provide an Authentication header
7791 // for first_realm. The server will reject and provide a challenge with
7792 // second_realm.
7793 MockWrite data_writes2[] = {
7794 MockWrite("GET / HTTP/1.1\r\n"
7795 "Host: www.google.com\r\n"
7796 "Connection: keep-alive\r\n"
7797 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
7798 "\r\n"),
7799 };
7800 MockRead data_reads2[] = {
7801 MockRead("HTTP/1.1 401 Unauthorized\r\n"
7802 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
7803 "\r\n"),
7804 };
7805
7806 // This again fails, and goes back to first_realm. Make sure that the
7807 // entry is removed from cache.
7808 MockWrite data_writes3[] = {
7809 MockWrite("GET / HTTP/1.1\r\n"
7810 "Host: www.google.com\r\n"
7811 "Connection: keep-alive\r\n"
7812 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
7813 "\r\n"),
7814 };
7815 MockRead data_reads3[] = {
7816 MockRead("HTTP/1.1 401 Unauthorized\r\n"
7817 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
7818 "\r\n"),
7819 };
7820
7821 // Try one last time (with the correct password) and get the resource.
7822 MockWrite data_writes4[] = {
7823 MockWrite("GET / HTTP/1.1\r\n"
7824 "Host: www.google.com\r\n"
7825 "Connection: keep-alive\r\n"
7826 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
7827 "\r\n"),
7828 };
7829 MockRead data_reads4[] = {
7830 MockRead("HTTP/1.1 200 OK\r\n"
7831 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:507832 "Content-Length: 5\r\n"
7833 "\r\n"
7834 "hello"),
[email protected]aeefc9e82010-02-19 16:18:277835 };
7836
7837 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7838 data_writes1, arraysize(data_writes1));
7839 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7840 data_writes2, arraysize(data_writes2));
7841 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
7842 data_writes3, arraysize(data_writes3));
7843 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
7844 data_writes4, arraysize(data_writes4));
[email protected]bb88e1d32013-05-03 23:11:077845 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7846 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7847 session_deps_.socket_factory->AddSocketDataProvider(&data3);
7848 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:277849
[email protected]49639fa2011-12-20 23:22:417850 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:277851
[email protected]0b0bf032010-09-21 18:08:507852 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:367853 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:077854 CreateSession(&session_deps_)));
[email protected]0b0bf032010-09-21 18:08:507855
[email protected]aeefc9e82010-02-19 16:18:277856 // Issue the first request with Authorize headers. There should be a
7857 // password prompt for first_realm waiting to be filled in after the
7858 // transaction completes.
[email protected]49639fa2011-12-20 23:22:417859 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]aeefc9e82010-02-19 16:18:277860 EXPECT_EQ(ERR_IO_PENDING, rv);
7861 rv = callback1.WaitForResult();
7862 EXPECT_EQ(OK, rv);
7863 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507864 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:047865 const AuthChallengeInfo* challenge = response->auth_challenge.get();
7866 ASSERT_FALSE(challenge == NULL);
7867 EXPECT_FALSE(challenge->is_proxy);
7868 EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
7869 EXPECT_EQ("first_realm", challenge->realm);
7870 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:277871
7872 // Issue the second request with an incorrect password. There should be a
7873 // password prompt for second_realm waiting to be filled in after the
7874 // transaction completes.
[email protected]49639fa2011-12-20 23:22:417875 TestCompletionCallback callback2;
7876 rv = trans->RestartWithAuth(
7877 AuthCredentials(kFirst, kBaz), callback2.callback());
[email protected]aeefc9e82010-02-19 16:18:277878 EXPECT_EQ(ERR_IO_PENDING, rv);
7879 rv = callback2.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("second_realm", challenge->realm);
7888 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:277889
7890 // Issue the third request with another incorrect password. There should be
7891 // a password prompt for first_realm waiting to be filled in. If the password
7892 // prompt is not present, it indicates that the HttpAuthCacheEntry for
7893 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:417894 TestCompletionCallback callback3;
7895 rv = trans->RestartWithAuth(
7896 AuthCredentials(kSecond, kFou), callback3.callback());
[email protected]aeefc9e82010-02-19 16:18:277897 EXPECT_EQ(ERR_IO_PENDING, rv);
7898 rv = callback3.WaitForResult();
7899 EXPECT_EQ(OK, rv);
7900 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507901 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:047902 challenge = response->auth_challenge.get();
7903 ASSERT_FALSE(challenge == NULL);
7904 EXPECT_FALSE(challenge->is_proxy);
7905 EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
7906 EXPECT_EQ("first_realm", challenge->realm);
7907 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:277908
7909 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:417910 TestCompletionCallback callback4;
7911 rv = trans->RestartWithAuth(
7912 AuthCredentials(kFirst, kBar), callback4.callback());
[email protected]aeefc9e82010-02-19 16:18:277913 EXPECT_EQ(ERR_IO_PENDING, rv);
7914 rv = callback4.WaitForResult();
7915 EXPECT_EQ(OK, rv);
7916 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507917 ASSERT_TRUE(response != NULL);
[email protected]aeefc9e82010-02-19 16:18:277918 EXPECT_TRUE(response->auth_challenge.get() == NULL);
7919}
7920
[email protected]23e482282013-06-14 16:08:027921TEST_P(HttpNetworkTransactionTest, HonorAlternateProtocolHeader) {
[email protected]ecf96e52012-03-03 00:43:037922 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]448d4ca52012-03-04 04:12:237923 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]a2cb8122010-03-10 17:22:427924
[email protected]8a0fc822013-06-27 20:52:437925 std::string alternate_protocol_http_header =
7926 GetAlternateProtocolHttpHeader();
7927
[email protected]564b4912010-03-09 16:30:427928 MockRead data_reads[] = {
7929 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:437930 MockRead(alternate_protocol_http_header.c_str()),
[email protected]564b4912010-03-09 16:30:427931 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:067932 MockRead(SYNCHRONOUS, OK),
[email protected]564b4912010-03-09 16:30:427933 };
7934
7935 HttpRequestInfo request;
7936 request.method = "GET";
7937 request.url = GURL("http://www.google.com/");
7938 request.load_flags = 0;
7939
7940 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
7941
[email protected]bb88e1d32013-05-03 23:11:077942 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]564b4912010-03-09 16:30:427943
[email protected]49639fa2011-12-20 23:22:417944 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:427945
[email protected]bb88e1d32013-05-03 23:11:077946 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:367947 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507948 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]564b4912010-03-09 16:30:427949
[email protected]49639fa2011-12-20 23:22:417950 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:427951 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]9e743cd2010-03-16 07:03:537952
[email protected]2fbaecf22010-07-22 22:20:357953 HostPortPair http_host_port_pair("www.google.com", 80);
[email protected]17291a022011-10-10 07:32:537954 const HttpServerProperties& http_server_properties =
7955 *session->http_server_properties();
[email protected]564b4912010-03-09 16:30:427956 EXPECT_FALSE(
[email protected]17291a022011-10-10 07:32:537957 http_server_properties.HasAlternateProtocol(http_host_port_pair));
[email protected]564b4912010-03-09 16:30:427958
7959 EXPECT_EQ(OK, callback.WaitForResult());
7960
7961 const HttpResponseInfo* response = trans->GetResponseInfo();
7962 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:507963 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:427964 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:537965 EXPECT_FALSE(response->was_fetched_via_spdy);
7966 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]564b4912010-03-09 16:30:427967
7968 std::string response_data;
7969 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
7970 EXPECT_EQ("hello world", response_data);
7971
[email protected]17291a022011-10-10 07:32:537972 ASSERT_TRUE(http_server_properties.HasAlternateProtocol(http_host_port_pair));
7973 const PortAlternateProtocolPair alternate =
7974 http_server_properties.GetAlternateProtocol(http_host_port_pair);
7975 PortAlternateProtocolPair expected_alternate;
[email protected]564b4912010-03-09 16:30:427976 expected_alternate.port = 443;
[email protected]8a0fc822013-06-27 20:52:437977 expected_alternate.protocol = AlternateProtocolFromNextProto(GetParam());
[email protected]564b4912010-03-09 16:30:427978 EXPECT_TRUE(expected_alternate.Equals(alternate));
[email protected]a2cb8122010-03-10 17:22:427979
[email protected]ecf96e52012-03-03 00:43:037980 HttpStreamFactory::SetNextProtos(std::vector<std::string>());
[email protected]564b4912010-03-09 16:30:427981}
7982
[email protected]23e482282013-06-14 16:08:027983TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:237984 MarkBrokenAlternateProtocolAndFallback) {
[email protected]8e6441ca2010-08-19 05:56:387985 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]564b4912010-03-09 16:30:427986
7987 HttpRequestInfo request;
7988 request.method = "GET";
7989 request.url = GURL("http://www.google.com/");
7990 request.load_flags = 0;
7991
[email protected]d973e99a2012-02-17 21:02:367992 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:427993 StaticSocketDataProvider first_data;
7994 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:077995 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]564b4912010-03-09 16:30:427996
7997 MockRead data_reads[] = {
7998 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
7999 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068000 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:428001 };
8002 StaticSocketDataProvider second_data(
8003 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078004 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:428005
[email protected]bb88e1d32013-05-03 23:11:078006 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:428007
[email protected]17291a022011-10-10 07:32:538008 HttpServerProperties* http_server_properties =
8009 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118010 // Port must be < 1024, or the header will be ignored (since initial port was
8011 // port 80 (another restricted port).
[email protected]17291a022011-10-10 07:32:538012 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118013 HostPortPair::FromURL(request.url),
8014 666 /* port is ignored by MockConnect anyway */,
[email protected]8a0fc822013-06-27 20:52:438015 AlternateProtocolFromNextProto(GetParam()));
[email protected]564b4912010-03-09 16:30:428016
[email protected]262eec82013-03-19 21:01:368017 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508018 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418019 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:428020
[email protected]49639fa2011-12-20 23:22:418021 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:428022 EXPECT_EQ(ERR_IO_PENDING, rv);
8023 EXPECT_EQ(OK, callback.WaitForResult());
8024
8025 const HttpResponseInfo* response = trans->GetResponseInfo();
8026 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508027 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:428028 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8029
8030 std::string response_data;
8031 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8032 EXPECT_EQ("hello world", response_data);
8033
[email protected]17291a022011-10-10 07:32:538034 ASSERT_TRUE(http_server_properties->HasAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118035 HostPortPair::FromURL(request.url)));
[email protected]17291a022011-10-10 07:32:538036 const PortAlternateProtocolPair alternate =
8037 http_server_properties->GetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118038 HostPortPair::FromURL(request.url));
[email protected]17291a022011-10-10 07:32:538039 EXPECT_EQ(ALTERNATE_PROTOCOL_BROKEN, alternate.protocol);
[email protected]564b4912010-03-09 16:30:428040}
8041
[email protected]23e482282013-06-14 16:08:028042TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238043 AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:118044 // Ensure that we're not allowed to redirect traffic via an alternate
8045 // protocol to an unrestricted (port >= 1024) when the original traffic was
8046 // on a restricted port (port < 1024). Ensure that we can redirect in all
8047 // other cases.
8048 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]3912662a32011-10-04 00:51:118049
8050 HttpRequestInfo restricted_port_request;
8051 restricted_port_request.method = "GET";
8052 restricted_port_request.url = GURL("http://www.google.com:1023/");
8053 restricted_port_request.load_flags = 0;
8054
[email protected]d973e99a2012-02-17 21:02:368055 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118056 StaticSocketDataProvider first_data;
8057 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078058 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118059
8060 MockRead data_reads[] = {
8061 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8062 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068063 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118064 };
8065 StaticSocketDataProvider second_data(
8066 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078067 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118068
[email protected]bb88e1d32013-05-03 23:11:078069 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118070
[email protected]17291a022011-10-10 07:32:538071 HttpServerProperties* http_server_properties =
8072 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118073 const int kUnrestrictedAlternatePort = 1024;
[email protected]17291a022011-10-10 07:32:538074 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118075 HostPortPair::FromURL(restricted_port_request.url),
8076 kUnrestrictedAlternatePort,
[email protected]8a0fc822013-06-27 20:52:438077 AlternateProtocolFromNextProto(GetParam()));
[email protected]3912662a32011-10-04 00:51:118078
[email protected]262eec82013-03-19 21:01:368079 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508080 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418081 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118082
[email protected]49639fa2011-12-20 23:22:418083 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:368084 &restricted_port_request,
8085 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118086 EXPECT_EQ(ERR_IO_PENDING, rv);
8087 // Invalid change to unrestricted port should fail.
8088 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.WaitForResult());
[email protected]c54c6962013-02-01 04:53:198089}
[email protected]3912662a32011-10-04 00:51:118090
[email protected]23e482282013-06-14 16:08:028091TEST_P(HttpNetworkTransactionTest,
[email protected]c54c6962013-02-01 04:53:198092 AlternateProtocolPortRestrictedPermitted) {
8093 // Ensure that we're allowed to redirect traffic via an alternate
8094 // protocol to an unrestricted (port >= 1024) when the original traffic was
8095 // on a restricted port (port < 1024) if we set
8096 // enable_user_alternate_protocol_ports.
8097
8098 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]bb88e1d32013-05-03 23:11:078099 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:198100
8101 HttpRequestInfo restricted_port_request;
8102 restricted_port_request.method = "GET";
8103 restricted_port_request.url = GURL("http://www.google.com:1023/");
8104 restricted_port_request.load_flags = 0;
8105
8106 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
8107 StaticSocketDataProvider first_data;
8108 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078109 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:198110
8111 MockRead data_reads[] = {
8112 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8113 MockRead("hello world"),
8114 MockRead(ASYNC, OK),
8115 };
8116 StaticSocketDataProvider second_data(
8117 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078118 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]c54c6962013-02-01 04:53:198119
[email protected]bb88e1d32013-05-03 23:11:078120 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:198121
8122 HttpServerProperties* http_server_properties =
8123 session->http_server_properties();
8124 const int kUnrestrictedAlternatePort = 1024;
8125 http_server_properties->SetAlternateProtocol(
8126 HostPortPair::FromURL(restricted_port_request.url),
8127 kUnrestrictedAlternatePort,
[email protected]8a0fc822013-06-27 20:52:438128 AlternateProtocolFromNextProto(GetParam()));
[email protected]c54c6962013-02-01 04:53:198129
[email protected]262eec82013-03-19 21:01:368130 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508131 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]c54c6962013-02-01 04:53:198132 TestCompletionCallback callback;
8133
8134 EXPECT_EQ(ERR_IO_PENDING, trans->Start(
[email protected]262eec82013-03-19 21:01:368135 &restricted_port_request,
8136 callback.callback(), BoundNetLog()));
[email protected]c54c6962013-02-01 04:53:198137 // Change to unrestricted port should succeed.
8138 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:118139}
8140
[email protected]23e482282013-06-14 16:08:028141TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238142 AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:118143 // Ensure that we're not allowed to redirect traffic via an alternate
8144 // protocol to an unrestricted (port >= 1024) when the original traffic was
8145 // on a restricted port (port < 1024). Ensure that we can redirect in all
8146 // other cases.
8147 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]3912662a32011-10-04 00:51:118148
8149 HttpRequestInfo restricted_port_request;
8150 restricted_port_request.method = "GET";
8151 restricted_port_request.url = GURL("http://www.google.com:1023/");
8152 restricted_port_request.load_flags = 0;
8153
[email protected]d973e99a2012-02-17 21:02:368154 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118155 StaticSocketDataProvider first_data;
8156 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078157 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118158
8159 MockRead data_reads[] = {
8160 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8161 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068162 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118163 };
8164 StaticSocketDataProvider second_data(
8165 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078166 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118167
[email protected]bb88e1d32013-05-03 23:11:078168 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118169
[email protected]17291a022011-10-10 07:32:538170 HttpServerProperties* http_server_properties =
8171 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118172 const int kRestrictedAlternatePort = 80;
[email protected]17291a022011-10-10 07:32:538173 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118174 HostPortPair::FromURL(restricted_port_request.url),
8175 kRestrictedAlternatePort,
[email protected]8a0fc822013-06-27 20:52:438176 AlternateProtocolFromNextProto(GetParam()));
[email protected]3912662a32011-10-04 00:51:118177
[email protected]262eec82013-03-19 21:01:368178 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508179 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418180 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118181
[email protected]49639fa2011-12-20 23:22:418182 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:368183 &restricted_port_request,
8184 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118185 EXPECT_EQ(ERR_IO_PENDING, rv);
8186 // Valid change to restricted port should pass.
8187 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:118188}
8189
[email protected]23e482282013-06-14 16:08:028190TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238191 AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:118192 // Ensure that we're not allowed to redirect traffic via an alternate
8193 // protocol to an unrestricted (port >= 1024) when the original traffic was
8194 // on a restricted port (port < 1024). Ensure that we can redirect in all
8195 // other cases.
8196 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]3912662a32011-10-04 00:51:118197
8198 HttpRequestInfo unrestricted_port_request;
8199 unrestricted_port_request.method = "GET";
8200 unrestricted_port_request.url = GURL("http://www.google.com:1024/");
8201 unrestricted_port_request.load_flags = 0;
8202
[email protected]d973e99a2012-02-17 21:02:368203 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118204 StaticSocketDataProvider first_data;
8205 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078206 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118207
8208 MockRead data_reads[] = {
8209 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8210 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068211 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118212 };
8213 StaticSocketDataProvider second_data(
8214 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078215 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118216
[email protected]bb88e1d32013-05-03 23:11:078217 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118218
[email protected]17291a022011-10-10 07:32:538219 HttpServerProperties* http_server_properties =
8220 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118221 const int kRestrictedAlternatePort = 80;
[email protected]17291a022011-10-10 07:32:538222 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118223 HostPortPair::FromURL(unrestricted_port_request.url),
8224 kRestrictedAlternatePort,
[email protected]8a0fc822013-06-27 20:52:438225 AlternateProtocolFromNextProto(GetParam()));
[email protected]3912662a32011-10-04 00:51:118226
[email protected]262eec82013-03-19 21:01:368227 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508228 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418229 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118230
[email protected]49639fa2011-12-20 23:22:418231 int rv = trans->Start(
8232 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118233 EXPECT_EQ(ERR_IO_PENDING, rv);
8234 // Valid change to restricted port should pass.
8235 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:118236}
8237
[email protected]23e482282013-06-14 16:08:028238TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238239 AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:118240 // Ensure that we're not allowed to redirect traffic via an alternate
8241 // protocol to an unrestricted (port >= 1024) when the original traffic was
8242 // on a restricted port (port < 1024). Ensure that we can redirect in all
8243 // other cases.
8244 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]3912662a32011-10-04 00:51:118245
8246 HttpRequestInfo unrestricted_port_request;
8247 unrestricted_port_request.method = "GET";
8248 unrestricted_port_request.url = GURL("http://www.google.com:1024/");
8249 unrestricted_port_request.load_flags = 0;
8250
[email protected]d973e99a2012-02-17 21:02:368251 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118252 StaticSocketDataProvider first_data;
8253 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078254 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118255
8256 MockRead data_reads[] = {
8257 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8258 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068259 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118260 };
8261 StaticSocketDataProvider second_data(
8262 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078263 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118264
[email protected]bb88e1d32013-05-03 23:11:078265 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118266
[email protected]17291a022011-10-10 07:32:538267 HttpServerProperties* http_server_properties =
8268 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118269 const int kUnrestrictedAlternatePort = 1024;
[email protected]17291a022011-10-10 07:32:538270 http_server_properties->SetAlternateProtocol(
[email protected]3912662a32011-10-04 00:51:118271 HostPortPair::FromURL(unrestricted_port_request.url),
8272 kUnrestrictedAlternatePort,
[email protected]8a0fc822013-06-27 20:52:438273 AlternateProtocolFromNextProto(GetParam()));
[email protected]3912662a32011-10-04 00:51:118274
[email protected]262eec82013-03-19 21:01:368275 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508276 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418277 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118278
[email protected]49639fa2011-12-20 23:22:418279 int rv = trans->Start(
8280 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118281 EXPECT_EQ(ERR_IO_PENDING, rv);
8282 // Valid change to an unrestricted port should pass.
8283 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:118284}
8285
[email protected]23e482282013-06-14 16:08:028286TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238287 AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:028288 // Ensure that we're not allowed to redirect traffic via an alternate
8289 // protocol to an unsafe port, and that we resume the second
8290 // HttpStreamFactoryImpl::Job once the alternate protocol request fails.
8291 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]eb6234e2012-01-19 01:50:028292
8293 HttpRequestInfo request;
8294 request.method = "GET";
8295 request.url = GURL("http://www.google.com/");
8296 request.load_flags = 0;
8297
8298 // The alternate protocol request will error out before we attempt to connect,
8299 // so only the standard HTTP request will try to connect.
8300 MockRead data_reads[] = {
8301 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8302 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068303 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:028304 };
8305 StaticSocketDataProvider data(
8306 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078307 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:028308
[email protected]bb88e1d32013-05-03 23:11:078309 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:028310
8311 HttpServerProperties* http_server_properties =
8312 session->http_server_properties();
8313 const int kUnsafePort = 7;
8314 http_server_properties->SetAlternateProtocol(
8315 HostPortPair::FromURL(request.url),
8316 kUnsafePort,
[email protected]8a0fc822013-06-27 20:52:438317 AlternateProtocolFromNextProto(GetParam()));
[email protected]eb6234e2012-01-19 01:50:028318
[email protected]262eec82013-03-19 21:01:368319 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508320 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]eb6234e2012-01-19 01:50:028321 TestCompletionCallback callback;
8322
8323 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8324 EXPECT_EQ(ERR_IO_PENDING, rv);
8325 // The HTTP request should succeed.
8326 EXPECT_EQ(OK, callback.WaitForResult());
8327
8328 // Disable alternate protocol before the asserts.
8329 HttpStreamFactory::set_use_alternate_protocols(false);
8330
8331 const HttpResponseInfo* response = trans->GetResponseInfo();
8332 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508333 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]eb6234e2012-01-19 01:50:028334 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8335
8336 std::string response_data;
8337 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8338 EXPECT_EQ("hello world", response_data);
8339}
8340
[email protected]23e482282013-06-14 16:08:028341TEST_P(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]8e6441ca2010-08-19 05:56:388342 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:038343 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]2ff8b312010-04-26 22:20:548344
8345 HttpRequestInfo request;
8346 request.method = "GET";
8347 request.url = GURL("http://www.google.com/");
8348 request.load_flags = 0;
8349
[email protected]8a0fc822013-06-27 20:52:438350 std::string alternate_protocol_http_header =
8351 GetAlternateProtocolHttpHeader();
8352
[email protected]2ff8b312010-04-26 22:20:548353 MockRead data_reads[] = {
8354 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438355 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2ff8b312010-04-26 22:20:548356 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:178357 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
8358 MockRead(ASYNC, OK)
[email protected]2ff8b312010-04-26 22:20:548359 };
8360
8361 StaticSocketDataProvider first_transaction(
8362 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078363 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:548364
[email protected]8ddf8322012-02-23 18:08:068365 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:028366 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:078367 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:548368
[email protected]cdf8f7e72013-05-23 10:56:468369 scoped_ptr<SpdyFrame> req(
8370 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]e7f75092010-07-01 22:39:138371 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
[email protected]2ff8b312010-04-26 22:20:548372
[email protected]23e482282013-06-14 16:08:028373 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
8374 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:548375 MockRead spdy_reads[] = {
[email protected]e7f75092010-07-01 22:39:138376 CreateMockRead(*resp),
8377 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:068378 MockRead(ASYNC, 0, 0),
[email protected]2ff8b312010-04-26 22:20:548379 };
8380
[email protected]dd54bd82012-07-19 23:44:578381 DelayedSocketData spdy_data(
8382 1, // wait for one write to finish before reading.
8383 spdy_reads, arraysize(spdy_reads),
8384 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078385 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:548386
[email protected]d973e99a2012-02-17 21:02:368387 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:558388 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
8389 NULL, 0, NULL, 0);
8390 hanging_non_alternate_protocol_socket.set_connect_data(
8391 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:078392 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:558393 &hanging_non_alternate_protocol_socket);
8394
[email protected]49639fa2011-12-20 23:22:418395 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:548396
[email protected]bb88e1d32013-05-03 23:11:078397 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:368398 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508399 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:548400
[email protected]49639fa2011-12-20 23:22:418401 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:548402 EXPECT_EQ(ERR_IO_PENDING, rv);
8403 EXPECT_EQ(OK, callback.WaitForResult());
8404
8405 const HttpResponseInfo* response = trans->GetResponseInfo();
8406 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508407 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:548408 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8409
8410 std::string response_data;
8411 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8412 EXPECT_EQ("hello world", response_data);
8413
[email protected]90499482013-06-01 00:39:508414 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:548415
[email protected]49639fa2011-12-20 23:22:418416 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:548417 EXPECT_EQ(ERR_IO_PENDING, rv);
8418 EXPECT_EQ(OK, callback.WaitForResult());
8419
8420 response = trans->GetResponseInfo();
8421 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508422 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:548423 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:538424 EXPECT_TRUE(response->was_fetched_via_spdy);
8425 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:548426
8427 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8428 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:548429}
8430
[email protected]23e482282013-06-14 16:08:028431TEST_P(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]2d6728692011-03-12 01:39:558432 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:038433 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]2d6728692011-03-12 01:39:558434
8435 HttpRequestInfo request;
8436 request.method = "GET";
8437 request.url = GURL("http://www.google.com/");
8438 request.load_flags = 0;
8439
[email protected]8a0fc822013-06-27 20:52:438440 std::string alternate_protocol_http_header =
8441 GetAlternateProtocolHttpHeader();
8442
[email protected]2d6728692011-03-12 01:39:558443 MockRead data_reads[] = {
8444 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438445 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2d6728692011-03-12 01:39:558446 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:178447 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:068448 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:558449 };
8450
8451 StaticSocketDataProvider first_transaction(
8452 data_reads, arraysize(data_reads), NULL, 0);
8453 // Socket 1 is the HTTP transaction with the Alternate-Protocol header.
[email protected]bb88e1d32013-05-03 23:11:078454 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:558455
[email protected]d973e99a2012-02-17 21:02:368456 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:558457 StaticSocketDataProvider hanging_socket(
8458 NULL, 0, NULL, 0);
8459 hanging_socket.set_connect_data(never_finishing_connect);
8460 // Socket 2 and 3 are the hanging Alternate-Protocol and
8461 // non-Alternate-Protocol jobs from the 2nd transaction.
[email protected]bb88e1d32013-05-03 23:11:078462 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
8463 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
[email protected]2d6728692011-03-12 01:39:558464
[email protected]8ddf8322012-02-23 18:08:068465 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:028466 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:078467 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:558468
[email protected]cdf8f7e72013-05-23 10:56:468469 scoped_ptr<SpdyFrame> req1(
8470 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
8471 scoped_ptr<SpdyFrame> req2(
8472 spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
[email protected]2d6728692011-03-12 01:39:558473 MockWrite spdy_writes[] = {
8474 CreateMockWrite(*req1),
8475 CreateMockWrite(*req2),
8476 };
[email protected]23e482282013-06-14 16:08:028477 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
8478 scoped_ptr<SpdyFrame> data1(spdy_util_.ConstructSpdyBodyFrame(1, true));
8479 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
8480 scoped_ptr<SpdyFrame> data2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]2d6728692011-03-12 01:39:558481 MockRead spdy_reads[] = {
8482 CreateMockRead(*resp1),
8483 CreateMockRead(*data1),
8484 CreateMockRead(*resp2),
8485 CreateMockRead(*data2),
[email protected]8ddf8322012-02-23 18:08:068486 MockRead(ASYNC, 0, 0),
[email protected]2d6728692011-03-12 01:39:558487 };
8488
[email protected]dd54bd82012-07-19 23:44:578489 DelayedSocketData spdy_data(
8490 2, // wait for writes to finish before reading.
8491 spdy_reads, arraysize(spdy_reads),
8492 spdy_writes, arraysize(spdy_writes));
[email protected]2d6728692011-03-12 01:39:558493 // Socket 4 is the successful Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:078494 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:558495
8496 // Socket 5 is the unsuccessful non-Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:078497 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
[email protected]2d6728692011-03-12 01:39:558498
[email protected]bb88e1d32013-05-03 23:11:078499 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:418500 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:508501 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:558502
[email protected]49639fa2011-12-20 23:22:418503 int rv = trans1.Start(&request, callback1.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:558504 EXPECT_EQ(ERR_IO_PENDING, rv);
8505 EXPECT_EQ(OK, callback1.WaitForResult());
8506
8507 const HttpResponseInfo* response = trans1.GetResponseInfo();
8508 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508509 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:558510 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8511
8512 std::string response_data;
8513 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
8514 EXPECT_EQ("hello world", response_data);
8515
[email protected]49639fa2011-12-20 23:22:418516 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:508517 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:418518 rv = trans2.Start(&request, callback2.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:558519 EXPECT_EQ(ERR_IO_PENDING, rv);
8520
[email protected]49639fa2011-12-20 23:22:418521 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:508522 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:418523 rv = trans3.Start(&request, callback3.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:558524 EXPECT_EQ(ERR_IO_PENDING, rv);
8525
8526 EXPECT_EQ(OK, callback2.WaitForResult());
8527 EXPECT_EQ(OK, callback3.WaitForResult());
8528
8529 response = trans2.GetResponseInfo();
8530 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508531 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:558532 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8533 EXPECT_TRUE(response->was_fetched_via_spdy);
8534 EXPECT_TRUE(response->was_npn_negotiated);
8535 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
8536 EXPECT_EQ("hello!", response_data);
8537
8538 response = trans3.GetResponseInfo();
8539 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508540 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:558541 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8542 EXPECT_TRUE(response->was_fetched_via_spdy);
8543 EXPECT_TRUE(response->was_npn_negotiated);
8544 ASSERT_EQ(OK, ReadTransaction(&trans3, &response_data));
8545 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:558546}
8547
[email protected]23e482282013-06-14 16:08:028548TEST_P(HttpNetworkTransactionTest, StallAlternateProtocolForNpnSpdy) {
[email protected]2d6728692011-03-12 01:39:558549 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:038550 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]2d6728692011-03-12 01:39:558551
8552 HttpRequestInfo request;
8553 request.method = "GET";
8554 request.url = GURL("http://www.google.com/");
8555 request.load_flags = 0;
8556
[email protected]8a0fc822013-06-27 20:52:438557 std::string alternate_protocol_http_header =
8558 GetAlternateProtocolHttpHeader();
8559
[email protected]2d6728692011-03-12 01:39:558560 MockRead data_reads[] = {
8561 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438562 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2d6728692011-03-12 01:39:558563 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:178564 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:068565 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:558566 };
8567
8568 StaticSocketDataProvider first_transaction(
8569 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078570 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:558571
[email protected]8ddf8322012-02-23 18:08:068572 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:028573 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:078574 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:558575
[email protected]d973e99a2012-02-17 21:02:368576 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:558577 StaticSocketDataProvider hanging_alternate_protocol_socket(
8578 NULL, 0, NULL, 0);
8579 hanging_alternate_protocol_socket.set_connect_data(
8580 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:078581 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:558582 &hanging_alternate_protocol_socket);
8583
8584 // 2nd request is just a copy of the first one, over HTTP again.
[email protected]bb88e1d32013-05-03 23:11:078585 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:558586
[email protected]49639fa2011-12-20 23:22:418587 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:558588
[email protected]bb88e1d32013-05-03 23:11:078589 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:368590 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508591 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:558592
[email protected]49639fa2011-12-20 23:22:418593 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:558594 EXPECT_EQ(ERR_IO_PENDING, rv);
8595 EXPECT_EQ(OK, callback.WaitForResult());
8596
8597 const HttpResponseInfo* response = trans->GetResponseInfo();
8598 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508599 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:558600 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8601
8602 std::string response_data;
8603 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8604 EXPECT_EQ("hello world", response_data);
8605
[email protected]90499482013-06-01 00:39:508606 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:558607
[email protected]49639fa2011-12-20 23:22:418608 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:558609 EXPECT_EQ(ERR_IO_PENDING, rv);
8610 EXPECT_EQ(OK, callback.WaitForResult());
8611
8612 response = trans->GetResponseInfo();
8613 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508614 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:558615 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8616 EXPECT_FALSE(response->was_fetched_via_spdy);
8617 EXPECT_FALSE(response->was_npn_negotiated);
8618
8619 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8620 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:558621}
8622
[email protected]631f1322010-04-30 17:59:118623class CapturingProxyResolver : public ProxyResolver {
8624 public:
8625 CapturingProxyResolver() : ProxyResolver(false /* expects_pac_bytes */) {}
8626 virtual ~CapturingProxyResolver() {}
8627
8628 virtual int GetProxyForURL(const GURL& url,
8629 ProxyInfo* results,
[email protected]235786812011-12-20 02:15:318630 const CompletionCallback& callback,
[email protected]631f1322010-04-30 17:59:118631 RequestHandle* request,
[email protected]46fadfd2013-02-06 09:40:168632 const BoundNetLog& net_log) OVERRIDE {
[email protected]fae7669f2010-08-02 21:49:408633 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
8634 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:428635 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:118636 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:428637 return OK;
[email protected]631f1322010-04-30 17:59:118638 }
8639
[email protected]46fadfd2013-02-06 09:40:168640 virtual void CancelRequest(RequestHandle request) OVERRIDE {
[email protected]631f1322010-04-30 17:59:118641 NOTREACHED();
8642 }
8643
[email protected]f2c971f2011-11-08 00:33:178644 virtual LoadState GetLoadState(RequestHandle request) const OVERRIDE {
8645 NOTREACHED();
8646 return LOAD_STATE_IDLE;
8647 }
8648
[email protected]46fadfd2013-02-06 09:40:168649 virtual void CancelSetPacScript() OVERRIDE {
[email protected]1e605472010-12-16 21:41:408650 NOTREACHED();
8651 }
8652
[email protected]24476402010-07-20 20:55:178653 virtual int SetPacScript(const scoped_refptr<ProxyResolverScriptData>&,
[email protected]46fadfd2013-02-06 09:40:168654 const CompletionCallback& /*callback*/) OVERRIDE {
[email protected]d911f1b2010-05-05 22:39:428655 return OK;
[email protected]631f1322010-04-30 17:59:118656 }
8657
[email protected]24476402010-07-20 20:55:178658 const std::vector<GURL>& resolved() const { return resolved_; }
8659
8660 private:
[email protected]631f1322010-04-30 17:59:118661 std::vector<GURL> resolved_;
8662
8663 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
8664};
8665
[email protected]23e482282013-06-14 16:08:028666TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238667 UseAlternateProtocolForTunneledNpnSpdy) {
[email protected]8e6441ca2010-08-19 05:56:388668 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:038669 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]631f1322010-04-30 17:59:118670
8671 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:428672 proxy_config.set_auto_detect(true);
8673 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:118674
[email protected]631f1322010-04-30 17:59:118675 CapturingProxyResolver* capturing_proxy_resolver =
8676 new CapturingProxyResolver();
[email protected]bb88e1d32013-05-03 23:11:078677 session_deps_.proxy_service.reset(new ProxyService(
[email protected]66761b952010-06-25 21:30:388678 new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver,
8679 NULL));
[email protected]029c83b62013-01-24 05:28:208680 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078681 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:118682
8683 HttpRequestInfo request;
8684 request.method = "GET";
8685 request.url = GURL("http://www.google.com/");
8686 request.load_flags = 0;
8687
[email protected]8a0fc822013-06-27 20:52:438688 std::string alternate_protocol_http_header =
8689 GetAlternateProtocolHttpHeader();
8690
[email protected]631f1322010-04-30 17:59:118691 MockRead data_reads[] = {
8692 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438693 MockRead(alternate_protocol_http_header.c_str()),
[email protected]631f1322010-04-30 17:59:118694 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:178695 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:068696 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:118697 };
8698
8699 StaticSocketDataProvider first_transaction(
8700 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078701 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]631f1322010-04-30 17:59:118702
[email protected]8ddf8322012-02-23 18:08:068703 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:028704 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:078705 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]631f1322010-04-30 17:59:118706
[email protected]cdf8f7e72013-05-23 10:56:468707 scoped_ptr<SpdyFrame> req(
8708 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]631f1322010-04-30 17:59:118709 MockWrite spdy_writes[] = {
8710 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
8711 "Host: www.google.com\r\n"
[email protected]d911f1b2010-05-05 22:39:428712 "Proxy-Connection: keep-alive\r\n\r\n"), // 0
[email protected]cdf8f7e72013-05-23 10:56:468713 CreateMockWrite(*req), // 3
[email protected]631f1322010-04-30 17:59:118714 };
8715
[email protected]d911f1b2010-05-05 22:39:428716 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
8717
[email protected]23e482282013-06-14 16:08:028718 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
8719 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]631f1322010-04-30 17:59:118720 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:068721 MockRead(ASYNC, kCONNECTResponse, arraysize(kCONNECTResponse) - 1, 1), // 1
[email protected]e7f75092010-07-01 22:39:138722 CreateMockRead(*resp.get(), 4), // 2, 4
8723 CreateMockRead(*data.get(), 4), // 5
[email protected]8ddf8322012-02-23 18:08:068724 MockRead(ASYNC, 0, 0, 4), // 6
[email protected]631f1322010-04-30 17:59:118725 };
8726
[email protected]dd54bd82012-07-19 23:44:578727 OrderedSocketData spdy_data(
8728 spdy_reads, arraysize(spdy_reads),
8729 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078730 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:118731
[email protected]d973e99a2012-02-17 21:02:368732 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:558733 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
8734 NULL, 0, NULL, 0);
8735 hanging_non_alternate_protocol_socket.set_connect_data(
8736 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:078737 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:558738 &hanging_non_alternate_protocol_socket);
8739
[email protected]49639fa2011-12-20 23:22:418740 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:118741
[email protected]bb88e1d32013-05-03 23:11:078742 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:368743 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508744 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:118745
[email protected]49639fa2011-12-20 23:22:418746 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:118747 EXPECT_EQ(ERR_IO_PENDING, rv);
8748 EXPECT_EQ(OK, callback.WaitForResult());
8749
8750 const HttpResponseInfo* response = trans->GetResponseInfo();
8751 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508752 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]631f1322010-04-30 17:59:118753 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:538754 EXPECT_FALSE(response->was_fetched_via_spdy);
8755 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:118756
8757 std::string response_data;
8758 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8759 EXPECT_EQ("hello world", response_data);
8760
[email protected]90499482013-06-01 00:39:508761 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:118762
[email protected]49639fa2011-12-20 23:22:418763 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:118764 EXPECT_EQ(ERR_IO_PENDING, rv);
8765 EXPECT_EQ(OK, callback.WaitForResult());
8766
8767 response = trans->GetResponseInfo();
8768 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508769 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]631f1322010-04-30 17:59:118770 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:538771 EXPECT_TRUE(response->was_fetched_via_spdy);
8772 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:118773
8774 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8775 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:558776 ASSERT_EQ(3u, capturing_proxy_resolver->resolved().size());
[email protected]d911f1b2010-05-05 22:39:428777 EXPECT_EQ("http://www.google.com/",
[email protected]631f1322010-04-30 17:59:118778 capturing_proxy_resolver->resolved()[0].spec());
[email protected]d911f1b2010-05-05 22:39:428779 EXPECT_EQ("https://www.google.com/",
8780 capturing_proxy_resolver->resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:118781
[email protected]029c83b62013-01-24 05:28:208782 LoadTimingInfo load_timing_info;
8783 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8784 TestLoadTimingNotReusedWithPac(load_timing_info,
8785 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:118786}
[email protected]631f1322010-04-30 17:59:118787
[email protected]23e482282013-06-14 16:08:028788TEST_P(HttpNetworkTransactionTest,
[email protected]2ff8b312010-04-26 22:20:548789 UseAlternateProtocolForNpnSpdyWithExistingSpdySession) {
[email protected]8e6441ca2010-08-19 05:56:388790 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:038791 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]2ff8b312010-04-26 22:20:548792
8793 HttpRequestInfo request;
8794 request.method = "GET";
8795 request.url = GURL("http://www.google.com/");
8796 request.load_flags = 0;
8797
[email protected]8a0fc822013-06-27 20:52:438798 std::string alternate_protocol_http_header =
8799 GetAlternateProtocolHttpHeader();
8800
[email protected]2ff8b312010-04-26 22:20:548801 MockRead data_reads[] = {
8802 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438803 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2ff8b312010-04-26 22:20:548804 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068805 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:548806 };
8807
8808 StaticSocketDataProvider first_transaction(
8809 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078810 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:548811
[email protected]8ddf8322012-02-23 18:08:068812 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:028813 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:078814 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:548815
[email protected]cdf8f7e72013-05-23 10:56:468816 scoped_ptr<SpdyFrame> req(
8817 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]e7f75092010-07-01 22:39:138818 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
[email protected]2ff8b312010-04-26 22:20:548819
[email protected]23e482282013-06-14 16:08:028820 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
8821 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:548822 MockRead spdy_reads[] = {
[email protected]e7f75092010-07-01 22:39:138823 CreateMockRead(*resp),
8824 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:068825 MockRead(ASYNC, 0, 0),
[email protected]2ff8b312010-04-26 22:20:548826 };
8827
[email protected]dd54bd82012-07-19 23:44:578828 DelayedSocketData spdy_data(
8829 1, // wait for one write to finish before reading.
8830 spdy_reads, arraysize(spdy_reads),
8831 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078832 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:548833
[email protected]83039bb2011-12-09 18:43:558834 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:548835
[email protected]bb88e1d32013-05-03 23:11:078836 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:548837
[email protected]262eec82013-03-19 21:01:368838 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508839 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:548840
[email protected]49639fa2011-12-20 23:22:418841 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:548842 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:418843 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:548844
8845 const HttpResponseInfo* response = trans->GetResponseInfo();
8846 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508847 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:548848 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8849
8850 std::string response_data;
8851 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8852 EXPECT_EQ("hello world", response_data);
8853
8854 // Set up an initial SpdySession in the pool to reuse.
[email protected]02b0c342010-09-25 21:09:388855 HostPortPair host_port_pair("www.google.com", 443);
[email protected]e6d017652013-05-17 18:01:408856 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
8857 kPrivacyModeDisabled);
[email protected]2ff8b312010-04-26 22:20:548858 scoped_refptr<SpdySession> spdy_session =
[email protected]e6d017652013-05-17 18:01:408859 session->spdy_session_pool()->Get(key, BoundNetLog());
[email protected]ab739042011-04-07 15:22:288860 scoped_refptr<TransportSocketParams> transport_params(
[email protected]d2b5f092012-06-08 23:55:028861 new TransportSocketParams(host_port_pair, MEDIUM, false, false,
8862 OnHostResolutionCallback()));
[email protected]02b0c342010-09-25 21:09:388863
8864 scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
8865 EXPECT_EQ(ERR_IO_PENDING,
[email protected]ab739042011-04-07 15:22:288866 connection->Init(host_port_pair.ToString(),
8867 transport_params,
8868 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:528869 callback.callback(),
[email protected]e5c026642012-03-17 00:14:028870 session->GetTransportSocketPool(
8871 HttpNetworkSession::NORMAL_SOCKET_POOL),
[email protected]02b0c342010-09-25 21:09:388872 BoundNetLog()));
[email protected]6ecf2b92011-12-15 01:14:528873 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]02b0c342010-09-25 21:09:388874
8875 SSLConfig ssl_config;
8876 session->ssl_config_service()->GetSSLConfig(&ssl_config);
[email protected]9e1bdd32011-02-03 21:48:348877 scoped_ptr<ClientSocketHandle> ssl_connection(new ClientSocketHandle);
[email protected]feb79bcd2011-07-21 16:55:178878 SSLClientSocketContext context;
[email protected]bb88e1d32013-05-03 23:11:078879 context.cert_verifier = session_deps_.cert_verifier.get();
[email protected]b1c988b2013-06-13 06:48:118880 context.transport_security_state =
8881 session_deps_.transport_security_state.get();
[email protected]bb88e1d32013-05-03 23:11:078882 ssl_connection->set_socket(
8883 session_deps_.socket_factory->CreateSSLClientSocket(
8884 connection.release(),
8885 HostPortPair(std::string(), 443),
8886 ssl_config,
8887 context));
[email protected]83039bb2011-12-09 18:43:558888 EXPECT_EQ(ERR_IO_PENDING,
8889 ssl_connection->socket()->Connect(callback.callback()));
[email protected]02b0c342010-09-25 21:09:388890 EXPECT_EQ(OK, callback.WaitForResult());
8891
[email protected]9e1bdd32011-02-03 21:48:348892 EXPECT_EQ(OK, spdy_session->InitializeWithSocket(ssl_connection.release(),
[email protected]02b0c342010-09-25 21:09:388893 true, OK));
8894
[email protected]90499482013-06-01 00:39:508895 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:548896
[email protected]49639fa2011-12-20 23:22:418897 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:548898 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:418899 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:548900
8901 response = trans->GetResponseInfo();
8902 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508903 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:548904 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:538905 EXPECT_TRUE(response->was_fetched_via_spdy);
8906 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:548907
8908 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8909 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:428910}
8911
[email protected]044de0642010-06-17 10:42:158912// GenerateAuthToken is a mighty big test.
8913// It tests all permutation of GenerateAuthToken behavior:
8914// - Synchronous and Asynchronous completion.
8915// - OK or error on completion.
8916// - Direct connection, non-authenticating proxy, and authenticating proxy.
8917// - HTTP or HTTPS backend (to include proxy tunneling).
8918// - Non-authenticating and authenticating backend.
8919//
[email protected]fe3b7dc2012-02-03 19:52:098920// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:158921// problems generating an auth token for an authenticating proxy, we don't
8922// need to test all permutations of the backend server).
8923//
8924// The test proceeds by going over each of the configuration cases, and
8925// potentially running up to three rounds in each of the tests. The TestConfig
8926// specifies both the configuration for the test as well as the expectations
8927// for the results.
[email protected]23e482282013-06-14 16:08:028928TEST_P(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:508929 static const char kServer[] = "http://www.example.com";
8930 static const char kSecureServer[] = "https://www.example.com";
8931 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:158932 const int kAuthErr = ERR_INVALID_AUTH_CREDENTIALS;
8933
8934 enum AuthTiming {
8935 AUTH_NONE,
8936 AUTH_SYNC,
8937 AUTH_ASYNC,
8938 };
8939
8940 const MockWrite kGet(
8941 "GET / HTTP/1.1\r\n"
8942 "Host: www.example.com\r\n"
8943 "Connection: keep-alive\r\n\r\n");
8944 const MockWrite kGetProxy(
8945 "GET http://www.example.com/ HTTP/1.1\r\n"
8946 "Host: www.example.com\r\n"
8947 "Proxy-Connection: keep-alive\r\n\r\n");
8948 const MockWrite kGetAuth(
8949 "GET / HTTP/1.1\r\n"
8950 "Host: www.example.com\r\n"
8951 "Connection: keep-alive\r\n"
8952 "Authorization: auth_token\r\n\r\n");
8953 const MockWrite kGetProxyAuth(
8954 "GET http://www.example.com/ HTTP/1.1\r\n"
8955 "Host: www.example.com\r\n"
8956 "Proxy-Connection: keep-alive\r\n"
8957 "Proxy-Authorization: auth_token\r\n\r\n");
8958 const MockWrite kGetAuthThroughProxy(
8959 "GET http://www.example.com/ HTTP/1.1\r\n"
8960 "Host: www.example.com\r\n"
8961 "Proxy-Connection: keep-alive\r\n"
8962 "Authorization: auth_token\r\n\r\n");
8963 const MockWrite kGetAuthWithProxyAuth(
8964 "GET http://www.example.com/ HTTP/1.1\r\n"
8965 "Host: www.example.com\r\n"
8966 "Proxy-Connection: keep-alive\r\n"
8967 "Proxy-Authorization: auth_token\r\n"
8968 "Authorization: auth_token\r\n\r\n");
8969 const MockWrite kConnect(
8970 "CONNECT www.example.com:443 HTTP/1.1\r\n"
8971 "Host: www.example.com\r\n"
8972 "Proxy-Connection: keep-alive\r\n\r\n");
8973 const MockWrite kConnectProxyAuth(
8974 "CONNECT www.example.com:443 HTTP/1.1\r\n"
8975 "Host: www.example.com\r\n"
8976 "Proxy-Connection: keep-alive\r\n"
8977 "Proxy-Authorization: auth_token\r\n\r\n");
8978
8979 const MockRead kSuccess(
8980 "HTTP/1.1 200 OK\r\n"
8981 "Content-Type: text/html; charset=iso-8859-1\r\n"
8982 "Content-Length: 3\r\n\r\n"
8983 "Yes");
8984 const MockRead kFailure(
8985 "Should not be called.");
8986 const MockRead kServerChallenge(
8987 "HTTP/1.1 401 Unauthorized\r\n"
8988 "WWW-Authenticate: Mock realm=server\r\n"
8989 "Content-Type: text/html; charset=iso-8859-1\r\n"
8990 "Content-Length: 14\r\n\r\n"
8991 "Unauthorized\r\n");
8992 const MockRead kProxyChallenge(
8993 "HTTP/1.1 407 Unauthorized\r\n"
8994 "Proxy-Authenticate: Mock realm=proxy\r\n"
8995 "Proxy-Connection: close\r\n"
8996 "Content-Type: text/html; charset=iso-8859-1\r\n"
8997 "Content-Length: 14\r\n\r\n"
8998 "Unauthorized\r\n");
8999 const MockRead kProxyConnected(
9000 "HTTP/1.1 200 Connection Established\r\n\r\n");
9001
9002 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
9003 // no constructors, but the C++ compiler on Windows warns about
9004 // unspecified data in compound literals. So, moved to using constructors,
9005 // and TestRound's created with the default constructor should not be used.
9006 struct TestRound {
9007 TestRound()
9008 : expected_rv(ERR_UNEXPECTED),
9009 extra_write(NULL),
9010 extra_read(NULL) {
9011 }
9012 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
9013 int expected_rv_arg)
9014 : write(write_arg),
9015 read(read_arg),
9016 expected_rv(expected_rv_arg),
9017 extra_write(NULL),
9018 extra_read(NULL) {
9019 }
9020 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
9021 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:019022 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:159023 : write(write_arg),
9024 read(read_arg),
9025 expected_rv(expected_rv_arg),
9026 extra_write(extra_write_arg),
9027 extra_read(extra_read_arg) {
9028 }
9029 MockWrite write;
9030 MockRead read;
9031 int expected_rv;
9032 const MockWrite* extra_write;
9033 const MockRead* extra_read;
9034 };
9035
9036 static const int kNoSSL = 500;
9037
9038 struct TestConfig {
9039 const char* proxy_url;
9040 AuthTiming proxy_auth_timing;
9041 int proxy_auth_rv;
9042 const char* server_url;
9043 AuthTiming server_auth_timing;
9044 int server_auth_rv;
9045 int num_auth_rounds;
9046 int first_ssl_round;
9047 TestRound rounds[3];
9048 } test_configs[] = {
9049 // Non-authenticating HTTP server with a direct connection.
9050 { NULL, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
9051 { TestRound(kGet, kSuccess, OK)}},
9052 // Authenticating HTTP server with a direct connection.
9053 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
9054 { TestRound(kGet, kServerChallenge, OK),
9055 TestRound(kGetAuth, kSuccess, OK)}},
9056 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
9057 { TestRound(kGet, kServerChallenge, OK),
9058 TestRound(kGetAuth, kFailure, kAuthErr)}},
9059 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
9060 { TestRound(kGet, kServerChallenge, OK),
9061 TestRound(kGetAuth, kSuccess, OK)}},
9062 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
9063 { TestRound(kGet, kServerChallenge, OK),
9064 TestRound(kGetAuth, kFailure, kAuthErr)}},
9065 // Non-authenticating HTTP server through a non-authenticating proxy.
9066 { kProxy, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
9067 { TestRound(kGetProxy, kSuccess, OK)}},
9068 // Authenticating HTTP server through a non-authenticating proxy.
9069 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
9070 { TestRound(kGetProxy, kServerChallenge, OK),
9071 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
9072 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
9073 { TestRound(kGetProxy, kServerChallenge, OK),
9074 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
9075 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
9076 { TestRound(kGetProxy, kServerChallenge, OK),
9077 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
9078 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
9079 { TestRound(kGetProxy, kServerChallenge, OK),
9080 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
9081 // Non-authenticating HTTP server through an authenticating proxy.
9082 { kProxy, AUTH_SYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
9083 { TestRound(kGetProxy, kProxyChallenge, OK),
9084 TestRound(kGetProxyAuth, kSuccess, OK)}},
9085 { kProxy, AUTH_SYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
9086 { TestRound(kGetProxy, kProxyChallenge, OK),
9087 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
9088 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
9089 { TestRound(kGetProxy, kProxyChallenge, OK),
9090 TestRound(kGetProxyAuth, kSuccess, OK)}},
9091 { kProxy, AUTH_ASYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
9092 { TestRound(kGetProxy, kProxyChallenge, OK),
9093 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
9094 // Authenticating HTTP server through an authenticating proxy.
9095 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
9096 { TestRound(kGetProxy, kProxyChallenge, OK),
9097 TestRound(kGetProxyAuth, kServerChallenge, OK),
9098 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9099 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
9100 { TestRound(kGetProxy, kProxyChallenge, OK),
9101 TestRound(kGetProxyAuth, kServerChallenge, OK),
9102 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9103 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
9104 { TestRound(kGetProxy, kProxyChallenge, OK),
9105 TestRound(kGetProxyAuth, kServerChallenge, OK),
9106 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9107 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
9108 { TestRound(kGetProxy, kProxyChallenge, OK),
9109 TestRound(kGetProxyAuth, kServerChallenge, OK),
9110 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9111 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
9112 { TestRound(kGetProxy, kProxyChallenge, OK),
9113 TestRound(kGetProxyAuth, kServerChallenge, OK),
9114 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9115 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
9116 { TestRound(kGetProxy, kProxyChallenge, OK),
9117 TestRound(kGetProxyAuth, kServerChallenge, OK),
9118 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9119 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
9120 { TestRound(kGetProxy, kProxyChallenge, OK),
9121 TestRound(kGetProxyAuth, kServerChallenge, OK),
9122 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9123 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
9124 { TestRound(kGetProxy, kProxyChallenge, OK),
9125 TestRound(kGetProxyAuth, kServerChallenge, OK),
9126 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9127 // Non-authenticating HTTPS server with a direct connection.
9128 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
9129 { TestRound(kGet, kSuccess, OK)}},
9130 // Authenticating HTTPS server with a direct connection.
9131 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
9132 { TestRound(kGet, kServerChallenge, OK),
9133 TestRound(kGetAuth, kSuccess, OK)}},
9134 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
9135 { TestRound(kGet, kServerChallenge, OK),
9136 TestRound(kGetAuth, kFailure, kAuthErr)}},
9137 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
9138 { TestRound(kGet, kServerChallenge, OK),
9139 TestRound(kGetAuth, kSuccess, OK)}},
9140 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
9141 { TestRound(kGet, kServerChallenge, OK),
9142 TestRound(kGetAuth, kFailure, kAuthErr)}},
9143 // Non-authenticating HTTPS server with a non-authenticating proxy.
9144 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
9145 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
9146 // Authenticating HTTPS server through a non-authenticating proxy.
9147 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
9148 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9149 TestRound(kGetAuth, kSuccess, OK)}},
9150 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
9151 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9152 TestRound(kGetAuth, kFailure, kAuthErr)}},
9153 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
9154 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9155 TestRound(kGetAuth, kSuccess, OK)}},
9156 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
9157 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9158 TestRound(kGetAuth, kFailure, kAuthErr)}},
9159 // Non-Authenticating HTTPS server through an authenticating proxy.
9160 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
9161 { TestRound(kConnect, kProxyChallenge, OK),
9162 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
9163 { kProxy, AUTH_SYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
9164 { TestRound(kConnect, kProxyChallenge, OK),
9165 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
9166 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
9167 { TestRound(kConnect, kProxyChallenge, OK),
9168 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
9169 { kProxy, AUTH_ASYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
9170 { TestRound(kConnect, kProxyChallenge, OK),
9171 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
9172 // Authenticating HTTPS server through an authenticating proxy.
9173 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
9174 { TestRound(kConnect, kProxyChallenge, OK),
9175 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9176 &kGet, &kServerChallenge),
9177 TestRound(kGetAuth, kSuccess, OK)}},
9178 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
9179 { TestRound(kConnect, kProxyChallenge, OK),
9180 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9181 &kGet, &kServerChallenge),
9182 TestRound(kGetAuth, kFailure, kAuthErr)}},
9183 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
9184 { TestRound(kConnect, kProxyChallenge, OK),
9185 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9186 &kGet, &kServerChallenge),
9187 TestRound(kGetAuth, kSuccess, OK)}},
9188 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
9189 { TestRound(kConnect, kProxyChallenge, OK),
9190 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9191 &kGet, &kServerChallenge),
9192 TestRound(kGetAuth, kFailure, kAuthErr)}},
9193 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
9194 { TestRound(kConnect, kProxyChallenge, OK),
9195 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9196 &kGet, &kServerChallenge),
9197 TestRound(kGetAuth, kSuccess, OK)}},
9198 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
9199 { TestRound(kConnect, kProxyChallenge, OK),
9200 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9201 &kGet, &kServerChallenge),
9202 TestRound(kGetAuth, kFailure, kAuthErr)}},
9203 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
9204 { TestRound(kConnect, kProxyChallenge, OK),
9205 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9206 &kGet, &kServerChallenge),
9207 TestRound(kGetAuth, kSuccess, OK)}},
9208 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
9209 { TestRound(kConnect, kProxyChallenge, OK),
9210 TestRound(kConnectProxyAuth, kProxyConnected, OK,
9211 &kGet, &kServerChallenge),
9212 TestRound(kGetAuth, kFailure, kAuthErr)}},
9213 };
9214
[email protected]044de0642010-06-17 10:42:159215 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_configs); ++i) {
[email protected]2d01c262011-08-11 23:07:089216 HttpAuthHandlerMock::Factory* auth_factory(
9217 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:079218 session_deps_.http_auth_handler_factory.reset(auth_factory);
[email protected]044de0642010-06-17 10:42:159219 const TestConfig& test_config = test_configs[i];
[email protected]65d34382010-07-01 18:12:269220
9221 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:159222 if (test_config.proxy_auth_timing != AUTH_NONE) {
[email protected]2d01c262011-08-11 23:07:089223 for (int n = 0; n < 2; n++) {
9224 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
9225 std::string auth_challenge = "Mock realm=proxy";
9226 GURL origin(test_config.proxy_url);
9227 HttpAuth::ChallengeTokenizer tokenizer(auth_challenge.begin(),
9228 auth_challenge.end());
9229 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
9230 origin, BoundNetLog());
9231 auth_handler->SetGenerateExpectation(
9232 test_config.proxy_auth_timing == AUTH_ASYNC,
9233 test_config.proxy_auth_rv);
9234 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
9235 }
[email protected]044de0642010-06-17 10:42:159236 }
9237 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:009238 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:159239 std::string auth_challenge = "Mock realm=server";
9240 GURL origin(test_config.server_url);
9241 HttpAuth::ChallengeTokenizer tokenizer(auth_challenge.begin(),
9242 auth_challenge.end());
9243 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
9244 origin, BoundNetLog());
9245 auth_handler->SetGenerateExpectation(
9246 test_config.server_auth_timing == AUTH_ASYNC,
9247 test_config.server_auth_rv);
[email protected]2d01c262011-08-11 23:07:089248 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:159249 }
9250 if (test_config.proxy_url) {
[email protected]bb88e1d32013-05-03 23:11:079251 session_deps_.proxy_service.reset(
[email protected]6104ea5d2011-04-27 21:37:129252 ProxyService::CreateFixed(test_config.proxy_url));
[email protected]044de0642010-06-17 10:42:159253 } else {
[email protected]bb88e1d32013-05-03 23:11:079254 session_deps_.proxy_service.reset(ProxyService::CreateDirect());
[email protected]044de0642010-06-17 10:42:159255 }
9256
9257 HttpRequestInfo request;
9258 request.method = "GET";
9259 request.url = GURL(test_config.server_url);
9260 request.load_flags = 0;
9261
[email protected]bb88e1d32013-05-03 23:11:079262 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369263 HttpNetworkTransaction trans(
[email protected]bb88e1d32013-05-03 23:11:079264 DEFAULT_PRIORITY, CreateSession(&session_deps_));
[email protected]044de0642010-06-17 10:42:159265
9266 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
9267 const TestRound& read_write_round = test_config.rounds[round];
9268
9269 // Set up expected reads and writes.
9270 MockRead reads[2];
9271 reads[0] = read_write_round.read;
9272 size_t length_reads = 1;
9273 if (read_write_round.extra_read) {
9274 reads[1] = *read_write_round.extra_read;
9275 length_reads = 2;
9276 }
9277
9278 MockWrite writes[2];
9279 writes[0] = read_write_round.write;
9280 size_t length_writes = 1;
9281 if (read_write_round.extra_write) {
9282 writes[1] = *read_write_round.extra_write;
9283 length_writes = 2;
9284 }
9285 StaticSocketDataProvider data_provider(
9286 reads, length_reads, writes, length_writes);
[email protected]bb88e1d32013-05-03 23:11:079287 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]044de0642010-06-17 10:42:159288
9289 // Add an SSL sequence if necessary.
[email protected]8ddf8322012-02-23 18:08:069290 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
[email protected]044de0642010-06-17 10:42:159291 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:079292 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:159293 &ssl_socket_data_provider);
9294
9295 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:419296 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:159297 int rv;
9298 if (round == 0) {
[email protected]49639fa2011-12-20 23:22:419299 rv = trans.Start(&request, callback.callback(), BoundNetLog());
[email protected]044de0642010-06-17 10:42:159300 } else {
[email protected]49639fa2011-12-20 23:22:419301 rv = trans.RestartWithAuth(
9302 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:159303 }
9304 if (rv == ERR_IO_PENDING)
9305 rv = callback.WaitForResult();
9306
9307 // Compare results with expected data.
9308 EXPECT_EQ(read_write_round.expected_rv, rv);
[email protected]0b0bf032010-09-21 18:08:509309 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]044de0642010-06-17 10:42:159310 if (read_write_round.expected_rv == OK) {
[email protected]fe2255a2011-09-20 19:37:509311 ASSERT_TRUE(response != NULL);
[email protected]044de0642010-06-17 10:42:159312 } else {
9313 EXPECT_TRUE(response == NULL);
9314 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
9315 continue;
9316 }
9317 if (round + 1 < test_config.num_auth_rounds) {
9318 EXPECT_FALSE(response->auth_challenge.get() == NULL);
9319 } else {
9320 EXPECT_TRUE(response->auth_challenge.get() == NULL);
9321 }
9322 }
[email protected]e5ae96a2010-04-14 20:12:459323 }
9324}
9325
[email protected]23e482282013-06-14 16:08:029326TEST_P(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:149327 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:149328 HttpAuthHandlerMock::Factory* auth_factory(
9329 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:079330 session_deps_.http_auth_handler_factory.reset(auth_factory);
9331 session_deps_.proxy_service.reset(ProxyService::CreateDirect());
9332 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
9333 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:149334
9335 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
9336 auth_handler->set_connection_based(true);
9337 std::string auth_challenge = "Mock realm=server";
9338 GURL origin("http://www.example.com");
9339 HttpAuth::ChallengeTokenizer tokenizer(auth_challenge.begin(),
9340 auth_challenge.end());
9341 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
9342 origin, BoundNetLog());
[email protected]2d01c262011-08-11 23:07:089343 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:149344
[email protected]c871bce92010-07-15 21:51:149345 int rv = OK;
9346 const HttpResponseInfo* response = NULL;
9347 HttpRequestInfo request;
9348 request.method = "GET";
9349 request.url = origin;
9350 request.load_flags = 0;
[email protected]cb9bf6ca2011-01-28 13:15:279351
[email protected]bb88e1d32013-05-03 23:11:079352 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:109353
9354 // Use a TCP Socket Pool with only one connection per group. This is used
9355 // to validate that the TCP socket is not released to the pool between
9356 // each round of multi-round authentication.
9357 HttpNetworkSessionPeer session_peer(session);
[email protected]ab739042011-04-07 15:22:289358 ClientSocketPoolHistograms transport_pool_histograms("SmallTCP");
9359 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:109360 50, // Max sockets for pool
9361 1, // Max sockets per group
[email protected]ab739042011-04-07 15:22:289362 &transport_pool_histograms,
[email protected]bb88e1d32013-05-03 23:11:079363 session_deps_.host_resolver.get(),
9364 session_deps_.socket_factory.get(),
9365 session_deps_.net_log);
[email protected]a42dbd142011-11-17 16:42:029366 MockClientSocketPoolManager* mock_pool_manager =
9367 new MockClientSocketPoolManager;
9368 mock_pool_manager->SetTransportSocketPool(transport_pool);
9369 session_peer.SetClientSocketPoolManager(mock_pool_manager);
[email protected]7ef4cbbb2011-02-06 11:19:109370
[email protected]262eec82013-03-19 21:01:369371 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509372 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419373 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:149374
9375 const MockWrite kGet(
9376 "GET / HTTP/1.1\r\n"
9377 "Host: www.example.com\r\n"
9378 "Connection: keep-alive\r\n\r\n");
9379 const MockWrite kGetAuth(
9380 "GET / HTTP/1.1\r\n"
9381 "Host: www.example.com\r\n"
9382 "Connection: keep-alive\r\n"
9383 "Authorization: auth_token\r\n\r\n");
9384
9385 const MockRead kServerChallenge(
9386 "HTTP/1.1 401 Unauthorized\r\n"
9387 "WWW-Authenticate: Mock realm=server\r\n"
9388 "Content-Type: text/html; charset=iso-8859-1\r\n"
9389 "Content-Length: 14\r\n\r\n"
9390 "Unauthorized\r\n");
9391 const MockRead kSuccess(
9392 "HTTP/1.1 200 OK\r\n"
9393 "Content-Type: text/html; charset=iso-8859-1\r\n"
9394 "Content-Length: 3\r\n\r\n"
9395 "Yes");
9396
9397 MockWrite writes[] = {
9398 // First round
9399 kGet,
9400 // Second round
9401 kGetAuth,
9402 // Third round
9403 kGetAuth,
[email protected]eca50e122010-09-11 14:03:309404 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:109405 kGetAuth,
9406 // Competing request
9407 kGet,
[email protected]c871bce92010-07-15 21:51:149408 };
9409 MockRead reads[] = {
9410 // First round
9411 kServerChallenge,
9412 // Second round
9413 kServerChallenge,
9414 // Third round
[email protected]eca50e122010-09-11 14:03:309415 kServerChallenge,
9416 // Fourth round
[email protected]c871bce92010-07-15 21:51:149417 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:109418 // Competing response
9419 kSuccess,
[email protected]c871bce92010-07-15 21:51:149420 };
9421 StaticSocketDataProvider data_provider(reads, arraysize(reads),
9422 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:079423 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:149424
[email protected]7ef4cbbb2011-02-06 11:19:109425 const char* const kSocketGroup = "www.example.com:80";
9426
9427 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:149428 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:419429 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]c871bce92010-07-15 21:51:149430 if (rv == ERR_IO_PENDING)
9431 rv = callback.WaitForResult();
9432 EXPECT_EQ(OK, rv);
9433 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509434 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:149435 EXPECT_FALSE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:289436 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:149437
[email protected]7ef4cbbb2011-02-06 11:19:109438 // In between rounds, another request comes in for the same domain.
9439 // It should not be able to grab the TCP socket that trans has already
9440 // claimed.
9441 scoped_ptr<HttpTransaction> trans_compete(
[email protected]90499482013-06-01 00:39:509442 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419443 TestCompletionCallback callback_compete;
9444 rv = trans_compete->Start(
9445 &request, callback_compete.callback(), BoundNetLog());
[email protected]7ef4cbbb2011-02-06 11:19:109446 EXPECT_EQ(ERR_IO_PENDING, rv);
9447 // callback_compete.WaitForResult at this point would stall forever,
9448 // since the HttpNetworkTransaction does not release the request back to
9449 // the pool until after authentication completes.
9450
9451 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:149452 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:419453 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:149454 if (rv == ERR_IO_PENDING)
9455 rv = callback.WaitForResult();
9456 EXPECT_EQ(OK, rv);
9457 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509458 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:149459 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:289460 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:149461
[email protected]7ef4cbbb2011-02-06 11:19:109462 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:149463 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:419464 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:149465 if (rv == ERR_IO_PENDING)
9466 rv = callback.WaitForResult();
9467 EXPECT_EQ(OK, rv);
9468 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509469 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:149470 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:289471 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]eca50e122010-09-11 14:03:309472
[email protected]7ef4cbbb2011-02-06 11:19:109473 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:309474 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:419475 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:309476 if (rv == ERR_IO_PENDING)
9477 rv = callback.WaitForResult();
9478 EXPECT_EQ(OK, rv);
9479 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509480 ASSERT_TRUE(response != NULL);
[email protected]eca50e122010-09-11 14:03:309481 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:289482 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:109483
9484 // Read the body since the fourth round was successful. This will also
9485 // release the socket back to the pool.
9486 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
[email protected]90499482013-06-01 00:39:509487 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:109488 if (rv == ERR_IO_PENDING)
9489 rv = callback.WaitForResult();
9490 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:509491 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:109492 EXPECT_EQ(0, rv);
9493 // There are still 0 idle sockets, since the trans_compete transaction
9494 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:289495 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:109496
9497 // The competing request can now finish. Wait for the headers and then
9498 // read the body.
9499 rv = callback_compete.WaitForResult();
9500 EXPECT_EQ(OK, rv);
[email protected]90499482013-06-01 00:39:509501 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:109502 if (rv == ERR_IO_PENDING)
9503 rv = callback.WaitForResult();
9504 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:509505 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:109506 EXPECT_EQ(0, rv);
9507
9508 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:289509 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:149510}
9511
[email protected]65041fa2010-05-21 06:56:539512// This tests the case that a request is issued via http instead of spdy after
9513// npn is negotiated.
[email protected]23e482282013-06-14 16:08:029514TEST_P(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]8e6441ca2010-08-19 05:56:389515 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:039516 HttpStreamFactory::SetNextProtos(
[email protected]5285d972011-10-18 18:56:349517 MakeNextProtos("http/1.1", "http1.1", NULL));
[email protected]65041fa2010-05-21 06:56:539518 HttpRequestInfo request;
9519 request.method = "GET";
9520 request.url = GURL("https://www.google.com/");
9521 request.load_flags = 0;
9522
9523 MockWrite data_writes[] = {
9524 MockWrite("GET / HTTP/1.1\r\n"
9525 "Host: www.google.com\r\n"
9526 "Connection: keep-alive\r\n\r\n"),
9527 };
9528
[email protected]8a0fc822013-06-27 20:52:439529 std::string alternate_protocol_http_header =
9530 GetAlternateProtocolHttpHeader();
9531
[email protected]65041fa2010-05-21 06:56:539532 MockRead data_reads[] = {
9533 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439534 MockRead(alternate_protocol_http_header.c_str()),
[email protected]65041fa2010-05-21 06:56:539535 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069536 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:539537 };
9538
[email protected]8ddf8322012-02-23 18:08:069539 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]65041fa2010-05-21 06:56:539540 ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
9541 ssl.next_proto = "http/1.1";
[email protected]8e3c78cb2012-03-31 03:58:469542 ssl.protocol_negotiated = kProtoHTTP11;
[email protected]65041fa2010-05-21 06:56:539543
[email protected]bb88e1d32013-05-03 23:11:079544 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:539545
9546 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9547 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079548 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:539549
[email protected]49639fa2011-12-20 23:22:419550 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:539551
[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]65041fa2010-05-21 06:56:539555
[email protected]49639fa2011-12-20 23:22:419556 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]65041fa2010-05-21 06:56:539557
9558 EXPECT_EQ(ERR_IO_PENDING, rv);
9559 EXPECT_EQ(OK, callback.WaitForResult());
9560
9561 const HttpResponseInfo* response = trans->GetResponseInfo();
9562 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509563 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]65041fa2010-05-21 06:56:539564 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9565
9566 std::string response_data;
9567 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9568 EXPECT_EQ("hello world", response_data);
9569
9570 EXPECT_FALSE(response->was_fetched_via_spdy);
9571 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]65041fa2010-05-21 06:56:539572}
[email protected]26ef6582010-06-24 02:30:479573
[email protected]23e482282013-06-14 16:08:029574TEST_P(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:479575 // Simulate the SSL handshake completing with an NPN negotiation
9576 // followed by an immediate server closing of the socket.
9577 // Fix crash: http://crbug.com/46369
[email protected]8e6441ca2010-08-19 05:56:389578 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:039579 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]26ef6582010-06-24 02:30:479580
9581 HttpRequestInfo request;
9582 request.method = "GET";
9583 request.url = GURL("https://www.google.com/");
9584 request.load_flags = 0;
9585
[email protected]8ddf8322012-02-23 18:08:069586 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029587 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:079588 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:479589
[email protected]cdf8f7e72013-05-23 10:56:469590 scoped_ptr<SpdyFrame> req(
9591 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]e7f75092010-07-01 22:39:139592 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
[email protected]26ef6582010-06-24 02:30:479593
9594 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:069595 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:479596 };
9597
[email protected]dd54bd82012-07-19 23:44:579598 DelayedSocketData spdy_data(
9599 0, // don't wait in this case, immediate hangup.
9600 spdy_reads, arraysize(spdy_reads),
9601 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079602 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:479603
[email protected]49639fa2011-12-20 23:22:419604 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:479605
[email protected]bb88e1d32013-05-03 23:11:079606 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369607 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509608 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]26ef6582010-06-24 02:30:479609
[email protected]49639fa2011-12-20 23:22:419610 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]26ef6582010-06-24 02:30:479611 EXPECT_EQ(ERR_IO_PENDING, rv);
9612 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult());
[email protected]26ef6582010-06-24 02:30:479613}
[email protected]65d34382010-07-01 18:12:269614
[email protected]23e482282013-06-14 16:08:029615TEST_P(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) {
[email protected]f45c1ee2010-08-03 00:54:309616 // This test ensures that the URL passed into the proxy is upgraded
9617 // to https when doing an Alternate Protocol upgrade.
[email protected]8e6441ca2010-08-19 05:56:389618 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]8a0fc822013-06-27 20:52:439619 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]f45c1ee2010-08-03 00:54:309620
[email protected]bb88e1d32013-05-03 23:11:079621 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:209622 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
9623 CapturingNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079624 session_deps_.net_log = &net_log;
[email protected]f45c1ee2010-08-03 00:54:309625 HttpAuthHandlerMock::Factory* auth_factory =
9626 new HttpAuthHandlerMock::Factory();
[email protected]767257802011-12-14 17:33:189627 HttpAuthHandlerMock* auth_handler = new HttpAuthHandlerMock();
9628 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
[email protected]f45c1ee2010-08-03 00:54:309629 auth_factory->set_do_init_from_challenge(true);
[email protected]bb88e1d32013-05-03 23:11:079630 session_deps_.http_auth_handler_factory.reset(auth_factory);
[email protected]f45c1ee2010-08-03 00:54:309631
9632 HttpRequestInfo request;
9633 request.method = "GET";
9634 request.url = GURL("http://www.google.com");
9635 request.load_flags = 0;
9636
9637 // First round goes unauthenticated through the proxy.
9638 MockWrite data_writes_1[] = {
9639 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
9640 "Host: www.google.com\r\n"
9641 "Proxy-Connection: keep-alive\r\n"
9642 "\r\n"),
9643 };
9644 MockRead data_reads_1[] = {
[email protected]8ddf8322012-02-23 18:08:069645 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]f45c1ee2010-08-03 00:54:309646 MockRead("HTTP/1.1 200 OK\r\n"
[email protected]448d4ca52012-03-04 04:12:239647 "Alternate-Protocol: 443:npn-spdy/2\r\n"
[email protected]f45c1ee2010-08-03 00:54:309648 "Proxy-Connection: close\r\n"
9649 "\r\n"),
9650 };
9651 StaticSocketDataProvider data_1(data_reads_1, arraysize(data_reads_1),
9652 data_writes_1, arraysize(data_writes_1));
9653
9654 // Second round tries to tunnel to www.google.com due to the
9655 // Alternate-Protocol announcement in the first round. It fails due
9656 // to a proxy authentication challenge.
[email protected]394816e92010-08-03 07:38:599657 // After the failure, a tunnel is established to www.google.com using
9658 // Proxy-Authorization headers. There is then a SPDY request round.
9659 //
[email protected]fe3b7dc2012-02-03 19:52:099660 // NOTE: Despite the "Proxy-Connection: Close", these are done on the
9661 // same MockTCPClientSocket since the underlying HttpNetworkClientSocket
9662 // does a Disconnect and Connect on the same socket, rather than trying
9663 // to obtain a new one.
9664 //
[email protected]394816e92010-08-03 07:38:599665 // NOTE: Originally, the proxy response to the second CONNECT request
9666 // simply returned another 407 so the unit test could skip the SSL connection
9667 // establishment and SPDY framing issues. Alas, the
9668 // retry-http-when-alternate-protocol fails logic kicks in, which was more
[email protected]f45c1ee2010-08-03 00:54:309669 // complicated to set up expectations for than the SPDY session.
[email protected]394816e92010-08-03 07:38:599670
[email protected]cdf8f7e72013-05-23 10:56:469671 scoped_ptr<SpdyFrame> req(
9672 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]23e482282013-06-14 16:08:029673 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9674 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]f45c1ee2010-08-03 00:54:309675
[email protected]394816e92010-08-03 07:38:599676 MockWrite data_writes_2[] = {
9677 // First connection attempt without Proxy-Authorization.
9678 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
9679 "Host: www.google.com\r\n"
9680 "Proxy-Connection: keep-alive\r\n"
9681 "\r\n"),
9682
9683 // Second connection attempt with Proxy-Authorization.
[email protected]f45c1ee2010-08-03 00:54:309684 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
9685 "Host: www.google.com\r\n"
9686 "Proxy-Connection: keep-alive\r\n"
9687 "Proxy-Authorization: auth_token\r\n"
9688 "\r\n"),
[email protected]f45c1ee2010-08-03 00:54:309689
[email protected]394816e92010-08-03 07:38:599690 // SPDY request
9691 CreateMockWrite(*req),
[email protected]f45c1ee2010-08-03 00:54:309692 };
[email protected]394816e92010-08-03 07:38:599693 const char kRejectConnectResponse[] = ("HTTP/1.1 407 Unauthorized\r\n"
9694 "Proxy-Authenticate: Mock\r\n"
9695 "Proxy-Connection: close\r\n"
9696 "\r\n");
9697 const char kAcceptConnectResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
9698 MockRead data_reads_2[] = {
9699 // First connection attempt fails
[email protected]8ddf8322012-02-23 18:08:069700 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ, 1),
9701 MockRead(ASYNC, kRejectConnectResponse,
[email protected]394816e92010-08-03 07:38:599702 arraysize(kRejectConnectResponse) - 1, 1),
9703
9704 // Second connection attempt passes
[email protected]8ddf8322012-02-23 18:08:069705 MockRead(ASYNC, kAcceptConnectResponse,
[email protected]fe3b7dc2012-02-03 19:52:099706 arraysize(kAcceptConnectResponse) -1, 4),
[email protected]394816e92010-08-03 07:38:599707
9708 // SPDY response
[email protected]fe3b7dc2012-02-03 19:52:099709 CreateMockRead(*resp.get(), 6),
9710 CreateMockRead(*data.get(), 6),
[email protected]8ddf8322012-02-23 18:08:069711 MockRead(ASYNC, 0, 0, 6),
[email protected]394816e92010-08-03 07:38:599712 };
[email protected]dd54bd82012-07-19 23:44:579713 OrderedSocketData data_2(
9714 data_reads_2, arraysize(data_reads_2),
9715 data_writes_2, arraysize(data_writes_2));
[email protected]f45c1ee2010-08-03 00:54:309716
[email protected]8ddf8322012-02-23 18:08:069717 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029718 ssl.SetNextProto(GetParam());
[email protected]f45c1ee2010-08-03 00:54:309719
[email protected]d973e99a2012-02-17 21:02:369720 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559721 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
9722 NULL, 0, NULL, 0);
9723 hanging_non_alternate_protocol_socket.set_connect_data(
9724 never_finishing_connect);
9725
[email protected]bb88e1d32013-05-03 23:11:079726 session_deps_.socket_factory->AddSocketDataProvider(&data_1);
9727 session_deps_.socket_factory->AddSocketDataProvider(&data_2);
9728 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9729 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:559730 &hanging_non_alternate_protocol_socket);
[email protected]bb88e1d32013-05-03 23:11:079731 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f45c1ee2010-08-03 00:54:309732
9733 // First round should work and provide the Alternate-Protocol state.
[email protected]49639fa2011-12-20 23:22:419734 TestCompletionCallback callback_1;
[email protected]262eec82013-03-19 21:01:369735 scoped_ptr<HttpTransaction> trans_1(
[email protected]90499482013-06-01 00:39:509736 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419737 int rv = trans_1->Start(&request, callback_1.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:309738 EXPECT_EQ(ERR_IO_PENDING, rv);
9739 EXPECT_EQ(OK, callback_1.WaitForResult());
9740
9741 // Second round should attempt a tunnel connect and get an auth challenge.
[email protected]49639fa2011-12-20 23:22:419742 TestCompletionCallback callback_2;
[email protected]262eec82013-03-19 21:01:369743 scoped_ptr<HttpTransaction> trans_2(
[email protected]90499482013-06-01 00:39:509744 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419745 rv = trans_2->Start(&request, callback_2.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:309746 EXPECT_EQ(ERR_IO_PENDING, rv);
9747 EXPECT_EQ(OK, callback_2.WaitForResult());
9748 const HttpResponseInfo* response = trans_2->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509749 ASSERT_TRUE(response != NULL);
[email protected]f45c1ee2010-08-03 00:54:309750 ASSERT_FALSE(response->auth_challenge.get() == NULL);
9751
9752 // Restart with auth. Tunnel should work and response received.
[email protected]49639fa2011-12-20 23:22:419753 TestCompletionCallback callback_3;
9754 rv = trans_2->RestartWithAuth(
9755 AuthCredentials(kFoo, kBar), callback_3.callback());
[email protected]f45c1ee2010-08-03 00:54:309756 EXPECT_EQ(ERR_IO_PENDING, rv);
9757 EXPECT_EQ(OK, callback_3.WaitForResult());
9758
9759 // After all that work, these two lines (or actually, just the scheme) are
9760 // what this test is all about. Make sure it happens correctly.
[email protected]767257802011-12-14 17:33:189761 const GURL& request_url = auth_handler->request_url();
[email protected]f45c1ee2010-08-03 00:54:309762 EXPECT_EQ("https", request_url.scheme());
9763 EXPECT_EQ("www.google.com", request_url.host());
9764
[email protected]029c83b62013-01-24 05:28:209765 LoadTimingInfo load_timing_info;
9766 EXPECT_TRUE(trans_2->GetLoadTimingInfo(&load_timing_info));
9767 TestLoadTimingNotReusedWithPac(load_timing_info,
9768 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]8e6441ca2010-08-19 05:56:389769}
9770
9771// Test that if we cancel the transaction as the connection is completing, that
9772// everything tears down correctly.
[email protected]23e482282013-06-14 16:08:029773TEST_P(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:389774 // Setup everything about the connection to complete synchronously, so that
9775 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
9776 // for is the callback from the HttpStreamRequest.
9777 // Then cancel the transaction.
9778 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:369779 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:389780 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:069781 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
9782 MockRead(SYNCHRONOUS, "hello world"),
9783 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:389784 };
9785
[email protected]8e6441ca2010-08-19 05:56:389786 HttpRequestInfo request;
9787 request.method = "GET";
9788 request.url = GURL("http://www.google.com/");
9789 request.load_flags = 0;
9790
[email protected]bb88e1d32013-05-03 23:11:079791 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]cb9bf6ca2011-01-28 13:15:279792 scoped_ptr<HttpTransaction> trans(
[email protected]262eec82013-03-19 21:01:369793 new HttpNetworkTransaction(DEFAULT_PRIORITY,
[email protected]bb88e1d32013-05-03 23:11:079794 CreateSession(&session_deps_)));
[email protected]cb9bf6ca2011-01-28 13:15:279795
[email protected]8e6441ca2010-08-19 05:56:389796 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
9797 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079798 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:389799
[email protected]49639fa2011-12-20 23:22:419800 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:389801
[email protected]333bdf62012-06-08 22:57:299802 CapturingBoundNetLog log;
[email protected]49639fa2011-12-20 23:22:419803 int rv = trans->Start(&request, callback.callback(), log.bound());
[email protected]8e6441ca2010-08-19 05:56:389804 EXPECT_EQ(ERR_IO_PENDING, rv);
9805 trans.reset(); // Cancel the transaction here.
9806
[email protected]2da659e2013-05-23 20:51:349807 base::MessageLoop::current()->RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:309808}
9809
[email protected]76a505b2010-08-25 06:23:009810// Test a basic GET request through a proxy.
[email protected]23e482282013-06-14 16:08:029811TEST_P(HttpNetworkTransactionTest, ProxyGet) {
[email protected]bb88e1d32013-05-03 23:11:079812 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:209813 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
[email protected]333bdf62012-06-08 22:57:299814 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:079815 session_deps_.net_log = log.bound().net_log();
9816 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:009817
[email protected]76a505b2010-08-25 06:23:009818 HttpRequestInfo request;
9819 request.method = "GET";
9820 request.url = GURL("http://www.google.com/");
9821
9822 MockWrite data_writes1[] = {
9823 MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
9824 "Host: www.google.com\r\n"
9825 "Proxy-Connection: keep-alive\r\n\r\n"),
9826 };
9827
9828 MockRead data_reads1[] = {
9829 MockRead("HTTP/1.1 200 OK\r\n"),
9830 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9831 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069832 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:009833 };
9834
9835 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
9836 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:079837 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:009838
[email protected]49639fa2011-12-20 23:22:419839 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:009840
[email protected]262eec82013-03-19 21:01:369841 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509842 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:509843
[email protected]49639fa2011-12-20 23:22:419844 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:009845 EXPECT_EQ(ERR_IO_PENDING, rv);
9846
9847 rv = callback1.WaitForResult();
9848 EXPECT_EQ(OK, rv);
9849
9850 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509851 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:009852
9853 EXPECT_TRUE(response->headers->IsKeepAlive());
9854 EXPECT_EQ(200, response->headers->response_code());
9855 EXPECT_EQ(100, response->headers->GetContentLength());
9856 EXPECT_TRUE(response->was_fetched_via_proxy);
9857 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:209858
9859 LoadTimingInfo load_timing_info;
9860 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
9861 TestLoadTimingNotReusedWithPac(load_timing_info,
9862 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:009863}
9864
9865// Test a basic HTTPS GET request through a proxy.
[email protected]23e482282013-06-14 16:08:029866TEST_P(HttpNetworkTransactionTest, ProxyTunnelGet) {
[email protected]bb88e1d32013-05-03 23:11:079867 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:209868 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
[email protected]333bdf62012-06-08 22:57:299869 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:079870 session_deps_.net_log = log.bound().net_log();
9871 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:009872
[email protected]76a505b2010-08-25 06:23:009873 HttpRequestInfo request;
9874 request.method = "GET";
9875 request.url = GURL("https://www.google.com/");
9876
9877 // Since we have proxy, should try to establish tunnel.
9878 MockWrite data_writes1[] = {
9879 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
9880 "Host: www.google.com\r\n"
9881 "Proxy-Connection: keep-alive\r\n\r\n"),
9882
9883 MockWrite("GET / HTTP/1.1\r\n"
9884 "Host: www.google.com\r\n"
9885 "Connection: keep-alive\r\n\r\n"),
9886 };
9887
9888 MockRead data_reads1[] = {
9889 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
9890
9891 MockRead("HTTP/1.1 200 OK\r\n"),
9892 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9893 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069894 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:009895 };
9896
9897 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
9898 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:079899 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:069900 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:079901 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:009902
[email protected]49639fa2011-12-20 23:22:419903 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:009904
[email protected]262eec82013-03-19 21:01:369905 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509906 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:509907
[email protected]49639fa2011-12-20 23:22:419908 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:009909 EXPECT_EQ(ERR_IO_PENDING, rv);
9910
9911 rv = callback1.WaitForResult();
9912 EXPECT_EQ(OK, rv);
[email protected]f3da152d2012-06-02 01:00:579913 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:409914 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:009915 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:409916 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:009917 NetLog::PHASE_NONE);
9918 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:409919 entries, pos,
[email protected]76a505b2010-08-25 06:23:009920 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
9921 NetLog::PHASE_NONE);
9922
9923 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509924 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:009925
9926 EXPECT_TRUE(response->headers->IsKeepAlive());
9927 EXPECT_EQ(200, response->headers->response_code());
9928 EXPECT_EQ(100, response->headers->GetContentLength());
9929 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
9930 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]029c83b62013-01-24 05:28:209931
9932 LoadTimingInfo load_timing_info;
9933 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
9934 TestLoadTimingNotReusedWithPac(load_timing_info,
9935 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:009936}
9937
9938// Test a basic HTTPS GET request through a proxy, but the server hangs up
9939// while establishing the tunnel.
[email protected]23e482282013-06-14 16:08:029940TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
[email protected]bb88e1d32013-05-03 23:11:079941 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]333bdf62012-06-08 22:57:299942 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:079943 session_deps_.net_log = log.bound().net_log();
9944 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:009945
[email protected]76a505b2010-08-25 06:23:009946 HttpRequestInfo request;
9947 request.method = "GET";
9948 request.url = GURL("https://www.google.com/");
9949
9950 // Since we have proxy, should try to establish tunnel.
9951 MockWrite data_writes1[] = {
9952 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
9953 "Host: www.google.com\r\n"
9954 "Proxy-Connection: keep-alive\r\n\r\n"),
9955
9956 MockWrite("GET / HTTP/1.1\r\n"
9957 "Host: www.google.com\r\n"
9958 "Connection: keep-alive\r\n\r\n"),
9959 };
9960
9961 MockRead data_reads1[] = {
[email protected]8ddf8322012-02-23 18:08:069962 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:009963 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069964 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:009965 };
9966
9967 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
9968 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:079969 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:069970 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:079971 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:009972
[email protected]49639fa2011-12-20 23:22:419973 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:009974
[email protected]262eec82013-03-19 21:01:369975 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509976 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:509977
[email protected]49639fa2011-12-20 23:22:419978 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:009979 EXPECT_EQ(ERR_IO_PENDING, rv);
9980
9981 rv = callback1.WaitForResult();
9982 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
[email protected]f3da152d2012-06-02 01:00:579983 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:409984 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:009985 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:409986 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:009987 NetLog::PHASE_NONE);
9988 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:409989 entries, pos,
[email protected]76a505b2010-08-25 06:23:009990 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
9991 NetLog::PHASE_NONE);
9992}
9993
[email protected]749eefa82010-09-13 22:14:039994// Test for crbug.com/55424.
[email protected]23e482282013-06-14 16:08:029995TEST_P(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
[email protected]cdf8f7e72013-05-23 10:56:469996 scoped_ptr<SpdyFrame> req(
9997 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
[email protected]749eefa82010-09-13 22:14:039998 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
9999
[email protected]23e482282013-06-14 16:08:0210000 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10001 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0310002 MockRead spdy_reads[] = {
10003 CreateMockRead(*resp),
10004 CreateMockRead(*data),
[email protected]8ddf8322012-02-23 18:08:0610005 MockRead(ASYNC, 0, 0),
[email protected]749eefa82010-09-13 22:14:0310006 };
10007
[email protected]dd54bd82012-07-19 23:44:5710008 DelayedSocketData spdy_data(
10009 1, // wait for one write to finish before reading.
10010 spdy_reads, arraysize(spdy_reads),
10011 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710012 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0310013
[email protected]8ddf8322012-02-23 18:08:0610014 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210015 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710016 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0310017
[email protected]bb88e1d32013-05-03 23:11:0710018 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0310019
10020 // Set up an initial SpdySession in the pool to reuse.
[email protected]02b0c342010-09-25 21:09:3810021 HostPortPair host_port_pair("www.google.com", 443);
[email protected]e6d017652013-05-17 18:01:4010022 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
10023 kPrivacyModeDisabled);
[email protected]749eefa82010-09-13 22:14:0310024 scoped_refptr<SpdySession> spdy_session =
[email protected]e6d017652013-05-17 18:01:4010025 session->spdy_session_pool()->Get(key, BoundNetLog());
[email protected]ab739042011-04-07 15:22:2810026 scoped_refptr<TransportSocketParams> transport_params(
[email protected]d2b5f092012-06-08 23:55:0210027 new TransportSocketParams(host_port_pair, MEDIUM, false, false,
10028 OnHostResolutionCallback()));
[email protected]6ecf2b92011-12-15 01:14:5210029 TestCompletionCallback callback;
[email protected]02b0c342010-09-25 21:09:3810030
10031 scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
10032 EXPECT_EQ(ERR_IO_PENDING,
[email protected]e5c026642012-03-17 00:14:0210033 connection->Init(host_port_pair.ToString(),
10034 transport_params,
10035 LOWEST,
10036 callback.callback(),
10037 session->GetTransportSocketPool(
10038 HttpNetworkSession::NORMAL_SOCKET_POOL),
10039 BoundNetLog()));
[email protected]02b0c342010-09-25 21:09:3810040 EXPECT_EQ(OK, callback.WaitForResult());
10041 spdy_session->InitializeWithSocket(connection.release(), false, OK);
[email protected]749eefa82010-09-13 22:14:0310042
10043 HttpRequestInfo request;
10044 request.method = "GET";
10045 request.url = GURL("https://www.google.com/");
10046 request.load_flags = 0;
10047
10048 // This is the important line that marks this as a preconnect.
10049 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
10050
[email protected]262eec82013-03-19 21:01:3610051 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010052 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]749eefa82010-09-13 22:14:0310053
[email protected]49639fa2011-12-20 23:22:4110054 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0310055 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110056 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]749eefa82010-09-13 22:14:0310057}
10058
[email protected]73b8dd222010-11-11 19:55:2410059// Given a net error, cause that error to be returned from the first Write()
10060// call and verify that the HttpTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0210061void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0710062 int error, IoMode mode) {
[email protected]cb9bf6ca2011-01-28 13:15:2710063 net::HttpRequestInfo request_info;
10064 request_info.url = GURL("https://www.example.com/");
10065 request_info.method = "GET";
10066 request_info.load_flags = net::LOAD_NORMAL;
10067
[email protected]8ddf8322012-02-23 18:08:0610068 SSLSocketDataProvider ssl_data(mode, OK);
[email protected]73b8dd222010-11-11 19:55:2410069 net::MockWrite data_writes[] = {
[email protected]8ddf8322012-02-23 18:08:0610070 net::MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2410071 };
10072 net::StaticSocketDataProvider data(NULL, 0,
10073 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0710074 session_deps_.socket_factory->AddSocketDataProvider(&data);
10075 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2410076
[email protected]bb88e1d32013-05-03 23:11:0710077 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610078 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010079 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]73b8dd222010-11-11 19:55:2410080
[email protected]49639fa2011-12-20 23:22:4110081 TestCompletionCallback callback;
10082 int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
[email protected]73b8dd222010-11-11 19:55:2410083 if (rv == net::ERR_IO_PENDING)
10084 rv = callback.WaitForResult();
10085 ASSERT_EQ(error, rv);
10086}
10087
[email protected]23e482282013-06-14 16:08:0210088TEST_P(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2410089 // Just check a grab bag of cert errors.
10090 static const int kErrors[] = {
10091 ERR_CERT_COMMON_NAME_INVALID,
10092 ERR_CERT_AUTHORITY_INVALID,
10093 ERR_CERT_DATE_INVALID,
10094 };
10095 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0610096 CheckErrorIsPassedBack(kErrors[i], ASYNC);
10097 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2410098 }
10099}
10100
[email protected]bd0b6772011-01-11 19:59:3010101// Ensure that a client certificate is removed from the SSL client auth
10102// cache when:
10103// 1) No proxy is involved.
10104// 2) TLS False Start is disabled.
10105// 3) The initial TLS handshake requests a client certificate.
10106// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0210107TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310108 ClientAuthCertCache_Direct_NoFalseStart) {
[email protected]cb9bf6ca2011-01-28 13:15:2710109 net::HttpRequestInfo request_info;
10110 request_info.url = GURL("https://www.example.com/");
10111 request_info.method = "GET";
10112 request_info.load_flags = net::LOAD_NORMAL;
10113
[email protected]bd0b6772011-01-11 19:59:3010114 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
10115 cert_request->host_and_port = "www.example.com:443";
10116
10117 // [ssl_]data1 contains the data for the first SSL handshake. When a
10118 // CertificateRequest is received for the first time, the handshake will
10119 // be aborted to allow the caller to provide a certificate.
[email protected]8ddf8322012-02-23 18:08:0610120 SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3010121 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710122 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
[email protected]bd0b6772011-01-11 19:59:3010123 net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710124 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3010125
10126 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
10127 // False Start is not being used, the result of the SSL handshake will be
10128 // returned as part of the SSLClientSocket::Connect() call. This test
10129 // matches the result of a server sending a handshake_failure alert,
10130 // rather than a Finished message, because it requires a client
10131 // certificate and none was supplied.
[email protected]8ddf8322012-02-23 18:08:0610132 SSLSocketDataProvider ssl_data2(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3010133 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710134 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
[email protected]bd0b6772011-01-11 19:59:3010135 net::StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710136 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3010137
10138 // [ssl_]data3 contains the data for the third SSL handshake. When a
10139 // connection to a server fails during an SSL handshake,
[email protected]80c75f682012-05-26 16:22:1710140 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
10141 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3010142 // of the HttpNetworkTransaction. Because this test failure is due to
10143 // requiring a client certificate, this fallback handshake should also
10144 // fail.
[email protected]8ddf8322012-02-23 18:08:0610145 SSLSocketDataProvider ssl_data3(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3010146 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710147 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
[email protected]bd0b6772011-01-11 19:59:3010148 net::StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710149 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3010150
[email protected]80c75f682012-05-26 16:22:1710151 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
10152 // connection to a server fails during an SSL handshake,
10153 // HttpNetworkTransaction will attempt to fallback to SSLv3 if the previous
10154 // connection was attempted with TLSv1. This is transparent to the caller
10155 // of the HttpNetworkTransaction. Because this test failure is due to
10156 // requiring a client certificate, this fallback handshake should also
10157 // fail.
10158 SSLSocketDataProvider ssl_data4(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
10159 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710160 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
[email protected]80c75f682012-05-26 16:22:1710161 net::StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710162 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1710163
[email protected]7799de12013-05-30 05:52:5110164 // Need one more if TLSv1.2 is enabled.
10165 SSLSocketDataProvider ssl_data5(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
10166 ssl_data5.cert_request_info = cert_request.get();
10167 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
10168 net::StaticSocketDataProvider data5(NULL, 0, NULL, 0);
10169 session_deps_.socket_factory->AddSocketDataProvider(&data5);
10170
[email protected]bb88e1d32013-05-03 23:11:0710171 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610172 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010173 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3010174
[email protected]bd0b6772011-01-11 19:59:3010175 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4110176 TestCompletionCallback callback;
10177 int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
[email protected]bd0b6772011-01-11 19:59:3010178 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10179
10180 // Complete the SSL handshake, which should abort due to requiring a
10181 // client certificate.
10182 rv = callback.WaitForResult();
10183 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
10184
10185 // Indicate that no certificate should be supplied. From the perspective
10186 // of SSLClientCertCache, NULL is just as meaningful as a real
10187 // certificate, so this is the same as supply a
10188 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4110189 rv = trans->RestartWithCertificate(NULL, callback.callback());
[email protected]bd0b6772011-01-11 19:59:3010190 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10191
10192 // Ensure the certificate was added to the client auth cache before
10193 // allowing the connection to continue restarting.
10194 scoped_refptr<X509Certificate> client_cert;
10195 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
10196 &client_cert));
10197 ASSERT_EQ(NULL, client_cert.get());
10198
10199 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1710200 // then consume ssl_data3 and ssl_data4, both of which should also fail.
10201 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3010202 rv = callback.WaitForResult();
10203 ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
10204
10205 // Ensure that the client certificate is removed from the cache on a
10206 // handshake failure.
10207 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
10208 &client_cert));
10209}
10210
10211// Ensure that a client certificate is removed from the SSL client auth
10212// cache when:
10213// 1) No proxy is involved.
10214// 2) TLS False Start is enabled.
10215// 3) The initial TLS handshake requests a client certificate.
10216// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0210217TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310218 ClientAuthCertCache_Direct_FalseStart) {
[email protected]cb9bf6ca2011-01-28 13:15:2710219 net::HttpRequestInfo request_info;
10220 request_info.url = GURL("https://www.example.com/");
10221 request_info.method = "GET";
10222 request_info.load_flags = net::LOAD_NORMAL;
10223
[email protected]bd0b6772011-01-11 19:59:3010224 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
10225 cert_request->host_and_port = "www.example.com:443";
10226
10227 // When TLS False Start is used, SSLClientSocket::Connect() calls will
10228 // return successfully after reading up to the peer's Certificate message.
10229 // This is to allow the caller to call SSLClientSocket::Write(), which can
10230 // enqueue application data to be sent in the same packet as the
10231 // ChangeCipherSpec and Finished messages.
10232 // The actual handshake will be finished when SSLClientSocket::Read() is
10233 // called, which expects to process the peer's ChangeCipherSpec and
10234 // Finished messages. If there was an error negotiating with the peer,
10235 // such as due to the peer requiring a client certificate when none was
10236 // supplied, the alert sent by the peer won't be processed until Read() is
10237 // called.
10238
10239 // Like the non-False Start case, when a client certificate is requested by
10240 // the peer, the handshake is aborted during the Connect() call.
10241 // [ssl_]data1 represents the initial SSL handshake with the peer.
[email protected]8ddf8322012-02-23 18:08:0610242 SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3010243 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710244 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
[email protected]bd0b6772011-01-11 19:59:3010245 net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710246 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3010247
10248 // When a client certificate is supplied, Connect() will not be aborted
10249 // when the peer requests the certificate. Instead, the handshake will
10250 // artificially succeed, allowing the caller to write the HTTP request to
10251 // the socket. The handshake messages are not processed until Read() is
10252 // called, which then detects that the handshake was aborted, due to the
10253 // peer sending a handshake_failure because it requires a client
10254 // certificate.
[email protected]8ddf8322012-02-23 18:08:0610255 SSLSocketDataProvider ssl_data2(ASYNC, net::OK);
[email protected]bd0b6772011-01-11 19:59:3010256 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710257 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
[email protected]bd0b6772011-01-11 19:59:3010258 net::MockRead data2_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0610259 net::MockRead(ASYNC /* async */, net::ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3010260 };
10261 net::StaticSocketDataProvider data2(
10262 data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710263 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3010264
10265 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1710266 // the data for the SSL handshake once the TLSv1.1 connection falls back to
10267 // TLSv1. It has the same behaviour as [ssl_]data2.
[email protected]8ddf8322012-02-23 18:08:0610268 SSLSocketDataProvider ssl_data3(ASYNC, net::OK);
[email protected]bd0b6772011-01-11 19:59:3010269 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710270 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
[email protected]bd0b6772011-01-11 19:59:3010271 net::StaticSocketDataProvider data3(
10272 data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710273 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3010274
[email protected]80c75f682012-05-26 16:22:1710275 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
10276 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
10277 SSLSocketDataProvider ssl_data4(ASYNC, net::OK);
10278 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710279 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
[email protected]80c75f682012-05-26 16:22:1710280 net::StaticSocketDataProvider data4(
10281 data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710282 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1710283
[email protected]7799de12013-05-30 05:52:5110284 // Need one more if TLSv1.2 is enabled.
10285 SSLSocketDataProvider ssl_data5(ASYNC, net::OK);
10286 ssl_data5.cert_request_info = cert_request.get();
10287 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
10288 net::StaticSocketDataProvider data5(
10289 data2_reads, arraysize(data2_reads), NULL, 0);
10290 session_deps_.socket_factory->AddSocketDataProvider(&data5);
10291
[email protected]bb88e1d32013-05-03 23:11:0710292 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610293 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010294 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3010295
[email protected]bd0b6772011-01-11 19:59:3010296 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4110297 TestCompletionCallback callback;
10298 int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
[email protected]bd0b6772011-01-11 19:59:3010299 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10300
10301 // Complete the SSL handshake, which should abort due to requiring a
10302 // client certificate.
10303 rv = callback.WaitForResult();
10304 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
10305
10306 // Indicate that no certificate should be supplied. From the perspective
10307 // of SSLClientCertCache, NULL is just as meaningful as a real
10308 // certificate, so this is the same as supply a
10309 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4110310 rv = trans->RestartWithCertificate(NULL, callback.callback());
[email protected]bd0b6772011-01-11 19:59:3010311 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10312
10313 // Ensure the certificate was added to the client auth cache before
10314 // allowing the connection to continue restarting.
10315 scoped_refptr<X509Certificate> client_cert;
10316 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
10317 &client_cert));
10318 ASSERT_EQ(NULL, client_cert.get());
10319
[email protected]bd0b6772011-01-11 19:59:3010320 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1710321 // then consume ssl_data3 and ssl_data4, both of which should also fail.
10322 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3010323 rv = callback.WaitForResult();
10324 ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
10325
10326 // Ensure that the client certificate is removed from the cache on a
10327 // handshake failure.
10328 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
10329 &client_cert));
10330}
10331
[email protected]8c405132011-01-11 22:03:1810332// Ensure that a client certificate is removed from the SSL client auth
10333// cache when:
10334// 1) An HTTPS proxy is involved.
10335// 3) The HTTPS proxy requests a client certificate.
10336// 4) The client supplies an invalid/unacceptable certificate for the
10337// proxy.
10338// The test is repeated twice, first for connecting to an HTTPS endpoint,
10339// then for connecting to an HTTP endpoint.
[email protected]23e482282013-06-14 16:08:0210340TEST_P(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
[email protected]bb88e1d32013-05-03 23:11:0710341 session_deps_.proxy_service.reset(
[email protected]8c405132011-01-11 22:03:1810342 ProxyService::CreateFixed("https://proxy:70"));
[email protected]333bdf62012-06-08 22:57:2910343 CapturingBoundNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710344 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1810345
10346 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
10347 cert_request->host_and_port = "proxy:70";
10348
10349 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
10350 // [ssl_]data[1-3]. Rather than represending the endpoint
10351 // (www.example.com:443), they represent failures with the HTTPS proxy
10352 // (proxy:70).
[email protected]8ddf8322012-02-23 18:08:0610353 SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1810354 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710355 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
[email protected]8c405132011-01-11 22:03:1810356 net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710357 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1810358
[email protected]8ddf8322012-02-23 18:08:0610359 SSLSocketDataProvider ssl_data2(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1810360 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710361 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
[email protected]8c405132011-01-11 22:03:1810362 net::StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710363 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1810364
[email protected]80c75f682012-05-26 16:22:1710365 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
10366#if 0
[email protected]8ddf8322012-02-23 18:08:0610367 SSLSocketDataProvider ssl_data3(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1810368 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0710369 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
[email protected]8c405132011-01-11 22:03:1810370 net::StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710371 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1710372#endif
[email protected]8c405132011-01-11 22:03:1810373
10374 net::HttpRequestInfo requests[2];
10375 requests[0].url = GURL("https://www.example.com/");
10376 requests[0].method = "GET";
10377 requests[0].load_flags = net::LOAD_NORMAL;
10378
10379 requests[1].url = GURL("http://www.example.com/");
10380 requests[1].method = "GET";
10381 requests[1].load_flags = net::LOAD_NORMAL;
10382
10383 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0710384 session_deps_.socket_factory->ResetNextMockIndexes();
10385 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c405132011-01-11 22:03:1810386 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5010387 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c405132011-01-11 22:03:1810388
10389 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4110390 TestCompletionCallback callback;
10391 int rv = trans->Start(
10392 &requests[i], callback.callback(), net::BoundNetLog());
[email protected]8c405132011-01-11 22:03:1810393 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10394
10395 // Complete the SSL handshake, which should abort due to requiring a
10396 // client certificate.
10397 rv = callback.WaitForResult();
10398 ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
10399
10400 // Indicate that no certificate should be supplied. From the perspective
10401 // of SSLClientCertCache, NULL is just as meaningful as a real
10402 // certificate, so this is the same as supply a
10403 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4110404 rv = trans->RestartWithCertificate(NULL, callback.callback());
[email protected]8c405132011-01-11 22:03:1810405 ASSERT_EQ(net::ERR_IO_PENDING, rv);
10406
10407 // Ensure the certificate was added to the client auth cache before
10408 // allowing the connection to continue restarting.
10409 scoped_refptr<X509Certificate> client_cert;
10410 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup("proxy:70",
10411 &client_cert));
10412 ASSERT_EQ(NULL, client_cert.get());
10413 // Ensure the certificate was NOT cached for the endpoint. This only
10414 // applies to HTTPS requests, but is fine to check for HTTP requests.
10415 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
10416 &client_cert));
10417
10418 // Restart the handshake. This will consume ssl_data2, which fails, and
10419 // then consume ssl_data3, which should also fail. The result code is
10420 // checked against what ssl_data3 should return.
10421 rv = callback.WaitForResult();
10422 ASSERT_EQ(net::ERR_PROXY_CONNECTION_FAILED, rv);
10423
10424 // Now that the new handshake has failed, ensure that the client
10425 // certificate was removed from the client auth cache.
10426 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("proxy:70",
10427 &client_cert));
10428 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
10429 &client_cert));
10430 }
10431}
10432
[email protected]23e482282013-06-14 16:08:0210433// Unlike TEST/TEST_F, which are macros that expand to further macros,
10434// TEST_P is a macro that expands directly to code that stringizes the
10435// arguments. As a result, macros passed as parameters (such as prefix
10436// or test_case_name) will not be expanded by the preprocessor. To
10437// work around this, indirect the macro for TEST_P, so that the
10438// pre-processor will expand macros such as MAYBE_test_name before
10439// instantiating the test.
10440#define WRAPPED_TEST_P(test_case_name, test_name) \
10441 TEST_P(test_case_name, test_name)
10442
[email protected]45b170822012-05-04 21:18:1410443// Times out on Win7 dbg(2) bot. http://crbug.com/124776
10444#if defined(OS_WIN)
10445#define MAYBE_UseIPConnectionPooling DISABLED_UseIPConnectionPooling
10446#else
10447#define MAYBE_UseIPConnectionPooling UseIPConnectionPooling
10448#endif
[email protected]23e482282013-06-14 16:08:0210449WRAPPED_TEST_P(HttpNetworkTransactionTest, MAYBE_UseIPConnectionPooling) {
[email protected]e3ceb682011-06-28 23:55:4610450 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:0310451 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]e3ceb682011-06-28 23:55:4610452
10453 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0710454 session_deps_.host_resolver.reset(new MockCachingHostResolver());
10455 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2610456 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
10457 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4610458
[email protected]8ddf8322012-02-23 18:08:0610459 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210460 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710461 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4610462
[email protected]cdf8f7e72013-05-23 10:56:4610463 scoped_ptr<SpdyFrame> host1_req(
10464 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
10465 scoped_ptr<SpdyFrame> host2_req(
10466 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4610467 MockWrite spdy_writes[] = {
10468 CreateMockWrite(*host1_req, 1),
10469 CreateMockWrite(*host2_req, 4),
10470 };
[email protected]23e482282013-06-14 16:08:0210471 scoped_ptr<SpdyFrame> host1_resp(
10472 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10473 scoped_ptr<SpdyFrame> host1_resp_body(
10474 spdy_util_.ConstructSpdyBodyFrame(1, true));
10475 scoped_ptr<SpdyFrame> host2_resp(
10476 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
10477 scoped_ptr<SpdyFrame> host2_resp_body(
10478 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4610479 MockRead spdy_reads[] = {
10480 CreateMockRead(*host1_resp, 2),
10481 CreateMockRead(*host1_resp_body, 3),
10482 CreateMockRead(*host2_resp, 5),
10483 CreateMockRead(*host2_resp_body, 6),
[email protected]8ddf8322012-02-23 18:08:0610484 MockRead(ASYNC, 0, 7),
[email protected]e3ceb682011-06-28 23:55:4610485 };
10486
[email protected]d2b5f092012-06-08 23:55:0210487 IPAddressNumber ip;
10488 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
10489 IPEndPoint peer_addr = IPEndPoint(ip, 443);
10490 MockConnect connect(ASYNC, OK, peer_addr);
[email protected]dd54bd82012-07-19 23:44:5710491 OrderedSocketData spdy_data(
10492 connect,
10493 spdy_reads, arraysize(spdy_reads),
10494 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710495 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4610496
[email protected]aa22b242011-11-16 18:58:2910497 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4610498 HttpRequestInfo request1;
10499 request1.method = "GET";
10500 request1.url = GURL("https://www.google.com/");
10501 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010502 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4610503
[email protected]49639fa2011-12-20 23:22:4110504 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4610505 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110506 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4610507
10508 const HttpResponseInfo* response = trans1.GetResponseInfo();
10509 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010510 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4610511 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10512
10513 std::string response_data;
10514 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
10515 EXPECT_EQ("hello!", response_data);
10516
10517 // Preload www.gmail.com into HostCache.
10518 HostPortPair host_port("www.gmail.com", 443);
10519 HostResolver::RequestInfo resolve_info(host_port);
10520 AddressList ignored;
[email protected]bb88e1d32013-05-03 23:11:0710521 rv = session_deps_.host_resolver->Resolve(resolve_info, &ignored,
[email protected]c6bf8152012-12-02 07:43:3410522 callback.callback(), NULL,
10523 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4710524 EXPECT_EQ(ERR_IO_PENDING, rv);
10525 rv = callback.WaitForResult();
10526 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4610527
10528 HttpRequestInfo request2;
10529 request2.method = "GET";
10530 request2.url = GURL("https://www.gmail.com/");
10531 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010532 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4610533
[email protected]49639fa2011-12-20 23:22:4110534 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4610535 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110536 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4610537
10538 response = trans2.GetResponseInfo();
10539 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010540 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4610541 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10542 EXPECT_TRUE(response->was_fetched_via_spdy);
10543 EXPECT_TRUE(response->was_npn_negotiated);
10544 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
10545 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4610546}
[email protected]45b170822012-05-04 21:18:1410547#undef MAYBE_UseIPConnectionPooling
[email protected]e3ceb682011-06-28 23:55:4610548
[email protected]23e482282013-06-14 16:08:0210549TEST_P(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d2b5f092012-06-08 23:55:0210550 HttpStreamFactory::set_use_alternate_protocols(true);
10551 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
10552
10553 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0710554 session_deps_.host_resolver.reset(new MockCachingHostResolver());
10555 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0210556 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
10557 pool_peer.DisableDomainAuthenticationVerification();
10558
10559 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210560 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710561 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]d2b5f092012-06-08 23:55:0210562
[email protected]cdf8f7e72013-05-23 10:56:4610563 scoped_ptr<SpdyFrame> host1_req(
10564 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
10565 scoped_ptr<SpdyFrame> host2_req(
10566 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0210567 MockWrite spdy_writes[] = {
10568 CreateMockWrite(*host1_req, 1),
10569 CreateMockWrite(*host2_req, 4),
10570 };
[email protected]23e482282013-06-14 16:08:0210571 scoped_ptr<SpdyFrame> host1_resp(
10572 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10573 scoped_ptr<SpdyFrame> host1_resp_body(
10574 spdy_util_.ConstructSpdyBodyFrame(1, true));
10575 scoped_ptr<SpdyFrame> host2_resp(
10576 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
10577 scoped_ptr<SpdyFrame> host2_resp_body(
10578 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0210579 MockRead spdy_reads[] = {
10580 CreateMockRead(*host1_resp, 2),
10581 CreateMockRead(*host1_resp_body, 3),
10582 CreateMockRead(*host2_resp, 5),
10583 CreateMockRead(*host2_resp_body, 6),
10584 MockRead(ASYNC, 0, 7),
10585 };
10586
10587 IPAddressNumber ip;
10588 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
10589 IPEndPoint peer_addr = IPEndPoint(ip, 443);
10590 MockConnect connect(ASYNC, OK, peer_addr);
[email protected]dd54bd82012-07-19 23:44:5710591 OrderedSocketData spdy_data(
10592 connect,
10593 spdy_reads, arraysize(spdy_reads),
10594 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710595 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0210596
10597 TestCompletionCallback callback;
10598 HttpRequestInfo request1;
10599 request1.method = "GET";
10600 request1.url = GURL("https://www.google.com/");
10601 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010602 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0210603
10604 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
10605 EXPECT_EQ(ERR_IO_PENDING, rv);
10606 EXPECT_EQ(OK, callback.WaitForResult());
10607
10608 const HttpResponseInfo* response = trans1.GetResponseInfo();
10609 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010610 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d2b5f092012-06-08 23:55:0210611 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10612
10613 std::string response_data;
10614 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
10615 EXPECT_EQ("hello!", response_data);
10616
10617 HttpRequestInfo request2;
10618 request2.method = "GET";
10619 request2.url = GURL("https://www.gmail.com/");
10620 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010621 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0210622
10623 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
10624 EXPECT_EQ(ERR_IO_PENDING, rv);
10625 EXPECT_EQ(OK, callback.WaitForResult());
10626
10627 response = trans2.GetResponseInfo();
10628 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010629 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d2b5f092012-06-08 23:55:0210630 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10631 EXPECT_TRUE(response->was_fetched_via_spdy);
10632 EXPECT_TRUE(response->was_npn_negotiated);
10633 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
10634 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0210635}
10636
[email protected]e3ceb682011-06-28 23:55:4610637class OneTimeCachingHostResolver : public net::HostResolver {
10638 public:
10639 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
10640 : host_port_(host_port) {}
10641 virtual ~OneTimeCachingHostResolver() {}
10642
10643 RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); }
10644
10645 // HostResolver methods:
10646 virtual int Resolve(const RequestInfo& info,
10647 AddressList* addresses,
[email protected]aa22b242011-11-16 18:58:2910648 const CompletionCallback& callback,
[email protected]e3ceb682011-06-28 23:55:4610649 RequestHandle* out_req,
[email protected]95a214c2011-08-04 21:50:4010650 const BoundNetLog& net_log) OVERRIDE {
10651 return host_resolver_.Resolve(
[email protected]e3ceb682011-06-28 23:55:4610652 info, addresses, callback, out_req, net_log);
[email protected]95a214c2011-08-04 21:50:4010653 }
10654
10655 virtual int ResolveFromCache(const RequestInfo& info,
10656 AddressList* addresses,
10657 const BoundNetLog& net_log) OVERRIDE {
10658 int rv = host_resolver_.ResolveFromCache(info, addresses, net_log);
10659 if (rv == OK && info.host_port_pair().Equals(host_port_))
[email protected]98e1cd012011-11-08 15:33:0910660 host_resolver_.GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4610661 return rv;
10662 }
10663
[email protected]95a214c2011-08-04 21:50:4010664 virtual void CancelRequest(RequestHandle req) OVERRIDE {
[email protected]e3ceb682011-06-28 23:55:4610665 host_resolver_.CancelRequest(req);
10666 }
10667
[email protected]46da33be2011-07-19 21:58:0410668 MockCachingHostResolver* GetMockHostResolver() {
10669 return &host_resolver_;
10670 }
10671
[email protected]e3ceb682011-06-28 23:55:4610672 private:
10673 MockCachingHostResolver host_resolver_;
10674 const HostPortPair host_port_;
10675};
10676
[email protected]45b170822012-05-04 21:18:1410677// Times out on Win7 dbg(2) bot. http://crbug.com/124776
10678#if defined(OS_WIN)
[email protected]bb88e1d32013-05-03 23:11:0710679#define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \
10680 DISABLED_UseIPConnectionPoolingWithHostCacheExpiration
[email protected]45b170822012-05-04 21:18:1410681#else
[email protected]bb88e1d32013-05-03 23:11:0710682#define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \
10683 UseIPConnectionPoolingWithHostCacheExpiration
[email protected]45b170822012-05-04 21:18:1410684#endif
[email protected]23e482282013-06-14 16:08:0210685WRAPPED_TEST_P(HttpNetworkTransactionTest,
10686 MAYBE_UseIPConnectionPoolingWithHostCacheExpiration) {
[email protected]23e482282013-06-14 16:08:0210687// Times out on Win7 dbg(2) bot. http://crbug.com/124776 . (MAYBE_
10688// prefix doesn't work with parametrized tests).
10689#if defined(OS_WIN)
10690 return;
10691#endif
10692
[email protected]e3ceb682011-06-28 23:55:4610693 HttpStreamFactory::set_use_alternate_protocols(true);
[email protected]ecf96e52012-03-03 00:43:0310694 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
[email protected]e3ceb682011-06-28 23:55:4610695
10696 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
[email protected]e3ceb682011-06-28 23:55:4610697 OneTimeCachingHostResolver host_resolver(HostPortPair("www.gmail.com", 443));
[email protected]c6bf8152012-12-02 07:43:3410698 HttpNetworkSession::Params params =
[email protected]bb88e1d32013-05-03 23:11:0710699 SpdySessionDependencies::CreateSessionParams(&session_deps_);
[email protected]e3ceb682011-06-28 23:55:4610700 params.host_resolver = &host_resolver;
[email protected]bb88e1d32013-05-03 23:11:0710701 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2610702 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
10703 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4610704
[email protected]8ddf8322012-02-23 18:08:0610705 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210706 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710707 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4610708
[email protected]cdf8f7e72013-05-23 10:56:4610709 scoped_ptr<SpdyFrame> host1_req(
10710 spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
10711 scoped_ptr<SpdyFrame> host2_req(
10712 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4610713 MockWrite spdy_writes[] = {
10714 CreateMockWrite(*host1_req, 1),
10715 CreateMockWrite(*host2_req, 4),
10716 };
[email protected]23e482282013-06-14 16:08:0210717 scoped_ptr<SpdyFrame> host1_resp(
10718 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10719 scoped_ptr<SpdyFrame> host1_resp_body(
10720 spdy_util_.ConstructSpdyBodyFrame(1, true));
10721 scoped_ptr<SpdyFrame> host2_resp(
10722 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
10723 scoped_ptr<SpdyFrame> host2_resp_body(
10724 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4610725 MockRead spdy_reads[] = {
10726 CreateMockRead(*host1_resp, 2),
10727 CreateMockRead(*host1_resp_body, 3),
10728 CreateMockRead(*host2_resp, 5),
10729 CreateMockRead(*host2_resp_body, 6),
[email protected]8ddf8322012-02-23 18:08:0610730 MockRead(ASYNC, 0, 7),
[email protected]e3ceb682011-06-28 23:55:4610731 };
10732
[email protected]d2b5f092012-06-08 23:55:0210733 IPAddressNumber ip;
10734 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
10735 IPEndPoint peer_addr = IPEndPoint(ip, 443);
10736 MockConnect connect(ASYNC, OK, peer_addr);
[email protected]dd54bd82012-07-19 23:44:5710737 OrderedSocketData spdy_data(
10738 connect,
10739 spdy_reads, arraysize(spdy_reads),
10740 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710741 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4610742
[email protected]aa22b242011-11-16 18:58:2910743 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4610744 HttpRequestInfo request1;
10745 request1.method = "GET";
10746 request1.url = GURL("https://www.google.com/");
10747 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010748 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4610749
[email protected]49639fa2011-12-20 23:22:4110750 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4610751 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110752 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4610753
10754 const HttpResponseInfo* response = trans1.GetResponseInfo();
10755 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010756 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4610757 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10758
10759 std::string response_data;
10760 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
10761 EXPECT_EQ("hello!", response_data);
10762
10763 // Preload cache entries into HostCache.
10764 HostResolver::RequestInfo resolve_info(HostPortPair("www.gmail.com", 443));
10765 AddressList ignored;
[email protected]c6bf8152012-12-02 07:43:3410766 rv = host_resolver.Resolve(resolve_info, &ignored, callback.callback(),
10767 NULL, BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4710768 EXPECT_EQ(ERR_IO_PENDING, rv);
10769 rv = callback.WaitForResult();
10770 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4610771
10772 HttpRequestInfo request2;
10773 request2.method = "GET";
10774 request2.url = GURL("https://www.gmail.com/");
10775 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010776 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4610777
[email protected]49639fa2011-12-20 23:22:4110778 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4610779 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110780 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4610781
10782 response = trans2.GetResponseInfo();
10783 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010784 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4610785 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10786 EXPECT_TRUE(response->was_fetched_via_spdy);
10787 EXPECT_TRUE(response->was_npn_negotiated);
10788 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
10789 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4610790}
[email protected]45b170822012-05-04 21:18:1410791#undef MAYBE_UseIPConnectionPoolingWithHostCacheExpiration
[email protected]e3ceb682011-06-28 23:55:4610792
[email protected]23e482282013-06-14 16:08:0210793TEST_P(HttpNetworkTransactionTest, ReadPipelineEvictionFallback) {
[email protected]5a60c8b2011-10-19 20:14:2910794 MockRead data_reads1[] = {
[email protected]8ddf8322012-02-23 18:08:0610795 MockRead(SYNCHRONOUS, ERR_PIPELINE_EVICTION),
[email protected]5a60c8b2011-10-19 20:14:2910796 };
10797 MockRead data_reads2[] = {
10798 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
10799 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610800 MockRead(SYNCHRONOUS, OK),
[email protected]5a60c8b2011-10-19 20:14:2910801 };
10802 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), NULL, 0);
10803 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), NULL, 0);
10804 StaticSocketDataProvider* data[] = { &data1, &data2 };
10805
10806 SimpleGetHelperResult out = SimpleGetHelperForData(data, arraysize(data));
10807
10808 EXPECT_EQ(OK, out.rv);
10809 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
10810 EXPECT_EQ("hello world", out.response_data);
10811}
10812
[email protected]23e482282013-06-14 16:08:0210813TEST_P(HttpNetworkTransactionTest, SendPipelineEvictionFallback) {
[email protected]5a60c8b2011-10-19 20:14:2910814 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:0610815 MockWrite(SYNCHRONOUS, ERR_PIPELINE_EVICTION),
[email protected]5a60c8b2011-10-19 20:14:2910816 };
10817 MockWrite data_writes2[] = {
10818 MockWrite("GET / HTTP/1.1\r\n"
10819 "Host: www.google.com\r\n"
10820 "Connection: keep-alive\r\n\r\n"),
10821 };
10822 MockRead data_reads2[] = {
10823 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
10824 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610825 MockRead(SYNCHRONOUS, OK),
[email protected]5a60c8b2011-10-19 20:14:2910826 };
10827 StaticSocketDataProvider data1(NULL, 0,
10828 data_writes1, arraysize(data_writes1));
10829 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
10830 data_writes2, arraysize(data_writes2));
10831 StaticSocketDataProvider* data[] = { &data1, &data2 };
10832
10833 SimpleGetHelperResult out = SimpleGetHelperForData(data, arraysize(data));
10834
10835 EXPECT_EQ(OK, out.rv);
10836 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
10837 EXPECT_EQ("hello world", out.response_data);
10838}
10839
[email protected]23e482282013-06-14 16:08:0210840TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
[email protected]8450d722012-07-02 19:14:0410841 const std::string https_url = "https://www.google.com/";
10842 const std::string http_url = "http://www.google.com:443/";
10843
10844 // SPDY GET for HTTPS URL
[email protected]cdf8f7e72013-05-23 10:56:4610845 scoped_ptr<SpdyFrame> req1(
10846 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0410847
10848 MockWrite writes1[] = {
10849 CreateMockWrite(*req1, 0),
10850 };
10851
[email protected]23e482282013-06-14 16:08:0210852 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10853 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8450d722012-07-02 19:14:0410854 MockRead reads1[] = {
10855 CreateMockRead(*resp1, 1),
10856 CreateMockRead(*body1, 2),
10857 MockRead(ASYNC, ERR_IO_PENDING, 3)
10858 };
10859
[email protected]dd54bd82012-07-19 23:44:5710860 DelayedSocketData data1(
10861 1, reads1, arraysize(reads1),
10862 writes1, arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0410863 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5710864 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0410865
10866 // HTTP GET for the HTTP URL
10867 MockWrite writes2[] = {
10868 MockWrite(ASYNC, 4,
10869 "GET / HTTP/1.1\r\n"
10870 "Host: www.google.com:443\r\n"
10871 "Connection: keep-alive\r\n\r\n"),
10872 };
10873
10874 MockRead reads2[] = {
10875 MockRead(ASYNC, 5, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
10876 MockRead(ASYNC, 6, "hello"),
10877 MockRead(ASYNC, 7, OK),
10878 };
10879
[email protected]dd54bd82012-07-19 23:44:5710880 DelayedSocketData data2(
10881 1, reads2, arraysize(reads2),
10882 writes2, arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0410883
[email protected]8450d722012-07-02 19:14:0410884 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210885 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710886 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10887 session_deps_.socket_factory->AddSocketDataProvider(&data1);
10888 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0410889
[email protected]bb88e1d32013-05-03 23:11:0710890 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0410891
10892 // Start the first transaction to set up the SpdySession
10893 HttpRequestInfo request1;
10894 request1.method = "GET";
10895 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0410896 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010897 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0410898 TestCompletionCallback callback1;
10899 EXPECT_EQ(ERR_IO_PENDING,
10900 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3410901 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0410902
10903 EXPECT_EQ(OK, callback1.WaitForResult());
10904 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
10905
10906 // Now, start the HTTP request
10907 HttpRequestInfo request2;
10908 request2.method = "GET";
10909 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0410910 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010911 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0410912 TestCompletionCallback callback2;
10913 EXPECT_EQ(ERR_IO_PENDING,
10914 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3410915 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0410916
10917 EXPECT_EQ(OK, callback2.WaitForResult());
10918 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
10919}
10920
[email protected]23e482282013-06-14 16:08:0210921TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
[email protected]8450d722012-07-02 19:14:0410922 const std::string https_url = "https://www.google.com/";
10923 const std::string http_url = "http://www.google.com:443/";
10924
10925 // SPDY GET for HTTPS URL (through CONNECT tunnel)
[email protected]fba2dbde2013-05-24 16:09:0110926 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1));
[email protected]cdf8f7e72013-05-23 10:56:4610927 scoped_ptr<SpdyFrame> req1(
10928 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0410929
10930 // SPDY GET for HTTP URL (through the proxy, but not the tunnel)
[email protected]23e482282013-06-14 16:08:0210931 scoped_ptr<SpdyFrame> wrapped_req1(
10932 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]8450d722012-07-02 19:14:0410933 const char* const headers[] = {
[email protected]23e482282013-06-14 16:08:0210934 spdy_util_.GetMethodKey(), "GET",
10935 spdy_util_.GetPathKey(), spdy_util_.is_spdy2() ? http_url.c_str() : "/",
10936 spdy_util_.GetHostKey(), "www.google.com:443",
10937 spdy_util_.GetSchemeKey(), "http",
10938 spdy_util_.GetVersionKey(), "HTTP/1.1"
[email protected]8450d722012-07-02 19:14:0410939 };
[email protected]4bd46222013-05-14 19:32:2310940 scoped_ptr<SpdyFrame> req2(spdy_util_.ConstructSpdyControlFrame(
10941 NULL, 0, false, 3, MEDIUM, SYN_STREAM, CONTROL_FLAG_FIN,
10942 headers, arraysize(headers), 0));
[email protected]8450d722012-07-02 19:14:0410943
10944 MockWrite writes1[] = {
10945 CreateMockWrite(*connect, 0),
10946 CreateMockWrite(*wrapped_req1, 2),
10947 CreateMockWrite(*req2, 5),
10948 };
10949
[email protected]23e482282013-06-14 16:08:0210950 scoped_ptr<SpdyFrame> conn_resp(
10951 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10952 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10953 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
10954 scoped_ptr<SpdyFrame> wrapped_resp1(
10955 spdy_util_.ConstructWrappedSpdyFrame(resp1, 1));
10956 scoped_ptr<SpdyFrame> wrapped_body1(
10957 spdy_util_.ConstructWrappedSpdyFrame(body1, 1));
10958 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
10959 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]8450d722012-07-02 19:14:0410960 MockRead reads1[] = {
10961 CreateMockRead(*conn_resp, 1),
10962 CreateMockRead(*wrapped_resp1, 3),
10963 CreateMockRead(*wrapped_body1, 4),
10964 CreateMockRead(*resp2, 6),
10965 CreateMockRead(*body2, 7),
10966 MockRead(ASYNC, ERR_IO_PENDING, 8)
10967 };
10968
[email protected]dd54bd82012-07-19 23:44:5710969 DeterministicSocketData data1(reads1, arraysize(reads1),
10970 writes1, arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0410971 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5710972 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0410973
[email protected]bb88e1d32013-05-03 23:11:0710974 session_deps_.proxy_service.reset(
[email protected]f6c63db52013-02-02 00:35:2210975 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
10976 CapturingNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710977 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0410978 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
[email protected]23e482282013-06-14 16:08:0210979 ssl1.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710980 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0410981 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
[email protected]23e482282013-06-14 16:08:0210982 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710983 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
10984 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0410985
10986 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0710987 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]8450d722012-07-02 19:14:0410988
10989 // Start the first transaction to set up the SpdySession
10990 HttpRequestInfo request1;
10991 request1.method = "GET";
10992 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0410993 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5010994 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0410995 TestCompletionCallback callback1;
10996 EXPECT_EQ(ERR_IO_PENDING,
10997 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3410998 base::MessageLoop::current()->RunUntilIdle();
[email protected]dd54bd82012-07-19 23:44:5710999 data1.RunFor(4);
[email protected]8450d722012-07-02 19:14:0411000
11001 EXPECT_EQ(OK, callback1.WaitForResult());
11002 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11003
[email protected]f6c63db52013-02-02 00:35:2211004 LoadTimingInfo load_timing_info1;
11005 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
11006 TestLoadTimingNotReusedWithPac(load_timing_info1,
11007 CONNECT_TIMING_HAS_SSL_TIMES);
11008
[email protected]8450d722012-07-02 19:14:0411009 // Now, start the HTTP request
11010 HttpRequestInfo request2;
11011 request2.method = "GET";
11012 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0411013 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011014 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0411015 TestCompletionCallback callback2;
11016 EXPECT_EQ(ERR_IO_PENDING,
11017 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411018 base::MessageLoop::current()->RunUntilIdle();
[email protected]dd54bd82012-07-19 23:44:5711019 data1.RunFor(3);
[email protected]8450d722012-07-02 19:14:0411020
11021 EXPECT_EQ(OK, callback2.WaitForResult());
11022 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2211023
11024 LoadTimingInfo load_timing_info2;
11025 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
11026 // The established SPDY sessions is considered reused by the HTTP request.
11027 TestLoadTimingReusedWithPac(load_timing_info2);
11028 // HTTP requests over a SPDY session should have a different connection
11029 // socket_log_id than requests over a tunnel.
11030 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0411031}
11032
[email protected]23e482282013-06-14 16:08:0211033TEST_P(HttpNetworkTransactionTest, UseSpdySessionForHttpWhenForced) {
[email protected]8450d722012-07-02 19:14:0411034 HttpStreamFactory::set_force_spdy_always(true);
11035 const std::string https_url = "https://www.google.com/";
11036 const std::string http_url = "http://www.google.com:443/";
11037
11038 // SPDY GET for HTTPS URL
[email protected]cdf8f7e72013-05-23 10:56:4611039 scoped_ptr<SpdyFrame> req1(
11040 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0411041 // SPDY GET for the HTTP URL
[email protected]cdf8f7e72013-05-23 10:56:4611042 scoped_ptr<SpdyFrame> req2(
11043 spdy_util_.ConstructSpdyGet(http_url.c_str(), false, 3, MEDIUM));
[email protected]8450d722012-07-02 19:14:0411044
11045 MockWrite writes[] = {
11046 CreateMockWrite(*req1, 1),
11047 CreateMockWrite(*req2, 4),
11048 };
11049
[email protected]23e482282013-06-14 16:08:0211050 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11051 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
11052 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11053 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]8450d722012-07-02 19:14:0411054 MockRead reads[] = {
11055 CreateMockRead(*resp1, 2),
11056 CreateMockRead(*body1, 3),
11057 CreateMockRead(*resp2, 5),
11058 CreateMockRead(*body2, 6),
11059 MockRead(ASYNC, ERR_IO_PENDING, 7)
11060 };
11061
[email protected]dd54bd82012-07-19 23:44:5711062 OrderedSocketData data(reads, arraysize(reads),
11063 writes, arraysize(writes));
[email protected]8450d722012-07-02 19:14:0411064
[email protected]8450d722012-07-02 19:14:0411065 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211066 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711067 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11068 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8450d722012-07-02 19:14:0411069
[email protected]bb88e1d32013-05-03 23:11:0711070 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0411071
11072 // Start the first transaction to set up the SpdySession
11073 HttpRequestInfo request1;
11074 request1.method = "GET";
11075 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0411076 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011077 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0411078 TestCompletionCallback callback1;
11079 EXPECT_EQ(ERR_IO_PENDING,
11080 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411081 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411082
11083 EXPECT_EQ(OK, callback1.WaitForResult());
11084 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11085
11086 // Now, start the HTTP request
11087 HttpRequestInfo request2;
11088 request2.method = "GET";
11089 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0411090 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011091 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0411092 TestCompletionCallback callback2;
11093 EXPECT_EQ(ERR_IO_PENDING,
11094 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411095 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411096
11097 EXPECT_EQ(OK, callback2.WaitForResult());
11098 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11099}
11100
[email protected]2d88e7d2012-07-19 17:55:1711101// Test that in the case where we have a SPDY session to a SPDY proxy
11102// that we do not pool other origins that resolve to the same IP when
11103// the certificate does not match the new origin.
11104// http://crbug.com/134690
[email protected]23e482282013-06-14 16:08:0211105TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
[email protected]2d88e7d2012-07-19 17:55:1711106 const std::string url1 = "http://www.google.com/";
11107 const std::string url2 = "https://mail.google.com/";
11108 const std::string ip_addr = "1.2.3.4";
11109
11110 // SPDY GET for HTTP URL (through SPDY proxy)
[email protected]23e482282013-06-14 16:08:0211111 scoped_ptr<SpdyHeaderBlock> headers(
11112 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/"));
[email protected]4bd46222013-05-14 19:32:2311113 scoped_ptr<SpdyFrame> req1(spdy_util_.ConstructSpdyControlFrame(
[email protected]23e482282013-06-14 16:08:0211114 headers.Pass(), false, 1, LOWEST, SYN_STREAM, CONTROL_FLAG_FIN, 0));
[email protected]2d88e7d2012-07-19 17:55:1711115
11116 MockWrite writes1[] = {
11117 CreateMockWrite(*req1, 0),
11118 };
11119
[email protected]23e482282013-06-14 16:08:0211120 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11121 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1711122 MockRead reads1[] = {
11123 CreateMockRead(*resp1, 1),
11124 CreateMockRead(*body1, 2),
11125 MockRead(ASYNC, OK, 3) // EOF
11126 };
11127
11128 scoped_ptr<DeterministicSocketData> data1(
11129 new DeterministicSocketData(reads1, arraysize(reads1),
11130 writes1, arraysize(writes1)));
11131 IPAddressNumber ip;
11132 ASSERT_TRUE(ParseIPLiteralToNumber(ip_addr, &ip));
11133 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11134 MockConnect connect_data1(ASYNC, OK, peer_addr);
11135 data1->set_connect_data(connect_data1);
11136
11137 // SPDY GET for HTTPS URL (direct)
[email protected]cdf8f7e72013-05-23 10:56:4611138 scoped_ptr<SpdyFrame> req2(
11139 spdy_util_.ConstructSpdyGet(url2.c_str(), false, 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1711140
11141 MockWrite writes2[] = {
11142 CreateMockWrite(*req2, 0),
11143 };
11144
[email protected]23e482282013-06-14 16:08:0211145 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11146 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1711147 MockRead reads2[] = {
11148 CreateMockRead(*resp2, 1),
11149 CreateMockRead(*body2, 2),
11150 MockRead(ASYNC, OK, 3) // EOF
11151 };
11152
11153 scoped_ptr<DeterministicSocketData> data2(
11154 new DeterministicSocketData(reads2, arraysize(reads2),
11155 writes2, arraysize(writes2)));
11156 MockConnect connect_data2(ASYNC, OK);
11157 data2->set_connect_data(connect_data2);
11158
11159 // Set up a proxy config that sends HTTP requests to a proxy, and
11160 // all others direct.
11161 ProxyConfig proxy_config;
11162 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
11163 CapturingProxyResolver* capturing_proxy_resolver =
11164 new CapturingProxyResolver();
[email protected]bb88e1d32013-05-03 23:11:0711165 session_deps_.proxy_service.reset(new ProxyService(
[email protected]2d88e7d2012-07-19 17:55:1711166 new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver,
11167 NULL));
11168
11169 // Load a valid cert. Note, that this does not need to
11170 // be valid for proxy because the MockSSLClientSocket does
11171 // not actually verify it. But SpdySession will use this
11172 // to see if it is valid for the new origin
[email protected]6cdfd7f2013-02-08 20:40:1511173 base::FilePath certs_dir = GetTestCertsDirectory();
[email protected]2d88e7d2012-07-19 17:55:1711174 scoped_refptr<X509Certificate> server_cert(
11175 ImportCertFromFile(certs_dir, "ok_cert.pem"));
11176 ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert);
11177
11178 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
[email protected]23e482282013-06-14 16:08:0211179 ssl1.SetNextProto(GetParam());
[email protected]2d88e7d2012-07-19 17:55:1711180 ssl1.cert = server_cert;
[email protected]bb88e1d32013-05-03 23:11:0711181 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
11182 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11183 data1.get());
[email protected]2d88e7d2012-07-19 17:55:1711184
11185 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
[email protected]23e482282013-06-14 16:08:0211186 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711187 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11188 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11189 data2.get());
[email protected]2d88e7d2012-07-19 17:55:1711190
[email protected]bb88e1d32013-05-03 23:11:0711191 session_deps_.host_resolver.reset(new MockCachingHostResolver());
11192 session_deps_.host_resolver->rules()->AddRule("mail.google.com", ip_addr);
11193 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1711194
11195 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0711196 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]2d88e7d2012-07-19 17:55:1711197
11198 // Start the first transaction to set up the SpdySession
11199 HttpRequestInfo request1;
11200 request1.method = "GET";
11201 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1711202 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011203 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1711204 TestCompletionCallback callback1;
11205 ASSERT_EQ(ERR_IO_PENDING,
11206 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
11207 data1->RunFor(3);
11208
11209 ASSERT_TRUE(callback1.have_result());
11210 EXPECT_EQ(OK, callback1.WaitForResult());
11211 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11212
11213 // Now, start the HTTP request
11214 HttpRequestInfo request2;
11215 request2.method = "GET";
11216 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1711217 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011218 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1711219 TestCompletionCallback callback2;
11220 EXPECT_EQ(ERR_IO_PENDING,
11221 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411222 base::MessageLoop::current()->RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1711223 data2->RunFor(3);
11224
11225 ASSERT_TRUE(callback2.have_result());
11226 EXPECT_EQ(OK, callback2.WaitForResult());
11227 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11228}
11229
[email protected]85f97342013-04-17 06:12:2411230// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
11231// error) in SPDY session, removes the socket from pool and closes the SPDY
11232// session. Verify that new url's from the same HttpNetworkSession (and a new
11233// SpdySession) do work. http://crbug.com/224701
[email protected]23e482282013-06-14 16:08:0211234TEST_P(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
[email protected]85f97342013-04-17 06:12:2411235 const std::string https_url = "https://www.google.com/";
11236
11237 MockRead reads1[] = {
11238 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
11239 };
11240
11241 scoped_ptr<DeterministicSocketData> data1(
11242 new DeterministicSocketData(reads1, arraysize(reads1), NULL, 0));
11243 data1->SetStop(1);
11244
[email protected]cdf8f7e72013-05-23 10:56:4611245 scoped_ptr<SpdyFrame> req2(
11246 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2411247 MockWrite writes2[] = {
11248 CreateMockWrite(*req2, 0),
11249 };
11250
[email protected]23e482282013-06-14 16:08:0211251 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11252 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]85f97342013-04-17 06:12:2411253 MockRead reads2[] = {
11254 CreateMockRead(*resp2, 1),
11255 CreateMockRead(*body2, 2),
11256 MockRead(ASYNC, OK, 3) // EOF
11257 };
11258
11259 scoped_ptr<DeterministicSocketData> data2(
11260 new DeterministicSocketData(reads2, arraysize(reads2),
11261 writes2, arraysize(writes2)));
11262
[email protected]85f97342013-04-17 06:12:2411263 SSLSocketDataProvider ssl1(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211264 ssl1.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711265 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
11266 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11267 data1.get());
[email protected]85f97342013-04-17 06:12:2411268
11269 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211270 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711271 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11272 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11273 data2.get());
[email protected]85f97342013-04-17 06:12:2411274
11275 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0711276 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]85f97342013-04-17 06:12:2411277
11278 // Start the first transaction to set up the SpdySession and verify that
11279 // connection was closed.
11280 HttpRequestInfo request1;
11281 request1.method = "GET";
11282 request1.url = GURL(https_url);
11283 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011284 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2411285 TestCompletionCallback callback1;
11286 EXPECT_EQ(ERR_IO_PENDING,
11287 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411288 base::MessageLoop::current()->RunUntilIdle();
[email protected]85f97342013-04-17 06:12:2411289 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback1.WaitForResult());
11290
11291 // Now, start the second request and make sure it succeeds.
11292 HttpRequestInfo request2;
11293 request2.method = "GET";
11294 request2.url = GURL(https_url);
11295 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011296 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2411297 TestCompletionCallback callback2;
11298 EXPECT_EQ(ERR_IO_PENDING,
11299 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411300 base::MessageLoop::current()->RunUntilIdle();
[email protected]85f97342013-04-17 06:12:2411301 data2->RunFor(3);
11302
11303 ASSERT_TRUE(callback2.have_result());
11304 EXPECT_EQ(OK, callback2.WaitForResult());
11305 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11306}
11307
[email protected]23e482282013-06-14 16:08:0211308TEST_P(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]483fa202013-05-14 01:07:0311309 HttpStreamFactory::SetNextProtos(SpdyNextProtos());
11310 ClientSocketPoolManager::set_max_sockets_per_group(
11311 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
11312 ClientSocketPoolManager::set_max_sockets_per_pool(
11313 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
11314
11315 // Use two different hosts with different IPs so they don't get pooled.
11316 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
11317 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
11318 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11319
11320 SSLSocketDataProvider ssl1(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211321 ssl1.SetNextProto(GetParam());
[email protected]483fa202013-05-14 01:07:0311322 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211323 ssl2.SetNextProto(GetParam());
[email protected]483fa202013-05-14 01:07:0311324 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
11325 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
11326
[email protected]cdf8f7e72013-05-23 10:56:4611327 scoped_ptr<SpdyFrame> host1_req(spdy_util_.ConstructSpdyGet(
[email protected]483fa202013-05-14 01:07:0311328 "https://www.a.com", false, 1, DEFAULT_PRIORITY));
11329 MockWrite spdy1_writes[] = {
11330 CreateMockWrite(*host1_req, 1),
11331 };
[email protected]23e482282013-06-14 16:08:0211332 scoped_ptr<SpdyFrame> host1_resp(
11333 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11334 scoped_ptr<SpdyFrame> host1_resp_body(
11335 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0311336 MockRead spdy1_reads[] = {
11337 CreateMockRead(*host1_resp, 2),
11338 CreateMockRead(*host1_resp_body, 3),
11339 MockRead(ASYNC, ERR_IO_PENDING, 4),
11340 };
11341
11342 scoped_ptr<OrderedSocketData> spdy1_data(
11343 new OrderedSocketData(
11344 spdy1_reads, arraysize(spdy1_reads),
11345 spdy1_writes, arraysize(spdy1_writes)));
11346 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
11347
[email protected]cdf8f7e72013-05-23 10:56:4611348 scoped_ptr<SpdyFrame> host2_req(spdy_util_.ConstructSpdyGet(
[email protected]483fa202013-05-14 01:07:0311349 "https://www.b.com", false, 1, DEFAULT_PRIORITY));
11350 MockWrite spdy2_writes[] = {
11351 CreateMockWrite(*host2_req, 1),
11352 };
[email protected]23e482282013-06-14 16:08:0211353 scoped_ptr<SpdyFrame> host2_resp(
11354 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11355 scoped_ptr<SpdyFrame> host2_resp_body(
11356 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0311357 MockRead spdy2_reads[] = {
11358 CreateMockRead(*host2_resp, 2),
11359 CreateMockRead(*host2_resp_body, 3),
11360 MockRead(ASYNC, ERR_IO_PENDING, 4),
11361 };
11362
11363 scoped_ptr<OrderedSocketData> spdy2_data(
11364 new OrderedSocketData(
11365 spdy2_reads, arraysize(spdy2_reads),
11366 spdy2_writes, arraysize(spdy2_writes)));
11367 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
11368
11369 MockWrite http_write[] = {
11370 MockWrite("GET / HTTP/1.1\r\n"
11371 "Host: www.a.com\r\n"
11372 "Connection: keep-alive\r\n\r\n"),
11373 };
11374
11375 MockRead http_read[] = {
11376 MockRead("HTTP/1.1 200 OK\r\n"),
11377 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11378 MockRead("Content-Length: 6\r\n\r\n"),
11379 MockRead("hello!"),
11380 };
11381 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
11382 http_write, arraysize(http_write));
11383 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
11384
11385 HostPortPair host_port_pair_a("www.a.com", 443);
[email protected]e6d017652013-05-17 18:01:4011386 SpdySessionKey spdy_session_key_a(
11387 host_port_pair_a, ProxyServer::Direct(), kPrivacyModeDisabled);
[email protected]483fa202013-05-14 01:07:0311388 EXPECT_FALSE(
[email protected]e6d017652013-05-17 18:01:4011389 session->spdy_session_pool()->HasSession(spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0311390
11391 TestCompletionCallback callback;
11392 HttpRequestInfo request1;
11393 request1.method = "GET";
11394 request1.url = GURL("https://www.a.com/");
11395 request1.load_flags = 0;
11396 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5011397 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0311398
11399 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
11400 EXPECT_EQ(ERR_IO_PENDING, rv);
11401 EXPECT_EQ(OK, callback.WaitForResult());
11402
11403 const HttpResponseInfo* response = trans->GetResponseInfo();
11404 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011405 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0311406 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11407 EXPECT_TRUE(response->was_fetched_via_spdy);
11408 EXPECT_TRUE(response->was_npn_negotiated);
11409
11410 std::string response_data;
11411 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11412 EXPECT_EQ("hello!", response_data);
11413 trans.reset();
11414 EXPECT_TRUE(
[email protected]e6d017652013-05-17 18:01:4011415 session->spdy_session_pool()->HasSession(spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0311416
11417 HostPortPair host_port_pair_b("www.b.com", 443);
[email protected]e6d017652013-05-17 18:01:4011418 SpdySessionKey spdy_session_key_b(
11419 host_port_pair_b, ProxyServer::Direct(), kPrivacyModeDisabled);
[email protected]483fa202013-05-14 01:07:0311420 EXPECT_FALSE(
[email protected]e6d017652013-05-17 18:01:4011421 session->spdy_session_pool()->HasSession(spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0311422 HttpRequestInfo request2;
11423 request2.method = "GET";
11424 request2.url = GURL("https://www.b.com/");
11425 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011426 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0311427
11428 rv = trans->Start(&request2, callback.callback(), BoundNetLog());
11429 EXPECT_EQ(ERR_IO_PENDING, rv);
11430 EXPECT_EQ(OK, callback.WaitForResult());
11431
11432 response = trans->GetResponseInfo();
11433 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011434 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0311435 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11436 EXPECT_TRUE(response->was_fetched_via_spdy);
11437 EXPECT_TRUE(response->was_npn_negotiated);
11438 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11439 EXPECT_EQ("hello!", response_data);
11440 EXPECT_FALSE(
[email protected]e6d017652013-05-17 18:01:4011441 session->spdy_session_pool()->HasSession(spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0311442 EXPECT_TRUE(
[email protected]e6d017652013-05-17 18:01:4011443 session->spdy_session_pool()->HasSession(spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0311444
11445 HostPortPair host_port_pair_a1("www.a.com", 80);
[email protected]e6d017652013-05-17 18:01:4011446 SpdySessionKey spdy_session_key_a1(
11447 host_port_pair_a1, ProxyServer::Direct(), kPrivacyModeDisabled);
[email protected]483fa202013-05-14 01:07:0311448 EXPECT_FALSE(
[email protected]e6d017652013-05-17 18:01:4011449 session->spdy_session_pool()->HasSession(spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0311450 HttpRequestInfo request3;
11451 request3.method = "GET";
11452 request3.url = GURL("http://www.a.com/");
11453 request3.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011454 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0311455
11456 rv = trans->Start(&request3, callback.callback(), BoundNetLog());
11457 EXPECT_EQ(ERR_IO_PENDING, rv);
11458 EXPECT_EQ(OK, callback.WaitForResult());
11459
11460 response = trans->GetResponseInfo();
11461 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011462 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0311463 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11464 EXPECT_FALSE(response->was_fetched_via_spdy);
11465 EXPECT_FALSE(response->was_npn_negotiated);
11466 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11467 EXPECT_EQ("hello!", response_data);
11468 EXPECT_FALSE(
[email protected]e6d017652013-05-17 18:01:4011469 session->spdy_session_pool()->HasSession(spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0311470 EXPECT_FALSE(
[email protected]e6d017652013-05-17 18:01:4011471 session->spdy_session_pool()->HasSession(spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0311472
11473 HttpStreamFactory::SetNextProtos(std::vector<std::string>());
11474}
11475
[email protected]79e1fd62013-06-20 06:50:0411476TEST_P(HttpNetworkTransactionTest, HttpSyncConnectError) {
11477 HttpRequestInfo request;
11478 request.method = "GET";
11479 request.url = GURL("http://www.google.com/");
11480 request.load_flags = 0;
11481
11482 scoped_ptr<HttpTransaction> trans(
11483 new HttpNetworkTransaction(DEFAULT_PRIORITY,
11484 CreateSession(&session_deps_)));
11485
11486 MockConnect mock_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
11487 StaticSocketDataProvider data;
11488 data.set_connect_data(mock_connect);
11489 session_deps_.socket_factory->AddSocketDataProvider(&data);
11490
11491 TestCompletionCallback callback;
11492
11493 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11494 EXPECT_EQ(ERR_IO_PENDING, rv);
11495
11496 rv = callback.WaitForResult();
11497 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
11498
11499 EXPECT_EQ(NULL, trans->GetResponseInfo());
11500
11501 // We don't care whether this succeeds or fails, but it shouldn't crash.
11502 HttpRequestHeaders request_headers;
11503 trans->GetFullRequestHeaders(&request_headers);
11504}
11505
11506TEST_P(HttpNetworkTransactionTest, HttpAsyncConnectError) {
11507 HttpRequestInfo request;
11508 request.method = "GET";
11509 request.url = GURL("http://www.google.com/");
11510 request.load_flags = 0;
11511
11512 scoped_ptr<HttpTransaction> trans(
11513 new HttpNetworkTransaction(DEFAULT_PRIORITY,
11514 CreateSession(&session_deps_)));
11515
11516 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11517 StaticSocketDataProvider data;
11518 data.set_connect_data(mock_connect);
11519 session_deps_.socket_factory->AddSocketDataProvider(&data);
11520
11521 TestCompletionCallback callback;
11522
11523 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11524 EXPECT_EQ(ERR_IO_PENDING, rv);
11525
11526 rv = callback.WaitForResult();
11527 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
11528
11529 EXPECT_EQ(NULL, trans->GetResponseInfo());
11530
11531 // We don't care whether this succeeds or fails, but it shouldn't crash.
11532 HttpRequestHeaders request_headers;
11533 trans->GetFullRequestHeaders(&request_headers);
11534}
11535
11536TEST_P(HttpNetworkTransactionTest, HttpSyncWriteError) {
11537 HttpRequestInfo request;
11538 request.method = "GET";
11539 request.url = GURL("http://www.google.com/");
11540 request.load_flags = 0;
11541
11542 scoped_ptr<HttpTransaction> trans(
11543 new HttpNetworkTransaction(DEFAULT_PRIORITY,
11544 CreateSession(&session_deps_)));
11545
11546 MockWrite data_writes[] = {
11547 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
11548 };
11549 MockRead data_reads[] = {
11550 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
11551 };
11552
11553 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11554 data_writes, arraysize(data_writes));
11555 session_deps_.socket_factory->AddSocketDataProvider(&data);
11556
11557 TestCompletionCallback callback;
11558
11559 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11560 EXPECT_EQ(ERR_IO_PENDING, rv);
11561
11562 rv = callback.WaitForResult();
11563 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
11564
11565 EXPECT_EQ(NULL, trans->GetResponseInfo());
11566
11567 HttpRequestHeaders request_headers;
11568 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
11569 EXPECT_TRUE(request_headers.HasHeader("Host"));
11570}
11571
11572TEST_P(HttpNetworkTransactionTest, HttpAsyncWriteError) {
11573 HttpRequestInfo request;
11574 request.method = "GET";
11575 request.url = GURL("http://www.google.com/");
11576 request.load_flags = 0;
11577
11578 scoped_ptr<HttpTransaction> trans(
11579 new HttpNetworkTransaction(DEFAULT_PRIORITY,
11580 CreateSession(&session_deps_)));
11581
11582 MockWrite data_writes[] = {
11583 MockWrite(ASYNC, ERR_CONNECTION_RESET),
11584 };
11585 MockRead data_reads[] = {
11586 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
11587 };
11588
11589 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11590 data_writes, arraysize(data_writes));
11591 session_deps_.socket_factory->AddSocketDataProvider(&data);
11592
11593 TestCompletionCallback callback;
11594
11595 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11596 EXPECT_EQ(ERR_IO_PENDING, rv);
11597
11598 rv = callback.WaitForResult();
11599 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
11600
11601 EXPECT_EQ(NULL, trans->GetResponseInfo());
11602
11603 HttpRequestHeaders request_headers;
11604 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
11605 EXPECT_TRUE(request_headers.HasHeader("Host"));
11606}
11607
11608TEST_P(HttpNetworkTransactionTest, HttpSyncReadError) {
11609 HttpRequestInfo request;
11610 request.method = "GET";
11611 request.url = GURL("http://www.google.com/");
11612 request.load_flags = 0;
11613
11614 scoped_ptr<HttpTransaction> trans(
11615 new HttpNetworkTransaction(DEFAULT_PRIORITY,
11616 CreateSession(&session_deps_)));
11617
11618 MockWrite data_writes[] = {
11619 MockWrite("GET / HTTP/1.1\r\n"
11620 "Host: www.google.com\r\n"
11621 "Connection: keep-alive\r\n\r\n"),
11622 };
11623 MockRead data_reads[] = {
11624 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
11625 };
11626
11627 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11628 data_writes, arraysize(data_writes));
11629 session_deps_.socket_factory->AddSocketDataProvider(&data);
11630
11631 TestCompletionCallback callback;
11632
11633 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11634 EXPECT_EQ(ERR_IO_PENDING, rv);
11635
11636 rv = callback.WaitForResult();
11637 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
11638
11639 EXPECT_EQ(NULL, trans->GetResponseInfo());
11640
11641 HttpRequestHeaders request_headers;
11642 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
11643 EXPECT_TRUE(request_headers.HasHeader("Host"));
11644}
11645
11646TEST_P(HttpNetworkTransactionTest, HttpAsyncReadError) {
11647 HttpRequestInfo request;
11648 request.method = "GET";
11649 request.url = GURL("http://www.google.com/");
11650 request.load_flags = 0;
11651
11652 scoped_ptr<HttpTransaction> trans(
11653 new HttpNetworkTransaction(DEFAULT_PRIORITY,
11654 CreateSession(&session_deps_)));
11655
11656 MockWrite data_writes[] = {
11657 MockWrite("GET / HTTP/1.1\r\n"
11658 "Host: www.google.com\r\n"
11659 "Connection: keep-alive\r\n\r\n"),
11660 };
11661 MockRead data_reads[] = {
11662 MockRead(ASYNC, ERR_CONNECTION_RESET),
11663 };
11664
11665 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11666 data_writes, arraysize(data_writes));
11667 session_deps_.socket_factory->AddSocketDataProvider(&data);
11668
11669 TestCompletionCallback callback;
11670
11671 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11672 EXPECT_EQ(ERR_IO_PENDING, rv);
11673
11674 rv = callback.WaitForResult();
11675 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
11676
11677 EXPECT_EQ(NULL, trans->GetResponseInfo());
11678
11679 HttpRequestHeaders request_headers;
11680 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
11681 EXPECT_TRUE(request_headers.HasHeader("Host"));
11682}
11683
11684TEST_P(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
11685 HttpRequestInfo request;
11686 request.method = "GET";
11687 request.url = GURL("http://www.google.com/");
11688 request.load_flags = 0;
11689 request.extra_headers.SetHeader("X-Foo", "bar");
11690
11691 scoped_ptr<HttpTransaction> trans(
11692 new HttpNetworkTransaction(DEFAULT_PRIORITY,
11693 CreateSession(&session_deps_)));
11694
11695 MockWrite data_writes[] = {
11696 MockWrite("GET / HTTP/1.1\r\n"
11697 "Host: www.google.com\r\n"
11698 "Connection: keep-alive\r\n"
11699 "X-Foo: bar\r\n\r\n"),
11700 };
11701 MockRead data_reads[] = {
11702 MockRead("HTTP/1.1 200 OK\r\n"
11703 "Content-Length: 5\r\n\r\n"
11704 "hello"),
11705 MockRead(ASYNC, ERR_UNEXPECTED),
11706 };
11707
11708 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11709 data_writes, arraysize(data_writes));
11710 session_deps_.socket_factory->AddSocketDataProvider(&data);
11711
11712 TestCompletionCallback callback;
11713
11714 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11715 EXPECT_EQ(ERR_IO_PENDING, rv);
11716
11717 rv = callback.WaitForResult();
11718 EXPECT_EQ(OK, rv);
11719
11720 HttpRequestHeaders request_headers;
11721 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
11722 std::string foo;
11723 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
11724 EXPECT_EQ("bar", foo);
11725}
11726
[email protected]89ceba9a2009-03-21 03:46:0611727} // namespace net