blob: 7939921ed8f331b8d7b77fa3937b6cd68015d7f7 [file] [log] [blame]
[email protected]23e482282013-06-14 16:08:021// Copyright 2013 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit586acc5fe2008-07-26 22:42:524
[email protected]2d731a32010-04-29 01:04:065#include "net/http/http_network_transaction.h"
6
[email protected]77848d12008-11-14 00:00:227#include <math.h> // ceil
[email protected]5285d972011-10-18 18:56:348#include <stdarg.h>
9#include <string>
[email protected]95d88ffe2010-02-04 21:25:3310#include <vector>
[email protected]77848d12008-11-14 00:00:2211
[email protected]2d731a32010-04-29 01:04:0612#include "base/basictypes.h"
[email protected]68bf9152008-09-25 19:47:3013#include "base/compiler_specific.h"
[email protected]57999812013-02-24 05:40:5214#include "base/files/file_path.h"
thestigd8df0332014-09-04 06:33:2915#include "base/files/file_util.h"
[email protected]f3da152d2012-06-02 01:00:5716#include "base/json/json_writer.h"
Adam Rice425cf122015-01-19 06:18:2417#include "base/logging.h"
[email protected]3b63f8f42011-03-28 01:54:1518#include "base/memory/scoped_ptr.h"
[email protected]bf828982013-08-14 18:01:4719#include "base/memory/weak_ptr.h"
[email protected]a34f61ee2014-03-18 20:59:4920#include "base/run_loop.h"
bnc1b0e36852015-04-28 15:32:5921#include "base/stl_util.h"
[email protected]125ef482013-06-11 18:32:4722#include "base/strings/string_util.h"
[email protected]750b2f3c2013-06-07 18:41:0523#include "base/strings/utf_string_conversions.h"
[email protected]f36a8132011-09-02 18:36:3324#include "base/test/test_file_util.h"
[email protected]277d5942010-08-11 21:02:3525#include "net/base/auth.h"
mmenkecbc2b712014-10-09 20:29:0726#include "net/base/chunked_upload_data_stream.h"
[email protected]bacff652009-03-31 17:50:3327#include "net/base/completion_callback.h"
mmenkecbc2b712014-10-09 20:29:0728#include "net/base/elements_upload_data_stream.h"
[email protected]58e32bb2013-01-21 18:23:2529#include "net/base/load_timing_info.h"
30#include "net/base/load_timing_info_test_util.h"
Adam Rice425cf122015-01-19 06:18:2431#include "net/base/net_errors.h"
[email protected]ac790b42009-12-02 04:31:3132#include "net/base/request_priority.h"
initial.commit586acc5fe2008-07-26 22:42:5233#include "net/base/test_completion_callback.h"
[email protected]42fdb452012-11-01 12:44:4034#include "net/base/test_data_directory.h"
[email protected]b2d26cfd2012-12-11 10:36:0635#include "net/base/upload_bytes_element_reader.h"
[email protected]d98961652012-09-11 20:27:2136#include "net/base/upload_file_element_reader.h"
[email protected]6e7845ae2013-03-29 21:48:1137#include "net/cert/mock_cert_verifier.h"
[email protected]bc71b8772013-04-10 20:55:1638#include "net/dns/host_cache.h"
[email protected]f2cb3cf2013-03-21 01:40:5339#include "net/dns/mock_host_resolver.h"
[email protected]df41d0d82014-03-13 00:43:2440#include "net/http/http_auth_challenge_tokenizer.h"
[email protected]3c32c5f2010-05-18 15:18:1241#include "net/http/http_auth_handler_digest.h"
[email protected]3fd9dae2010-06-21 11:39:0042#include "net/http/http_auth_handler_mock.h"
[email protected]385a4672009-03-11 22:21:2943#include "net/http/http_auth_handler_ntlm.h"
Adam Rice425cf122015-01-19 06:18:2444#include "net/http/http_basic_state.h"
[email protected]0877e3d2009-10-17 22:29:5745#include "net/http/http_basic_stream.h"
initial.commit586acc5fe2008-07-26 22:42:5246#include "net/http/http_network_session.h"
[email protected]87bfa3f2010-09-30 14:54:5647#include "net/http/http_network_session_peer.h"
Adam Rice425cf122015-01-19 06:18:2448#include "net/http/http_request_headers.h"
[email protected]17291a022011-10-10 07:32:5349#include "net/http/http_server_properties_impl.h"
[email protected]0877e3d2009-10-17 22:29:5750#include "net/http/http_stream.h"
[email protected]8e6441ca2010-08-19 05:56:3851#include "net/http/http_stream_factory.h"
Adam Rice425cf122015-01-19 06:18:2452#include "net/http/http_stream_parser.h"
[email protected]c41737d2014-05-14 07:47:1953#include "net/http/http_transaction_test_util.h"
eroman87c53d62015-04-02 06:51:0754#include "net/log/net_log.h"
vishal.b62985ca92015-04-17 08:45:5155#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4656#include "net/log/test_net_log_entry.h"
57#include "net/log/test_net_log_util.h"
sammc5dd160c2015-04-02 02:43:1358#include "net/proxy/mock_proxy_resolver.h"
[email protected]51fff29d2008-12-19 22:17:5359#include "net/proxy/proxy_config_service_fixed.h"
[email protected]e86839fd2013-08-14 18:29:0360#include "net/proxy/proxy_info.h"
[email protected]631f1322010-04-30 17:59:1161#include "net/proxy/proxy_resolver.h"
62#include "net/proxy/proxy_service.h"
[email protected]f7984fc62009-06-22 23:26:4463#include "net/socket/client_socket_factory.h"
[email protected]483fa202013-05-14 01:07:0364#include "net/socket/client_socket_pool_manager.h"
ttuttle1f2d7e92015-04-28 16:17:4765#include "net/socket/connection_attempts.h"
[email protected]a42dbd142011-11-17 16:42:0266#include "net/socket/mock_client_socket_pool_manager.h"
[email protected]bb88e1d32013-05-03 23:11:0767#include "net/socket/next_proto.h"
[email protected]f7984fc62009-06-22 23:26:4468#include "net/socket/socket_test_util.h"
69#include "net/socket/ssl_client_socket.h"
[email protected]2ff8b312010-04-26 22:20:5470#include "net/spdy/spdy_framer.h"
71#include "net/spdy/spdy_session.h"
72#include "net/spdy/spdy_session_pool.h"
[email protected]23e482282013-06-14 16:08:0273#include "net/spdy/spdy_test_util_common.h"
[email protected]536fd0b2013-03-14 17:41:5774#include "net/ssl/ssl_cert_request_info.h"
[email protected]e86839fd2013-08-14 18:29:0375#include "net/ssl/ssl_config_service.h"
[email protected]536fd0b2013-03-14 17:41:5776#include "net/ssl/ssl_config_service_defaults.h"
77#include "net/ssl/ssl_info.h"
[email protected]6e7845ae2013-03-29 21:48:1178#include "net/test/cert_test_util.h"
[email protected]831e4a32013-11-14 02:14:4479#include "net/websockets/websocket_handshake_stream_base.h"
initial.commit586acc5fe2008-07-26 22:42:5280#include "testing/gtest/include/gtest/gtest.h"
[email protected]23887f04f2008-12-02 19:20:1581#include "testing/platform_test.h"
[email protected]795cbf82013-07-22 09:37:2782#include "url/gurl.h"
initial.commit586acc5fe2008-07-26 22:42:5283
[email protected]ad65a3e2013-12-25 18:18:0184using base::ASCIIToUTF16;
85
initial.commit586acc5fe2008-07-26 22:42:5286//-----------------------------------------------------------------------------
87
ttuttle859dc7a2015-04-23 19:42:2988namespace net {
89
[email protected]13c8a092010-07-29 06:15:4490namespace {
91
[email protected]42cba2fb2013-03-29 19:58:5792const base::string16 kBar(ASCIIToUTF16("bar"));
93const base::string16 kBar2(ASCIIToUTF16("bar2"));
94const base::string16 kBar3(ASCIIToUTF16("bar3"));
95const base::string16 kBaz(ASCIIToUTF16("baz"));
96const base::string16 kFirst(ASCIIToUTF16("first"));
97const base::string16 kFoo(ASCIIToUTF16("foo"));
98const base::string16 kFoo2(ASCIIToUTF16("foo2"));
99const base::string16 kFoo3(ASCIIToUTF16("foo3"));
100const base::string16 kFou(ASCIIToUTF16("fou"));
101const base::string16 kSecond(ASCIIToUTF16("second"));
102const base::string16 kTestingNTLM(ASCIIToUTF16("testing-ntlm"));
103const base::string16 kWrongPassword(ASCIIToUTF16("wrongpassword"));
[email protected]13c8a092010-07-29 06:15:44104
ttuttle859dc7a2015-04-23 19:42:29105int GetIdleSocketCountInTransportSocketPool(HttpNetworkSession* session) {
106 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
107 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02108}
109
ttuttle859dc7a2015-04-23 19:42:29110int GetIdleSocketCountInSSLSocketPool(HttpNetworkSession* session) {
111 return session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
112 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02113}
114
ttuttle859dc7a2015-04-23 19:42:29115bool IsTransportSocketPoolStalled(HttpNetworkSession* session) {
116 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
117 ->IsStalled();
[email protected]043b68c82013-08-22 23:41:52118}
119
[email protected]f3da152d2012-06-02 01:00:57120// Takes in a Value created from a NetLogHttpResponseParameter, and returns
121// a JSONified list of headers as a single string. Uses single quotes instead
122// of double quotes for easier comparison. Returns false on failure.
[email protected]ea5ef4c2013-06-13 22:50:27123bool GetHeaders(base::DictionaryValue* params, std::string* headers) {
[email protected]f3da152d2012-06-02 01:00:57124 if (!params)
125 return false;
[email protected]ea5ef4c2013-06-13 22:50:27126 base::ListValue* header_list;
[email protected]f3da152d2012-06-02 01:00:57127 if (!params->GetList("headers", &header_list))
128 return false;
129 std::string double_quote_headers;
130 base::JSONWriter::Write(header_list, &double_quote_headers);
[email protected]466c9862013-12-03 22:05:28131 base::ReplaceChars(double_quote_headers, "\"", "'", headers);
[email protected]f3da152d2012-06-02 01:00:57132 return true;
133}
134
[email protected]029c83b62013-01-24 05:28:20135// Tests LoadTimingInfo in the case a socket is reused and no PAC script is
136// used.
ttuttle859dc7a2015-04-23 19:42:29137void TestLoadTimingReused(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20138 EXPECT_TRUE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:29139 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]58e32bb2013-01-21 18:23:25140
[email protected]029c83b62013-01-24 05:28:20141 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
142 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
143
ttuttle859dc7a2015-04-23 19:42:29144 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20145 EXPECT_FALSE(load_timing_info.send_start.is_null());
[email protected]58e32bb2013-01-21 18:23:25146
147 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]58e32bb2013-01-21 18:23:25148
[email protected]3b23a222013-05-15 21:33:25149 // Set at a higher level.
[email protected]58e32bb2013-01-21 18:23:25150 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
151 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25152 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25153}
154
[email protected]029c83b62013-01-24 05:28:20155// Tests LoadTimingInfo in the case a new socket is used and no PAC script is
156// used.
ttuttle859dc7a2015-04-23 19:42:29157void TestLoadTimingNotReused(const LoadTimingInfo& load_timing_info,
[email protected]58e32bb2013-01-21 18:23:25158 int connect_timing_flags) {
[email protected]029c83b62013-01-24 05:28:20159 EXPECT_FALSE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:29160 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20161
162 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
163 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
164
ttuttle859dc7a2015-04-23 19:42:29165 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
166 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20167 EXPECT_LE(load_timing_info.connect_timing.connect_end,
168 load_timing_info.send_start);
169
170 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20171
[email protected]3b23a222013-05-15 21:33:25172 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20173 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
174 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25175 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20176}
177
178// Tests LoadTimingInfo in the case a socket is reused and a PAC script is
179// used.
ttuttle859dc7a2015-04-23 19:42:29180void TestLoadTimingReusedWithPac(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20181 EXPECT_TRUE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:29182 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20183
ttuttle859dc7a2015-04-23 19:42:29184 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20185
186 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
187 EXPECT_LE(load_timing_info.proxy_resolve_start,
188 load_timing_info.proxy_resolve_end);
189 EXPECT_LE(load_timing_info.proxy_resolve_end,
190 load_timing_info.send_start);
191 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20192
[email protected]3b23a222013-05-15 21:33:25193 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20194 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
195 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25196 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20197}
198
199// Tests LoadTimingInfo in the case a new socket is used and a PAC script is
200// used.
ttuttle859dc7a2015-04-23 19:42:29201void TestLoadTimingNotReusedWithPac(const LoadTimingInfo& load_timing_info,
[email protected]029c83b62013-01-24 05:28:20202 int connect_timing_flags) {
203 EXPECT_FALSE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:29204 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20205
206 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
207 EXPECT_LE(load_timing_info.proxy_resolve_start,
208 load_timing_info.proxy_resolve_end);
209 EXPECT_LE(load_timing_info.proxy_resolve_end,
210 load_timing_info.connect_timing.connect_start);
ttuttle859dc7a2015-04-23 19:42:29211 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
212 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20213 EXPECT_LE(load_timing_info.connect_timing.connect_end,
214 load_timing_info.send_start);
215
216 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20217
[email protected]3b23a222013-05-15 21:33:25218 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20219 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
220 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25221 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25222}
223
ttuttle859dc7a2015-04-23 19:42:29224void AddWebSocketHeaders(HttpRequestHeaders* headers) {
Adam Rice425cf122015-01-19 06:18:24225 headers->SetHeader("Connection", "Upgrade");
226 headers->SetHeader("Upgrade", "websocket");
bncce36dca22015-04-21 22:11:23227 headers->SetHeader("Origin", "http://www.example.org");
Adam Rice425cf122015-01-19 06:18:24228 headers->SetHeader("Sec-WebSocket-Version", "13");
229 headers->SetHeader("Sec-WebSocket-Key", "dGhlIHNhbXBsZSBub25jZQ==");
230}
231
[email protected]c6bf8152012-12-02 07:43:34232HttpNetworkSession* CreateSession(SpdySessionDependencies* session_deps) {
233 return SpdySessionDependencies::SpdyCreateSession(session_deps);
[email protected]e8d536192008-10-17 22:21:14234}
235
[email protected]448d4ca52012-03-04 04:12:23236} // namespace
237
[email protected]23e482282013-06-14 16:08:02238class HttpNetworkTransactionTest
239 : public PlatformTest,
240 public ::testing::WithParamInterface<NextProto> {
[email protected]483fa202013-05-14 01:07:03241 public:
[email protected]23e482282013-06-14 16:08:02242 virtual ~HttpNetworkTransactionTest() {
[email protected]483fa202013-05-14 01:07:03243 // Important to restore the per-pool limit first, since the pool limit must
244 // always be greater than group limit, and the tests reduce both limits.
245 ClientSocketPoolManager::set_max_sockets_per_pool(
246 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
247 ClientSocketPoolManager::set_max_sockets_per_group(
248 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
249 }
250
[email protected]e3ceb682011-06-28 23:55:46251 protected:
[email protected]23e482282013-06-14 16:08:02252 HttpNetworkTransactionTest()
253 : spdy_util_(GetParam()),
254 session_deps_(GetParam()),
[email protected]483fa202013-05-14 01:07:03255 old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
256 HttpNetworkSession::NORMAL_SOCKET_POOL)),
257 old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
258 HttpNetworkSession::NORMAL_SOCKET_POOL)) {
259 }
[email protected]bb88e1d32013-05-03 23:11:07260
[email protected]e3ceb682011-06-28 23:55:46261 struct SimpleGetHelperResult {
262 int rv;
263 std::string status_line;
264 std::string response_data;
[email protected]b8015c42013-12-24 15:18:19265 int64 totalReceivedBytes;
[email protected]58e32bb2013-01-21 18:23:25266 LoadTimingInfo load_timing_info;
ttuttle1f2d7e92015-04-28 16:17:47267 ConnectionAttempts connection_attempts;
[email protected]e3ceb682011-06-28 23:55:46268 };
269
dcheng67be2b1f2014-10-27 21:47:29270 void SetUp() override {
[email protected]0b0bf032010-09-21 18:08:50271 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:34272 base::MessageLoop::current()->RunUntilIdle();
[email protected]2ff8b312010-04-26 22:20:54273 }
274
dcheng67be2b1f2014-10-27 21:47:29275 void TearDown() override {
[email protected]0b0bf032010-09-21 18:08:50276 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:34277 base::MessageLoop::current()->RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09278 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:34279 base::MessageLoop::current()->RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09280 PlatformTest::TearDown();
[email protected]0b0bf032010-09-21 18:08:50281 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:34282 base::MessageLoop::current()->RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09283 }
284
bnc33b8cef42014-11-19 17:30:38285 const char* GetAlternateProtocolFromParam() {
286 return
287 AlternateProtocolToString(AlternateProtocolFromNextProto(GetParam()));
288 }
289
[email protected]8a0fc822013-06-27 20:52:43290 // This is the expected return from a current server advertising SPDY.
291 std::string GetAlternateProtocolHttpHeader() {
bnc33b8cef42014-11-19 17:30:38292 return std::string("Alternate-Protocol: 443:") +
293 GetAlternateProtocolFromParam() + "\r\n\r\n";
[email protected]8a0fc822013-06-27 20:52:43294 }
295
[email protected]202965992011-12-07 23:04:51296 // Either |write_failure| specifies a write failure or |read_failure|
297 // specifies a read failure when using a reused socket. In either case, the
298 // failure should cause the network transaction to resend the request, and the
299 // other argument should be NULL.
300 void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
301 const MockRead* read_failure);
initial.commit586acc5fe2008-07-26 22:42:52302
[email protected]a34f61ee2014-03-18 20:59:49303 // Either |write_failure| specifies a write failure or |read_failure|
304 // specifies a read failure when using a reused socket. In either case, the
305 // failure should cause the network transaction to resend the request, and the
306 // other argument should be NULL.
307 void PreconnectErrorResendRequestTest(const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:10308 const MockRead* read_failure,
309 bool use_spdy);
[email protected]a34f61ee2014-03-18 20:59:49310
[email protected]5a60c8b2011-10-19 20:14:29311 SimpleGetHelperResult SimpleGetHelperForData(StaticSocketDataProvider* data[],
312 size_t data_count) {
[email protected]ff007e162009-05-23 09:13:15313 SimpleGetHelperResult out;
initial.commit586acc5fe2008-07-26 22:42:52314
[email protected]ff007e162009-05-23 09:13:15315 HttpRequestInfo request;
316 request.method = "GET";
bncce36dca22015-04-21 22:11:23317 request.url = GURL("http://www.example.org/");
[email protected]ff007e162009-05-23 09:13:15318 request.load_flags = 0;
initial.commit586acc5fe2008-07-26 22:42:52319
vishal.b62985ca92015-04-17 08:45:51320 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:07321 session_deps_.net_log = log.bound().net_log();
[email protected]3fe8d2f82013-10-17 08:56:07322 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:27323 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:41324 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:27325
[email protected]5a60c8b2011-10-19 20:14:29326 for (size_t i = 0; i < data_count; ++i) {
[email protected]bb88e1d32013-05-03 23:11:07327 session_deps_.socket_factory->AddSocketDataProvider(data[i]);
[email protected]5a60c8b2011-10-19 20:14:29328 }
initial.commit586acc5fe2008-07-26 22:42:52329
[email protected]49639fa2011-12-20 23:22:41330 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52331
eroman001c3742015-04-23 03:11:17332 EXPECT_TRUE(log.bound().GetCaptureMode().enabled());
[email protected]49639fa2011-12-20 23:22:41333 int rv = trans->Start(&request, callback.callback(), log.bound());
[email protected]ff007e162009-05-23 09:13:15334 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:52335
[email protected]ff007e162009-05-23 09:13:15336 out.rv = callback.WaitForResult();
[email protected]58e32bb2013-01-21 18:23:25337
338 // Even in the failure cases that use this function, connections are always
339 // successfully established before the error.
340 EXPECT_TRUE(trans->GetLoadTimingInfo(&out.load_timing_info));
341 TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
342
[email protected]ff007e162009-05-23 09:13:15343 if (out.rv != OK)
344 return out;
345
346 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50347 // Can't use ASSERT_* inside helper functions like this, so
348 // return an error.
[email protected]90499482013-06-01 00:39:50349 if (response == NULL || response->headers.get() == NULL) {
[email protected]fe2255a2011-09-20 19:37:50350 out.rv = ERR_UNEXPECTED;
351 return out;
352 }
[email protected]ff007e162009-05-23 09:13:15353 out.status_line = response->headers->GetStatusLine();
354
[email protected]80a09a82012-11-16 17:40:06355 EXPECT_EQ("127.0.0.1", response->socket_address.host());
356 EXPECT_EQ(80, response->socket_address.port());
[email protected]6d81b482011-02-22 19:47:19357
[email protected]ff007e162009-05-23 09:13:15358 rv = ReadTransaction(trans.get(), &out.response_data);
359 EXPECT_EQ(OK, rv);
[email protected]b2fcd0e2010-12-01 15:19:40360
mmenke43758e62015-05-04 21:09:46361 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40362 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:39363 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:40364 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
[email protected]169d0012010-05-10 23:20:12365 NetLog::PHASE_NONE);
[email protected]dbb83db2010-05-11 18:13:39366 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:40367 entries, pos,
[email protected]dbb83db2010-05-11 18:13:39368 NetLog::TYPE_HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
369 NetLog::PHASE_NONE);
[email protected]ff007e162009-05-23 09:13:15370
[email protected]f3da152d2012-06-02 01:00:57371 std::string line;
372 EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
373 EXPECT_EQ("GET / HTTP/1.1\r\n", line);
374
[email protected]79e1fd62013-06-20 06:50:04375 HttpRequestHeaders request_headers;
376 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
377 std::string value;
378 EXPECT_TRUE(request_headers.GetHeader("Host", &value));
bncce36dca22015-04-21 22:11:23379 EXPECT_EQ("www.example.org", value);
[email protected]79e1fd62013-06-20 06:50:04380 EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
381 EXPECT_EQ("keep-alive", value);
382
383 std::string response_headers;
384 EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
bncce36dca22015-04-21 22:11:23385 EXPECT_EQ("['Host: www.example.org','Connection: keep-alive']",
[email protected]79e1fd62013-06-20 06:50:04386 response_headers);
[email protected]3deb9a52010-11-11 00:24:40387
[email protected]b8015c42013-12-24 15:18:19388 out.totalReceivedBytes = trans->GetTotalReceivedBytes();
ttuttle1f2d7e92015-04-28 16:17:47389 trans->GetConnectionAttempts(&out.connection_attempts);
[email protected]aecfbf22008-10-16 02:02:47390 return out;
[email protected]ff007e162009-05-23 09:13:15391 }
initial.commit586acc5fe2008-07-26 22:42:52392
[email protected]5a60c8b2011-10-19 20:14:29393 SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[],
394 size_t reads_count) {
395 StaticSocketDataProvider reads(data_reads, reads_count, NULL, 0);
396 StaticSocketDataProvider* data[] = { &reads };
397 return SimpleGetHelperForData(data, 1);
398 }
399
[email protected]b8015c42013-12-24 15:18:19400 int64 ReadsSize(MockRead data_reads[], size_t reads_count) {
401 int64 size = 0;
402 for (size_t i = 0; i < reads_count; ++i)
403 size += data_reads[i].data_len;
404 return size;
405 }
406
[email protected]ff007e162009-05-23 09:13:15407 void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
408 int expected_status);
initial.commit586acc5fe2008-07-26 22:42:52409
[email protected]ff007e162009-05-23 09:13:15410 void ConnectStatusHelper(const MockRead& status);
[email protected]bb88e1d32013-05-03 23:11:07411
412 void BypassHostCacheOnRefreshHelper(int load_flags);
413
414 void CheckErrorIsPassedBack(int error, IoMode mode);
415
[email protected]4bd46222013-05-14 19:32:23416 SpdyTestUtil spdy_util_;
[email protected]bb88e1d32013-05-03 23:11:07417 SpdySessionDependencies session_deps_;
[email protected]483fa202013-05-14 01:07:03418
419 // Original socket limits. Some tests set these. Safest to always restore
420 // them once each test has been run.
421 int old_max_group_sockets_;
422 int old_max_pool_sockets_;
[email protected]ff007e162009-05-23 09:13:15423};
[email protected]231d5a32008-09-13 00:45:27424
bnc57685ae62015-03-10 21:27:20425INSTANTIATE_TEST_CASE_P(NextProto,
426 HttpNetworkTransactionTest,
427 testing::Values(kProtoSPDY31,
428 kProtoSPDY4_14,
429 kProtoSPDY4));
[email protected]23e482282013-06-14 16:08:02430
[email protected]448d4ca52012-03-04 04:12:23431namespace {
432
[email protected]1826a402014-01-08 15:40:48433class BeforeNetworkStartHandler {
434 public:
435 explicit BeforeNetworkStartHandler(bool defer)
436 : defer_on_before_network_start_(defer),
437 observed_before_network_start_(false) {}
438
439 void OnBeforeNetworkStart(bool* defer) {
440 *defer = defer_on_before_network_start_;
441 observed_before_network_start_ = true;
442 }
443
444 bool observed_before_network_start() const {
445 return observed_before_network_start_;
446 }
447
448 private:
449 const bool defer_on_before_network_start_;
450 bool observed_before_network_start_;
451
452 DISALLOW_COPY_AND_ASSIGN(BeforeNetworkStartHandler);
453};
454
[email protected]597a1ab2014-06-26 08:12:27455class BeforeProxyHeadersSentHandler {
456 public:
457 BeforeProxyHeadersSentHandler()
458 : observed_before_proxy_headers_sent_(false) {}
459
[email protected]1252d42f2014-07-01 21:20:20460 void OnBeforeProxyHeadersSent(const ProxyInfo& proxy_info,
461 HttpRequestHeaders* request_headers) {
[email protected]597a1ab2014-06-26 08:12:27462 observed_before_proxy_headers_sent_ = true;
463 observed_proxy_server_uri_ = proxy_info.proxy_server().ToURI();
464 }
465
466 bool observed_before_proxy_headers_sent() const {
467 return observed_before_proxy_headers_sent_;
468 }
469
470 std::string observed_proxy_server_uri() const {
471 return observed_proxy_server_uri_;
472 }
473
474 private:
475 bool observed_before_proxy_headers_sent_;
476 std::string observed_proxy_server_uri_;
477
478 DISALLOW_COPY_AND_ASSIGN(BeforeProxyHeadersSentHandler);
479};
480
[email protected]15a5ccf82008-10-23 19:57:43481// Fill |str| with a long header list that consumes >= |size| bytes.
482void FillLargeHeadersString(std::string* str, int size) {
thestig9d3bb0c2015-01-24 00:49:51483 const char row[] =
[email protected]4ddaf2502008-10-23 18:26:19484 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
485 const int sizeof_row = strlen(row);
486 const int num_rows = static_cast<int>(
487 ceil(static_cast<float>(size) / sizeof_row));
488 const int sizeof_data = num_rows * sizeof_row;
489 DCHECK(sizeof_data >= size);
[email protected]15a5ccf82008-10-23 19:57:43490 str->reserve(sizeof_data);
[email protected]372d34a2008-11-05 21:30:51491
[email protected]4ddaf2502008-10-23 18:26:19492 for (int i = 0; i < num_rows; ++i)
[email protected]15a5ccf82008-10-23 19:57:43493 str->append(row, sizeof_row);
[email protected]4ddaf2502008-10-23 18:26:19494}
495
[email protected]385a4672009-03-11 22:21:29496// Alternative functions that eliminate randomness and dependency on the local
497// host name so that the generated NTLM messages are reproducible.
[email protected]fe2bc6a2009-03-23 16:52:20498void MockGenerateRandom1(uint8* output, size_t n) {
[email protected]385a4672009-03-11 22:21:29499 static const uint8 bytes[] = {
500 0x55, 0x29, 0x66, 0x26, 0x6b, 0x9c, 0x73, 0x54
501 };
502 static size_t current_byte = 0;
503 for (size_t i = 0; i < n; ++i) {
504 output[i] = bytes[current_byte++];
505 current_byte %= arraysize(bytes);
506 }
507}
508
[email protected]fe2bc6a2009-03-23 16:52:20509void MockGenerateRandom2(uint8* output, size_t n) {
[email protected]385a4672009-03-11 22:21:29510 static const uint8 bytes[] = {
511 0x96, 0x79, 0x85, 0xe7, 0x49, 0x93, 0x70, 0xa1,
512 0x4e, 0xe7, 0x87, 0x45, 0x31, 0x5b, 0xd3, 0x1f
513 };
514 static size_t current_byte = 0;
515 for (size_t i = 0; i < n; ++i) {
516 output[i] = bytes[current_byte++];
517 current_byte %= arraysize(bytes);
518 }
519}
520
[email protected]fe2bc6a2009-03-23 16:52:20521std::string MockGetHostName() {
522 return "WTC-WIN7";
[email protected]385a4672009-03-11 22:21:29523}
524
[email protected]e60e47a2010-07-14 03:37:18525template<typename ParentPool>
526class CaptureGroupNameSocketPool : public ParentPool {
[email protected]04e5be32009-06-26 20:00:31527 public:
[email protected]9e1bdd32011-02-03 21:48:34528 CaptureGroupNameSocketPool(HostResolver* host_resolver,
529 CertVerifier* cert_verifier);
[email protected]e60e47a2010-07-14 03:37:18530
[email protected]d80a4322009-08-14 07:07:49531 const std::string last_group_name_received() const {
532 return last_group_name_;
533 }
534
dmichaeld6e570d2014-12-18 22:30:57535 int RequestSocket(const std::string& group_name,
536 const void* socket_params,
537 RequestPriority priority,
538 ClientSocketHandle* handle,
539 const CompletionCallback& callback,
540 const BoundNetLog& net_log) override {
[email protected]04e5be32009-06-26 20:00:31541 last_group_name_ = group_name;
542 return ERR_IO_PENDING;
543 }
dmichaeld6e570d2014-12-18 22:30:57544 void CancelRequest(const std::string& group_name,
545 ClientSocketHandle* handle) override {}
546 void ReleaseSocket(const std::string& group_name,
547 scoped_ptr<StreamSocket> socket,
548 int id) override {}
549 void CloseIdleSockets() override {}
550 int IdleSocketCount() const override { return 0; }
551 int IdleSocketCountInGroup(const std::string& group_name) const override {
[email protected]04e5be32009-06-26 20:00:31552 return 0;
553 }
dmichaeld6e570d2014-12-18 22:30:57554 LoadState GetLoadState(const std::string& group_name,
555 const ClientSocketHandle* handle) const override {
[email protected]04e5be32009-06-26 20:00:31556 return LOAD_STATE_IDLE;
557 }
dmichaeld6e570d2014-12-18 22:30:57558 base::TimeDelta ConnectionTimeout() const override {
[email protected]a796bcec2010-03-22 17:17:26559 return base::TimeDelta();
560 }
[email protected]d80a4322009-08-14 07:07:49561
562 private:
[email protected]04e5be32009-06-26 20:00:31563 std::string last_group_name_;
564};
565
[email protected]ab739042011-04-07 15:22:28566typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
567CaptureGroupNameTransportSocketPool;
[email protected]e772db3f2010-07-12 18:11:13568typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
569CaptureGroupNameHttpProxySocketPool;
[email protected]2d731a32010-04-29 01:04:06570typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
[email protected]2227c692010-05-04 15:36:11571CaptureGroupNameSOCKSSocketPool;
[email protected]e60e47a2010-07-14 03:37:18572typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
573CaptureGroupNameSSLSocketPool;
574
rkaplowd90695c2015-03-25 22:12:41575template <typename ParentPool>
[email protected]e60e47a2010-07-14 03:37:18576CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34577 HostResolver* host_resolver,
578 CertVerifier* /* cert_verifier */)
rkaplowd90695c2015-03-25 22:12:41579 : ParentPool(0, 0, host_resolver, NULL, NULL) {
580}
[email protected]e60e47a2010-07-14 03:37:18581
hashimoto0d3e4fb2015-01-09 05:02:50582template <>
[email protected]2df19bb2010-08-25 20:13:46583CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21584 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34585 CertVerifier* /* cert_verifier */)
rkaplowd90695c2015-03-25 22:12:41586 : HttpProxyClientSocketPool(0, 0, NULL, NULL, NULL) {
hashimoto0d3e4fb2015-01-09 05:02:50587}
[email protected]2df19bb2010-08-25 20:13:46588
[email protected]007b3f82013-04-09 08:46:45589template <>
[email protected]e60e47a2010-07-14 03:37:18590CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21591 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34592 CertVerifier* cert_verifier)
[email protected]007b3f82013-04-09 08:46:45593 : SSLClientSocketPool(0,
594 0,
[email protected]007b3f82013-04-09 08:46:45595 cert_verifier,
596 NULL,
597 NULL,
[email protected]284303b62013-11-28 15:11:54598 NULL,
eranm6571b2b2014-12-03 15:53:23599 NULL,
[email protected]007b3f82013-04-09 08:46:45600 std::string(),
601 NULL,
602 NULL,
603 NULL,
604 NULL,
605 NULL,
[email protected]8e458552014-08-05 00:02:15606 NULL) {
607}
[email protected]2227c692010-05-04 15:36:11608
[email protected]231d5a32008-09-13 00:45:27609//-----------------------------------------------------------------------------
610
[email protected]79cb5c12011-09-12 13:12:04611// Helper functions for validating that AuthChallengeInfo's are correctly
612// configured for common cases.
613bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
614 if (!auth_challenge)
615 return false;
616 EXPECT_FALSE(auth_challenge->is_proxy);
bncce36dca22015-04-21 22:11:23617 EXPECT_EQ("www.example.org:80", auth_challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:04618 EXPECT_EQ("MyRealm1", auth_challenge->realm);
619 EXPECT_EQ("basic", auth_challenge->scheme);
620 return true;
621}
622
623bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
624 if (!auth_challenge)
625 return false;
626 EXPECT_TRUE(auth_challenge->is_proxy);
627 EXPECT_EQ("myproxy:70", auth_challenge->challenger.ToString());
628 EXPECT_EQ("MyRealm1", auth_challenge->realm);
629 EXPECT_EQ("basic", auth_challenge->scheme);
630 return true;
631}
632
633bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
634 if (!auth_challenge)
635 return false;
636 EXPECT_FALSE(auth_challenge->is_proxy);
bncce36dca22015-04-21 22:11:23637 EXPECT_EQ("www.example.org:80", auth_challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:04638 EXPECT_EQ("digestive", auth_challenge->realm);
639 EXPECT_EQ("digest", auth_challenge->scheme);
640 return true;
641}
642
643bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
644 if (!auth_challenge)
645 return false;
646 EXPECT_FALSE(auth_challenge->is_proxy);
647 EXPECT_EQ("172.22.68.17:80", auth_challenge->challenger.ToString());
648 EXPECT_EQ(std::string(), auth_challenge->realm);
649 EXPECT_EQ("ntlm", auth_challenge->scheme);
650 return true;
651}
652
[email protected]448d4ca52012-03-04 04:12:23653} // namespace
654
[email protected]23e482282013-06-14 16:08:02655TEST_P(HttpNetworkTransactionTest, Basic) {
[email protected]3fe8d2f82013-10-17 08:56:07656 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:40657 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:41658 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]231d5a32008-09-13 00:45:27659}
660
[email protected]23e482282013-06-14 16:08:02661TEST_P(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27662 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35663 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
664 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06665 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27666 };
[email protected]31a2bfe2010-02-09 08:03:39667 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
668 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42669 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27670 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
671 EXPECT_EQ("hello world", out.response_data);
[email protected]b8015c42013-12-24 15:18:19672 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
673 EXPECT_EQ(reads_size, out.totalReceivedBytes);
ttuttle1f2d7e92015-04-28 16:17:47674 EXPECT_EQ(0u, out.connection_attempts.size());
[email protected]231d5a32008-09-13 00:45:27675}
676
677// Response with no status line.
[email protected]23e482282013-06-14 16:08:02678TEST_P(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27679 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35680 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06681 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27682 };
[email protected]31a2bfe2010-02-09 08:03:39683 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
684 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42685 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27686 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
687 EXPECT_EQ("hello world", out.response_data);
[email protected]b8015c42013-12-24 15:18:19688 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
689 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27690}
691
692// Allow up to 4 bytes of junk to precede status line.
[email protected]23e482282013-06-14 16:08:02693TEST_P(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27694 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35695 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06696 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27697 };
[email protected]31a2bfe2010-02-09 08:03:39698 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
699 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42700 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27701 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
702 EXPECT_EQ("DATA", out.response_data);
[email protected]b8015c42013-12-24 15:18:19703 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
704 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27705}
706
707// Allow up to 4 bytes of junk to precede status line.
[email protected]23e482282013-06-14 16:08:02708TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27709 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35710 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06711 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27712 };
[email protected]31a2bfe2010-02-09 08:03:39713 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
714 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42715 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27716 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
717 EXPECT_EQ("DATA", out.response_data);
[email protected]b8015c42013-12-24 15:18:19718 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
719 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27720}
721
722// Beyond 4 bytes of slop and it should fail to find a status line.
[email protected]23e482282013-06-14 16:08:02723TEST_P(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27724 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35725 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06726 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27727 };
[email protected]31a2bfe2010-02-09 08:03:39728 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
729 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42730 EXPECT_EQ(OK, out.rv);
[email protected]3d2a59b2008-09-26 19:44:25731 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
732 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
[email protected]b8015c42013-12-24 15:18:19733 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
734 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27735}
736
737// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
[email protected]23e482282013-06-14 16:08:02738TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27739 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35740 MockRead("\n"),
741 MockRead("\n"),
742 MockRead("Q"),
743 MockRead("J"),
744 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06745 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27746 };
[email protected]31a2bfe2010-02-09 08:03:39747 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
748 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42749 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27750 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
751 EXPECT_EQ("DATA", out.response_data);
[email protected]b8015c42013-12-24 15:18:19752 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
753 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27754}
755
756// Close the connection before enough bytes to have a status line.
[email protected]23e482282013-06-14 16:08:02757TEST_P(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:27758 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35759 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:06760 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27761 };
[email protected]31a2bfe2010-02-09 08:03:39762 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
763 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42764 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27765 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
766 EXPECT_EQ("HTT", out.response_data);
[email protected]b8015c42013-12-24 15:18:19767 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
768 EXPECT_EQ(reads_size, out.totalReceivedBytes);
initial.commit586acc5fe2008-07-26 22:42:52769}
770
[email protected]f9d44aa2008-09-23 23:57:17771// Simulate a 204 response, lacking a Content-Length header, sent over a
772// persistent connection. The response should still terminate since a 204
773// cannot have a response body.
[email protected]23e482282013-06-14 16:08:02774TEST_P(HttpNetworkTransactionTest, StopsReading204) {
[email protected]b8015c42013-12-24 15:18:19775 char junk[] = "junk";
[email protected]f9d44aa2008-09-23 23:57:17776 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35777 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
[email protected]b8015c42013-12-24 15:18:19778 MockRead(junk), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:06779 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:17780 };
[email protected]31a2bfe2010-02-09 08:03:39781 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
782 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42783 EXPECT_EQ(OK, out.rv);
[email protected]f9d44aa2008-09-23 23:57:17784 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
785 EXPECT_EQ("", out.response_data);
[email protected]b8015c42013-12-24 15:18:19786 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
787 int64 response_size = reads_size - strlen(junk);
788 EXPECT_EQ(response_size, out.totalReceivedBytes);
[email protected]f9d44aa2008-09-23 23:57:17789}
790
[email protected]0877e3d2009-10-17 22:29:57791// A simple request using chunked encoding with some extra data after.
[email protected]23e482282013-06-14 16:08:02792TEST_P(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]b8015c42013-12-24 15:18:19793 std::string final_chunk = "0\r\n\r\n";
794 std::string extra_data = "HTTP/1.1 200 OK\r\n";
795 std::string last_read = final_chunk + extra_data;
[email protected]0877e3d2009-10-17 22:29:57796 MockRead data_reads[] = {
797 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
798 MockRead("5\r\nHello\r\n"),
799 MockRead("1\r\n"),
800 MockRead(" \r\n"),
801 MockRead("5\r\nworld\r\n"),
[email protected]b8015c42013-12-24 15:18:19802 MockRead(last_read.data()),
[email protected]8ddf8322012-02-23 18:08:06803 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:57804 };
[email protected]31a2bfe2010-02-09 08:03:39805 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
806 arraysize(data_reads));
[email protected]0877e3d2009-10-17 22:29:57807 EXPECT_EQ(OK, out.rv);
808 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
809 EXPECT_EQ("Hello world", out.response_data);
[email protected]b8015c42013-12-24 15:18:19810 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
811 int64 response_size = reads_size - extra_data.size();
812 EXPECT_EQ(response_size, out.totalReceivedBytes);
[email protected]0877e3d2009-10-17 22:29:57813}
814
[email protected]9fe44f52010-09-23 18:36:00815// Next tests deal with http://crbug.com/56344.
816
[email protected]23e482282013-06-14 16:08:02817TEST_P(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00818 MultipleContentLengthHeadersNoTransferEncoding) {
819 MockRead data_reads[] = {
820 MockRead("HTTP/1.1 200 OK\r\n"),
821 MockRead("Content-Length: 10\r\n"),
822 MockRead("Content-Length: 5\r\n\r\n"),
823 };
824 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
825 arraysize(data_reads));
826 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
827}
828
[email protected]23e482282013-06-14 16:08:02829TEST_P(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04830 DuplicateContentLengthHeadersNoTransferEncoding) {
831 MockRead data_reads[] = {
832 MockRead("HTTP/1.1 200 OK\r\n"),
833 MockRead("Content-Length: 5\r\n"),
834 MockRead("Content-Length: 5\r\n\r\n"),
835 MockRead("Hello"),
836 };
837 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
838 arraysize(data_reads));
839 EXPECT_EQ(OK, out.rv);
840 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
841 EXPECT_EQ("Hello", out.response_data);
842}
843
[email protected]23e482282013-06-14 16:08:02844TEST_P(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04845 ComplexContentLengthHeadersNoTransferEncoding) {
846 // More than 2 dupes.
847 {
848 MockRead data_reads[] = {
849 MockRead("HTTP/1.1 200 OK\r\n"),
850 MockRead("Content-Length: 5\r\n"),
851 MockRead("Content-Length: 5\r\n"),
852 MockRead("Content-Length: 5\r\n\r\n"),
853 MockRead("Hello"),
854 };
855 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
856 arraysize(data_reads));
857 EXPECT_EQ(OK, out.rv);
858 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
859 EXPECT_EQ("Hello", out.response_data);
860 }
861 // HTTP/1.0
862 {
863 MockRead data_reads[] = {
864 MockRead("HTTP/1.0 200 OK\r\n"),
865 MockRead("Content-Length: 5\r\n"),
866 MockRead("Content-Length: 5\r\n"),
867 MockRead("Content-Length: 5\r\n\r\n"),
868 MockRead("Hello"),
869 };
870 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
871 arraysize(data_reads));
872 EXPECT_EQ(OK, out.rv);
873 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
874 EXPECT_EQ("Hello", out.response_data);
875 }
876 // 2 dupes and one mismatched.
877 {
878 MockRead data_reads[] = {
879 MockRead("HTTP/1.1 200 OK\r\n"),
880 MockRead("Content-Length: 10\r\n"),
881 MockRead("Content-Length: 10\r\n"),
882 MockRead("Content-Length: 5\r\n\r\n"),
883 };
884 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
885 arraysize(data_reads));
886 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
887 }
888}
889
[email protected]23e482282013-06-14 16:08:02890TEST_P(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00891 MultipleContentLengthHeadersTransferEncoding) {
892 MockRead data_reads[] = {
893 MockRead("HTTP/1.1 200 OK\r\n"),
894 MockRead("Content-Length: 666\r\n"),
895 MockRead("Content-Length: 1337\r\n"),
896 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
897 MockRead("5\r\nHello\r\n"),
898 MockRead("1\r\n"),
899 MockRead(" \r\n"),
900 MockRead("5\r\nworld\r\n"),
901 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:06902 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:00903 };
904 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
905 arraysize(data_reads));
906 EXPECT_EQ(OK, out.rv);
907 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
908 EXPECT_EQ("Hello world", out.response_data);
909}
910
[email protected]1628fe92011-10-04 23:04:55911// Next tests deal with http://crbug.com/98895.
912
913// Checks that a single Content-Disposition header results in no error.
[email protected]23e482282013-06-14 16:08:02914TEST_P(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:55915 MockRead data_reads[] = {
916 MockRead("HTTP/1.1 200 OK\r\n"),
917 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
918 MockRead("Content-Length: 5\r\n\r\n"),
919 MockRead("Hello"),
920 };
921 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
922 arraysize(data_reads));
923 EXPECT_EQ(OK, out.rv);
924 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
925 EXPECT_EQ("Hello", out.response_data);
926}
927
[email protected]54a9c6e52012-03-21 20:10:59928// Checks that two identical Content-Disposition headers result in no error.
[email protected]23e482282013-06-14 16:08:02929TEST_P(HttpNetworkTransactionTest,
[email protected]54a9c6e52012-03-21 20:10:59930 TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:55931 MockRead data_reads[] = {
932 MockRead("HTTP/1.1 200 OK\r\n"),
933 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
934 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
935 MockRead("Content-Length: 5\r\n\r\n"),
936 MockRead("Hello"),
937 };
938 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
939 arraysize(data_reads));
[email protected]54a9c6e52012-03-21 20:10:59940 EXPECT_EQ(OK, out.rv);
941 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
942 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:55943}
944
945// Checks that two distinct Content-Disposition headers result in an error.
[email protected]23e482282013-06-14 16:08:02946TEST_P(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:55947 MockRead data_reads[] = {
948 MockRead("HTTP/1.1 200 OK\r\n"),
949 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
950 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
951 MockRead("Content-Length: 5\r\n\r\n"),
952 MockRead("Hello"),
953 };
954 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
955 arraysize(data_reads));
956 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION, out.rv);
957}
958
[email protected]54a9c6e52012-03-21 20:10:59959// Checks that two identical Location headers result in no error.
960// Also tests Location header behavior.
[email protected]23e482282013-06-14 16:08:02961TEST_P(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:55962 MockRead data_reads[] = {
963 MockRead("HTTP/1.1 302 Redirect\r\n"),
964 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:59965 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:55966 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:06967 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:55968 };
969
970 HttpRequestInfo request;
971 request.method = "GET";
972 request.url = GURL("http://redirect.com/");
973 request.load_flags = 0;
974
[email protected]3fe8d2f82013-10-17 08:56:07975 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1628fe92011-10-04 23:04:55976 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:41977 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]1628fe92011-10-04 23:04:55978
979 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:07980 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:55981
[email protected]49639fa2011-12-20 23:22:41982 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:55983
[email protected]49639fa2011-12-20 23:22:41984 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1628fe92011-10-04 23:04:55985 EXPECT_EQ(ERR_IO_PENDING, rv);
986
987 EXPECT_EQ(OK, callback.WaitForResult());
988
989 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]90499482013-06-01 00:39:50990 ASSERT_TRUE(response != NULL && response->headers.get() != NULL);
[email protected]1628fe92011-10-04 23:04:55991 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
992 std::string url;
993 EXPECT_TRUE(response->headers->IsRedirect(&url));
994 EXPECT_EQ("http://good.com/", url);
[email protected]d8fc4722014-06-13 13:17:15995 EXPECT_TRUE(response->proxy_server.IsEmpty());
[email protected]1628fe92011-10-04 23:04:55996}
997
[email protected]1628fe92011-10-04 23:04:55998// Checks that two distinct Location headers result in an error.
[email protected]23e482282013-06-14 16:08:02999TEST_P(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551000 MockRead data_reads[] = {
1001 MockRead("HTTP/1.1 302 Redirect\r\n"),
1002 MockRead("Location: http://good.com/\r\n"),
1003 MockRead("Location: http://evil.com/\r\n"),
1004 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061005 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551006 };
1007 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1008 arraysize(data_reads));
1009 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION, out.rv);
1010}
1011
[email protected]ef0faf2e72009-03-05 23:27:231012// Do a request using the HEAD method. Verify that we don't try to read the
1013// message body (since HEAD has none).
[email protected]23e482282013-06-14 16:08:021014TEST_P(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:421015 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:231016 request.method = "HEAD";
bncce36dca22015-04-21 22:11:231017 request.url = GURL("http://www.example.org/");
[email protected]ef0faf2e72009-03-05 23:27:231018 request.load_flags = 0;
1019
[email protected]3fe8d2f82013-10-17 08:56:071020 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271021 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411022 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]597a1ab2014-06-26 08:12:271023 BeforeProxyHeadersSentHandler proxy_headers_handler;
1024 trans->SetBeforeProxyHeadersSentCallback(
1025 base::Bind(&BeforeProxyHeadersSentHandler::OnBeforeProxyHeadersSent,
1026 base::Unretained(&proxy_headers_handler)));
[email protected]cb9bf6ca2011-01-28 13:15:271027
[email protected]ef0faf2e72009-03-05 23:27:231028 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:231029 MockWrite(
1030 "HEAD / HTTP/1.1\r\n"
1031 "Host: www.example.org\r\n"
1032 "Connection: keep-alive\r\n"
1033 "Content-Length: 0\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231034 };
1035 MockRead data_reads1[] = {
1036 MockRead("HTTP/1.1 404 Not Found\r\n"),
1037 MockRead("Server: Blah\r\n"),
1038 MockRead("Content-Length: 1234\r\n\r\n"),
1039
1040 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:061041 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]ef0faf2e72009-03-05 23:27:231042 };
1043
[email protected]31a2bfe2010-02-09 08:03:391044 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1045 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:071046 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:231047
[email protected]49639fa2011-12-20 23:22:411048 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:231049
[email protected]49639fa2011-12-20 23:22:411050 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421051 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]ef0faf2e72009-03-05 23:27:231052
1053 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421054 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:231055
[email protected]1c773ea12009-04-28 19:58:421056 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501057 ASSERT_TRUE(response != NULL);
[email protected]ef0faf2e72009-03-05 23:27:231058
1059 // Check that the headers got parsed.
[email protected]90499482013-06-01 00:39:501060 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]ef0faf2e72009-03-05 23:27:231061 EXPECT_EQ(1234, response->headers->GetContentLength());
1062 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
[email protected]d8fc4722014-06-13 13:17:151063 EXPECT_TRUE(response->proxy_server.IsEmpty());
[email protected]597a1ab2014-06-26 08:12:271064 EXPECT_FALSE(proxy_headers_handler.observed_before_proxy_headers_sent());
[email protected]ef0faf2e72009-03-05 23:27:231065
1066 std::string server_header;
1067 void* iter = NULL;
1068 bool has_server_header = response->headers->EnumerateHeader(
1069 &iter, "Server", &server_header);
1070 EXPECT_TRUE(has_server_header);
1071 EXPECT_EQ("Blah", server_header);
1072
1073 // Reading should give EOF right away, since there is no message body
1074 // (despite non-zero content-length).
1075 std::string response_data;
1076 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421077 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:231078 EXPECT_EQ("", response_data);
1079}
1080
[email protected]23e482282013-06-14 16:08:021081TEST_P(HttpNetworkTransactionTest, ReuseConnection) {
[email protected]bb88e1d32013-05-03 23:11:071082 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:521083
1084 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351085 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1086 MockRead("hello"),
1087 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1088 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061089 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521090 };
[email protected]31a2bfe2010-02-09 08:03:391091 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071092 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521093
[email protected]0b0bf032010-09-21 18:08:501094 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521095 "hello", "world"
1096 };
1097
1098 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:421099 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521100 request.method = "GET";
bncce36dca22015-04-21 22:11:231101 request.url = GURL("http://www.example.org/");
initial.commit586acc5fe2008-07-26 22:42:521102 request.load_flags = 0;
1103
[email protected]262eec82013-03-19 21:01:361104 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501105 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271106
[email protected]49639fa2011-12-20 23:22:411107 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521108
[email protected]49639fa2011-12-20 23:22:411109 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421110 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521111
1112 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421113 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521114
[email protected]1c773ea12009-04-28 19:58:421115 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501116 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521117
[email protected]90499482013-06-01 00:39:501118 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251119 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]d8fc4722014-06-13 13:17:151120 EXPECT_TRUE(response->proxy_server.IsEmpty());
initial.commit586acc5fe2008-07-26 22:42:521121
1122 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571123 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421124 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251125 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521126 }
1127}
1128
[email protected]23e482282013-06-14 16:08:021129TEST_P(HttpNetworkTransactionTest, Ignores100) {
[email protected]b2d26cfd2012-12-11 10:36:061130 ScopedVector<UploadElementReader> element_readers;
1131 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:071132 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:271133
[email protected]1c773ea12009-04-28 19:58:421134 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521135 request.method = "POST";
1136 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271137 request.upload_data_stream = &upload_data_stream;
initial.commit586acc5fe2008-07-26 22:42:521138 request.load_flags = 0;
1139
[email protected]3fe8d2f82013-10-17 08:56:071140 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271141 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411142 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271143
initial.commit586acc5fe2008-07-26 22:42:521144 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351145 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1146 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1147 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061148 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521149 };
[email protected]31a2bfe2010-02-09 08:03:391150 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071151 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521152
[email protected]49639fa2011-12-20 23:22:411153 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521154
[email protected]49639fa2011-12-20 23:22:411155 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421156 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521157
1158 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421159 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521160
[email protected]1c773ea12009-04-28 19:58:421161 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501162 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521163
[email protected]90499482013-06-01 00:39:501164 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251165 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521166
1167 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571168 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421169 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251170 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521171}
1172
[email protected]3a2d3662009-03-27 03:49:141173// This test is almost the same as Ignores100 above, but the response contains
1174// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571175// HTTP/1.1 and the two status headers are read in one read.
[email protected]23e482282013-06-14 16:08:021176TEST_P(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421177 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141178 request.method = "GET";
1179 request.url = GURL("http://www.foo.com/");
1180 request.load_flags = 0;
1181
[email protected]3fe8d2f82013-10-17 08:56:071182 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271183 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411184 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271185
[email protected]3a2d3662009-03-27 03:49:141186 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571187 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1188 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141189 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061190 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141191 };
[email protected]31a2bfe2010-02-09 08:03:391192 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071193 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141194
[email protected]49639fa2011-12-20 23:22:411195 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141196
[email protected]49639fa2011-12-20 23:22:411197 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421198 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3a2d3662009-03-27 03:49:141199
1200 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421201 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:141202
[email protected]1c773ea12009-04-28 19:58:421203 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501204 ASSERT_TRUE(response != NULL);
[email protected]3a2d3662009-03-27 03:49:141205
[email protected]90499482013-06-01 00:39:501206 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3a2d3662009-03-27 03:49:141207 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1208
1209 std::string response_data;
1210 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421211 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:141212 EXPECT_EQ("hello world", response_data);
1213}
1214
[email protected]23e482282013-06-14 16:08:021215TEST_P(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
[email protected]ee9410e72010-01-07 01:42:381216 HttpRequestInfo request;
1217 request.method = "POST";
1218 request.url = GURL("http://www.foo.com/");
1219 request.load_flags = 0;
1220
[email protected]3fe8d2f82013-10-17 08:56:071221 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271222 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411223 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271224
[email protected]ee9410e72010-01-07 01:42:381225 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061226 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1227 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381228 };
[email protected]31a2bfe2010-02-09 08:03:391229 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071230 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381231
[email protected]49639fa2011-12-20 23:22:411232 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381233
[email protected]49639fa2011-12-20 23:22:411234 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]ee9410e72010-01-07 01:42:381235 EXPECT_EQ(ERR_IO_PENDING, rv);
1236
1237 rv = callback.WaitForResult();
1238 EXPECT_EQ(OK, rv);
1239
1240 std::string response_data;
1241 rv = ReadTransaction(trans.get(), &response_data);
1242 EXPECT_EQ(OK, rv);
1243 EXPECT_EQ("", response_data);
1244}
1245
[email protected]23e482282013-06-14 16:08:021246TEST_P(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381247 HttpRequestInfo request;
1248 request.method = "POST";
1249 request.url = GURL("http://www.foo.com/");
1250 request.load_flags = 0;
1251
[email protected]3fe8d2f82013-10-17 08:56:071252 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271253 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411254 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271255
[email protected]ee9410e72010-01-07 01:42:381256 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061257 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381258 };
[email protected]31a2bfe2010-02-09 08:03:391259 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071260 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381261
[email protected]49639fa2011-12-20 23:22:411262 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381263
[email protected]49639fa2011-12-20 23:22:411264 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]ee9410e72010-01-07 01:42:381265 EXPECT_EQ(ERR_IO_PENDING, rv);
1266
1267 rv = callback.WaitForResult();
1268 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
1269}
1270
[email protected]23e482282013-06-14 16:08:021271void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511272 const MockWrite* write_failure,
1273 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421274 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521275 request.method = "GET";
1276 request.url = GURL("http://www.foo.com/");
1277 request.load_flags = 0;
1278
vishal.b62985ca92015-04-17 08:45:511279 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071280 session_deps_.net_log = &net_log;
1281 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271282
[email protected]202965992011-12-07 23:04:511283 // Written data for successfully sending both requests.
1284 MockWrite data1_writes[] = {
1285 MockWrite("GET / HTTP/1.1\r\n"
1286 "Host: www.foo.com\r\n"
1287 "Connection: keep-alive\r\n\r\n"),
1288 MockWrite("GET / HTTP/1.1\r\n"
1289 "Host: www.foo.com\r\n"
1290 "Connection: keep-alive\r\n\r\n")
1291 };
1292
1293 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521294 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351295 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1296 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061297 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521298 };
[email protected]202965992011-12-07 23:04:511299
1300 if (write_failure) {
[email protected]a34f61ee2014-03-18 20:59:491301 ASSERT_FALSE(read_failure);
[email protected]202965992011-12-07 23:04:511302 data1_writes[1] = *write_failure;
1303 } else {
1304 ASSERT_TRUE(read_failure);
1305 data1_reads[2] = *read_failure;
1306 }
1307
1308 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
1309 data1_writes, arraysize(data1_writes));
[email protected]bb88e1d32013-05-03 23:11:071310 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521311
1312 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351313 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1314 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061315 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521316 };
[email protected]31a2bfe2010-02-09 08:03:391317 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071318 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521319
thestig9d3bb0c2015-01-24 00:49:511320 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521321 "hello", "world"
1322 };
1323
[email protected]58e32bb2013-01-21 18:23:251324 uint32 first_socket_log_id = NetLog::Source::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521325 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411326 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521327
[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()));
initial.commit586acc5fe2008-07-26 22:42:521330
[email protected]49639fa2011-12-20 23:22:411331 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421332 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521333
1334 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421335 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521336
[email protected]58e32bb2013-01-21 18:23:251337 LoadTimingInfo load_timing_info;
1338 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1339 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1340 if (i == 0) {
1341 first_socket_log_id = load_timing_info.socket_log_id;
1342 } else {
1343 // The second request should be using a new socket.
1344 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1345 }
1346
[email protected]1c773ea12009-04-28 19:58:421347 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501348 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521349
[email protected]90499482013-06-01 00:39:501350 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251351 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521352
1353 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571354 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421355 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251356 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521357 }
1358}
[email protected]3d2a59b2008-09-26 19:44:251359
[email protected]a34f61ee2014-03-18 20:59:491360void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1361 const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:101362 const MockRead* read_failure,
1363 bool use_spdy) {
[email protected]a34f61ee2014-03-18 20:59:491364 HttpRequestInfo request;
1365 request.method = "GET";
[email protected]09356c652014-03-25 15:36:101366 request.url = GURL("https://www.foo.com/");
[email protected]a34f61ee2014-03-18 20:59:491367 request.load_flags = 0;
1368
vishal.b62985ca92015-04-17 08:45:511369 TestNetLog net_log;
[email protected]a34f61ee2014-03-18 20:59:491370 session_deps_.net_log = &net_log;
1371 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1372
[email protected]09356c652014-03-25 15:36:101373 SSLSocketDataProvider ssl1(ASYNC, OK);
1374 SSLSocketDataProvider ssl2(ASYNC, OK);
1375 if (use_spdy) {
1376 ssl1.SetNextProto(GetParam());
1377 ssl2.SetNextProto(GetParam());
1378 }
1379 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1380 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]a34f61ee2014-03-18 20:59:491381
[email protected]09356c652014-03-25 15:36:101382 // SPDY versions of the request and response.
1383 scoped_ptr<SpdyFrame> spdy_request(spdy_util_.ConstructSpdyGet(
1384 request.url.spec().c_str(), false, 1, DEFAULT_PRIORITY));
1385 scoped_ptr<SpdyFrame> spdy_response(
1386 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
1387 scoped_ptr<SpdyFrame> spdy_data(
1388 spdy_util_.ConstructSpdyBodyFrame(1, "hello", 5, true));
[email protected]a34f61ee2014-03-18 20:59:491389
[email protected]09356c652014-03-25 15:36:101390 // HTTP/1.1 versions of the request and response.
1391 const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1392 "Host: www.foo.com\r\n"
1393 "Connection: keep-alive\r\n\r\n";
1394 const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1395 const char kHttpData[] = "hello";
1396
1397 std::vector<MockRead> data1_reads;
1398 std::vector<MockWrite> data1_writes;
[email protected]a34f61ee2014-03-18 20:59:491399 if (write_failure) {
1400 ASSERT_FALSE(read_failure);
[email protected]09356c652014-03-25 15:36:101401 data1_writes.push_back(*write_failure);
1402 data1_reads.push_back(MockRead(ASYNC, OK));
[email protected]a34f61ee2014-03-18 20:59:491403 } else {
1404 ASSERT_TRUE(read_failure);
[email protected]09356c652014-03-25 15:36:101405 if (use_spdy) {
1406 data1_writes.push_back(CreateMockWrite(*spdy_request));
1407 } else {
1408 data1_writes.push_back(MockWrite(kHttpRequest));
1409 }
1410 data1_reads.push_back(*read_failure);
[email protected]a34f61ee2014-03-18 20:59:491411 }
1412
[email protected]09356c652014-03-25 15:36:101413 StaticSocketDataProvider data1(&data1_reads[0], data1_reads.size(),
1414 &data1_writes[0], data1_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491415 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1416
[email protected]09356c652014-03-25 15:36:101417 std::vector<MockRead> data2_reads;
1418 std::vector<MockWrite> data2_writes;
1419
1420 if (use_spdy) {
1421 data2_writes.push_back(CreateMockWrite(*spdy_request, 0, ASYNC));
1422
1423 data2_reads.push_back(CreateMockRead(*spdy_response, 1, ASYNC));
1424 data2_reads.push_back(CreateMockRead(*spdy_data, 2, ASYNC));
1425 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1426 } else {
1427 data2_writes.push_back(
1428 MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1429
1430 data2_reads.push_back(
1431 MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1432 data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1433 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1434 }
rch8e6c6c42015-05-01 14:05:131435 SequencedSocketData data2(&data2_reads[0], data2_reads.size(),
1436 &data2_writes[0], data2_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491437 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1438
1439 // Preconnect a socket.
ttuttle859dc7a2015-04-23 19:42:291440 SSLConfig ssl_config;
[email protected]a34f61ee2014-03-18 20:59:491441 session->ssl_config_service()->GetSSLConfig(&ssl_config);
[email protected]d7599122014-05-24 03:37:231442 session->GetNextProtos(&ssl_config.next_protos);
[email protected]a34f61ee2014-03-18 20:59:491443 session->http_stream_factory()->PreconnectStreams(
1444 1, request, DEFAULT_PRIORITY, ssl_config, ssl_config);
1445 // Wait for the preconnect to complete.
1446 // TODO(davidben): Some way to wait for an idle socket count might be handy.
1447 base::RunLoop().RunUntilIdle();
[email protected]09356c652014-03-25 15:36:101448 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]a34f61ee2014-03-18 20:59:491449
1450 // Make the request.
1451 TestCompletionCallback callback;
1452
1453 scoped_ptr<HttpTransaction> trans(
1454 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1455
1456 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1457 EXPECT_EQ(ERR_IO_PENDING, rv);
1458
1459 rv = callback.WaitForResult();
1460 EXPECT_EQ(OK, rv);
1461
1462 LoadTimingInfo load_timing_info;
1463 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
[email protected]09356c652014-03-25 15:36:101464 TestLoadTimingNotReused(
1465 load_timing_info,
1466 CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]a34f61ee2014-03-18 20:59:491467
1468 const HttpResponseInfo* response = trans->GetResponseInfo();
1469 ASSERT_TRUE(response != NULL);
1470
1471 EXPECT_TRUE(response->headers.get() != NULL);
1472 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1473
1474 std::string response_data;
1475 rv = ReadTransaction(trans.get(), &response_data);
1476 EXPECT_EQ(OK, rv);
[email protected]09356c652014-03-25 15:36:101477 EXPECT_EQ(kHttpData, response_data);
[email protected]a34f61ee2014-03-18 20:59:491478}
1479
[email protected]23e482282013-06-14 16:08:021480TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:231481 KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061482 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]202965992011-12-07 23:04:511483 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1484}
1485
[email protected]23e482282013-06-14 16:08:021486TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061487 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]202965992011-12-07 23:04:511488 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251489}
1490
[email protected]23e482282013-06-14 16:08:021491TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061492 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]202965992011-12-07 23:04:511493 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251494}
1495
[email protected]d58ceea82014-06-04 10:55:541496// Make sure that on a 408 response (Request Timeout), the request is retried,
1497// if the socket was a reused keep alive socket.
1498TEST_P(HttpNetworkTransactionTest, KeepAlive408) {
1499 MockRead read_failure(SYNCHRONOUS,
1500 "HTTP/1.1 408 Request Timeout\r\n"
1501 "Connection: Keep-Alive\r\n"
1502 "Content-Length: 6\r\n\r\n"
1503 "Pickle");
1504 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1505}
1506
[email protected]a34f61ee2014-03-18 20:59:491507TEST_P(HttpNetworkTransactionTest,
1508 PreconnectErrorNotConnectedOnWrite) {
1509 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]09356c652014-03-25 15:36:101510 PreconnectErrorResendRequestTest(&write_failure, NULL, false);
[email protected]a34f61ee2014-03-18 20:59:491511}
1512
1513TEST_P(HttpNetworkTransactionTest, PreconnectErrorReset) {
1514 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]09356c652014-03-25 15:36:101515 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
[email protected]a34f61ee2014-03-18 20:59:491516}
1517
1518TEST_P(HttpNetworkTransactionTest, PreconnectErrorEOF) {
1519 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]09356c652014-03-25 15:36:101520 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1521}
1522
1523TEST_P(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
1524 MockRead read_failure(ASYNC, OK); // EOF
1525 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1526}
1527
[email protected]d58ceea82014-06-04 10:55:541528// Make sure that on a 408 response (Request Timeout), the request is retried,
1529// if the socket was a preconnected (UNUSED_IDLE) socket.
1530TEST_P(HttpNetworkTransactionTest, RetryOnIdle408) {
1531 MockRead read_failure(SYNCHRONOUS,
1532 "HTTP/1.1 408 Request Timeout\r\n"
1533 "Connection: Keep-Alive\r\n"
1534 "Content-Length: 6\r\n\r\n"
1535 "Pickle");
1536 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1537 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1538}
1539
[email protected]09356c652014-03-25 15:36:101540TEST_P(HttpNetworkTransactionTest,
1541 SpdyPreconnectErrorNotConnectedOnWrite) {
1542 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1543 PreconnectErrorResendRequestTest(&write_failure, NULL, true);
1544}
1545
1546TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
1547 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1548 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1549}
1550
1551TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
1552 MockRead read_failure(SYNCHRONOUS, OK); // EOF
1553 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1554}
1555
1556TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
1557 MockRead read_failure(ASYNC, OK); // EOF
1558 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
[email protected]a34f61ee2014-03-18 20:59:491559}
1560
[email protected]23e482282013-06-14 16:08:021561TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:421562 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:251563 request.method = "GET";
bncce36dca22015-04-21 22:11:231564 request.url = GURL("http://www.example.org/");
[email protected]3d2a59b2008-09-26 19:44:251565 request.load_flags = 0;
1566
[email protected]3fe8d2f82013-10-17 08:56:071567 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271568 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411569 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271570
[email protected]3d2a59b2008-09-26 19:44:251571 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061572 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:351573 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1574 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061575 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251576 };
[email protected]31a2bfe2010-02-09 08:03:391577 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071578 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:251579
[email protected]49639fa2011-12-20 23:22:411580 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:251581
[email protected]49639fa2011-12-20 23:22:411582 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421583 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3d2a59b2008-09-26 19:44:251584
1585 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421586 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]3d2a59b2008-09-26 19:44:251587
[email protected]1c773ea12009-04-28 19:58:421588 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]3d2a59b2008-09-26 19:44:251589 EXPECT_TRUE(response == NULL);
[email protected]3d2a59b2008-09-26 19:44:251590}
1591
1592// What do various browsers do when the server closes a non-keepalive
1593// connection without sending any response header or body?
1594//
1595// IE7: error page
1596// Safari 3.1.2 (Windows): error page
1597// Firefox 3.0.1: blank page
1598// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:421599// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1600// Us: error page (EMPTY_RESPONSE)
[email protected]23e482282013-06-14 16:08:021601TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:251602 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061603 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:351604 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1605 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061606 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251607 };
[email protected]31a2bfe2010-02-09 08:03:391608 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1609 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:421610 EXPECT_EQ(ERR_EMPTY_RESPONSE, out.rv);
[email protected]3d2a59b2008-09-26 19:44:251611}
[email protected]038e9a32008-10-08 22:40:161612
[email protected]1826a402014-01-08 15:40:481613// Test that network access can be deferred and resumed.
1614TEST_P(HttpNetworkTransactionTest, ThrottleBeforeNetworkStart) {
1615 HttpRequestInfo request;
1616 request.method = "GET";
bncce36dca22015-04-21 22:11:231617 request.url = GURL("http://www.example.org/");
[email protected]1826a402014-01-08 15:40:481618 request.load_flags = 0;
1619
1620 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1621 scoped_ptr<HttpTransaction> trans(
1622 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1623
1624 // Defer on OnBeforeNetworkStart.
1625 BeforeNetworkStartHandler net_start_handler(true); // defer
1626 trans->SetBeforeNetworkStartCallback(
1627 base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
1628 base::Unretained(&net_start_handler)));
1629
1630 MockRead data_reads[] = {
1631 MockRead("HTTP/1.0 200 OK\r\n"),
1632 MockRead("Content-Length: 5\r\n\r\n"),
1633 MockRead("hello"),
1634 MockRead(SYNCHRONOUS, 0),
1635 };
1636 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1637 session_deps_.socket_factory->AddSocketDataProvider(&data);
1638
1639 TestCompletionCallback callback;
1640
1641 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1642 EXPECT_EQ(ERR_IO_PENDING, rv);
1643 base::MessageLoop::current()->RunUntilIdle();
1644
1645 // Should have deferred for network start.
1646 EXPECT_TRUE(net_start_handler.observed_before_network_start());
1647 EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
1648 EXPECT_TRUE(trans->GetResponseInfo() == NULL);
1649
1650 trans->ResumeNetworkStart();
1651 rv = callback.WaitForResult();
1652 EXPECT_EQ(OK, rv);
1653 EXPECT_TRUE(trans->GetResponseInfo() != NULL);
1654
1655 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
1656 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
1657 if (rv == ERR_IO_PENDING)
1658 rv = callback.WaitForResult();
1659 EXPECT_EQ(5, rv);
1660 trans.reset();
1661}
1662
1663// Test that network use can be deferred and canceled.
1664TEST_P(HttpNetworkTransactionTest, ThrottleAndCancelBeforeNetworkStart) {
1665 HttpRequestInfo request;
1666 request.method = "GET";
bncce36dca22015-04-21 22:11:231667 request.url = GURL("http://www.example.org/");
[email protected]1826a402014-01-08 15:40:481668 request.load_flags = 0;
1669
1670 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1671 scoped_ptr<HttpTransaction> trans(
1672 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1673
1674 // Defer on OnBeforeNetworkStart.
1675 BeforeNetworkStartHandler net_start_handler(true); // defer
1676 trans->SetBeforeNetworkStartCallback(
1677 base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
1678 base::Unretained(&net_start_handler)));
1679
1680 TestCompletionCallback callback;
1681
1682 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1683 EXPECT_EQ(ERR_IO_PENDING, rv);
1684 base::MessageLoop::current()->RunUntilIdle();
1685
1686 // Should have deferred for network start.
1687 EXPECT_TRUE(net_start_handler.observed_before_network_start());
1688 EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
1689 EXPECT_TRUE(trans->GetResponseInfo() == NULL);
1690}
1691
[email protected]7a5378b2012-11-04 03:25:171692// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
1693// tests. There was a bug causing HttpNetworkTransaction to hang in the
1694// destructor in such situations.
1695// See http://crbug.com/154712 and http://crbug.com/156609.
[email protected]23e482282013-06-14 16:08:021696TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:171697 HttpRequestInfo request;
1698 request.method = "GET";
bncce36dca22015-04-21 22:11:231699 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171700 request.load_flags = 0;
1701
[email protected]bb88e1d32013-05-03 23:11:071702 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:361703 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501704 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171705
1706 MockRead data_reads[] = {
1707 MockRead("HTTP/1.0 200 OK\r\n"),
1708 MockRead("Connection: keep-alive\r\n"),
1709 MockRead("Content-Length: 100\r\n\r\n"),
1710 MockRead("hello"),
1711 MockRead(SYNCHRONOUS, 0),
1712 };
1713 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071714 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171715
1716 TestCompletionCallback callback;
1717
1718 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1719 EXPECT_EQ(ERR_IO_PENDING, rv);
1720
1721 rv = callback.WaitForResult();
1722 EXPECT_EQ(OK, rv);
1723
1724 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501725 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171726 if (rv == ERR_IO_PENDING)
1727 rv = callback.WaitForResult();
1728 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:501729 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171730 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1731
1732 trans.reset();
[email protected]2da659e2013-05-23 20:51:341733 base::MessageLoop::current()->RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171734 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1735}
1736
[email protected]23e482282013-06-14 16:08:021737TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:171738 HttpRequestInfo request;
1739 request.method = "GET";
bncce36dca22015-04-21 22:11:231740 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171741 request.load_flags = 0;
1742
[email protected]bb88e1d32013-05-03 23:11:071743 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:361744 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501745 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171746
1747 MockRead data_reads[] = {
1748 MockRead("HTTP/1.0 200 OK\r\n"),
1749 MockRead("Connection: keep-alive\r\n"),
1750 MockRead("Content-Length: 100\r\n\r\n"),
1751 MockRead(SYNCHRONOUS, 0),
1752 };
1753 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071754 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171755
1756 TestCompletionCallback callback;
1757
1758 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1759 EXPECT_EQ(ERR_IO_PENDING, rv);
1760
1761 rv = callback.WaitForResult();
1762 EXPECT_EQ(OK, rv);
1763
1764 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501765 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171766 if (rv == ERR_IO_PENDING)
1767 rv = callback.WaitForResult();
1768 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1769
1770 trans.reset();
[email protected]2da659e2013-05-23 20:51:341771 base::MessageLoop::current()->RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171772 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1773}
1774
[email protected]0b0bf032010-09-21 18:08:501775// Test that we correctly reuse a keep-alive connection after not explicitly
1776// reading the body.
[email protected]23e482282013-06-14 16:08:021777TEST_P(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:131778 HttpRequestInfo request;
1779 request.method = "GET";
1780 request.url = GURL("http://www.foo.com/");
1781 request.load_flags = 0;
1782
vishal.b62985ca92015-04-17 08:45:511783 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071784 session_deps_.net_log = &net_log;
1785 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271786
[email protected]0b0bf032010-09-21 18:08:501787 // Note that because all these reads happen in the same
1788 // StaticSocketDataProvider, it shows that the same socket is being reused for
1789 // all transactions.
[email protected]fc31d6a42010-06-24 18:05:131790 MockRead data1_reads[] = {
[email protected]0b0bf032010-09-21 18:08:501791 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
1792 MockRead("HTTP/1.1 205 Reset Content\r\n\r\n"),
[email protected]fc31d6a42010-06-24 18:05:131793 MockRead("HTTP/1.1 304 Not Modified\r\n\r\n"),
[email protected]0b0bf032010-09-21 18:08:501794 MockRead("HTTP/1.1 302 Found\r\n"
1795 "Content-Length: 0\r\n\r\n"),
1796 MockRead("HTTP/1.1 302 Found\r\n"
1797 "Content-Length: 5\r\n\r\n"
1798 "hello"),
1799 MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1800 "Content-Length: 0\r\n\r\n"),
1801 MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1802 "Content-Length: 5\r\n\r\n"
1803 "hello"),
[email protected]fc31d6a42010-06-24 18:05:131804 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1805 MockRead("hello"),
1806 };
1807 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071808 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]fc31d6a42010-06-24 18:05:131809
1810 MockRead data2_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061811 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]fc31d6a42010-06-24 18:05:131812 };
1813 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071814 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]fc31d6a42010-06-24 18:05:131815
[email protected]0b0bf032010-09-21 18:08:501816 const int kNumUnreadBodies = arraysize(data1_reads) - 2;
1817 std::string response_lines[kNumUnreadBodies];
1818
[email protected]58e32bb2013-01-21 18:23:251819 uint32 first_socket_log_id = NetLog::Source::kInvalidId;
[email protected]0b0bf032010-09-21 18:08:501820 for (size_t i = 0; i < arraysize(data1_reads) - 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411821 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:131822
[email protected]262eec82013-03-19 21:01:361823 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501824 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]fc31d6a42010-06-24 18:05:131825
[email protected]49639fa2011-12-20 23:22:411826 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]fc31d6a42010-06-24 18:05:131827 EXPECT_EQ(ERR_IO_PENDING, rv);
1828
1829 rv = callback.WaitForResult();
1830 EXPECT_EQ(OK, rv);
1831
[email protected]58e32bb2013-01-21 18:23:251832 LoadTimingInfo load_timing_info;
1833 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1834 if (i == 0) {
1835 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1836 first_socket_log_id = load_timing_info.socket_log_id;
1837 } else {
1838 TestLoadTimingReused(load_timing_info);
1839 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
1840 }
1841
[email protected]fc31d6a42010-06-24 18:05:131842 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]0b0bf032010-09-21 18:08:501843 ASSERT_TRUE(response != NULL);
[email protected]fc31d6a42010-06-24 18:05:131844
[email protected]90499482013-06-01 00:39:501845 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]0b0bf032010-09-21 18:08:501846 response_lines[i] = response->headers->GetStatusLine();
1847
1848 // We intentionally don't read the response bodies.
[email protected]fc31d6a42010-06-24 18:05:131849 }
[email protected]0b0bf032010-09-21 18:08:501850
1851 const char* const kStatusLines[] = {
1852 "HTTP/1.1 204 No Content",
1853 "HTTP/1.1 205 Reset Content",
1854 "HTTP/1.1 304 Not Modified",
1855 "HTTP/1.1 302 Found",
1856 "HTTP/1.1 302 Found",
1857 "HTTP/1.1 301 Moved Permanently",
1858 "HTTP/1.1 301 Moved Permanently",
1859 };
1860
mostynb91e0da982015-01-20 19:17:271861 static_assert(kNumUnreadBodies == arraysize(kStatusLines),
1862 "forgot to update kStatusLines");
[email protected]0b0bf032010-09-21 18:08:501863
1864 for (int i = 0; i < kNumUnreadBodies; ++i)
1865 EXPECT_EQ(kStatusLines[i], response_lines[i]);
1866
[email protected]49639fa2011-12-20 23:22:411867 TestCompletionCallback callback;
[email protected]262eec82013-03-19 21:01:361868 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501869 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:411870 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0b0bf032010-09-21 18:08:501871 EXPECT_EQ(ERR_IO_PENDING, rv);
1872 rv = callback.WaitForResult();
1873 EXPECT_EQ(OK, rv);
1874 const HttpResponseInfo* response = trans->GetResponseInfo();
1875 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:501876 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]0b0bf032010-09-21 18:08:501877 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1878 std::string response_data;
1879 rv = ReadTransaction(trans.get(), &response_data);
1880 EXPECT_EQ(OK, rv);
1881 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:131882}
1883
[email protected]038e9a32008-10-08 22:40:161884// Test the request-challenge-retry sequence for basic auth.
1885// (basic auth is the easiest to mock, because it has no randomness).
[email protected]23e482282013-06-14 16:08:021886TEST_P(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:421887 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:161888 request.method = "GET";
bncce36dca22015-04-21 22:11:231889 request.url = GURL("http://www.example.org/");
[email protected]038e9a32008-10-08 22:40:161890 request.load_flags = 0;
1891
vishal.b62985ca92015-04-17 08:45:511892 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:071893 session_deps_.net_log = &log;
[email protected]3fe8d2f82013-10-17 08:56:071894 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271895 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411896 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271897
[email protected]f9ee6b52008-11-08 06:46:231898 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:231899 MockWrite(
1900 "GET / HTTP/1.1\r\n"
1901 "Host: www.example.org\r\n"
1902 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:231903 };
1904
[email protected]038e9a32008-10-08 22:40:161905 MockRead data_reads1[] = {
1906 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
1907 // Give a couple authenticate options (only the middle one is actually
1908 // supported).
[email protected]22927ad2009-09-21 19:56:191909 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:161910 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1911 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
1912 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1913 // Large content-length -- won't matter, as connection will be reset.
1914 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061915 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:161916 };
1917
1918 // After calling trans->RestartWithAuth(), this is the request we should
1919 // be issuing -- the final header line contains the credentials.
1920 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:231921 MockWrite(
1922 "GET / HTTP/1.1\r\n"
1923 "Host: www.example.org\r\n"
1924 "Connection: keep-alive\r\n"
1925 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:161926 };
1927
1928 // Lastly, the server responds with the actual content.
1929 MockRead data_reads2[] = {
1930 MockRead("HTTP/1.0 200 OK\r\n"),
1931 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1932 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061933 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:161934 };
1935
[email protected]31a2bfe2010-02-09 08:03:391936 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1937 data_writes1, arraysize(data_writes1));
1938 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1939 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:071940 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1941 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:161942
[email protected]49639fa2011-12-20 23:22:411943 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:161944
[email protected]49639fa2011-12-20 23:22:411945 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421946 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:161947
1948 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421949 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:161950
[email protected]58e32bb2013-01-21 18:23:251951 LoadTimingInfo load_timing_info1;
1952 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
1953 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
1954
[email protected]b8015c42013-12-24 15:18:191955 int64 reads_size1 = ReadsSize(data_reads1, arraysize(data_reads1));
1956 EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
1957
[email protected]1c773ea12009-04-28 19:58:421958 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501959 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:041960 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:161961
[email protected]49639fa2011-12-20 23:22:411962 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:161963
[email protected]49639fa2011-12-20 23:22:411964 rv = trans->RestartWithAuth(
1965 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:421966 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:161967
1968 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421969 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:161970
[email protected]58e32bb2013-01-21 18:23:251971 LoadTimingInfo load_timing_info2;
1972 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
1973 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
1974 // The load timing after restart should have a new socket ID, and times after
1975 // those of the first load timing.
1976 EXPECT_LE(load_timing_info1.receive_headers_end,
1977 load_timing_info2.connect_timing.connect_start);
1978 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
1979
[email protected]b8015c42013-12-24 15:18:191980 int64 reads_size2 = ReadsSize(data_reads2, arraysize(data_reads2));
1981 EXPECT_EQ(reads_size1 + reads_size2, trans->GetTotalReceivedBytes());
1982
[email protected]038e9a32008-10-08 22:40:161983 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501984 ASSERT_TRUE(response != NULL);
[email protected]038e9a32008-10-08 22:40:161985 EXPECT_TRUE(response->auth_challenge.get() == NULL);
1986 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:161987}
1988
[email protected]23e482282013-06-14 16:08:021989TEST_P(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:461990 HttpRequestInfo request;
1991 request.method = "GET";
bncce36dca22015-04-21 22:11:231992 request.url = GURL("http://www.example.org/");
ttuttle859dc7a2015-04-23 19:42:291993 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]861fcd52009-08-26 02:33:461994
[email protected]3fe8d2f82013-10-17 08:56:071995 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271996 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411997 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271998
[email protected]861fcd52009-08-26 02:33:461999 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:232000 MockWrite(
2001 "GET / HTTP/1.1\r\n"
2002 "Host: www.example.org\r\n"
2003 "Connection: keep-alive\r\n\r\n"),
[email protected]861fcd52009-08-26 02:33:462004 };
2005
2006 MockRead data_reads[] = {
2007 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2008 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2009 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2010 // Large content-length -- won't matter, as connection will be reset.
2011 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062012 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:462013 };
2014
[email protected]31a2bfe2010-02-09 08:03:392015 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2016 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072017 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:412018 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:462019
[email protected]49639fa2011-12-20 23:22:412020 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]861fcd52009-08-26 02:33:462021 EXPECT_EQ(ERR_IO_PENDING, rv);
2022
2023 rv = callback.WaitForResult();
2024 EXPECT_EQ(0, rv);
2025
[email protected]b8015c42013-12-24 15:18:192026 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
2027 EXPECT_EQ(reads_size, trans->GetTotalReceivedBytes());
2028
[email protected]861fcd52009-08-26 02:33:462029 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502030 ASSERT_TRUE(response != NULL);
[email protected]861fcd52009-08-26 02:33:462031 EXPECT_TRUE(response->auth_challenge.get() == NULL);
2032}
2033
[email protected]2d2697f92009-02-18 21:00:322034// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2035// connection.
[email protected]23e482282013-06-14 16:08:022036TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
[email protected]1c773ea12009-04-28 19:58:422037 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322038 request.method = "GET";
bncce36dca22015-04-21 22:11:232039 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322040 request.load_flags = 0;
2041
vishal.b62985ca92015-04-17 08:45:512042 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072043 session_deps_.net_log = &log;
2044 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272045
[email protected]2d2697f92009-02-18 21:00:322046 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232047 MockWrite(
2048 "GET / HTTP/1.1\r\n"
2049 "Host: www.example.org\r\n"
2050 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322051
bncce36dca22015-04-21 22:11:232052 // After calling trans->RestartWithAuth(), this is the request we should
2053 // be issuing -- the final header line contains the credentials.
2054 MockWrite(
2055 "GET / HTTP/1.1\r\n"
2056 "Host: www.example.org\r\n"
2057 "Connection: keep-alive\r\n"
2058 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322059 };
2060
2061 MockRead data_reads1[] = {
2062 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2063 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2064 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2065 MockRead("Content-Length: 14\r\n\r\n"),
2066 MockRead("Unauthorized\r\n"),
2067
2068 // Lastly, the server responds with the actual content.
2069 MockRead("HTTP/1.1 200 OK\r\n"),
2070 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502071 MockRead("Content-Length: 5\r\n\r\n"),
2072 MockRead("Hello"),
[email protected]2d2697f92009-02-18 21:00:322073 };
2074
[email protected]2d0a4f92011-05-05 16:38:462075 // If there is a regression where we disconnect a Keep-Alive
2076 // connection during an auth roundtrip, we'll end up reading this.
2077 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062078 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462079 };
2080
[email protected]31a2bfe2010-02-09 08:03:392081 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2082 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462083 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2084 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072085 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2086 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322087
[email protected]49639fa2011-12-20 23:22:412088 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322089
[email protected]262eec82013-03-19 21:01:362090 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502091 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412092 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422093 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322094
2095 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422096 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322097
[email protected]58e32bb2013-01-21 18:23:252098 LoadTimingInfo load_timing_info1;
2099 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
2100 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2101
[email protected]1c773ea12009-04-28 19:58:422102 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502103 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042104 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322105
[email protected]49639fa2011-12-20 23:22:412106 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322107
[email protected]49639fa2011-12-20 23:22:412108 rv = trans->RestartWithAuth(
2109 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422110 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322111
2112 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422113 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322114
[email protected]58e32bb2013-01-21 18:23:252115 LoadTimingInfo load_timing_info2;
2116 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
2117 TestLoadTimingReused(load_timing_info2);
2118 // The load timing after restart should have the same socket ID, and times
2119 // those of the first load timing.
2120 EXPECT_LE(load_timing_info1.receive_headers_end,
2121 load_timing_info2.send_start);
2122 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2123
[email protected]2d2697f92009-02-18 21:00:322124 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502125 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322126 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502127 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]b8015c42013-12-24 15:18:192128
2129 std::string response_data;
2130 rv = ReadTransaction(trans.get(), &response_data);
2131 EXPECT_EQ(OK, rv);
2132 int64 reads_size1 = ReadsSize(data_reads1, arraysize(data_reads1));
2133 EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
[email protected]2d2697f92009-02-18 21:00:322134}
2135
2136// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2137// connection and with no response body to drain.
[email protected]23e482282013-06-14 16:08:022138TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:422139 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322140 request.method = "GET";
bncce36dca22015-04-21 22:11:232141 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322142 request.load_flags = 0;
2143
[email protected]bb88e1d32013-05-03 23:11:072144 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272145
[email protected]2d2697f92009-02-18 21:00:322146 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232147 MockWrite(
2148 "GET / HTTP/1.1\r\n"
2149 "Host: www.example.org\r\n"
2150 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322151
bncce36dca22015-04-21 22:11:232152 // After calling trans->RestartWithAuth(), this is the request we should
2153 // be issuing -- the final header line contains the credentials.
2154 MockWrite(
2155 "GET / HTTP/1.1\r\n"
2156 "Host: www.example.org\r\n"
2157 "Connection: keep-alive\r\n"
2158 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322159 };
2160
[email protected]2d2697f92009-02-18 21:00:322161 MockRead data_reads1[] = {
2162 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2163 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:312164 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:322165
2166 // Lastly, the server responds with the actual content.
2167 MockRead("HTTP/1.1 200 OK\r\n"),
2168 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502169 MockRead("Content-Length: 5\r\n\r\n"),
2170 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322171 };
2172
[email protected]2d0a4f92011-05-05 16:38:462173 // An incorrect reconnect would cause this to be read.
2174 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062175 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462176 };
2177
[email protected]31a2bfe2010-02-09 08:03:392178 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2179 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462180 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2181 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072182 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2183 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322184
[email protected]49639fa2011-12-20 23:22:412185 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322186
[email protected]262eec82013-03-19 21:01:362187 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502188 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412189 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422190 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322191
2192 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422193 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322194
[email protected]1c773ea12009-04-28 19:58:422195 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502196 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042197 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322198
[email protected]49639fa2011-12-20 23:22:412199 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322200
[email protected]49639fa2011-12-20 23:22:412201 rv = trans->RestartWithAuth(
2202 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422203 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322204
2205 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422206 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322207
2208 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502209 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322210 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502211 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322212}
2213
2214// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2215// connection and with a large response body to drain.
[email protected]23e482282013-06-14 16:08:022216TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:422217 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322218 request.method = "GET";
bncce36dca22015-04-21 22:11:232219 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322220 request.load_flags = 0;
2221
[email protected]bb88e1d32013-05-03 23:11:072222 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272223
[email protected]2d2697f92009-02-18 21:00:322224 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232225 MockWrite(
2226 "GET / HTTP/1.1\r\n"
2227 "Host: www.example.org\r\n"
2228 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322229
bncce36dca22015-04-21 22:11:232230 // After calling trans->RestartWithAuth(), this is the request we should
2231 // be issuing -- the final header line contains the credentials.
2232 MockWrite(
2233 "GET / HTTP/1.1\r\n"
2234 "Host: www.example.org\r\n"
2235 "Connection: keep-alive\r\n"
2236 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322237 };
2238
2239 // Respond with 5 kb of response body.
2240 std::string large_body_string("Unauthorized");
2241 large_body_string.append(5 * 1024, ' ');
2242 large_body_string.append("\r\n");
2243
2244 MockRead data_reads1[] = {
2245 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2246 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2247 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2248 // 5134 = 12 + 5 * 1024 + 2
2249 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062250 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:322251
2252 // Lastly, the server responds with the actual content.
2253 MockRead("HTTP/1.1 200 OK\r\n"),
2254 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502255 MockRead("Content-Length: 5\r\n\r\n"),
2256 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322257 };
2258
[email protected]2d0a4f92011-05-05 16:38:462259 // An incorrect reconnect would cause this to be read.
2260 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062261 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462262 };
2263
[email protected]31a2bfe2010-02-09 08:03:392264 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2265 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462266 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2267 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072268 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2269 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322270
[email protected]49639fa2011-12-20 23:22:412271 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322272
[email protected]262eec82013-03-19 21:01:362273 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502274 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412275 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422276 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322277
2278 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422279 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322280
[email protected]1c773ea12009-04-28 19:58:422281 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502282 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042283 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322284
[email protected]49639fa2011-12-20 23:22:412285 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322286
[email protected]49639fa2011-12-20 23:22:412287 rv = trans->RestartWithAuth(
2288 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422289 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322290
2291 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422292 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322293
2294 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502295 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322296 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502297 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322298}
2299
2300// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:312301// connection, but the server gets impatient and closes the connection.
[email protected]23e482282013-06-14 16:08:022302TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:312303 HttpRequestInfo request;
2304 request.method = "GET";
bncce36dca22015-04-21 22:11:232305 request.url = GURL("http://www.example.org/");
[email protected]11203f012009-11-12 23:02:312306 request.load_flags = 0;
2307
[email protected]bb88e1d32013-05-03 23:11:072308 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272309
[email protected]11203f012009-11-12 23:02:312310 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232311 MockWrite(
2312 "GET / HTTP/1.1\r\n"
2313 "Host: www.example.org\r\n"
2314 "Connection: keep-alive\r\n\r\n"),
2315 // This simulates the seemingly successful write to a closed connection
2316 // if the bug is not fixed.
2317 MockWrite(
2318 "GET / HTTP/1.1\r\n"
2319 "Host: www.example.org\r\n"
2320 "Connection: keep-alive\r\n"
2321 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312322 };
2323
2324 MockRead data_reads1[] = {
2325 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2326 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2327 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2328 MockRead("Content-Length: 14\r\n\r\n"),
2329 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:062330 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:312331 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:062332 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:312333 };
2334
2335 // After calling trans->RestartWithAuth(), this is the request we should
2336 // be issuing -- the final header line contains the credentials.
2337 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232338 MockWrite(
2339 "GET / HTTP/1.1\r\n"
2340 "Host: www.example.org\r\n"
2341 "Connection: keep-alive\r\n"
2342 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312343 };
2344
2345 // Lastly, the server responds with the actual content.
2346 MockRead data_reads2[] = {
2347 MockRead("HTTP/1.1 200 OK\r\n"),
2348 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502349 MockRead("Content-Length: 5\r\n\r\n"),
2350 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:312351 };
2352
[email protected]31a2bfe2010-02-09 08:03:392353 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2354 data_writes1, arraysize(data_writes1));
2355 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2356 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072357 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2358 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:312359
[email protected]49639fa2011-12-20 23:22:412360 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:312361
[email protected]262eec82013-03-19 21:01:362362 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502363 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412364 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]11203f012009-11-12 23:02:312365 EXPECT_EQ(ERR_IO_PENDING, rv);
2366
2367 rv = callback1.WaitForResult();
2368 EXPECT_EQ(OK, rv);
2369
2370 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502371 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042372 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:312373
[email protected]49639fa2011-12-20 23:22:412374 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:312375
[email protected]49639fa2011-12-20 23:22:412376 rv = trans->RestartWithAuth(
2377 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]11203f012009-11-12 23:02:312378 EXPECT_EQ(ERR_IO_PENDING, rv);
2379
2380 rv = callback2.WaitForResult();
2381 EXPECT_EQ(OK, rv);
2382
2383 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502384 ASSERT_TRUE(response != NULL);
[email protected]11203f012009-11-12 23:02:312385 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502386 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:312387}
2388
[email protected]394816e92010-08-03 07:38:592389// Test the request-challenge-retry sequence for basic auth, over a connection
2390// that requires a restart when setting up an SSL tunnel.
ttuttle34f63b52015-03-05 04:33:012391TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
2392 HttpRequestInfo request;
2393 request.method = "GET";
bncce36dca22015-04-21 22:11:232394 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:012395 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292396 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:012397
2398 // Configure against proxy server "myproxy:70".
2399 session_deps_.proxy_service.reset(
2400 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
vishal.b62985ca92015-04-17 08:45:512401 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:012402 session_deps_.net_log = log.bound().net_log();
2403 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2404
2405 // Since we have proxy, should try to establish tunnel.
2406 MockWrite data_writes1[] = {
2407 MockWrite(
bncce36dca22015-04-21 22:11:232408 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2409 "Host: www.example.org\r\n"
ttuttle34f63b52015-03-05 04:33:012410 "Proxy-Connection: keep-alive\r\n\r\n"),
2411
2412 // After calling trans->RestartWithAuth(), this is the request we should
2413 // be issuing -- the final header line contains the credentials.
2414 MockWrite(
bncce36dca22015-04-21 22:11:232415 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2416 "Host: www.example.org\r\n"
ttuttle34f63b52015-03-05 04:33:012417 "Proxy-Connection: keep-alive\r\n"
2418 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2419
2420 MockWrite(
2421 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:232422 "Host: www.example.org\r\n"
ttuttle34f63b52015-03-05 04:33:012423 "Connection: keep-alive\r\n\r\n"),
2424 };
2425
2426 // The proxy responds to the connect with a 407, using a persistent
2427 // connection.
2428 MockRead data_reads1[] = {
2429 // No credentials.
2430 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
2431 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
2432
2433 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
2434
2435 MockRead("HTTP/1.1 200 OK\r\n"),
2436 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2437 MockRead("Content-Length: 5\r\n\r\n"),
2438 MockRead(SYNCHRONOUS, "hello"),
2439 };
2440
2441 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2442 data_writes1, arraysize(data_writes1));
2443 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2444 SSLSocketDataProvider ssl(ASYNC, OK);
2445 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
2446
2447 TestCompletionCallback callback1;
2448
2449 scoped_ptr<HttpTransaction> trans(
2450 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2451
2452 int rv = trans->Start(&request, callback1.callback(), log.bound());
2453 EXPECT_EQ(ERR_IO_PENDING, rv);
2454
2455 rv = callback1.WaitForResult();
2456 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:462457 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:012458 log.GetEntries(&entries);
2459 size_t pos = ExpectLogContainsSomewhere(
2460 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
2461 NetLog::PHASE_NONE);
2462 ExpectLogContainsSomewhere(
2463 entries, pos, NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2464 NetLog::PHASE_NONE);
2465
2466 const HttpResponseInfo* response = trans->GetResponseInfo();
2467 ASSERT_TRUE(response != NULL);
2468 EXPECT_FALSE(response->headers->IsKeepAlive());
2469 ASSERT_FALSE(response->headers.get() == NULL);
2470 EXPECT_EQ(407, response->headers->response_code());
2471 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
2472 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2473
2474 LoadTimingInfo load_timing_info;
2475 // CONNECT requests and responses are handled at the connect job level, so
2476 // the transaction does not yet have a connection.
2477 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
2478
2479 TestCompletionCallback callback2;
2480
2481 rv =
2482 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
2483 EXPECT_EQ(ERR_IO_PENDING, rv);
2484
2485 rv = callback2.WaitForResult();
2486 EXPECT_EQ(OK, rv);
2487
2488 response = trans->GetResponseInfo();
2489 ASSERT_TRUE(response != NULL);
2490
2491 EXPECT_TRUE(response->headers->IsKeepAlive());
2492 EXPECT_EQ(200, response->headers->response_code());
2493 EXPECT_EQ(5, response->headers->GetContentLength());
2494 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2495
2496 // The password prompt info should not be set.
2497 EXPECT_TRUE(response->auth_challenge.get() == NULL);
2498
2499 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2500 TestLoadTimingNotReusedWithPac(load_timing_info,
2501 CONNECT_TIMING_HAS_SSL_TIMES);
2502
2503 trans.reset();
2504 session->CloseAllConnections();
2505}
2506
2507// Test the request-challenge-retry sequence for basic auth, over a connection
2508// that requires a restart when setting up an SSL tunnel.
2509TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) {
[email protected]394816e92010-08-03 07:38:592510 HttpRequestInfo request;
2511 request.method = "GET";
bncce36dca22015-04-21 22:11:232512 request.url = GURL("https://www.example.org/");
[email protected]394816e92010-08-03 07:38:592513 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292514 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]394816e92010-08-03 07:38:592515
[email protected]cb9bf6ca2011-01-28 13:15:272516 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072517 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:202518 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
vishal.b62985ca92015-04-17 08:45:512519 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072520 session_deps_.net_log = log.bound().net_log();
2521 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272522
[email protected]394816e92010-08-03 07:38:592523 // Since we have proxy, should try to establish tunnel.
2524 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232525 MockWrite(
2526 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2527 "Host: www.example.org\r\n"
2528 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]394816e92010-08-03 07:38:592529
bncce36dca22015-04-21 22:11:232530 // After calling trans->RestartWithAuth(), this is the request we should
2531 // be issuing -- the final header line contains the credentials.
2532 MockWrite(
2533 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2534 "Host: www.example.org\r\n"
2535 "Proxy-Connection: keep-alive\r\n"
2536 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]394816e92010-08-03 07:38:592537
bncce36dca22015-04-21 22:11:232538 MockWrite(
2539 "GET / HTTP/1.1\r\n"
2540 "Host: www.example.org\r\n"
2541 "Connection: keep-alive\r\n\r\n"),
[email protected]394816e92010-08-03 07:38:592542 };
2543
2544 // The proxy responds to the connect with a 407, using a persistent
2545 // connection.
2546 MockRead data_reads1[] = {
2547 // No credentials.
2548 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2549 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2550 MockRead("Proxy-Connection: close\r\n\r\n"),
2551
2552 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2553
2554 MockRead("HTTP/1.1 200 OK\r\n"),
2555 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502556 MockRead("Content-Length: 5\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062557 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:592558 };
2559
2560 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2561 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072562 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:062563 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072564 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:592565
[email protected]49639fa2011-12-20 23:22:412566 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:592567
[email protected]262eec82013-03-19 21:01:362568 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502569 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:502570
[email protected]49639fa2011-12-20 23:22:412571 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]394816e92010-08-03 07:38:592572 EXPECT_EQ(ERR_IO_PENDING, rv);
2573
2574 rv = callback1.WaitForResult();
2575 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:462576 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:402577 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:592578 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402579 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]394816e92010-08-03 07:38:592580 NetLog::PHASE_NONE);
2581 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402582 entries, pos,
[email protected]394816e92010-08-03 07:38:592583 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2584 NetLog::PHASE_NONE);
2585
2586 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502587 ASSERT_TRUE(response != NULL);
ttuttle34f63b52015-03-05 04:33:012588 EXPECT_FALSE(response->headers->IsKeepAlive());
[email protected]90499482013-06-01 00:39:502589 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]394816e92010-08-03 07:38:592590 EXPECT_EQ(407, response->headers->response_code());
2591 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042592 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:592593
[email protected]029c83b62013-01-24 05:28:202594 LoadTimingInfo load_timing_info;
2595 // CONNECT requests and responses are handled at the connect job level, so
2596 // the transaction does not yet have a connection.
2597 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
2598
[email protected]49639fa2011-12-20 23:22:412599 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:592600
[email protected]49639fa2011-12-20 23:22:412601 rv = trans->RestartWithAuth(
2602 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]394816e92010-08-03 07:38:592603 EXPECT_EQ(ERR_IO_PENDING, rv);
2604
2605 rv = callback2.WaitForResult();
2606 EXPECT_EQ(OK, rv);
2607
2608 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502609 ASSERT_TRUE(response != NULL);
[email protected]394816e92010-08-03 07:38:592610
2611 EXPECT_TRUE(response->headers->IsKeepAlive());
2612 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:502613 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:592614 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2615
2616 // The password prompt info should not be set.
2617 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502618
[email protected]029c83b62013-01-24 05:28:202619 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2620 TestLoadTimingNotReusedWithPac(load_timing_info,
2621 CONNECT_TIMING_HAS_SSL_TIMES);
2622
[email protected]0b0bf032010-09-21 18:08:502623 trans.reset();
[email protected]102e27c2011-02-23 01:01:312624 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:592625}
2626
[email protected]11203f012009-11-12 23:02:312627// Test the request-challenge-retry sequence for basic auth, over a keep-alive
ttuttle34f63b52015-03-05 04:33:012628// proxy connection with HTTP/1.0 responses, when setting up an SSL tunnel.
2629TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
2630 HttpRequestInfo request;
2631 request.method = "GET";
bncce36dca22015-04-21 22:11:232632 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:012633 // Ensure that proxy authentication is attempted even
2634 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292635 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:012636
2637 // Configure against proxy server "myproxy:70".
2638 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
vishal.b62985ca92015-04-17 08:45:512639 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:012640 session_deps_.net_log = log.bound().net_log();
2641 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2642
2643 scoped_ptr<HttpTransaction> trans(
2644 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2645
2646 // Since we have proxy, should try to establish tunnel.
2647 MockWrite data_writes1[] = {
2648 MockWrite(
bncce36dca22015-04-21 22:11:232649 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2650 "Host: www.example.org\r\n"
ttuttle34f63b52015-03-05 04:33:012651 "Proxy-Connection: keep-alive\r\n\r\n"),
2652
2653 // After calling trans->RestartWithAuth(), this is the request we should
2654 // be issuing -- the final header line contains the credentials.
2655 MockWrite(
bncce36dca22015-04-21 22:11:232656 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2657 "Host: www.example.org\r\n"
ttuttle34f63b52015-03-05 04:33:012658 "Proxy-Connection: keep-alive\r\n"
2659 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
2660 };
2661
2662 // The proxy responds to the connect with a 407, using a persistent
2663 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
2664 MockRead data_reads1[] = {
2665 // No credentials.
2666 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
2667 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2668 MockRead("Proxy-Connection: keep-alive\r\n"),
2669 MockRead("Content-Length: 10\r\n\r\n"),
2670 MockRead("0123456789"),
2671
2672 // Wrong credentials (wrong password).
2673 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
2674 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2675 MockRead("Proxy-Connection: keep-alive\r\n"),
2676 MockRead("Content-Length: 10\r\n\r\n"),
2677 // No response body because the test stops reading here.
2678 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
2679 };
2680
2681 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2682 data_writes1, arraysize(data_writes1));
2683 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2684
2685 TestCompletionCallback callback1;
2686
2687 int rv = trans->Start(&request, callback1.callback(), log.bound());
2688 EXPECT_EQ(ERR_IO_PENDING, rv);
2689
2690 rv = callback1.WaitForResult();
2691 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:462692 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:012693 log.GetEntries(&entries);
2694 size_t pos = ExpectLogContainsSomewhere(
2695 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
2696 NetLog::PHASE_NONE);
2697 ExpectLogContainsSomewhere(
2698 entries, pos, NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2699 NetLog::PHASE_NONE);
2700
2701 const HttpResponseInfo* response = trans->GetResponseInfo();
2702 ASSERT_TRUE(response);
2703 ASSERT_TRUE(response->headers);
2704 EXPECT_TRUE(response->headers->IsKeepAlive());
2705 EXPECT_EQ(407, response->headers->response_code());
2706 EXPECT_EQ(10, response->headers->GetContentLength());
2707 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
2708 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2709
2710 TestCompletionCallback callback2;
2711
2712 // Wrong password (should be "bar").
2713 rv =
2714 trans->RestartWithAuth(AuthCredentials(kFoo, kBaz), callback2.callback());
2715 EXPECT_EQ(ERR_IO_PENDING, rv);
2716
2717 rv = callback2.WaitForResult();
2718 EXPECT_EQ(OK, rv);
2719
2720 response = trans->GetResponseInfo();
2721 ASSERT_TRUE(response);
2722 ASSERT_TRUE(response->headers);
2723 EXPECT_TRUE(response->headers->IsKeepAlive());
2724 EXPECT_EQ(407, response->headers->response_code());
2725 EXPECT_EQ(10, response->headers->GetContentLength());
2726 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
2727 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2728
2729 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
2730 // out of scope.
2731 session->CloseAllConnections();
2732}
2733
2734// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2735// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel.
2736TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
[email protected]cb9bf6ca2011-01-28 13:15:272737 HttpRequestInfo request;
2738 request.method = "GET";
bncce36dca22015-04-21 22:11:232739 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:272740 // Ensure that proxy authentication is attempted even
2741 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292742 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]cb9bf6ca2011-01-28 13:15:272743
[email protected]2d2697f92009-02-18 21:00:322744 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072745 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
vishal.b62985ca92015-04-17 08:45:512746 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072747 session_deps_.net_log = log.bound().net_log();
2748 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:322749
[email protected]262eec82013-03-19 21:01:362750 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502751 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d2697f92009-02-18 21:00:322752
[email protected]2d2697f92009-02-18 21:00:322753 // Since we have proxy, should try to establish tunnel.
2754 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232755 MockWrite(
2756 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2757 "Host: www.example.org\r\n"
2758 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322759
bncce36dca22015-04-21 22:11:232760 // After calling trans->RestartWithAuth(), this is the request we should
2761 // be issuing -- the final header line contains the credentials.
2762 MockWrite(
2763 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2764 "Host: www.example.org\r\n"
2765 "Proxy-Connection: keep-alive\r\n"
2766 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322767 };
2768
2769 // The proxy responds to the connect with a 407, using a persistent
2770 // connection.
2771 MockRead data_reads1[] = {
2772 // No credentials.
2773 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2774 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2775 MockRead("Content-Length: 10\r\n\r\n"),
2776 MockRead("0123456789"),
2777
2778 // Wrong credentials (wrong password).
2779 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2780 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2781 MockRead("Content-Length: 10\r\n\r\n"),
2782 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:062783 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]2d2697f92009-02-18 21:00:322784 };
2785
[email protected]31a2bfe2010-02-09 08:03:392786 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2787 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072788 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d2697f92009-02-18 21:00:322789
[email protected]49639fa2011-12-20 23:22:412790 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322791
[email protected]49639fa2011-12-20 23:22:412792 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]1c773ea12009-04-28 19:58:422793 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322794
2795 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422796 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:462797 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:402798 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:392799 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402800 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]dbb83db2010-05-11 18:13:392801 NetLog::PHASE_NONE);
2802 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402803 entries, pos,
[email protected]dbb83db2010-05-11 18:13:392804 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2805 NetLog::PHASE_NONE);
[email protected]2d2697f92009-02-18 21:00:322806
[email protected]1c773ea12009-04-28 19:58:422807 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:242808 ASSERT_TRUE(response);
2809 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:322810 EXPECT_TRUE(response->headers->IsKeepAlive());
2811 EXPECT_EQ(407, response->headers->response_code());
ttuttle34f63b52015-03-05 04:33:012812 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422813 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042814 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322815
[email protected]49639fa2011-12-20 23:22:412816 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322817
2818 // Wrong password (should be "bar").
[email protected]49639fa2011-12-20 23:22:412819 rv = trans->RestartWithAuth(
2820 AuthCredentials(kFoo, kBaz), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422821 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322822
2823 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422824 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322825
2826 response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:242827 ASSERT_TRUE(response);
2828 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:322829 EXPECT_TRUE(response->headers->IsKeepAlive());
2830 EXPECT_EQ(407, response->headers->response_code());
ttuttle34f63b52015-03-05 04:33:012831 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422832 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042833 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]e772db3f2010-07-12 18:11:132834
[email protected]e60e47a2010-07-14 03:37:182835 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
2836 // out of scope.
[email protected]102e27c2011-02-23 01:01:312837 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:322838}
2839
[email protected]a8e9b162009-03-12 00:06:442840// Test that we don't read the response body when we fail to establish a tunnel,
2841// even if the user cancels the proxy's auth attempt.
[email protected]23e482282013-06-14 16:08:022842TEST_P(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:272843 HttpRequestInfo request;
2844 request.method = "GET";
bncce36dca22015-04-21 22:11:232845 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:272846 request.load_flags = 0;
2847
[email protected]a8e9b162009-03-12 00:06:442848 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072849 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]a8e9b162009-03-12 00:06:442850
[email protected]bb88e1d32013-05-03 23:11:072851 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:442852
[email protected]262eec82013-03-19 21:01:362853 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502854 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]a8e9b162009-03-12 00:06:442855
[email protected]a8e9b162009-03-12 00:06:442856 // Since we have proxy, should try to establish tunnel.
2857 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:232858 MockWrite(
2859 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2860 "Host: www.example.org\r\n"
2861 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:442862 };
2863
2864 // The proxy responds to the connect with a 407.
2865 MockRead data_reads[] = {
ttuttle7933c112015-01-06 00:55:242866 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2867 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2868 MockRead("Content-Length: 10\r\n\r\n"),
2869 MockRead("0123456789"), // Should not be reached.
2870 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]a8e9b162009-03-12 00:06:442871 };
2872
[email protected]31a2bfe2010-02-09 08:03:392873 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2874 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072875 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:442876
[email protected]49639fa2011-12-20 23:22:412877 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:442878
[email protected]49639fa2011-12-20 23:22:412879 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422880 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a8e9b162009-03-12 00:06:442881
2882 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422883 EXPECT_EQ(OK, rv);
[email protected]a8e9b162009-03-12 00:06:442884
[email protected]1c773ea12009-04-28 19:58:422885 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:242886 ASSERT_TRUE(response);
2887 ASSERT_TRUE(response->headers);
[email protected]a8e9b162009-03-12 00:06:442888 EXPECT_TRUE(response->headers->IsKeepAlive());
2889 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:422890 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:442891
2892 std::string response_data;
2893 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:422894 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]e60e47a2010-07-14 03:37:182895
2896 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:312897 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:442898}
2899
ttuttle7933c112015-01-06 00:55:242900// Test that we don't pass extraneous headers from the proxy's response to the
2901// caller when the proxy responds to CONNECT with 407.
2902TEST_P(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
2903 HttpRequestInfo request;
2904 request.method = "GET";
bncce36dca22015-04-21 22:11:232905 request.url = GURL("https://www.example.org/");
ttuttle7933c112015-01-06 00:55:242906 request.load_flags = 0;
2907
2908 // Configure against proxy server "myproxy:70".
2909 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
2910
2911 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2912
2913 scoped_ptr<HttpTransaction> trans(
2914 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2915
2916 // Since we have proxy, should try to establish tunnel.
2917 MockWrite data_writes[] = {
2918 MockWrite(
bncce36dca22015-04-21 22:11:232919 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2920 "Host: www.example.org\r\n"
ttuttle7933c112015-01-06 00:55:242921 "Proxy-Connection: keep-alive\r\n\r\n"),
2922 };
2923
2924 // The proxy responds to the connect with a 407.
2925 MockRead data_reads[] = {
2926 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2927 MockRead("X-Foo: bar\r\n"),
2928 MockRead("Set-Cookie: foo=bar\r\n"),
2929 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2930 MockRead("Content-Length: 10\r\n\r\n"),
2931 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
2932 };
2933
2934 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
2935 arraysize(data_writes));
2936 session_deps_.socket_factory->AddSocketDataProvider(&data);
2937
2938 TestCompletionCallback callback;
2939
2940 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
2941 EXPECT_EQ(ERR_IO_PENDING, rv);
2942
2943 rv = callback.WaitForResult();
2944 EXPECT_EQ(OK, rv);
2945
2946 const HttpResponseInfo* response = trans->GetResponseInfo();
2947 ASSERT_TRUE(response);
2948 ASSERT_TRUE(response->headers);
2949 EXPECT_TRUE(response->headers->IsKeepAlive());
2950 EXPECT_EQ(407, response->headers->response_code());
2951 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2952 EXPECT_FALSE(response->headers->HasHeader("X-Foo"));
2953 EXPECT_FALSE(response->headers->HasHeader("Set-Cookie"));
2954
2955 std::string response_data;
2956 rv = ReadTransaction(trans.get(), &response_data);
2957 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
2958
2959 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
2960 session->CloseAllConnections();
2961}
2962
[email protected]8fdbcd22010-05-05 02:54:522963// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
2964// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
[email protected]23e482282013-06-14 16:08:022965TEST_P(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:522966 HttpRequestInfo request;
2967 request.method = "GET";
bncce36dca22015-04-21 22:11:232968 request.url = GURL("http://www.example.org/");
[email protected]8fdbcd22010-05-05 02:54:522969 request.load_flags = 0;
2970
[email protected]cb9bf6ca2011-01-28 13:15:272971 // We are using a DIRECT connection (i.e. no proxy) for this session.
[email protected]3fe8d2f82013-10-17 08:56:072972 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272973 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:412974 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:272975
[email protected]8fdbcd22010-05-05 02:54:522976 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232977 MockWrite(
2978 "GET / HTTP/1.1\r\n"
2979 "Host: www.example.org\r\n"
2980 "Connection: keep-alive\r\n\r\n"),
[email protected]8fdbcd22010-05-05 02:54:522981 };
2982
2983 MockRead data_reads1[] = {
2984 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
2985 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2986 // Large content-length -- won't matter, as connection will be reset.
2987 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062988 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:522989 };
2990
2991 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2992 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072993 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:522994
[email protected]49639fa2011-12-20 23:22:412995 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:522996
[email protected]49639fa2011-12-20 23:22:412997 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]8fdbcd22010-05-05 02:54:522998 EXPECT_EQ(ERR_IO_PENDING, rv);
2999
3000 rv = callback.WaitForResult();
3001 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
3002}
3003
[email protected]7a67a8152010-11-05 18:31:103004// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
3005// through a non-authenticating proxy. The request should fail with
3006// ERR_UNEXPECTED_PROXY_AUTH.
3007// Note that it is impossible to detect if an HTTP server returns a 407 through
3008// a non-authenticating proxy - there is nothing to indicate whether the
3009// response came from the proxy or the server, so it is treated as if the proxy
3010// issued the challenge.
[email protected]23e482282013-06-14 16:08:023011TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:233012 HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:273013 HttpRequestInfo request;
3014 request.method = "GET";
bncce36dca22015-04-21 22:11:233015 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273016
[email protected]bb88e1d32013-05-03 23:11:073017 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
vishal.b62985ca92015-04-17 08:45:513018 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073019 session_deps_.net_log = log.bound().net_log();
3020 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:103021
[email protected]7a67a8152010-11-05 18:31:103022 // Since we have proxy, should try to establish tunnel.
3023 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233024 MockWrite(
3025 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3026 "Host: www.example.org\r\n"
3027 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103028
bncce36dca22015-04-21 22:11:233029 MockWrite(
3030 "GET / HTTP/1.1\r\n"
3031 "Host: www.example.org\r\n"
3032 "Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103033 };
3034
3035 MockRead data_reads1[] = {
3036 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3037
3038 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
3039 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3040 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:063041 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:103042 };
3043
3044 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3045 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073046 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063047 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073048 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:103049
[email protected]49639fa2011-12-20 23:22:413050 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:103051
[email protected]262eec82013-03-19 21:01:363052 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503053 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a67a8152010-11-05 18:31:103054
[email protected]49639fa2011-12-20 23:22:413055 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7a67a8152010-11-05 18:31:103056 EXPECT_EQ(ERR_IO_PENDING, rv);
3057
3058 rv = callback1.WaitForResult();
3059 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
mmenke43758e62015-05-04 21:09:463060 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403061 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:103062 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403063 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]7a67a8152010-11-05 18:31:103064 NetLog::PHASE_NONE);
3065 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403066 entries, pos,
[email protected]7a67a8152010-11-05 18:31:103067 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3068 NetLog::PHASE_NONE);
3069}
[email protected]2df19bb2010-08-25 20:13:463070
[email protected]029c83b62013-01-24 05:28:203071// Test the load timing for HTTPS requests with an HTTP proxy.
[email protected]23e482282013-06-14 16:08:023072TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:203073 HttpRequestInfo request1;
3074 request1.method = "GET";
bncce36dca22015-04-21 22:11:233075 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:203076
3077 HttpRequestInfo request2;
3078 request2.method = "GET";
bncce36dca22015-04-21 22:11:233079 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:203080
3081 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073082 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:203083 ProxyService::CreateFixed("PROXY myproxy:70"));
vishal.b62985ca92015-04-17 08:45:513084 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073085 session_deps_.net_log = log.bound().net_log();
3086 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:203087
3088 // Since we have proxy, should try to establish tunnel.
3089 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233090 MockWrite(
3091 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3092 "Host: www.example.org\r\n"
3093 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203094
bncce36dca22015-04-21 22:11:233095 MockWrite(
3096 "GET /1 HTTP/1.1\r\n"
3097 "Host: www.example.org\r\n"
3098 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203099
bncce36dca22015-04-21 22:11:233100 MockWrite(
3101 "GET /2 HTTP/1.1\r\n"
3102 "Host: www.example.org\r\n"
3103 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203104 };
3105
3106 // The proxy responds to the connect with a 407, using a persistent
3107 // connection.
3108 MockRead data_reads1[] = {
3109 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3110
3111 MockRead("HTTP/1.1 200 OK\r\n"),
3112 MockRead("Content-Length: 1\r\n\r\n"),
3113 MockRead(SYNCHRONOUS, "1"),
3114
3115 MockRead("HTTP/1.1 200 OK\r\n"),
3116 MockRead("Content-Length: 2\r\n\r\n"),
3117 MockRead(SYNCHRONOUS, "22"),
3118 };
3119
3120 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3121 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073122 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:203123 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073124 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:203125
3126 TestCompletionCallback callback1;
[email protected]262eec82013-03-19 21:01:363127 scoped_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:503128 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:203129
3130 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
3131 EXPECT_EQ(ERR_IO_PENDING, rv);
3132
3133 rv = callback1.WaitForResult();
3134 EXPECT_EQ(OK, rv);
3135
3136 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
3137 ASSERT_TRUE(response1 != NULL);
[email protected]90499482013-06-01 00:39:503138 ASSERT_TRUE(response1->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:203139 EXPECT_EQ(1, response1->headers->GetContentLength());
3140
3141 LoadTimingInfo load_timing_info1;
3142 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
3143 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
3144
3145 trans1.reset();
3146
3147 TestCompletionCallback callback2;
[email protected]262eec82013-03-19 21:01:363148 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503149 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:203150
3151 rv = trans2->Start(&request2, callback2.callback(), log.bound());
3152 EXPECT_EQ(ERR_IO_PENDING, rv);
3153
3154 rv = callback2.WaitForResult();
3155 EXPECT_EQ(OK, rv);
3156
3157 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
3158 ASSERT_TRUE(response2 != NULL);
[email protected]90499482013-06-01 00:39:503159 ASSERT_TRUE(response2->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:203160 EXPECT_EQ(2, response2->headers->GetContentLength());
3161
3162 LoadTimingInfo load_timing_info2;
3163 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3164 TestLoadTimingReused(load_timing_info2);
3165
3166 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
3167
3168 trans2.reset();
3169 session->CloseAllConnections();
3170}
3171
3172// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
[email protected]23e482282013-06-14 16:08:023173TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:203174 HttpRequestInfo request1;
3175 request1.method = "GET";
bncce36dca22015-04-21 22:11:233176 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:203177
3178 HttpRequestInfo request2;
3179 request2.method = "GET";
bncce36dca22015-04-21 22:11:233180 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:203181
3182 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073183 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:203184 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
vishal.b62985ca92015-04-17 08:45:513185 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073186 session_deps_.net_log = log.bound().net_log();
3187 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:203188
3189 // Since we have proxy, should try to establish tunnel.
3190 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233191 MockWrite(
3192 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3193 "Host: www.example.org\r\n"
3194 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203195
bncce36dca22015-04-21 22:11:233196 MockWrite(
3197 "GET /1 HTTP/1.1\r\n"
3198 "Host: www.example.org\r\n"
3199 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203200
bncce36dca22015-04-21 22:11:233201 MockWrite(
3202 "GET /2 HTTP/1.1\r\n"
3203 "Host: www.example.org\r\n"
3204 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203205 };
3206
3207 // The proxy responds to the connect with a 407, using a persistent
3208 // connection.
3209 MockRead data_reads1[] = {
3210 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3211
3212 MockRead("HTTP/1.1 200 OK\r\n"),
3213 MockRead("Content-Length: 1\r\n\r\n"),
3214 MockRead(SYNCHRONOUS, "1"),
3215
3216 MockRead("HTTP/1.1 200 OK\r\n"),
3217 MockRead("Content-Length: 2\r\n\r\n"),
3218 MockRead(SYNCHRONOUS, "22"),
3219 };
3220
3221 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3222 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073223 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:203224 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073225 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:203226
3227 TestCompletionCallback callback1;
[email protected]262eec82013-03-19 21:01:363228 scoped_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:503229 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:203230
3231 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
3232 EXPECT_EQ(ERR_IO_PENDING, rv);
3233
3234 rv = callback1.WaitForResult();
3235 EXPECT_EQ(OK, rv);
3236
3237 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
3238 ASSERT_TRUE(response1 != NULL);
[email protected]90499482013-06-01 00:39:503239 ASSERT_TRUE(response1->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:203240 EXPECT_EQ(1, response1->headers->GetContentLength());
3241
3242 LoadTimingInfo load_timing_info1;
3243 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
3244 TestLoadTimingNotReusedWithPac(load_timing_info1,
3245 CONNECT_TIMING_HAS_SSL_TIMES);
3246
3247 trans1.reset();
3248
3249 TestCompletionCallback callback2;
[email protected]262eec82013-03-19 21:01:363250 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503251 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:203252
3253 rv = trans2->Start(&request2, callback2.callback(), log.bound());
3254 EXPECT_EQ(ERR_IO_PENDING, rv);
3255
3256 rv = callback2.WaitForResult();
3257 EXPECT_EQ(OK, rv);
3258
3259 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
3260 ASSERT_TRUE(response2 != NULL);
[email protected]90499482013-06-01 00:39:503261 ASSERT_TRUE(response2->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:203262 EXPECT_EQ(2, response2->headers->GetContentLength());
3263
3264 LoadTimingInfo load_timing_info2;
3265 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3266 TestLoadTimingReusedWithPac(load_timing_info2);
3267
3268 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
3269
3270 trans2.reset();
3271 session->CloseAllConnections();
3272}
3273
[email protected]2df19bb2010-08-25 20:13:463274// Test a simple get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023275TEST_P(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:273276 HttpRequestInfo request;
3277 request.method = "GET";
bncce36dca22015-04-21 22:11:233278 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273279
[email protected]2df19bb2010-08-25 20:13:463280 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073281 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113282 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513283 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073284 session_deps_.net_log = log.bound().net_log();
3285 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:463286
[email protected]2df19bb2010-08-25 20:13:463287 // Since we have proxy, should use full url
3288 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233289 MockWrite(
3290 "GET http://www.example.org/ HTTP/1.1\r\n"
3291 "Host: www.example.org\r\n"
3292 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:463293 };
3294
3295 MockRead data_reads1[] = {
3296 MockRead("HTTP/1.1 200 OK\r\n"),
3297 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3298 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063299 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:463300 };
3301
3302 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3303 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073304 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063305 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073306 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:463307
[email protected]49639fa2011-12-20 23:22:413308 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:463309
[email protected]262eec82013-03-19 21:01:363310 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503311 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503312
[email protected]49639fa2011-12-20 23:22:413313 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:463314 EXPECT_EQ(ERR_IO_PENDING, rv);
3315
3316 rv = callback1.WaitForResult();
3317 EXPECT_EQ(OK, rv);
3318
[email protected]58e32bb2013-01-21 18:23:253319 LoadTimingInfo load_timing_info;
3320 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3321 TestLoadTimingNotReused(load_timing_info,
3322 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3323
[email protected]2df19bb2010-08-25 20:13:463324 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503325 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:463326
3327 EXPECT_TRUE(response->headers->IsKeepAlive());
3328 EXPECT_EQ(200, response->headers->response_code());
3329 EXPECT_EQ(100, response->headers->GetContentLength());
3330 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3331
3332 // The password prompt info should not be set.
3333 EXPECT_TRUE(response->auth_challenge.get() == NULL);
3334}
3335
[email protected]7642b5ae2010-09-01 20:55:173336// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023337TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:273338 HttpRequestInfo request;
3339 request.method = "GET";
bncce36dca22015-04-21 22:11:233340 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273341 request.load_flags = 0;
3342
[email protected]7642b5ae2010-09-01 20:55:173343 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073344 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113345 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513346 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073347 session_deps_.net_log = log.bound().net_log();
3348 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:173349
bncce36dca22015-04-21 22:11:233350 // fetch http://www.example.org/ via SPDY
[email protected]cdf8f7e72013-05-23 10:56:463351 scoped_ptr<SpdyFrame> req(
3352 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
rch8e6c6c42015-05-01 14:05:133353 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]7642b5ae2010-09-01 20:55:173354
[email protected]23e482282013-06-14 16:08:023355 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3356 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:173357 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:133358 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]7642b5ae2010-09-01 20:55:173359 };
3360
rch8e6c6c42015-05-01 14:05:133361 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3362 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073363 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:173364
[email protected]8ddf8322012-02-23 18:08:063365 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023366 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073367 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:173368
[email protected]49639fa2011-12-20 23:22:413369 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:173370
[email protected]262eec82013-03-19 21:01:363371 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503372 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503373
[email protected]49639fa2011-12-20 23:22:413374 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7642b5ae2010-09-01 20:55:173375 EXPECT_EQ(ERR_IO_PENDING, rv);
3376
3377 rv = callback1.WaitForResult();
3378 EXPECT_EQ(OK, rv);
3379
[email protected]58e32bb2013-01-21 18:23:253380 LoadTimingInfo load_timing_info;
3381 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3382 TestLoadTimingNotReused(load_timing_info,
3383 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3384
[email protected]7642b5ae2010-09-01 20:55:173385 const HttpResponseInfo* response = trans->GetResponseInfo();
3386 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503387 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]7642b5ae2010-09-01 20:55:173388 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3389
3390 std::string response_data;
3391 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:233392 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:173393}
3394
[email protected]1c173852014-06-19 12:51:503395// Verifies that a session which races and wins against the owning transaction
3396// (completing prior to host resolution), doesn't fail the transaction.
3397// Regression test for crbug.com/334413.
3398TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
3399 HttpRequestInfo request;
3400 request.method = "GET";
bncce36dca22015-04-21 22:11:233401 request.url = GURL("http://www.example.org/");
[email protected]1c173852014-06-19 12:51:503402 request.load_flags = 0;
3403
3404 // Configure SPDY proxy server "proxy:70".
3405 session_deps_.proxy_service.reset(
3406 ProxyService::CreateFixed("https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513407 BoundTestNetLog log;
[email protected]1c173852014-06-19 12:51:503408 session_deps_.net_log = log.bound().net_log();
3409 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3410
bncce36dca22015-04-21 22:11:233411 // Fetch http://www.example.org/ through the SPDY proxy.
[email protected]1c173852014-06-19 12:51:503412 scoped_ptr<SpdyFrame> req(
3413 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
rch8e6c6c42015-05-01 14:05:133414 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]1c173852014-06-19 12:51:503415
3416 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3417 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
3418 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:133419 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]1c173852014-06-19 12:51:503420 };
3421
rch8e6c6c42015-05-01 14:05:133422 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3423 arraysize(spdy_writes));
[email protected]1c173852014-06-19 12:51:503424 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
3425
3426 SSLSocketDataProvider ssl(ASYNC, OK);
3427 ssl.SetNextProto(GetParam());
3428 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3429
3430 TestCompletionCallback callback1;
3431
3432 scoped_ptr<HttpTransaction> trans(
3433 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3434
3435 // Stall the hostname resolution begun by the transaction.
3436 session_deps_.host_resolver->set_synchronous_mode(false);
3437 session_deps_.host_resolver->set_ondemand_mode(true);
3438
3439 int rv = trans->Start(&request, callback1.callback(), log.bound());
3440 EXPECT_EQ(ERR_IO_PENDING, rv);
3441
3442 // Race a session to the proxy, which completes first.
3443 session_deps_.host_resolver->set_ondemand_mode(false);
3444 SpdySessionKey key(
3445 HostPortPair("proxy", 70), ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
3446 base::WeakPtr<SpdySession> spdy_session =
3447 CreateSecureSpdySession(session, key, log.bound());
3448
3449 // Unstall the resolution begun by the transaction.
3450 session_deps_.host_resolver->set_ondemand_mode(true);
3451 session_deps_.host_resolver->ResolveAllPending();
3452
3453 EXPECT_FALSE(callback1.have_result());
3454 rv = callback1.WaitForResult();
3455 EXPECT_EQ(OK, rv);
3456
3457 const HttpResponseInfo* response = trans->GetResponseInfo();
3458 ASSERT_TRUE(response != NULL);
3459 ASSERT_TRUE(response->headers.get() != NULL);
3460 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3461
3462 std::string response_data;
3463 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
3464 EXPECT_EQ(kUploadData, response_data);
3465}
3466
[email protected]dc7bd1c52010-11-12 00:01:133467// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023468TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:273469 HttpRequestInfo request;
3470 request.method = "GET";
bncce36dca22015-04-21 22:11:233471 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273472 request.load_flags = 0;
3473
[email protected]79cb5c12011-09-12 13:12:043474 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073475 session_deps_.proxy_service.reset(
[email protected]79cb5c12011-09-12 13:12:043476 ProxyService::CreateFixed("https://myproxy:70"));
vishal.b62985ca92015-04-17 08:45:513477 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073478 session_deps_.net_log = log.bound().net_log();
3479 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:133480
[email protected]dc7bd1c52010-11-12 00:01:133481 // The first request will be a bare GET, the second request will be a
3482 // GET with a Proxy-Authorization header.
[email protected]ff98d7f02012-03-22 21:44:193483 scoped_ptr<SpdyFrame> req_get(
[email protected]cdf8f7e72013-05-23 10:56:463484 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]dc7bd1c52010-11-12 00:01:133485 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:463486 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:133487 };
[email protected]ff98d7f02012-03-22 21:44:193488 scoped_ptr<SpdyFrame> req_get_authorization(
[email protected]cdf8f7e72013-05-23 10:56:463489 spdy_util_.ConstructSpdyGet(kExtraAuthorizationHeaders,
3490 arraysize(kExtraAuthorizationHeaders) / 2,
3491 false,
3492 3,
3493 LOWEST,
3494 false));
[email protected]dc7bd1c52010-11-12 00:01:133495 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:133496 CreateMockWrite(*req_get, 0), CreateMockWrite(*req_get_authorization, 3),
[email protected]dc7bd1c52010-11-12 00:01:133497 };
3498
3499 // The first response is a 407 proxy authentication challenge, and the second
3500 // response will be a 200 response since the second request includes a valid
3501 // Authorization header.
3502 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:463503 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:133504 };
[email protected]ff98d7f02012-03-22 21:44:193505 scoped_ptr<SpdyFrame> resp_authentication(
[email protected]23e482282013-06-14 16:08:023506 spdy_util_.ConstructSpdySynReplyError(
[email protected]dc7bd1c52010-11-12 00:01:133507 "407 Proxy Authentication Required",
3508 kExtraAuthenticationHeaders, arraysize(kExtraAuthenticationHeaders)/2,
3509 1));
[email protected]ff98d7f02012-03-22 21:44:193510 scoped_ptr<SpdyFrame> body_authentication(
[email protected]23e482282013-06-14 16:08:023511 spdy_util_.ConstructSpdyBodyFrame(1, true));
3512 scoped_ptr<SpdyFrame> resp_data(
3513 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
3514 scoped_ptr<SpdyFrame> body_data(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:133515 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:133516 CreateMockRead(*resp_authentication, 1),
3517 CreateMockRead(*body_authentication, 2),
3518 CreateMockRead(*resp_data, 4),
3519 CreateMockRead(*body_data, 5),
3520 MockRead(ASYNC, 0, 6),
[email protected]dc7bd1c52010-11-12 00:01:133521 };
3522
rch8e6c6c42015-05-01 14:05:133523 SequencedSocketData data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3524 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073525 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:133526
[email protected]8ddf8322012-02-23 18:08:063527 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023528 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073529 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:133530
[email protected]49639fa2011-12-20 23:22:413531 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:133532
[email protected]262eec82013-03-19 21:01:363533 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503534 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]dc7bd1c52010-11-12 00:01:133535
[email protected]49639fa2011-12-20 23:22:413536 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]dc7bd1c52010-11-12 00:01:133537 EXPECT_EQ(ERR_IO_PENDING, rv);
3538
3539 rv = callback1.WaitForResult();
3540 EXPECT_EQ(OK, rv);
3541
3542 const HttpResponseInfo* const response = trans->GetResponseInfo();
3543
3544 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503545 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]dc7bd1c52010-11-12 00:01:133546 EXPECT_EQ(407, response->headers->response_code());
3547 EXPECT_TRUE(response->was_fetched_via_spdy);
[email protected]79cb5c12011-09-12 13:12:043548 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:133549
[email protected]49639fa2011-12-20 23:22:413550 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:133551
[email protected]49639fa2011-12-20 23:22:413552 rv = trans->RestartWithAuth(
3553 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]dc7bd1c52010-11-12 00:01:133554 EXPECT_EQ(ERR_IO_PENDING, rv);
3555
3556 rv = callback2.WaitForResult();
3557 EXPECT_EQ(OK, rv);
3558
3559 const HttpResponseInfo* const response_restart = trans->GetResponseInfo();
3560
3561 ASSERT_TRUE(response_restart != NULL);
[email protected]90499482013-06-01 00:39:503562 ASSERT_TRUE(response_restart->headers.get() != NULL);
[email protected]dc7bd1c52010-11-12 00:01:133563 EXPECT_EQ(200, response_restart->headers->response_code());
3564 // The password prompt info should not be set.
3565 EXPECT_TRUE(response_restart->auth_challenge.get() == NULL);
3566}
3567
[email protected]d9da5fe2010-10-13 22:37:163568// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
[email protected]23e482282013-06-14 16:08:023569TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:273570 HttpRequestInfo request;
3571 request.method = "GET";
bncce36dca22015-04-21 22:11:233572 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273573 request.load_flags = 0;
3574
[email protected]d9da5fe2010-10-13 22:37:163575 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073576 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113577 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513578 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073579 session_deps_.net_log = log.bound().net_log();
3580 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:163581
[email protected]262eec82013-03-19 21:01:363582 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503583 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:163584
bncce36dca22015-04-21 22:11:233585 // CONNECT to www.example.org:443 via SPDY
lgarrona91df87f2014-12-05 00:51:343586 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:233587 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
3588 // fetch https://www.example.org/ via HTTP
[email protected]d9da5fe2010-10-13 22:37:163589
bncce36dca22015-04-21 22:11:233590 const char get[] =
3591 "GET / HTTP/1.1\r\n"
3592 "Host: www.example.org\r\n"
3593 "Connection: keep-alive\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:193594 scoped_ptr<SpdyFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:023595 spdy_util_.ConstructSpdyBodyFrame(1, get, strlen(get), false));
3596 scoped_ptr<SpdyFrame> conn_resp(
3597 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:163598 const char resp[] = "HTTP/1.1 200 OK\r\n"
3599 "Content-Length: 10\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:193600 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:023601 spdy_util_.ConstructSpdyBodyFrame(1, resp, strlen(resp), false));
[email protected]ff98d7f02012-03-22 21:44:193602 scoped_ptr<SpdyFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:023603 spdy_util_.ConstructSpdyBodyFrame(1, "1234567890", 10, false));
[email protected]ff98d7f02012-03-22 21:44:193604 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203605 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
[email protected]8d2f7012012-02-16 00:08:043606
3607 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:133608 CreateMockWrite(*connect, 0),
3609 CreateMockWrite(*wrapped_get, 2),
3610 CreateMockWrite(*window_update, 6),
[email protected]8d2f7012012-02-16 00:08:043611 };
3612
[email protected]d9da5fe2010-10-13 22:37:163613 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:133614 CreateMockRead(*conn_resp, 1, ASYNC),
3615 CreateMockRead(*wrapped_get_resp, 3, ASYNC),
3616 CreateMockRead(*wrapped_body, 4, ASYNC),
3617 CreateMockRead(*wrapped_body, 5, ASYNC),
3618 MockRead(ASYNC, 0, 7),
[email protected]d9da5fe2010-10-13 22:37:163619 };
3620
rch8e6c6c42015-05-01 14:05:133621 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3622 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073623 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163624
[email protected]8ddf8322012-02-23 18:08:063625 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023626 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073627 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063628 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073629 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163630
[email protected]49639fa2011-12-20 23:22:413631 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163632
[email protected]49639fa2011-12-20 23:22:413633 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163634 EXPECT_EQ(ERR_IO_PENDING, rv);
3635
3636 rv = callback1.WaitForResult();
rch8e6c6c42015-05-01 14:05:133637 ASSERT_EQ(OK, rv);
[email protected]d9da5fe2010-10-13 22:37:163638
[email protected]58e32bb2013-01-21 18:23:253639 LoadTimingInfo load_timing_info;
3640 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3641 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3642
[email protected]d9da5fe2010-10-13 22:37:163643 const HttpResponseInfo* response = trans->GetResponseInfo();
3644 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503645 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d9da5fe2010-10-13 22:37:163646 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3647
3648 std::string response_data;
3649 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
3650 EXPECT_EQ("1234567890", response_data);
3651}
3652
3653// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
[email protected]23e482282013-06-14 16:08:023654TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
[email protected]cb9bf6ca2011-01-28 13:15:273655 HttpRequestInfo request;
3656 request.method = "GET";
bncce36dca22015-04-21 22:11:233657 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273658 request.load_flags = 0;
3659
[email protected]d9da5fe2010-10-13 22:37:163660 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073661 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113662 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513663 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073664 session_deps_.net_log = log.bound().net_log();
3665 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:163666
[email protected]262eec82013-03-19 21:01:363667 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503668 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:163669
bncce36dca22015-04-21 22:11:233670 // CONNECT to www.example.org:443 via SPDY
lgarrona91df87f2014-12-05 00:51:343671 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:233672 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
3673 // fetch https://www.example.org/ via SPDY
3674 const char kMyUrl[] = "https://www.example.org/";
[email protected]cdf8f7e72013-05-23 10:56:463675 scoped_ptr<SpdyFrame> get(
3676 spdy_util_.ConstructSpdyGet(kMyUrl, false, 1, LOWEST));
[email protected]23e482282013-06-14 16:08:023677 scoped_ptr<SpdyFrame> wrapped_get(
3678 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
3679 scoped_ptr<SpdyFrame> conn_resp(
3680 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3681 scoped_ptr<SpdyFrame> get_resp(
3682 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]ff98d7f02012-03-22 21:44:193683 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:023684 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
3685 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
3686 scoped_ptr<SpdyFrame> wrapped_body(
3687 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
[email protected]ff98d7f02012-03-22 21:44:193688 scoped_ptr<SpdyFrame> window_update_get_resp(
[email protected]c10b20852013-05-15 21:29:203689 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
[email protected]ff98d7f02012-03-22 21:44:193690 scoped_ptr<SpdyFrame> window_update_body(
[email protected]c10b20852013-05-15 21:29:203691 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body->size()));
[email protected]8d2f7012012-02-16 00:08:043692
3693 MockWrite spdy_writes[] = {
dbeamcd6674c72015-05-05 01:57:543694 CreateMockWrite(*connect, 1),
3695 CreateMockWrite(*wrapped_get, 3),
3696 CreateMockWrite(*window_update_get_resp, 5),
[email protected]8d2f7012012-02-16 00:08:043697 CreateMockWrite(*window_update_body, 7),
3698 };
3699
[email protected]d9da5fe2010-10-13 22:37:163700 MockRead spdy_reads[] = {
dbeamcd6674c72015-05-05 01:57:543701 CreateMockRead(*conn_resp, 2, ASYNC),
rch8e6c6c42015-05-01 14:05:133702 CreateMockRead(*wrapped_get_resp, 4, ASYNC),
dbeamcd6674c72015-05-05 01:57:543703 CreateMockRead(*wrapped_body, 6, ASYNC),
rch8e6c6c42015-05-01 14:05:133704 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:163705 };
3706
dbeamcd6674c72015-05-05 01:57:543707 OrderedSocketData spdy_data(
3708 spdy_reads, arraysize(spdy_reads),
3709 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073710 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163711
[email protected]8ddf8322012-02-23 18:08:063712 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023713 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073714 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063715 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023716 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073717 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163718
[email protected]49639fa2011-12-20 23:22:413719 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163720
[email protected]49639fa2011-12-20 23:22:413721 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163722 EXPECT_EQ(ERR_IO_PENDING, rv);
3723
3724 rv = callback1.WaitForResult();
3725 EXPECT_EQ(OK, rv);
3726
[email protected]58e32bb2013-01-21 18:23:253727 LoadTimingInfo load_timing_info;
3728 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3729 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3730
[email protected]d9da5fe2010-10-13 22:37:163731 const HttpResponseInfo* response = trans->GetResponseInfo();
3732 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503733 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d9da5fe2010-10-13 22:37:163734 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3735
3736 std::string response_data;
3737 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:233738 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:163739}
3740
3741// Test a SPDY CONNECT failure through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023742TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:273743 HttpRequestInfo request;
3744 request.method = "GET";
bncce36dca22015-04-21 22:11:233745 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273746 request.load_flags = 0;
3747
[email protected]d9da5fe2010-10-13 22:37:163748 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073749 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113750 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513751 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073752 session_deps_.net_log = log.bound().net_log();
3753 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:163754
[email protected]262eec82013-03-19 21:01:363755 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503756 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:163757
bncce36dca22015-04-21 22:11:233758 // CONNECT to www.example.org:443 via SPDY
lgarrona91df87f2014-12-05 00:51:343759 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:233760 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]c10b20852013-05-15 21:29:203761 scoped_ptr<SpdyFrame> get(
3762 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:163763
3764 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:133765 CreateMockWrite(*connect, 0), CreateMockWrite(*get, 2),
[email protected]d9da5fe2010-10-13 22:37:163766 };
3767
[email protected]23e482282013-06-14 16:08:023768 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdySynReplyError(1));
3769 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:163770 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:133771 CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 3),
[email protected]d9da5fe2010-10-13 22:37:163772 };
3773
rch8e6c6c42015-05-01 14:05:133774 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3775 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073776 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163777
[email protected]8ddf8322012-02-23 18:08:063778 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023779 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073780 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063781 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023782 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073783 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163784
[email protected]49639fa2011-12-20 23:22:413785 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163786
[email protected]49639fa2011-12-20 23:22:413787 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163788 EXPECT_EQ(ERR_IO_PENDING, rv);
3789
3790 rv = callback1.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:173791 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]d9da5fe2010-10-13 22:37:163792
[email protected]4eddbc732012-08-09 05:40:173793 // TODO(ttuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:163794}
3795
[email protected]f6c63db52013-02-02 00:35:223796// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
3797// HTTPS Proxy to different servers.
[email protected]23e482282013-06-14 16:08:023798TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:223799 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
3800 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073801 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:223802 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513803 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073804 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:223805 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:073806 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:223807
3808 HttpRequestInfo request1;
3809 request1.method = "GET";
bncce36dca22015-04-21 22:11:233810 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:223811 request1.load_flags = 0;
3812
3813 HttpRequestInfo request2;
3814 request2.method = "GET";
bncce36dca22015-04-21 22:11:233815 request2.url = GURL("https://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:223816 request2.load_flags = 0;
3817
bncce36dca22015-04-21 22:11:233818 // CONNECT to www.example.org:443 via SPDY.
lgarrona91df87f2014-12-05 00:51:343819 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:233820 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]23e482282013-06-14 16:08:023821 scoped_ptr<SpdyFrame> conn_resp1(
3822 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:223823
bncce36dca22015-04-21 22:11:233824 // Fetch https://www.example.org/ via HTTP.
3825 const char get1[] =
3826 "GET / HTTP/1.1\r\n"
3827 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:223828 "Connection: keep-alive\r\n\r\n";
3829 scoped_ptr<SpdyFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:023830 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:223831 const char resp1[] = "HTTP/1.1 200 OK\r\n"
3832 "Content-Length: 1\r\n\r\n";
3833 scoped_ptr<SpdyFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:023834 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
3835 scoped_ptr<SpdyFrame> wrapped_body1(
3836 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
[email protected]f6c63db52013-02-02 00:35:223837 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203838 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:223839
bncce36dca22015-04-21 22:11:233840 // CONNECT to mail.example.org:443 via SPDY.
[email protected]745aa9c2014-06-27 02:21:293841 SpdyHeaderBlock connect2_block;
3842 connect2_block[spdy_util_.GetMethodKey()] = "CONNECT";
bncce36dca22015-04-21 22:11:233843 connect2_block[spdy_util_.GetPathKey()] = "mail.example.org:443";
3844 connect2_block[spdy_util_.GetHostKey()] = "mail.example.org";
[email protected]745aa9c2014-06-27 02:21:293845 spdy_util_.MaybeAddVersionHeader(&connect2_block);
[email protected]f6c63db52013-02-02 00:35:223846 scoped_ptr<SpdyFrame> connect2(
[email protected]745aa9c2014-06-27 02:21:293847 spdy_util_.ConstructSpdySyn(3, connect2_block, LOWEST, false, false));
[email protected]601e03f12014-04-06 16:26:393848
[email protected]23e482282013-06-14 16:08:023849 scoped_ptr<SpdyFrame> conn_resp2(
3850 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:223851
bncce36dca22015-04-21 22:11:233852 // Fetch https://mail.example.org/ via HTTP.
3853 const char get2[] =
3854 "GET / HTTP/1.1\r\n"
3855 "Host: mail.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:223856 "Connection: keep-alive\r\n\r\n";
3857 scoped_ptr<SpdyFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:023858 spdy_util_.ConstructSpdyBodyFrame(3, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:223859 const char resp2[] = "HTTP/1.1 200 OK\r\n"
3860 "Content-Length: 2\r\n\r\n";
3861 scoped_ptr<SpdyFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:023862 spdy_util_.ConstructSpdyBodyFrame(3, resp2, strlen(resp2), false));
[email protected]f6c63db52013-02-02 00:35:223863 scoped_ptr<SpdyFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:023864 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:223865
3866 MockWrite spdy_writes[] = {
3867 CreateMockWrite(*connect1, 0),
3868 CreateMockWrite(*wrapped_get1, 2),
3869 CreateMockWrite(*connect2, 5),
3870 CreateMockWrite(*wrapped_get2, 7),
3871 };
3872
3873 MockRead spdy_reads[] = {
3874 CreateMockRead(*conn_resp1, 1, ASYNC),
3875 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
3876 CreateMockRead(*wrapped_body1, 4, ASYNC),
3877 CreateMockRead(*conn_resp2, 6, ASYNC),
3878 CreateMockRead(*wrapped_get_resp2, 8, ASYNC),
3879 CreateMockRead(*wrapped_body2, 9, ASYNC),
3880 MockRead(ASYNC, 0, 10),
3881 };
3882
3883 DeterministicSocketData spdy_data(
3884 spdy_reads, arraysize(spdy_reads),
3885 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073886 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:223887
3888 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023889 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073890 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:223891 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073892 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:223893 SSLSocketDataProvider ssl3(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073894 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:223895
3896 TestCompletionCallback callback;
3897
[email protected]262eec82013-03-19 21:01:363898 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503899 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223900 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
3901 EXPECT_EQ(ERR_IO_PENDING, rv);
3902 // The first connect and request, each of their responses, and the body.
3903 spdy_data.RunFor(5);
3904
3905 rv = callback.WaitForResult();
3906 EXPECT_EQ(OK, rv);
3907
3908 LoadTimingInfo load_timing_info;
3909 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3910 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3911
3912 const HttpResponseInfo* response = trans->GetResponseInfo();
3913 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503914 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:223915 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3916
3917 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:293918 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]90499482013-06-01 00:39:503919 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223920
[email protected]262eec82013-03-19 21:01:363921 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503922 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223923 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
3924 EXPECT_EQ(ERR_IO_PENDING, rv);
3925
3926 // The second connect and request, each of their responses, and the body.
3927 spdy_data.RunFor(5);
3928 rv = callback.WaitForResult();
3929 EXPECT_EQ(OK, rv);
3930
3931 LoadTimingInfo load_timing_info2;
3932 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3933 // Even though the SPDY connection is reused, a new tunnelled connection has
3934 // to be created, so the socket's load timing looks like a fresh connection.
3935 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
3936
3937 // The requests should have different IDs, since they each are using their own
3938 // separate stream.
3939 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
3940
[email protected]90499482013-06-01 00:39:503941 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223942}
3943
3944// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
3945// HTTPS Proxy to the same server.
[email protected]23e482282013-06-14 16:08:023946TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:223947 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
3948 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073949 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:223950 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513951 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073952 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:223953 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:073954 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:223955
3956 HttpRequestInfo request1;
3957 request1.method = "GET";
bncce36dca22015-04-21 22:11:233958 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:223959 request1.load_flags = 0;
3960
3961 HttpRequestInfo request2;
3962 request2.method = "GET";
bncce36dca22015-04-21 22:11:233963 request2.url = GURL("https://www.example.org/2");
[email protected]f6c63db52013-02-02 00:35:223964 request2.load_flags = 0;
3965
bncce36dca22015-04-21 22:11:233966 // CONNECT to www.example.org:443 via SPDY.
lgarrona91df87f2014-12-05 00:51:343967 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:233968 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]23e482282013-06-14 16:08:023969 scoped_ptr<SpdyFrame> conn_resp1(
3970 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:223971
bncce36dca22015-04-21 22:11:233972 // Fetch https://www.example.org/ via HTTP.
3973 const char get1[] =
3974 "GET / HTTP/1.1\r\n"
3975 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:223976 "Connection: keep-alive\r\n\r\n";
3977 scoped_ptr<SpdyFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:023978 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:223979 const char resp1[] = "HTTP/1.1 200 OK\r\n"
3980 "Content-Length: 1\r\n\r\n";
3981 scoped_ptr<SpdyFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:023982 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
3983 scoped_ptr<SpdyFrame> wrapped_body1(
3984 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
[email protected]f6c63db52013-02-02 00:35:223985 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203986 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:223987
bncce36dca22015-04-21 22:11:233988 // Fetch https://www.example.org/2 via HTTP.
3989 const char get2[] =
3990 "GET /2 HTTP/1.1\r\n"
3991 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:223992 "Connection: keep-alive\r\n\r\n";
3993 scoped_ptr<SpdyFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:023994 spdy_util_.ConstructSpdyBodyFrame(1, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:223995 const char resp2[] = "HTTP/1.1 200 OK\r\n"
3996 "Content-Length: 2\r\n\r\n";
3997 scoped_ptr<SpdyFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:023998 spdy_util_.ConstructSpdyBodyFrame(1, resp2, strlen(resp2), false));
[email protected]f6c63db52013-02-02 00:35:223999 scoped_ptr<SpdyFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:024000 spdy_util_.ConstructSpdyBodyFrame(1, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:224001
4002 MockWrite spdy_writes[] = {
4003 CreateMockWrite(*connect1, 0),
4004 CreateMockWrite(*wrapped_get1, 2),
4005 CreateMockWrite(*wrapped_get2, 5),
4006 };
4007
4008 MockRead spdy_reads[] = {
4009 CreateMockRead(*conn_resp1, 1, ASYNC),
4010 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
4011 CreateMockRead(*wrapped_body1, 4, ASYNC),
4012 CreateMockRead(*wrapped_get_resp2, 6, ASYNC),
4013 CreateMockRead(*wrapped_body2, 7, ASYNC),
4014 MockRead(ASYNC, 0, 8),
4015 };
4016
4017 DeterministicSocketData spdy_data(
4018 spdy_reads, arraysize(spdy_reads),
4019 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074020 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:224021
4022 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:024023 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:074024 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:224025 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074026 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:224027
4028 TestCompletionCallback callback;
4029
[email protected]262eec82013-03-19 21:01:364030 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504031 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224032 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
4033 EXPECT_EQ(ERR_IO_PENDING, rv);
4034 // The first connect and request, each of their responses, and the body.
4035 spdy_data.RunFor(5);
4036
4037 rv = callback.WaitForResult();
4038 EXPECT_EQ(OK, rv);
4039
4040 LoadTimingInfo load_timing_info;
4041 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4042 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
4043
4044 const HttpResponseInfo* response = trans->GetResponseInfo();
4045 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504046 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:224047 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4048
4049 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:294050 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]90499482013-06-01 00:39:504051 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:224052 trans.reset();
4053
[email protected]262eec82013-03-19 21:01:364054 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:504055 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224056 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
4057 EXPECT_EQ(ERR_IO_PENDING, rv);
4058
4059 // The second request, response, and body. There should not be a second
4060 // connect.
4061 spdy_data.RunFor(3);
4062 rv = callback.WaitForResult();
4063 EXPECT_EQ(OK, rv);
4064
4065 LoadTimingInfo load_timing_info2;
4066 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4067 TestLoadTimingReused(load_timing_info2);
4068
4069 // The requests should have the same ID.
4070 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
4071
[email protected]90499482013-06-01 00:39:504072 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:224073}
4074
4075// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
4076// Proxy to different servers.
[email protected]23e482282013-06-14 16:08:024077TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:224078 HttpsProxySpdyLoadTimingTwoHttpRequests) {
4079 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:074080 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:224081 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:514082 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074083 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:224084 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:074085 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:224086
4087 HttpRequestInfo request1;
4088 request1.method = "GET";
bncce36dca22015-04-21 22:11:234089 request1.url = GURL("http://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:224090 request1.load_flags = 0;
4091
4092 HttpRequestInfo request2;
4093 request2.method = "GET";
bncce36dca22015-04-21 22:11:234094 request2.url = GURL("http://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:224095 request2.load_flags = 0;
4096
bncce36dca22015-04-21 22:11:234097 // http://www.example.org/
[email protected]23e482282013-06-14 16:08:024098 scoped_ptr<SpdyHeaderBlock> headers(
bncce36dca22015-04-21 22:11:234099 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
[email protected]745aa9c2014-06-27 02:21:294100 scoped_ptr<SpdyFrame> get1(
4101 spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, false, true));
[email protected]23e482282013-06-14 16:08:024102 scoped_ptr<SpdyFrame> get_resp1(
4103 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
4104 scoped_ptr<SpdyFrame> body1(
4105 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, true));
[email protected]f6c63db52013-02-02 00:35:224106
bncce36dca22015-04-21 22:11:234107 // http://mail.example.org/
[email protected]23e482282013-06-14 16:08:024108 scoped_ptr<SpdyHeaderBlock> headers2(
bncce36dca22015-04-21 22:11:234109 spdy_util_.ConstructGetHeaderBlockForProxy("http://mail.example.org/"));
[email protected]745aa9c2014-06-27 02:21:294110 scoped_ptr<SpdyFrame> get2(
4111 spdy_util_.ConstructSpdySyn(3, *headers2, LOWEST, false, true));
[email protected]23e482282013-06-14 16:08:024112 scoped_ptr<SpdyFrame> get_resp2(
4113 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
4114 scoped_ptr<SpdyFrame> body2(
4115 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, true));
[email protected]f6c63db52013-02-02 00:35:224116
4117 MockWrite spdy_writes[] = {
4118 CreateMockWrite(*get1, 0),
4119 CreateMockWrite(*get2, 3),
4120 };
4121
4122 MockRead spdy_reads[] = {
4123 CreateMockRead(*get_resp1, 1, ASYNC),
4124 CreateMockRead(*body1, 2, ASYNC),
4125 CreateMockRead(*get_resp2, 4, ASYNC),
4126 CreateMockRead(*body2, 5, ASYNC),
4127 MockRead(ASYNC, 0, 6),
4128 };
4129
4130 DeterministicSocketData spdy_data(
4131 spdy_reads, arraysize(spdy_reads),
4132 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074133 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:224134
4135 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:024136 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:074137 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:224138
4139 TestCompletionCallback callback;
4140
[email protected]262eec82013-03-19 21:01:364141 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504142 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224143 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
4144 EXPECT_EQ(ERR_IO_PENDING, rv);
4145 spdy_data.RunFor(2);
4146
4147 rv = callback.WaitForResult();
4148 EXPECT_EQ(OK, rv);
4149
4150 LoadTimingInfo load_timing_info;
4151 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4152 TestLoadTimingNotReused(load_timing_info,
4153 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4154
4155 const HttpResponseInfo* response = trans->GetResponseInfo();
4156 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504157 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:224158 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4159
4160 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:294161 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]90499482013-06-01 00:39:504162 EXPECT_EQ(ERR_IO_PENDING, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:224163 spdy_data.RunFor(1);
4164 EXPECT_EQ(1, callback.WaitForResult());
4165 // Delete the first request, so the second one can reuse the socket.
4166 trans.reset();
4167
[email protected]262eec82013-03-19 21:01:364168 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:504169 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224170 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
4171 EXPECT_EQ(ERR_IO_PENDING, rv);
4172
4173 spdy_data.RunFor(2);
4174 rv = callback.WaitForResult();
4175 EXPECT_EQ(OK, rv);
4176
4177 LoadTimingInfo load_timing_info2;
4178 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4179 TestLoadTimingReused(load_timing_info2);
4180
4181 // The requests should have the same ID.
4182 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
4183
[email protected]90499482013-06-01 00:39:504184 EXPECT_EQ(ERR_IO_PENDING, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:224185 spdy_data.RunFor(1);
4186 EXPECT_EQ(2, callback.WaitForResult());
4187}
4188
[email protected]2df19bb2010-08-25 20:13:464189// Test the challenge-response-retry sequence through an HTTPS Proxy
[email protected]23e482282013-06-14 16:08:024190TEST_P(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:464191 HttpRequestInfo request;
4192 request.method = "GET";
bncce36dca22015-04-21 22:11:234193 request.url = GURL("http://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:464194 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:294195 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]2df19bb2010-08-25 20:13:464196
[email protected]79cb5c12011-09-12 13:12:044197 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:074198 session_deps_.proxy_service.reset(
[email protected]79cb5c12011-09-12 13:12:044199 ProxyService::CreateFixed("https://myproxy:70"));
vishal.b62985ca92015-04-17 08:45:514200 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074201 session_deps_.net_log = log.bound().net_log();
4202 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274203
[email protected]2df19bb2010-08-25 20:13:464204 // Since we have proxy, should use full url
4205 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:234206 MockWrite(
4207 "GET http://www.example.org/ HTTP/1.1\r\n"
4208 "Host: www.example.org\r\n"
4209 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:464210
bncce36dca22015-04-21 22:11:234211 // After calling trans->RestartWithAuth(), this is the request we should
4212 // be issuing -- the final header line contains the credentials.
4213 MockWrite(
4214 "GET http://www.example.org/ HTTP/1.1\r\n"
4215 "Host: www.example.org\r\n"
4216 "Proxy-Connection: keep-alive\r\n"
4217 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:464218 };
4219
4220 // The proxy responds to the GET with a 407, using a persistent
4221 // connection.
4222 MockRead data_reads1[] = {
4223 // No credentials.
4224 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4225 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4226 MockRead("Proxy-Connection: keep-alive\r\n"),
4227 MockRead("Content-Length: 0\r\n\r\n"),
4228
4229 MockRead("HTTP/1.1 200 OK\r\n"),
4230 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4231 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064232 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:464233 };
4234
4235 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4236 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074237 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:064238 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074239 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:464240
[email protected]49639fa2011-12-20 23:22:414241 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:464242
[email protected]262eec82013-03-19 21:01:364243 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504244 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504245
[email protected]49639fa2011-12-20 23:22:414246 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:464247 EXPECT_EQ(ERR_IO_PENDING, rv);
4248
4249 rv = callback1.WaitForResult();
4250 EXPECT_EQ(OK, rv);
4251
[email protected]58e32bb2013-01-21 18:23:254252 LoadTimingInfo load_timing_info;
4253 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4254 TestLoadTimingNotReused(load_timing_info,
4255 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4256
[email protected]2df19bb2010-08-25 20:13:464257 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504258 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504259 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]2df19bb2010-08-25 20:13:464260 EXPECT_EQ(407, response->headers->response_code());
4261 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:044262 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:464263
[email protected]49639fa2011-12-20 23:22:414264 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:464265
[email protected]49639fa2011-12-20 23:22:414266 rv = trans->RestartWithAuth(
4267 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]2df19bb2010-08-25 20:13:464268 EXPECT_EQ(ERR_IO_PENDING, rv);
4269
4270 rv = callback2.WaitForResult();
4271 EXPECT_EQ(OK, rv);
4272
[email protected]58e32bb2013-01-21 18:23:254273 load_timing_info = LoadTimingInfo();
4274 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4275 // Retrying with HTTP AUTH is considered to be reusing a socket.
4276 TestLoadTimingReused(load_timing_info);
4277
[email protected]2df19bb2010-08-25 20:13:464278 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504279 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:464280
4281 EXPECT_TRUE(response->headers->IsKeepAlive());
4282 EXPECT_EQ(200, response->headers->response_code());
4283 EXPECT_EQ(100, response->headers->GetContentLength());
4284 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4285
4286 // The password prompt info should not be set.
4287 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4288}
4289
[email protected]23e482282013-06-14 16:08:024290void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:084291 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:424292 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:084293 request.method = "GET";
bncce36dca22015-04-21 22:11:234294 request.url = GURL("https://www.example.org/");
[email protected]c744cf22009-02-27 07:28:084295 request.load_flags = 0;
4296
[email protected]cb9bf6ca2011-01-28 13:15:274297 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:074298 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]bb88e1d32013-05-03 23:11:074299 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274300
[email protected]c744cf22009-02-27 07:28:084301 // Since we have proxy, should try to establish tunnel.
4302 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:234303 MockWrite(
4304 "CONNECT www.example.org:443 HTTP/1.1\r\n"
4305 "Host: www.example.org\r\n"
4306 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:084307 };
4308
4309 MockRead data_reads[] = {
4310 status,
4311 MockRead("Content-Length: 10\r\n\r\n"),
4312 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:064313 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]c744cf22009-02-27 07:28:084314 };
4315
[email protected]31a2bfe2010-02-09 08:03:394316 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
4317 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:074318 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:084319
[email protected]49639fa2011-12-20 23:22:414320 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:084321
[email protected]262eec82013-03-19 21:01:364322 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504323 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504324
[email protected]49639fa2011-12-20 23:22:414325 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424326 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]c744cf22009-02-27 07:28:084327
4328 rv = callback.WaitForResult();
4329 EXPECT_EQ(expected_status, rv);
4330}
4331
[email protected]23e482282013-06-14 16:08:024332void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:234333 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:084334 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:424335 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:084336}
4337
[email protected]23e482282013-06-14 16:08:024338TEST_P(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:084339 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
4340}
4341
[email protected]23e482282013-06-14 16:08:024342TEST_P(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:084343 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
4344}
4345
[email protected]23e482282013-06-14 16:08:024346TEST_P(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:084347 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
4348}
4349
[email protected]23e482282013-06-14 16:08:024350TEST_P(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:084351 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
4352}
4353
[email protected]23e482282013-06-14 16:08:024354TEST_P(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:084355 ConnectStatusHelper(
4356 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
4357}
4358
[email protected]23e482282013-06-14 16:08:024359TEST_P(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:084360 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
4361}
4362
[email protected]23e482282013-06-14 16:08:024363TEST_P(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:084364 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
4365}
4366
[email protected]23e482282013-06-14 16:08:024367TEST_P(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:084368 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
4369}
4370
[email protected]23e482282013-06-14 16:08:024371TEST_P(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:084372 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
4373}
4374
[email protected]23e482282013-06-14 16:08:024375TEST_P(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:084376 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
4377}
4378
[email protected]23e482282013-06-14 16:08:024379TEST_P(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:084380 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
4381}
4382
[email protected]23e482282013-06-14 16:08:024383TEST_P(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:084384 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
4385}
4386
[email protected]23e482282013-06-14 16:08:024387TEST_P(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:084388 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
4389}
4390
[email protected]23e482282013-06-14 16:08:024391TEST_P(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:084392 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
4393}
4394
[email protected]23e482282013-06-14 16:08:024395TEST_P(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:084396 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
4397}
4398
[email protected]23e482282013-06-14 16:08:024399TEST_P(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:084400 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
4401}
4402
[email protected]0a17aab32014-04-24 03:32:374403TEST_P(HttpNetworkTransactionTest, ConnectStatus308) {
4404 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
4405}
4406
[email protected]23e482282013-06-14 16:08:024407TEST_P(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:084408 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
4409}
4410
[email protected]23e482282013-06-14 16:08:024411TEST_P(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:084412 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
4413}
4414
[email protected]23e482282013-06-14 16:08:024415TEST_P(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:084416 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
4417}
4418
[email protected]23e482282013-06-14 16:08:024419TEST_P(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:084420 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
4421}
4422
[email protected]23e482282013-06-14 16:08:024423TEST_P(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:084424 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
4425}
4426
[email protected]23e482282013-06-14 16:08:024427TEST_P(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:084428 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
4429}
4430
[email protected]23e482282013-06-14 16:08:024431TEST_P(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:084432 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
4433}
4434
[email protected]23e482282013-06-14 16:08:024435TEST_P(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:084436 ConnectStatusHelperWithExpectedStatus(
4437 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:544438 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:084439}
4440
[email protected]23e482282013-06-14 16:08:024441TEST_P(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:084442 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
4443}
4444
[email protected]23e482282013-06-14 16:08:024445TEST_P(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:084446 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
4447}
4448
[email protected]23e482282013-06-14 16:08:024449TEST_P(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:084450 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
4451}
4452
[email protected]23e482282013-06-14 16:08:024453TEST_P(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:084454 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
4455}
4456
[email protected]23e482282013-06-14 16:08:024457TEST_P(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:084458 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
4459}
4460
[email protected]23e482282013-06-14 16:08:024461TEST_P(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:084462 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
4463}
4464
[email protected]23e482282013-06-14 16:08:024465TEST_P(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:084466 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
4467}
4468
[email protected]23e482282013-06-14 16:08:024469TEST_P(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:084470 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
4471}
4472
[email protected]23e482282013-06-14 16:08:024473TEST_P(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:084474 ConnectStatusHelper(
4475 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
4476}
4477
[email protected]23e482282013-06-14 16:08:024478TEST_P(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:084479 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
4480}
4481
[email protected]23e482282013-06-14 16:08:024482TEST_P(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:084483 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
4484}
4485
[email protected]23e482282013-06-14 16:08:024486TEST_P(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:084487 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
4488}
4489
[email protected]23e482282013-06-14 16:08:024490TEST_P(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:084491 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
4492}
4493
[email protected]23e482282013-06-14 16:08:024494TEST_P(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:084495 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
4496}
4497
[email protected]23e482282013-06-14 16:08:024498TEST_P(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:084499 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
4500}
4501
[email protected]23e482282013-06-14 16:08:024502TEST_P(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:084503 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
4504}
4505
[email protected]038e9a32008-10-08 22:40:164506// Test the flow when both the proxy server AND origin server require
4507// authentication. Again, this uses basic auth for both since that is
4508// the simplest to mock.
[email protected]23e482282013-06-14 16:08:024509TEST_P(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:274510 HttpRequestInfo request;
4511 request.method = "GET";
bncce36dca22015-04-21 22:11:234512 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274513 request.load_flags = 0;
4514
[email protected]038e9a32008-10-08 22:40:164515 // Configure against proxy server "myproxy:70".
[email protected]3fe8d2f82013-10-17 08:56:074516 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
4517 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4518
4519 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:414520 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]038e9a32008-10-08 22:40:164521
[email protected]f9ee6b52008-11-08 06:46:234522 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:234523 MockWrite(
4524 "GET http://www.example.org/ HTTP/1.1\r\n"
4525 "Host: www.example.org\r\n"
4526 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:234527 };
4528
[email protected]038e9a32008-10-08 22:40:164529 MockRead data_reads1[] = {
4530 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
4531 // Give a couple authenticate options (only the middle one is actually
4532 // supported).
[email protected]22927ad2009-09-21 19:56:194533 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:164534 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4535 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
4536 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4537 // Large content-length -- won't matter, as connection will be reset.
4538 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064539 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:164540 };
4541
4542 // After calling trans->RestartWithAuth() the first time, this is the
4543 // request we should be issuing -- the final header line contains the
4544 // proxy's credentials.
4545 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:234546 MockWrite(
4547 "GET http://www.example.org/ HTTP/1.1\r\n"
4548 "Host: www.example.org\r\n"
4549 "Proxy-Connection: keep-alive\r\n"
4550 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:164551 };
4552
4553 // Now the proxy server lets the request pass through to origin server.
4554 // The origin server responds with a 401.
4555 MockRead data_reads2[] = {
4556 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4557 // Note: We are using the same realm-name as the proxy server. This is
4558 // completely valid, as realms are unique across hosts.
4559 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4560 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4561 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064562 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:164563 };
4564
4565 // After calling trans->RestartWithAuth() the second time, we should send
4566 // the credentials for both the proxy and origin server.
4567 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:234568 MockWrite(
4569 "GET http://www.example.org/ HTTP/1.1\r\n"
4570 "Host: www.example.org\r\n"
4571 "Proxy-Connection: keep-alive\r\n"
4572 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
4573 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:164574 };
4575
4576 // Lastly we get the desired content.
4577 MockRead data_reads3[] = {
4578 MockRead("HTTP/1.0 200 OK\r\n"),
4579 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4580 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064581 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:164582 };
4583
[email protected]31a2bfe2010-02-09 08:03:394584 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4585 data_writes1, arraysize(data_writes1));
4586 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4587 data_writes2, arraysize(data_writes2));
4588 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4589 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:074590 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4591 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4592 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:164593
[email protected]49639fa2011-12-20 23:22:414594 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:164595
[email protected]49639fa2011-12-20 23:22:414596 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424597 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:164598
4599 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424600 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:164601
[email protected]1c773ea12009-04-28 19:58:424602 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504603 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044604 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:164605
[email protected]49639fa2011-12-20 23:22:414606 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:164607
[email protected]49639fa2011-12-20 23:22:414608 rv = trans->RestartWithAuth(
4609 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:424610 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:164611
4612 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424613 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:164614
4615 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504616 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044617 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:164618
[email protected]49639fa2011-12-20 23:22:414619 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:164620
[email protected]49639fa2011-12-20 23:22:414621 rv = trans->RestartWithAuth(
4622 AuthCredentials(kFoo2, kBar2), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424623 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:164624
4625 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424626 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:164627
4628 response = trans->GetResponseInfo();
4629 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4630 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:164631}
[email protected]4ddaf2502008-10-23 18:26:194632
[email protected]ea9dc9a2009-09-05 00:43:324633// For the NTLM implementation using SSPI, we skip the NTLM tests since we
4634// can't hook into its internals to cause it to generate predictable NTLM
4635// authorization headers.
4636#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:294637// The NTLM authentication unit tests were generated by capturing the HTTP
4638// requests and responses using Fiddler 2 and inspecting the generated random
4639// bytes in the debugger.
4640
4641// Enter the correct password and authenticate successfully.
[email protected]23e482282013-06-14 16:08:024642TEST_P(HttpNetworkTransactionTest, NTLMAuth1) {
[email protected]1c773ea12009-04-28 19:58:424643 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:244644 request.method = "GET";
4645 request.url = GURL("http://172.22.68.17/kids/login.aspx");
[email protected]2217aa22013-10-11 03:03:544646
4647 // Ensure load is not disrupted by flags which suppress behaviour specific
4648 // to other auth schemes.
4649 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:244650
[email protected]cb9bf6ca2011-01-28 13:15:274651 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
4652 MockGetHostName);
[email protected]bb88e1d32013-05-03 23:11:074653 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274654
[email protected]3f918782009-02-28 01:29:244655 MockWrite data_writes1[] = {
4656 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4657 "Host: 172.22.68.17\r\n"
4658 "Connection: keep-alive\r\n\r\n"),
4659 };
4660
4661 MockRead data_reads1[] = {
4662 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:044663 // Negotiate and NTLM are often requested together. However, we only want
4664 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
4665 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:244666 MockRead("WWW-Authenticate: NTLM\r\n"),
4667 MockRead("Connection: close\r\n"),
4668 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364669 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:244670 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064671 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]3f918782009-02-28 01:29:244672 };
4673
4674 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:224675 // After restarting with a null identity, this is the
[email protected]3f918782009-02-28 01:29:244676 // request we should be issuing -- the final header line contains a Type
4677 // 1 message.
4678 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4679 "Host: 172.22.68.17\r\n"
4680 "Connection: keep-alive\r\n"
4681 "Authorization: NTLM "
4682 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4683
4684 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4685 // (the credentials for the origin server). The second request continues
4686 // on the same connection.
4687 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4688 "Host: 172.22.68.17\r\n"
4689 "Connection: keep-alive\r\n"
[email protected]385a4672009-03-11 22:21:294690 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4691 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4692 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
4693 "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
4694 "ahlhx5I=\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:244695 };
4696
4697 MockRead data_reads2[] = {
4698 // The origin server responds with a Type 2 message.
4699 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4700 MockRead("WWW-Authenticate: NTLM "
[email protected]385a4672009-03-11 22:21:294701 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
[email protected]3f918782009-02-28 01:29:244702 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4703 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4704 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4705 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4706 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4707 "BtAAAAAAA=\r\n"),
4708 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364709 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:244710 MockRead("You are not authorized to view this page\r\n"),
4711
4712 // Lastly we get the desired content.
4713 MockRead("HTTP/1.1 200 OK\r\n"),
4714 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
4715 MockRead("Content-Length: 13\r\n\r\n"),
4716 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:064717 MockRead(SYNCHRONOUS, OK),
[email protected]3f918782009-02-28 01:29:244718 };
4719
[email protected]31a2bfe2010-02-09 08:03:394720 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4721 data_writes1, arraysize(data_writes1));
4722 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4723 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:074724 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4725 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:244726
[email protected]49639fa2011-12-20 23:22:414727 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:244728
[email protected]262eec82013-03-19 21:01:364729 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504730 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504731
[email protected]49639fa2011-12-20 23:22:414732 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424733 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:244734
4735 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424736 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:244737
[email protected]0757e7702009-03-27 04:00:224738 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4739
[email protected]1c773ea12009-04-28 19:58:424740 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:044741 ASSERT_FALSE(response == NULL);
4742 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:244743
[email protected]49639fa2011-12-20 23:22:414744 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:254745
[email protected]f3cf9802011-10-28 18:44:584746 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:414747 callback2.callback());
[email protected]10af5fe72011-01-31 16:17:254748 EXPECT_EQ(ERR_IO_PENDING, rv);
4749
4750 rv = callback2.WaitForResult();
4751 EXPECT_EQ(OK, rv);
4752
4753 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4754
4755 response = trans->GetResponseInfo();
4756 ASSERT_TRUE(response != NULL);
[email protected]10af5fe72011-01-31 16:17:254757 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4758
[email protected]49639fa2011-12-20 23:22:414759 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:244760
[email protected]49639fa2011-12-20 23:22:414761 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424762 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:244763
[email protected]0757e7702009-03-27 04:00:224764 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424765 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:244766
4767 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504768 ASSERT_TRUE(response != NULL);
[email protected]3f918782009-02-28 01:29:244769 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4770 EXPECT_EQ(13, response->headers->GetContentLength());
4771}
4772
[email protected]385a4672009-03-11 22:21:294773// Enter a wrong password, and then the correct one.
[email protected]23e482282013-06-14 16:08:024774TEST_P(HttpNetworkTransactionTest, NTLMAuth2) {
[email protected]1c773ea12009-04-28 19:58:424775 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:294776 request.method = "GET";
4777 request.url = GURL("http://172.22.68.17/kids/login.aspx");
4778 request.load_flags = 0;
4779
[email protected]cb9bf6ca2011-01-28 13:15:274780 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
4781 MockGetHostName);
[email protected]bb88e1d32013-05-03 23:11:074782 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274783
[email protected]385a4672009-03-11 22:21:294784 MockWrite data_writes1[] = {
4785 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4786 "Host: 172.22.68.17\r\n"
4787 "Connection: keep-alive\r\n\r\n"),
4788 };
4789
4790 MockRead data_reads1[] = {
4791 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:044792 // Negotiate and NTLM are often requested together. However, we only want
4793 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
4794 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:294795 MockRead("WWW-Authenticate: NTLM\r\n"),
4796 MockRead("Connection: close\r\n"),
4797 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364798 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294799 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064800 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:294801 };
4802
4803 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:224804 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:294805 // request we should be issuing -- the final header line contains a Type
4806 // 1 message.
4807 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4808 "Host: 172.22.68.17\r\n"
4809 "Connection: keep-alive\r\n"
4810 "Authorization: NTLM "
4811 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4812
4813 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4814 // (the credentials for the origin server). The second request continues
4815 // on the same connection.
4816 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4817 "Host: 172.22.68.17\r\n"
4818 "Connection: keep-alive\r\n"
4819 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4820 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4821 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
4822 "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
4823 "4Ww7b7E=\r\n\r\n"),
4824 };
4825
4826 MockRead data_reads2[] = {
4827 // The origin server responds with a Type 2 message.
4828 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4829 MockRead("WWW-Authenticate: NTLM "
4830 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
4831 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4832 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4833 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4834 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4835 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4836 "BtAAAAAAA=\r\n"),
4837 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364838 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294839 MockRead("You are not authorized to view this page\r\n"),
4840
4841 // Wrong password.
4842 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]385a4672009-03-11 22:21:294843 MockRead("WWW-Authenticate: NTLM\r\n"),
4844 MockRead("Connection: close\r\n"),
4845 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364846 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294847 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064848 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:294849 };
4850
4851 MockWrite data_writes3[] = {
[email protected]0757e7702009-03-27 04:00:224852 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:294853 // request we should be issuing -- the final header line contains a Type
4854 // 1 message.
4855 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4856 "Host: 172.22.68.17\r\n"
4857 "Connection: keep-alive\r\n"
4858 "Authorization: NTLM "
4859 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4860
4861 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4862 // (the credentials for the origin server). The second request continues
4863 // on the same connection.
4864 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4865 "Host: 172.22.68.17\r\n"
4866 "Connection: keep-alive\r\n"
4867 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4868 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4869 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
4870 "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
4871 "+4MUm7c=\r\n\r\n"),
4872 };
4873
4874 MockRead data_reads3[] = {
4875 // The origin server responds with a Type 2 message.
4876 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4877 MockRead("WWW-Authenticate: NTLM "
4878 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
4879 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4880 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4881 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4882 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4883 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4884 "BtAAAAAAA=\r\n"),
4885 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364886 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294887 MockRead("You are not authorized to view this page\r\n"),
4888
4889 // Lastly we get the desired content.
4890 MockRead("HTTP/1.1 200 OK\r\n"),
4891 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
4892 MockRead("Content-Length: 13\r\n\r\n"),
4893 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:064894 MockRead(SYNCHRONOUS, OK),
[email protected]385a4672009-03-11 22:21:294895 };
4896
[email protected]31a2bfe2010-02-09 08:03:394897 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4898 data_writes1, arraysize(data_writes1));
4899 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4900 data_writes2, arraysize(data_writes2));
4901 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4902 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:074903 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4904 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4905 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:294906
[email protected]49639fa2011-12-20 23:22:414907 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:294908
[email protected]262eec82013-03-19 21:01:364909 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504910 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504911
[email protected]49639fa2011-12-20 23:22:414912 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424913 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:294914
4915 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424916 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:294917
[email protected]0757e7702009-03-27 04:00:224918 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:294919
[email protected]1c773ea12009-04-28 19:58:424920 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504921 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044922 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:294923
[email protected]49639fa2011-12-20 23:22:414924 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:294925
[email protected]0757e7702009-03-27 04:00:224926 // Enter the wrong password.
[email protected]f3cf9802011-10-28 18:44:584927 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword),
[email protected]49639fa2011-12-20 23:22:414928 callback2.callback());
[email protected]1c773ea12009-04-28 19:58:424929 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:294930
[email protected]10af5fe72011-01-31 16:17:254931 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424932 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:294933
[email protected]0757e7702009-03-27 04:00:224934 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:414935 TestCompletionCallback callback3;
4936 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424937 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]10af5fe72011-01-31 16:17:254938 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424939 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:224940 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4941
4942 response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:044943 ASSERT_FALSE(response == NULL);
4944 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:224945
[email protected]49639fa2011-12-20 23:22:414946 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:224947
4948 // Now enter the right password.
[email protected]f3cf9802011-10-28 18:44:584949 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:414950 callback4.callback());
[email protected]10af5fe72011-01-31 16:17:254951 EXPECT_EQ(ERR_IO_PENDING, rv);
4952
4953 rv = callback4.WaitForResult();
4954 EXPECT_EQ(OK, rv);
4955
4956 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4957
[email protected]49639fa2011-12-20 23:22:414958 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:254959
4960 // One more roundtrip
[email protected]49639fa2011-12-20 23:22:414961 rv = trans->RestartWithAuth(AuthCredentials(), callback5.callback());
[email protected]1c773ea12009-04-28 19:58:424962 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:224963
4964 rv = callback5.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424965 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:224966
[email protected]385a4672009-03-11 22:21:294967 response = trans->GetResponseInfo();
4968 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4969 EXPECT_EQ(13, response->headers->GetContentLength());
4970}
[email protected]ea9dc9a2009-09-05 00:43:324971#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:294972
[email protected]4ddaf2502008-10-23 18:26:194973// Test reading a server response which has only headers, and no body.
4974// After some maximum number of bytes is consumed, the transaction should
4975// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
[email protected]23e482282013-06-14 16:08:024976TEST_P(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:424977 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:194978 request.method = "GET";
bncce36dca22015-04-21 22:11:234979 request.url = GURL("http://www.example.org/");
[email protected]4ddaf2502008-10-23 18:26:194980 request.load_flags = 0;
4981
[email protected]3fe8d2f82013-10-17 08:56:074982 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274983 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:414984 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:274985
[email protected]b75b7b2f2009-10-06 00:54:534986 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:434987 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:534988 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:194989
4990 MockRead data_reads[] = {
4991 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:064992 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:194993 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:064994 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:194995 };
[email protected]31a2bfe2010-02-09 08:03:394996 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:074997 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:194998
[email protected]49639fa2011-12-20 23:22:414999 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:195000
[email protected]49639fa2011-12-20 23:22:415001 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425002 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]4ddaf2502008-10-23 18:26:195003
5004 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425005 EXPECT_EQ(ERR_RESPONSE_HEADERS_TOO_BIG, rv);
[email protected]4ddaf2502008-10-23 18:26:195006
[email protected]1c773ea12009-04-28 19:58:425007 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]4ddaf2502008-10-23 18:26:195008 EXPECT_TRUE(response == NULL);
5009}
[email protected]f4e426b2008-11-05 00:24:495010
5011// Make sure that we don't try to reuse a TCPClientSocket when failing to
5012// establish tunnel.
5013// http://code.google.com/p/chromium/issues/detail?id=3772
[email protected]23e482282013-06-14 16:08:025014TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:235015 DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:275016 HttpRequestInfo request;
5017 request.method = "GET";
bncce36dca22015-04-21 22:11:235018 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275019 request.load_flags = 0;
5020
[email protected]f4e426b2008-11-05 00:24:495021 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:075022 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]db8f44c2008-12-13 04:52:015023
[email protected]bb88e1d32013-05-03 23:11:075024 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:495025
[email protected]262eec82013-03-19 21:01:365026 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505027 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f4e426b2008-11-05 00:24:495028
[email protected]f4e426b2008-11-05 00:24:495029 // Since we have proxy, should try to establish tunnel.
5030 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235031 MockWrite(
5032 "CONNECT www.example.org:443 HTTP/1.1\r\n"
5033 "Host: www.example.org\r\n"
5034 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:495035 };
5036
[email protected]77848d12008-11-14 00:00:225037 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:495038 // connection. Usually a proxy would return 501 (not implemented),
5039 // or 200 (tunnel established).
5040 MockRead data_reads1[] = {
5041 MockRead("HTTP/1.1 404 Not Found\r\n"),
5042 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065043 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]f4e426b2008-11-05 00:24:495044 };
5045
[email protected]31a2bfe2010-02-09 08:03:395046 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5047 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075048 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:495049
[email protected]49639fa2011-12-20 23:22:415050 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:495051
[email protected]49639fa2011-12-20 23:22:415052 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425053 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f4e426b2008-11-05 00:24:495054
5055 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425056 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]f4e426b2008-11-05 00:24:495057
[email protected]1c773ea12009-04-28 19:58:425058 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]c744cf22009-02-27 07:28:085059 EXPECT_TRUE(response == NULL);
[email protected]f4e426b2008-11-05 00:24:495060
[email protected]b4404c02009-04-10 16:38:525061 // Empty the current queue. This is necessary because idle sockets are
5062 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345063 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:525064
[email protected]f4e426b2008-11-05 00:24:495065 // We now check to make sure the TCPClientSocket was not added back to
5066 // the pool.
[email protected]90499482013-06-01 00:39:505067 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:495068 trans.reset();
[email protected]2da659e2013-05-23 20:51:345069 base::MessageLoop::current()->RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:495070 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:505071 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:495072}
[email protected]372d34a2008-11-05 21:30:515073
[email protected]1b157c02009-04-21 01:55:405074// Make sure that we recycle a socket after reading all of the response body.
[email protected]23e482282013-06-14 16:08:025075TEST_P(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:425076 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:405077 request.method = "GET";
bncce36dca22015-04-21 22:11:235078 request.url = GURL("http://www.example.org/");
[email protected]1b157c02009-04-21 01:55:405079 request.load_flags = 0;
5080
[email protected]bb88e1d32013-05-03 23:11:075081 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275082
[email protected]262eec82013-03-19 21:01:365083 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505084 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275085
[email protected]1b157c02009-04-21 01:55:405086 MockRead data_reads[] = {
5087 // A part of the response body is received with the response headers.
5088 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
5089 // The rest of the response body is received in two parts.
5090 MockRead("lo"),
5091 MockRead(" world"),
5092 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:065093 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:405094 };
5095
[email protected]31a2bfe2010-02-09 08:03:395096 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:075097 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:405098
[email protected]49639fa2011-12-20 23:22:415099 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:405100
[email protected]49639fa2011-12-20 23:22:415101 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425102 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]1b157c02009-04-21 01:55:405103
5104 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425105 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:405106
[email protected]1c773ea12009-04-28 19:58:425107 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505108 ASSERT_TRUE(response != NULL);
[email protected]1b157c02009-04-21 01:55:405109
[email protected]90499482013-06-01 00:39:505110 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]1b157c02009-04-21 01:55:405111 std::string status_line = response->headers->GetStatusLine();
5112 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
5113
[email protected]90499482013-06-01 00:39:505114 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:405115
5116 std::string response_data;
5117 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:425118 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:405119 EXPECT_EQ("hello world", response_data);
5120
5121 // Empty the current queue. This is necessary because idle sockets are
5122 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345123 base::MessageLoop::current()->RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:405124
5125 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505126 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:405127}
5128
[email protected]76a505b2010-08-25 06:23:005129// Make sure that we recycle a SSL socket after reading all of the response
5130// body.
[email protected]23e482282013-06-14 16:08:025131TEST_P(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:005132 HttpRequestInfo request;
5133 request.method = "GET";
bncce36dca22015-04-21 22:11:235134 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:005135 request.load_flags = 0;
5136
5137 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:235138 MockWrite(
5139 "GET / HTTP/1.1\r\n"
5140 "Host: www.example.org\r\n"
5141 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:005142 };
5143
5144 MockRead data_reads[] = {
5145 MockRead("HTTP/1.1 200 OK\r\n"),
5146 MockRead("Content-Length: 11\r\n\r\n"),
5147 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:065148 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:005149 };
5150
[email protected]8ddf8322012-02-23 18:08:065151 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075152 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:005153
5154 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5155 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:075156 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:005157
[email protected]49639fa2011-12-20 23:22:415158 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:005159
[email protected]bb88e1d32013-05-03 23:11:075160 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:365161 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505162 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:005163
[email protected]49639fa2011-12-20 23:22:415164 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:005165
5166 EXPECT_EQ(ERR_IO_PENDING, rv);
5167 EXPECT_EQ(OK, callback.WaitForResult());
5168
5169 const HttpResponseInfo* response = trans->GetResponseInfo();
5170 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:505171 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:005172 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5173
[email protected]90499482013-06-01 00:39:505174 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005175
5176 std::string response_data;
5177 rv = ReadTransaction(trans.get(), &response_data);
5178 EXPECT_EQ(OK, rv);
5179 EXPECT_EQ("hello world", response_data);
5180
5181 // Empty the current queue. This is necessary because idle sockets are
5182 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345183 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:005184
5185 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505186 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005187}
5188
5189// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
5190// from the pool and make sure that we recover okay.
[email protected]23e482282013-06-14 16:08:025191TEST_P(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:005192 HttpRequestInfo request;
5193 request.method = "GET";
bncce36dca22015-04-21 22:11:235194 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:005195 request.load_flags = 0;
5196
5197 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:235198 MockWrite(
5199 "GET / HTTP/1.1\r\n"
5200 "Host: www.example.org\r\n"
5201 "Connection: keep-alive\r\n\r\n"),
5202 MockWrite(
5203 "GET / HTTP/1.1\r\n"
5204 "Host: www.example.org\r\n"
5205 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:005206 };
5207
5208 MockRead data_reads[] = {
5209 MockRead("HTTP/1.1 200 OK\r\n"),
5210 MockRead("Content-Length: 11\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065211 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:005212 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:065213 MockRead(ASYNC, 0, 0) // EOF
[email protected]76a505b2010-08-25 06:23:005214 };
5215
[email protected]8ddf8322012-02-23 18:08:065216 SSLSocketDataProvider ssl(ASYNC, OK);
5217 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075218 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5219 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:005220
5221 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5222 data_writes, arraysize(data_writes));
5223 StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
5224 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:075225 session_deps_.socket_factory->AddSocketDataProvider(&data);
5226 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:005227
[email protected]49639fa2011-12-20 23:22:415228 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:005229
[email protected]bb88e1d32013-05-03 23:11:075230 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:365231 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505232 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:005233
[email protected]49639fa2011-12-20 23:22:415234 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:005235
5236 EXPECT_EQ(ERR_IO_PENDING, rv);
5237 EXPECT_EQ(OK, callback.WaitForResult());
5238
5239 const HttpResponseInfo* response = trans->GetResponseInfo();
5240 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:505241 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:005242 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5243
[email protected]90499482013-06-01 00:39:505244 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005245
5246 std::string response_data;
5247 rv = ReadTransaction(trans.get(), &response_data);
5248 EXPECT_EQ(OK, rv);
5249 EXPECT_EQ("hello world", response_data);
5250
5251 // Empty the current queue. This is necessary because idle sockets are
5252 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345253 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:005254
5255 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505256 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005257
5258 // Now start the second transaction, which should reuse the previous socket.
5259
[email protected]90499482013-06-01 00:39:505260 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:005261
[email protected]49639fa2011-12-20 23:22:415262 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:005263
5264 EXPECT_EQ(ERR_IO_PENDING, rv);
5265 EXPECT_EQ(OK, callback.WaitForResult());
5266
5267 response = trans->GetResponseInfo();
5268 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:505269 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:005270 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5271
[email protected]90499482013-06-01 00:39:505272 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005273
5274 rv = ReadTransaction(trans.get(), &response_data);
5275 EXPECT_EQ(OK, rv);
5276 EXPECT_EQ("hello world", response_data);
5277
5278 // Empty the current queue. This is necessary because idle sockets are
5279 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345280 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:005281
5282 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505283 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005284}
5285
[email protected]b4404c02009-04-10 16:38:525286// Make sure that we recycle a socket after a zero-length response.
5287// http://crbug.com/9880
[email protected]23e482282013-06-14 16:08:025288TEST_P(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:425289 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:525290 request.method = "GET";
bncce36dca22015-04-21 22:11:235291 request.url = GURL(
5292 "http://www.example.org/csi?v=3&s=web&action=&"
5293 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
5294 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
5295 "rt=prt.2642,ol.2649,xjs.2951");
[email protected]b4404c02009-04-10 16:38:525296 request.load_flags = 0;
5297
[email protected]bb88e1d32013-05-03 23:11:075298 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275299
[email protected]262eec82013-03-19 21:01:365300 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505301 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275302
[email protected]b4404c02009-04-10 16:38:525303 MockRead data_reads[] = {
5304 MockRead("HTTP/1.1 204 No Content\r\n"
5305 "Content-Length: 0\r\n"
5306 "Content-Type: text/html\r\n\r\n"),
5307 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:065308 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:525309 };
5310
[email protected]31a2bfe2010-02-09 08:03:395311 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:075312 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:525313
[email protected]49639fa2011-12-20 23:22:415314 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:525315
[email protected]49639fa2011-12-20 23:22:415316 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425317 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]b4404c02009-04-10 16:38:525318
5319 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425320 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:525321
[email protected]1c773ea12009-04-28 19:58:425322 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505323 ASSERT_TRUE(response != NULL);
[email protected]b4404c02009-04-10 16:38:525324
[email protected]90499482013-06-01 00:39:505325 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]b4404c02009-04-10 16:38:525326 std::string status_line = response->headers->GetStatusLine();
5327 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
5328
[email protected]90499482013-06-01 00:39:505329 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:525330
5331 std::string response_data;
5332 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:425333 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:525334 EXPECT_EQ("", response_data);
5335
5336 // Empty the current queue. This is necessary because idle sockets are
5337 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345338 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:525339
5340 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505341 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:525342}
5343
[email protected]23e482282013-06-14 16:08:025344TEST_P(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
[email protected]b2d26cfd2012-12-11 10:36:065345 ScopedVector<UploadElementReader> element_readers;
5346 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:075347 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:275348
[email protected]1c773ea12009-04-28 19:58:425349 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:515350 // Transaction 1: a GET request that succeeds. The socket is recycled
5351 // after use.
5352 request[0].method = "GET";
5353 request[0].url = GURL("http://www.google.com/");
5354 request[0].load_flags = 0;
5355 // Transaction 2: a POST request. Reuses the socket kept alive from
5356 // transaction 1. The first attempts fails when writing the POST data.
5357 // This causes the transaction to retry with a new socket. The second
5358 // attempt succeeds.
5359 request[1].method = "POST";
5360 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:275361 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:515362 request[1].load_flags = 0;
5363
[email protected]bb88e1d32013-05-03 23:11:075364 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:515365
5366 // The first socket is used for transaction 1 and the first attempt of
5367 // transaction 2.
5368
5369 // The response of transaction 1.
5370 MockRead data_reads1[] = {
5371 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
5372 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:065373 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:515374 };
5375 // The mock write results of transaction 1 and the first attempt of
5376 // transaction 2.
5377 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:065378 MockWrite(SYNCHRONOUS, 64), // GET
5379 MockWrite(SYNCHRONOUS, 93), // POST
5380 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:515381 };
[email protected]31a2bfe2010-02-09 08:03:395382 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5383 data_writes1, arraysize(data_writes1));
[email protected]372d34a2008-11-05 21:30:515384
5385 // The second socket is used for the second attempt of transaction 2.
5386
5387 // The response of transaction 2.
5388 MockRead data_reads2[] = {
5389 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
5390 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:065391 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:515392 };
5393 // The mock write results of the second attempt of transaction 2.
5394 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:065395 MockWrite(SYNCHRONOUS, 93), // POST
5396 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:515397 };
[email protected]31a2bfe2010-02-09 08:03:395398 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5399 data_writes2, arraysize(data_writes2));
[email protected]372d34a2008-11-05 21:30:515400
[email protected]bb88e1d32013-05-03 23:11:075401 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5402 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:515403
thestig9d3bb0c2015-01-24 00:49:515404 const char* const kExpectedResponseData[] = {
[email protected]372d34a2008-11-05 21:30:515405 "hello world", "welcome"
5406 };
5407
5408 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:425409 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505410 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]372d34a2008-11-05 21:30:515411
[email protected]49639fa2011-12-20 23:22:415412 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:515413
[email protected]49639fa2011-12-20 23:22:415414 int rv = trans->Start(&request[i], callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425415 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]372d34a2008-11-05 21:30:515416
5417 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425418 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:515419
[email protected]1c773ea12009-04-28 19:58:425420 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505421 ASSERT_TRUE(response != NULL);
[email protected]372d34a2008-11-05 21:30:515422
[email protected]90499482013-06-01 00:39:505423 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]372d34a2008-11-05 21:30:515424 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5425
5426 std::string response_data;
5427 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:425428 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:515429 EXPECT_EQ(kExpectedResponseData[i], response_data);
5430 }
5431}
[email protected]f9ee6b52008-11-08 06:46:235432
5433// Test the request-challenge-retry sequence for basic auth when there is
5434// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:165435// it fails the identity from the URL is used to answer the challenge.
[email protected]23e482282013-06-14 16:08:025436TEST_P(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:425437 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235438 request.method = "GET";
bncce36dca22015-04-21 22:11:235439 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:415440 request.load_flags = LOAD_NORMAL;
[email protected]a97cca42009-08-14 01:00:295441
[email protected]3fe8d2f82013-10-17 08:56:075442 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275443 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415444 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275445
[email protected]a97cca42009-08-14 01:00:295446 // The password contains an escaped character -- for this test to pass it
5447 // will need to be unescaped by HttpNetworkTransaction.
5448 EXPECT_EQ("b%40r", request.url.password());
5449
[email protected]f9ee6b52008-11-08 06:46:235450 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235451 MockWrite(
5452 "GET / HTTP/1.1\r\n"
5453 "Host: www.example.org\r\n"
5454 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235455 };
5456
5457 MockRead data_reads1[] = {
5458 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5459 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5460 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065461 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235462 };
5463
[email protected]2262e3a2012-05-22 16:08:165464 // After the challenge above, the transaction will be restarted using the
5465 // identity from the url (foo, b@r) to answer the challenge.
5466 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235467 MockWrite(
5468 "GET / HTTP/1.1\r\n"
5469 "Host: www.example.org\r\n"
5470 "Connection: keep-alive\r\n"
5471 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:165472 };
5473
5474 MockRead data_reads2[] = {
5475 MockRead("HTTP/1.0 200 OK\r\n"),
5476 MockRead("Content-Length: 100\r\n\r\n"),
5477 MockRead(SYNCHRONOUS, OK),
5478 };
5479
[email protected]31a2bfe2010-02-09 08:03:395480 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5481 data_writes1, arraysize(data_writes1));
[email protected]2262e3a2012-05-22 16:08:165482 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5483 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075484 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5485 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235486
[email protected]49639fa2011-12-20 23:22:415487 TestCompletionCallback callback1;
[email protected]49639fa2011-12-20 23:22:415488 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425489 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235490 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425491 EXPECT_EQ(OK, rv);
[email protected]2262e3a2012-05-22 16:08:165492 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5493
5494 TestCompletionCallback callback2;
5495 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
5496 EXPECT_EQ(ERR_IO_PENDING, rv);
5497 rv = callback2.WaitForResult();
5498 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225499 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5500
[email protected]2262e3a2012-05-22 16:08:165501 const HttpResponseInfo* response = trans->GetResponseInfo();
5502 ASSERT_TRUE(response != NULL);
5503
5504 // There is no challenge info, since the identity in URL worked.
5505 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5506
5507 EXPECT_EQ(100, response->headers->GetContentLength());
5508
5509 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:345510 base::MessageLoop::current()->RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:165511}
5512
5513// Test the request-challenge-retry sequence for basic auth when there is an
5514// incorrect identity in the URL. The identity from the URL should be used only
5515// once.
[email protected]23e482282013-06-14 16:08:025516TEST_P(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:165517 HttpRequestInfo request;
5518 request.method = "GET";
5519 // Note: the URL has a username:password in it. The password "baz" is
5520 // wrong (should be "bar").
bncce36dca22015-04-21 22:11:235521 request.url = GURL("http://foo:[email protected]/");
[email protected]2262e3a2012-05-22 16:08:165522
5523 request.load_flags = LOAD_NORMAL;
5524
[email protected]3fe8d2f82013-10-17 08:56:075525 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2262e3a2012-05-22 16:08:165526 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415527 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2262e3a2012-05-22 16:08:165528
5529 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235530 MockWrite(
5531 "GET / HTTP/1.1\r\n"
5532 "Host: www.example.org\r\n"
5533 "Connection: keep-alive\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:165534 };
5535
5536 MockRead data_reads1[] = {
5537 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5538 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5539 MockRead("Content-Length: 10\r\n\r\n"),
5540 MockRead(SYNCHRONOUS, ERR_FAILED),
5541 };
5542
5543 // After the challenge above, the transaction will be restarted using the
5544 // identity from the url (foo, baz) to answer the challenge.
5545 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235546 MockWrite(
5547 "GET / HTTP/1.1\r\n"
5548 "Host: www.example.org\r\n"
5549 "Connection: keep-alive\r\n"
5550 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:165551 };
5552
5553 MockRead data_reads2[] = {
5554 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5555 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5556 MockRead("Content-Length: 10\r\n\r\n"),
5557 MockRead(SYNCHRONOUS, ERR_FAILED),
5558 };
5559
5560 // After the challenge above, the transaction will be restarted using the
5561 // identity supplied by the user (foo, bar) to answer the challenge.
5562 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:235563 MockWrite(
5564 "GET / HTTP/1.1\r\n"
5565 "Host: www.example.org\r\n"
5566 "Connection: keep-alive\r\n"
5567 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:165568 };
5569
5570 MockRead data_reads3[] = {
5571 MockRead("HTTP/1.0 200 OK\r\n"),
5572 MockRead("Content-Length: 100\r\n\r\n"),
5573 MockRead(SYNCHRONOUS, OK),
5574 };
5575
5576 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5577 data_writes1, arraysize(data_writes1));
5578 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5579 data_writes2, arraysize(data_writes2));
5580 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5581 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075582 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5583 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5584 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:165585
5586 TestCompletionCallback callback1;
5587
5588 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5589 EXPECT_EQ(ERR_IO_PENDING, rv);
5590
5591 rv = callback1.WaitForResult();
5592 EXPECT_EQ(OK, rv);
5593
5594 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5595 TestCompletionCallback callback2;
5596 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
5597 EXPECT_EQ(ERR_IO_PENDING, rv);
5598 rv = callback2.WaitForResult();
5599 EXPECT_EQ(OK, rv);
5600 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5601
5602 const HttpResponseInfo* response = trans->GetResponseInfo();
5603 ASSERT_TRUE(response != NULL);
5604 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
5605
5606 TestCompletionCallback callback3;
5607 rv = trans->RestartWithAuth(
5608 AuthCredentials(kFoo, kBar), callback3.callback());
5609 EXPECT_EQ(ERR_IO_PENDING, rv);
5610 rv = callback3.WaitForResult();
5611 EXPECT_EQ(OK, rv);
5612 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5613
5614 response = trans->GetResponseInfo();
5615 ASSERT_TRUE(response != NULL);
5616
5617 // There is no challenge info, since the identity worked.
5618 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5619
5620 EXPECT_EQ(100, response->headers->GetContentLength());
5621
[email protected]ea9dc9a2009-09-05 00:43:325622 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:345623 base::MessageLoop::current()->RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:325624}
5625
[email protected]2217aa22013-10-11 03:03:545626
5627// Test the request-challenge-retry sequence for basic auth when there is a
5628// correct identity in the URL, but its use is being suppressed. The identity
5629// from the URL should never be used.
5630TEST_P(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
5631 HttpRequestInfo request;
5632 request.method = "GET";
bncce36dca22015-04-21 22:11:235633 request.url = GURL("http://foo:[email protected]/");
[email protected]2217aa22013-10-11 03:03:545634 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
5635
[email protected]3fe8d2f82013-10-17 08:56:075636 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2217aa22013-10-11 03:03:545637 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415638 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2217aa22013-10-11 03:03:545639
5640 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235641 MockWrite(
5642 "GET / HTTP/1.1\r\n"
5643 "Host: www.example.org\r\n"
5644 "Connection: keep-alive\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:545645 };
5646
5647 MockRead data_reads1[] = {
5648 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5649 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5650 MockRead("Content-Length: 10\r\n\r\n"),
5651 MockRead(SYNCHRONOUS, ERR_FAILED),
5652 };
5653
5654 // After the challenge above, the transaction will be restarted using the
5655 // identity supplied by the user, not the one in the URL, to answer the
5656 // challenge.
5657 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:235658 MockWrite(
5659 "GET / HTTP/1.1\r\n"
5660 "Host: www.example.org\r\n"
5661 "Connection: keep-alive\r\n"
5662 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:545663 };
5664
5665 MockRead data_reads3[] = {
5666 MockRead("HTTP/1.0 200 OK\r\n"),
5667 MockRead("Content-Length: 100\r\n\r\n"),
5668 MockRead(SYNCHRONOUS, OK),
5669 };
5670
5671 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5672 data_writes1, arraysize(data_writes1));
5673 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5674 data_writes3, arraysize(data_writes3));
5675 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5676 session_deps_.socket_factory->AddSocketDataProvider(&data3);
5677
5678 TestCompletionCallback callback1;
5679 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5680 EXPECT_EQ(ERR_IO_PENDING, rv);
5681 rv = callback1.WaitForResult();
5682 EXPECT_EQ(OK, rv);
5683 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5684
5685 const HttpResponseInfo* response = trans->GetResponseInfo();
5686 ASSERT_TRUE(response != NULL);
5687 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
5688
5689 TestCompletionCallback callback3;
5690 rv = trans->RestartWithAuth(
5691 AuthCredentials(kFoo, kBar), callback3.callback());
5692 EXPECT_EQ(ERR_IO_PENDING, rv);
5693 rv = callback3.WaitForResult();
5694 EXPECT_EQ(OK, rv);
5695 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5696
5697 response = trans->GetResponseInfo();
5698 ASSERT_TRUE(response != NULL);
5699
5700 // There is no challenge info, since the identity worked.
5701 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5702 EXPECT_EQ(100, response->headers->GetContentLength());
5703
5704 // Empty the current queue.
5705 base::MessageLoop::current()->RunUntilIdle();
5706}
5707
[email protected]f9ee6b52008-11-08 06:46:235708// Test that previously tried username/passwords for a realm get re-used.
[email protected]23e482282013-06-14 16:08:025709TEST_P(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
[email protected]bb88e1d32013-05-03 23:11:075710 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:235711
5712 // Transaction 1: authenticate (foo, bar) on MyRealm1
5713 {
[email protected]1c773ea12009-04-28 19:58:425714 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235715 request.method = "GET";
bncce36dca22015-04-21 22:11:235716 request.url = GURL("http://www.example.org/x/y/z");
[email protected]f9ee6b52008-11-08 06:46:235717 request.load_flags = 0;
5718
[email protected]262eec82013-03-19 21:01:365719 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505720 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275721
[email protected]f9ee6b52008-11-08 06:46:235722 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235723 MockWrite(
5724 "GET /x/y/z HTTP/1.1\r\n"
5725 "Host: www.example.org\r\n"
5726 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235727 };
5728
5729 MockRead data_reads1[] = {
5730 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5731 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5732 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065733 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235734 };
5735
5736 // Resend with authorization (username=foo, password=bar)
5737 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235738 MockWrite(
5739 "GET /x/y/z HTTP/1.1\r\n"
5740 "Host: www.example.org\r\n"
5741 "Connection: keep-alive\r\n"
5742 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235743 };
5744
5745 // Sever accepts the authorization.
5746 MockRead data_reads2[] = {
5747 MockRead("HTTP/1.0 200 OK\r\n"),
5748 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065749 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235750 };
5751
[email protected]31a2bfe2010-02-09 08:03:395752 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5753 data_writes1, arraysize(data_writes1));
5754 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5755 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075756 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5757 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235758
[email protected]49639fa2011-12-20 23:22:415759 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235760
[email protected]49639fa2011-12-20 23:22:415761 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425762 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235763
5764 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425765 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235766
[email protected]1c773ea12009-04-28 19:58:425767 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505768 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045769 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:235770
[email protected]49639fa2011-12-20 23:22:415771 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:235772
[email protected]49639fa2011-12-20 23:22:415773 rv = trans->RestartWithAuth(
5774 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425775 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235776
5777 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425778 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235779
5780 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505781 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235782 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5783 EXPECT_EQ(100, response->headers->GetContentLength());
5784 }
5785
5786 // ------------------------------------------------------------------------
5787
5788 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
5789 {
[email protected]1c773ea12009-04-28 19:58:425790 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235791 request.method = "GET";
5792 // Note that Transaction 1 was at /x/y/z, so this is in the same
5793 // protection space as MyRealm1.
bncce36dca22015-04-21 22:11:235794 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]f9ee6b52008-11-08 06:46:235795 request.load_flags = 0;
5796
[email protected]262eec82013-03-19 21:01:365797 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505798 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275799
[email protected]f9ee6b52008-11-08 06:46:235800 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235801 MockWrite(
5802 "GET /x/y/a/b HTTP/1.1\r\n"
5803 "Host: www.example.org\r\n"
5804 "Connection: keep-alive\r\n"
5805 // Send preemptive authorization for MyRealm1
5806 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235807 };
5808
5809 // The server didn't like the preemptive authorization, and
5810 // challenges us for a different realm (MyRealm2).
5811 MockRead data_reads1[] = {
5812 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5813 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
5814 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065815 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235816 };
5817
5818 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
5819 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235820 MockWrite(
5821 "GET /x/y/a/b HTTP/1.1\r\n"
5822 "Host: www.example.org\r\n"
5823 "Connection: keep-alive\r\n"
5824 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235825 };
5826
5827 // Sever accepts the authorization.
5828 MockRead data_reads2[] = {
5829 MockRead("HTTP/1.0 200 OK\r\n"),
5830 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065831 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235832 };
5833
[email protected]31a2bfe2010-02-09 08:03:395834 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5835 data_writes1, arraysize(data_writes1));
5836 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5837 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075838 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5839 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235840
[email protected]49639fa2011-12-20 23:22:415841 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235842
[email protected]49639fa2011-12-20 23:22:415843 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425844 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235845
5846 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425847 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235848
[email protected]1c773ea12009-04-28 19:58:425849 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505850 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045851 ASSERT_TRUE(response->auth_challenge.get());
5852 EXPECT_FALSE(response->auth_challenge->is_proxy);
bncce36dca22015-04-21 22:11:235853 EXPECT_EQ("www.example.org:80",
[email protected]79cb5c12011-09-12 13:12:045854 response->auth_challenge->challenger.ToString());
5855 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
5856 EXPECT_EQ("basic", response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:235857
[email protected]49639fa2011-12-20 23:22:415858 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:235859
[email protected]49639fa2011-12-20 23:22:415860 rv = trans->RestartWithAuth(
5861 AuthCredentials(kFoo2, kBar2), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425862 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235863
5864 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425865 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235866
5867 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505868 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235869 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5870 EXPECT_EQ(100, response->headers->GetContentLength());
5871 }
5872
5873 // ------------------------------------------------------------------------
5874
5875 // Transaction 3: Resend a request in MyRealm's protection space --
5876 // succeed with preemptive authorization.
5877 {
[email protected]1c773ea12009-04-28 19:58:425878 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235879 request.method = "GET";
bncce36dca22015-04-21 22:11:235880 request.url = GURL("http://www.example.org/x/y/z2");
[email protected]f9ee6b52008-11-08 06:46:235881 request.load_flags = 0;
5882
[email protected]262eec82013-03-19 21:01:365883 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505884 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275885
[email protected]f9ee6b52008-11-08 06:46:235886 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235887 MockWrite(
5888 "GET /x/y/z2 HTTP/1.1\r\n"
5889 "Host: www.example.org\r\n"
5890 "Connection: keep-alive\r\n"
5891 // The authorization for MyRealm1 gets sent preemptively
5892 // (since the url is in the same protection space)
5893 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235894 };
5895
5896 // Sever accepts the preemptive authorization
5897 MockRead data_reads1[] = {
5898 MockRead("HTTP/1.0 200 OK\r\n"),
5899 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065900 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235901 };
5902
[email protected]31a2bfe2010-02-09 08:03:395903 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5904 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075905 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:235906
[email protected]49639fa2011-12-20 23:22:415907 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235908
[email protected]49639fa2011-12-20 23:22:415909 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425910 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235911
5912 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425913 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235914
[email protected]1c773ea12009-04-28 19:58:425915 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505916 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235917
5918 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5919 EXPECT_EQ(100, response->headers->GetContentLength());
5920 }
5921
5922 // ------------------------------------------------------------------------
5923
5924 // Transaction 4: request another URL in MyRealm (however the
5925 // url is not known to belong to the protection space, so no pre-auth).
5926 {
[email protected]1c773ea12009-04-28 19:58:425927 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235928 request.method = "GET";
bncce36dca22015-04-21 22:11:235929 request.url = GURL("http://www.example.org/x/1");
[email protected]f9ee6b52008-11-08 06:46:235930 request.load_flags = 0;
5931
[email protected]262eec82013-03-19 21:01:365932 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505933 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275934
[email protected]f9ee6b52008-11-08 06:46:235935 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235936 MockWrite(
5937 "GET /x/1 HTTP/1.1\r\n"
5938 "Host: www.example.org\r\n"
5939 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235940 };
5941
5942 MockRead data_reads1[] = {
5943 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5944 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5945 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065946 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235947 };
5948
5949 // Resend with authorization from MyRealm's cache.
5950 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235951 MockWrite(
5952 "GET /x/1 HTTP/1.1\r\n"
5953 "Host: www.example.org\r\n"
5954 "Connection: keep-alive\r\n"
5955 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235956 };
5957
5958 // Sever accepts the authorization.
5959 MockRead data_reads2[] = {
5960 MockRead("HTTP/1.0 200 OK\r\n"),
5961 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065962 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235963 };
5964
[email protected]31a2bfe2010-02-09 08:03:395965 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5966 data_writes1, arraysize(data_writes1));
5967 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5968 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075969 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5970 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235971
[email protected]49639fa2011-12-20 23:22:415972 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235973
[email protected]49639fa2011-12-20 23:22:415974 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425975 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235976
5977 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425978 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235979
[email protected]0757e7702009-03-27 04:00:225980 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:415981 TestCompletionCallback callback2;
5982 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425983 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:225984 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425985 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225986 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5987
[email protected]1c773ea12009-04-28 19:58:425988 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505989 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235990 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5991 EXPECT_EQ(100, response->headers->GetContentLength());
5992 }
5993
5994 // ------------------------------------------------------------------------
5995
5996 // Transaction 5: request a URL in MyRealm, but the server rejects the
5997 // cached identity. Should invalidate and re-prompt.
5998 {
[email protected]1c773ea12009-04-28 19:58:425999 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236000 request.method = "GET";
bncce36dca22015-04-21 22:11:236001 request.url = GURL("http://www.example.org/p/q/t");
[email protected]f9ee6b52008-11-08 06:46:236002 request.load_flags = 0;
6003
[email protected]262eec82013-03-19 21:01:366004 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506005 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276006
[email protected]f9ee6b52008-11-08 06:46:236007 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236008 MockWrite(
6009 "GET /p/q/t HTTP/1.1\r\n"
6010 "Host: www.example.org\r\n"
6011 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236012 };
6013
6014 MockRead data_reads1[] = {
6015 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6016 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6017 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066018 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236019 };
6020
6021 // Resend with authorization from cache for MyRealm.
6022 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236023 MockWrite(
6024 "GET /p/q/t HTTP/1.1\r\n"
6025 "Host: www.example.org\r\n"
6026 "Connection: keep-alive\r\n"
6027 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236028 };
6029
6030 // Sever rejects the authorization.
6031 MockRead data_reads2[] = {
6032 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6033 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6034 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066035 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236036 };
6037
6038 // At this point we should prompt for new credentials for MyRealm.
6039 // Restart with username=foo3, password=foo4.
6040 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236041 MockWrite(
6042 "GET /p/q/t HTTP/1.1\r\n"
6043 "Host: www.example.org\r\n"
6044 "Connection: keep-alive\r\n"
6045 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236046 };
6047
6048 // Sever accepts the authorization.
6049 MockRead data_reads3[] = {
6050 MockRead("HTTP/1.0 200 OK\r\n"),
6051 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066052 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:236053 };
6054
[email protected]31a2bfe2010-02-09 08:03:396055 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6056 data_writes1, arraysize(data_writes1));
6057 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6058 data_writes2, arraysize(data_writes2));
6059 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6060 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076061 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6062 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6063 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:236064
[email protected]49639fa2011-12-20 23:22:416065 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:236066
[email protected]49639fa2011-12-20 23:22:416067 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426068 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236069
6070 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426071 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236072
[email protected]0757e7702009-03-27 04:00:226073 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:416074 TestCompletionCallback callback2;
6075 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:426076 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:226077 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426078 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:226079 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6080
[email protected]1c773ea12009-04-28 19:58:426081 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506082 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:046083 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:236084
[email protected]49639fa2011-12-20 23:22:416085 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:236086
[email protected]49639fa2011-12-20 23:22:416087 rv = trans->RestartWithAuth(
6088 AuthCredentials(kFoo3, kBar3), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:426089 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236090
[email protected]0757e7702009-03-27 04:00:226091 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426092 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236093
6094 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506095 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:236096 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6097 EXPECT_EQ(100, response->headers->GetContentLength());
6098 }
6099}
[email protected]89ceba9a2009-03-21 03:46:066100
[email protected]3c32c5f2010-05-18 15:18:126101// Tests that nonce count increments when multiple auth attempts
6102// are started with the same nonce.
[email protected]23e482282013-06-14 16:08:026103TEST_P(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:446104 HttpAuthHandlerDigest::Factory* digest_factory =
6105 new HttpAuthHandlerDigest::Factory();
6106 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
6107 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
6108 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:076109 session_deps_.http_auth_handler_factory.reset(digest_factory);
6110 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:126111
6112 // Transaction 1: authenticate (foo, bar) on MyRealm1
6113 {
[email protected]3c32c5f2010-05-18 15:18:126114 HttpRequestInfo request;
6115 request.method = "GET";
bncce36dca22015-04-21 22:11:236116 request.url = GURL("http://www.example.org/x/y/z");
[email protected]3c32c5f2010-05-18 15:18:126117 request.load_flags = 0;
6118
[email protected]262eec82013-03-19 21:01:366119 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506120 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276121
[email protected]3c32c5f2010-05-18 15:18:126122 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236123 MockWrite(
6124 "GET /x/y/z HTTP/1.1\r\n"
6125 "Host: www.example.org\r\n"
6126 "Connection: keep-alive\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:126127 };
6128
6129 MockRead data_reads1[] = {
6130 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6131 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
6132 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066133 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:126134 };
6135
6136 // Resend with authorization (username=foo, password=bar)
6137 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236138 MockWrite(
6139 "GET /x/y/z HTTP/1.1\r\n"
6140 "Host: www.example.org\r\n"
6141 "Connection: keep-alive\r\n"
6142 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
6143 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
6144 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
6145 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:126146 };
6147
6148 // Sever accepts the authorization.
6149 MockRead data_reads2[] = {
6150 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:066151 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:126152 };
6153
6154 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6155 data_writes1, arraysize(data_writes1));
6156 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6157 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076158 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6159 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:126160
[email protected]49639fa2011-12-20 23:22:416161 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:126162
[email protected]49639fa2011-12-20 23:22:416163 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:126164 EXPECT_EQ(ERR_IO_PENDING, rv);
6165
6166 rv = callback1.WaitForResult();
6167 EXPECT_EQ(OK, rv);
6168
6169 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506170 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:046171 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:126172
[email protected]49639fa2011-12-20 23:22:416173 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:126174
[email protected]49639fa2011-12-20 23:22:416175 rv = trans->RestartWithAuth(
6176 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]3c32c5f2010-05-18 15:18:126177 EXPECT_EQ(ERR_IO_PENDING, rv);
6178
6179 rv = callback2.WaitForResult();
6180 EXPECT_EQ(OK, rv);
6181
6182 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506183 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:126184 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6185 }
6186
6187 // ------------------------------------------------------------------------
6188
6189 // Transaction 2: Request another resource in digestive's protection space.
6190 // This will preemptively add an Authorization header which should have an
6191 // "nc" value of 2 (as compared to 1 in the first use.
6192 {
[email protected]3c32c5f2010-05-18 15:18:126193 HttpRequestInfo request;
6194 request.method = "GET";
6195 // Note that Transaction 1 was at /x/y/z, so this is in the same
6196 // protection space as digest.
bncce36dca22015-04-21 22:11:236197 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]3c32c5f2010-05-18 15:18:126198 request.load_flags = 0;
6199
[email protected]262eec82013-03-19 21:01:366200 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506201 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276202
[email protected]3c32c5f2010-05-18 15:18:126203 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236204 MockWrite(
6205 "GET /x/y/a/b HTTP/1.1\r\n"
6206 "Host: www.example.org\r\n"
6207 "Connection: keep-alive\r\n"
6208 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
6209 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
6210 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
6211 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:126212 };
6213
6214 // Sever accepts the authorization.
6215 MockRead data_reads1[] = {
6216 MockRead("HTTP/1.0 200 OK\r\n"),
6217 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066218 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:126219 };
6220
6221 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6222 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:076223 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:126224
[email protected]49639fa2011-12-20 23:22:416225 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:126226
[email protected]49639fa2011-12-20 23:22:416227 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:126228 EXPECT_EQ(ERR_IO_PENDING, rv);
6229
6230 rv = callback1.WaitForResult();
6231 EXPECT_EQ(OK, rv);
6232
6233 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506234 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:126235 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6236 }
6237}
6238
[email protected]89ceba9a2009-03-21 03:46:066239// Test the ResetStateForRestart() private method.
[email protected]23e482282013-06-14 16:08:026240TEST_P(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:066241 // Create a transaction (the dependencies aren't important).
[email protected]3fe8d2f82013-10-17 08:56:076242 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:406243 scoped_ptr<HttpNetworkTransaction> trans(
dcheng48459ac22014-08-26 00:46:416244 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]89ceba9a2009-03-21 03:46:066245
6246 // Setup some state (which we expect ResetStateForRestart() will clear).
[email protected]89ceba9a2009-03-21 03:46:066247 trans->read_buf_ = new IOBuffer(15);
6248 trans->read_buf_len_ = 15;
[email protected]b94f92d2010-10-27 16:45:206249 trans->request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:066250
6251 // Setup state in response_
[email protected]a7e41312009-12-16 23:18:146252 HttpResponseInfo* response = &trans->response_;
[email protected]0877e3d2009-10-17 22:29:576253 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:086254 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:576255 response->response_time = base::Time::Now();
6256 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:066257
6258 { // Setup state for response_.vary_data
6259 HttpRequestInfo request;
6260 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
6261 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:276262 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:436263 request.extra_headers.SetHeader("Foo", "1");
6264 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:506265 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:066266 }
6267
6268 // Cause the above state to be reset.
6269 trans->ResetStateForRestart();
6270
6271 // Verify that the state that needed to be reset, has been reset.
[email protected]9b6fee12009-09-29 18:13:076272 EXPECT_TRUE(trans->read_buf_.get() == NULL);
[email protected]89ceba9a2009-03-21 03:46:066273 EXPECT_EQ(0, trans->read_buf_len_);
[email protected]b94f92d2010-10-27 16:45:206274 EXPECT_TRUE(trans->request_headers_.IsEmpty());
[email protected]0877e3d2009-10-17 22:29:576275 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6276 EXPECT_TRUE(response->headers.get() == NULL);
[email protected]34f40942010-10-04 00:34:046277 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:086278 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:576279 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:066280}
6281
[email protected]bacff652009-03-31 17:50:336282// Test HTTPS connections to a site with a bad certificate
[email protected]23e482282013-06-14 16:08:026283TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:336284 HttpRequestInfo request;
6285 request.method = "GET";
bncce36dca22015-04-21 22:11:236286 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:336287 request.load_flags = 0;
6288
[email protected]3fe8d2f82013-10-17 08:56:076289 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276290 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416291 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276292
[email protected]bacff652009-03-31 17:50:336293 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236294 MockWrite(
6295 "GET / HTTP/1.1\r\n"
6296 "Host: www.example.org\r\n"
6297 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:336298 };
6299
6300 MockRead data_reads[] = {
6301 MockRead("HTTP/1.0 200 OK\r\n"),
6302 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6303 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066304 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:336305 };
6306
[email protected]5ecc992a42009-11-11 01:41:596307 StaticSocketDataProvider ssl_bad_certificate;
[email protected]31a2bfe2010-02-09 08:03:396308 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6309 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066310 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
6311 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:336312
[email protected]bb88e1d32013-05-03 23:11:076313 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
6314 session_deps_.socket_factory->AddSocketDataProvider(&data);
6315 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
6316 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:336317
[email protected]49639fa2011-12-20 23:22:416318 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:336319
[email protected]49639fa2011-12-20 23:22:416320 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:336321 EXPECT_EQ(ERR_IO_PENDING, rv);
6322
6323 rv = callback.WaitForResult();
6324 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
6325
[email protected]49639fa2011-12-20 23:22:416326 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:336327 EXPECT_EQ(ERR_IO_PENDING, rv);
6328
6329 rv = callback.WaitForResult();
6330 EXPECT_EQ(OK, rv);
6331
6332 const HttpResponseInfo* response = trans->GetResponseInfo();
6333
[email protected]fe2255a2011-09-20 19:37:506334 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:336335 EXPECT_EQ(100, response->headers->GetContentLength());
6336}
6337
6338// Test HTTPS connections to a site with a bad certificate, going through a
6339// proxy
[email protected]23e482282013-06-14 16:08:026340TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
[email protected]bb88e1d32013-05-03 23:11:076341 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]bacff652009-03-31 17:50:336342
6343 HttpRequestInfo request;
6344 request.method = "GET";
bncce36dca22015-04-21 22:11:236345 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:336346 request.load_flags = 0;
6347
6348 MockWrite proxy_writes[] = {
bncce36dca22015-04-21 22:11:236349 MockWrite(
6350 "CONNECT www.example.org:443 HTTP/1.1\r\n"
6351 "Host: www.example.org\r\n"
6352 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:336353 };
6354
6355 MockRead proxy_reads[] = {
6356 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066357 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:336358 };
6359
6360 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236361 MockWrite(
6362 "CONNECT www.example.org:443 HTTP/1.1\r\n"
6363 "Host: www.example.org\r\n"
6364 "Proxy-Connection: keep-alive\r\n\r\n"),
6365 MockWrite(
6366 "GET / HTTP/1.1\r\n"
6367 "Host: www.example.org\r\n"
6368 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:336369 };
6370
6371 MockRead data_reads[] = {
6372 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
6373 MockRead("HTTP/1.0 200 OK\r\n"),
6374 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6375 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066376 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:336377 };
6378
[email protected]31a2bfe2010-02-09 08:03:396379 StaticSocketDataProvider ssl_bad_certificate(
6380 proxy_reads, arraysize(proxy_reads),
6381 proxy_writes, arraysize(proxy_writes));
6382 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6383 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066384 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
6385 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:336386
[email protected]bb88e1d32013-05-03 23:11:076387 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
6388 session_deps_.socket_factory->AddSocketDataProvider(&data);
6389 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
6390 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:336391
[email protected]49639fa2011-12-20 23:22:416392 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:336393
6394 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:076395 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:336396
[email protected]3fe8d2f82013-10-17 08:56:076397 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:406398 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416399 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bacff652009-03-31 17:50:336400
[email protected]49639fa2011-12-20 23:22:416401 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:336402 EXPECT_EQ(ERR_IO_PENDING, rv);
6403
6404 rv = callback.WaitForResult();
6405 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
6406
[email protected]49639fa2011-12-20 23:22:416407 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:336408 EXPECT_EQ(ERR_IO_PENDING, rv);
6409
6410 rv = callback.WaitForResult();
6411 EXPECT_EQ(OK, rv);
6412
6413 const HttpResponseInfo* response = trans->GetResponseInfo();
6414
[email protected]fe2255a2011-09-20 19:37:506415 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:336416 EXPECT_EQ(100, response->headers->GetContentLength());
6417 }
6418}
6419
[email protected]2df19bb2010-08-25 20:13:466420
6421// Test HTTPS connections to a site, going through an HTTPS proxy
[email protected]23e482282013-06-14 16:08:026422TEST_P(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076423 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206424 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
vishal.b62985ca92015-04-17 08:45:516425 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076426 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:466427
6428 HttpRequestInfo request;
6429 request.method = "GET";
bncce36dca22015-04-21 22:11:236430 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:466431 request.load_flags = 0;
6432
6433 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236434 MockWrite(
6435 "CONNECT www.example.org:443 HTTP/1.1\r\n"
6436 "Host: www.example.org\r\n"
6437 "Proxy-Connection: keep-alive\r\n\r\n"),
6438 MockWrite(
6439 "GET / HTTP/1.1\r\n"
6440 "Host: www.example.org\r\n"
6441 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:466442 };
6443
6444 MockRead data_reads[] = {
6445 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
6446 MockRead("HTTP/1.1 200 OK\r\n"),
6447 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6448 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066449 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:466450 };
6451
6452 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6453 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066454 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
6455 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:466456
[email protected]bb88e1d32013-05-03 23:11:076457 session_deps_.socket_factory->AddSocketDataProvider(&data);
6458 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
6459 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:466460
[email protected]49639fa2011-12-20 23:22:416461 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:466462
[email protected]3fe8d2f82013-10-17 08:56:076463 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:466464 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416465 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2df19bb2010-08-25 20:13:466466
[email protected]49639fa2011-12-20 23:22:416467 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:466468 EXPECT_EQ(ERR_IO_PENDING, rv);
6469
6470 rv = callback.WaitForResult();
6471 EXPECT_EQ(OK, rv);
6472 const HttpResponseInfo* response = trans->GetResponseInfo();
6473
[email protected]fe2255a2011-09-20 19:37:506474 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:466475
6476 EXPECT_TRUE(response->headers->IsKeepAlive());
6477 EXPECT_EQ(200, response->headers->response_code());
6478 EXPECT_EQ(100, response->headers->GetContentLength());
6479 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:206480
6481 LoadTimingInfo load_timing_info;
6482 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6483 TestLoadTimingNotReusedWithPac(load_timing_info,
6484 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:466485}
6486
[email protected]511f6f52010-12-17 03:58:296487// Test an HTTPS Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:026488TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076489 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206490 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
vishal.b62985ca92015-04-17 08:45:516491 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076492 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:296493
6494 HttpRequestInfo request;
6495 request.method = "GET";
bncce36dca22015-04-21 22:11:236496 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:296497 request.load_flags = 0;
6498
6499 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236500 MockWrite(
6501 "CONNECT www.example.org:443 HTTP/1.1\r\n"
6502 "Host: www.example.org\r\n"
6503 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:296504 };
6505
6506 MockRead data_reads[] = {
6507 MockRead("HTTP/1.1 302 Redirect\r\n"),
6508 MockRead("Location: http://login.example.com/\r\n"),
6509 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066510 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:296511 };
6512
6513 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6514 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066515 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:296516
[email protected]bb88e1d32013-05-03 23:11:076517 session_deps_.socket_factory->AddSocketDataProvider(&data);
6518 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296519
[email protected]49639fa2011-12-20 23:22:416520 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296521
[email protected]3fe8d2f82013-10-17 08:56:076522 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296523 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416524 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:296525
[email protected]49639fa2011-12-20 23:22:416526 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296527 EXPECT_EQ(ERR_IO_PENDING, rv);
6528
6529 rv = callback.WaitForResult();
6530 EXPECT_EQ(OK, rv);
6531 const HttpResponseInfo* response = trans->GetResponseInfo();
6532
[email protected]fe2255a2011-09-20 19:37:506533 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:296534
6535 EXPECT_EQ(302, response->headers->response_code());
6536 std::string url;
6537 EXPECT_TRUE(response->headers->IsRedirect(&url));
6538 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:206539
6540 // In the case of redirects from proxies, HttpNetworkTransaction returns
6541 // timing for the proxy connection instead of the connection to the host,
6542 // and no send / receive times.
6543 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
6544 LoadTimingInfo load_timing_info;
6545 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6546
6547 EXPECT_FALSE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:296548 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:206549
6550 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
6551 EXPECT_LE(load_timing_info.proxy_resolve_start,
6552 load_timing_info.proxy_resolve_end);
6553 EXPECT_LE(load_timing_info.proxy_resolve_end,
6554 load_timing_info.connect_timing.connect_start);
6555 ExpectConnectTimingHasTimes(
6556 load_timing_info.connect_timing,
6557 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
6558
6559 EXPECT_TRUE(load_timing_info.send_start.is_null());
6560 EXPECT_TRUE(load_timing_info.send_end.is_null());
6561 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:296562}
6563
6564// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:026565TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
[email protected]bb88e1d32013-05-03 23:11:076566 session_deps_.proxy_service.reset(
[email protected]511f6f52010-12-17 03:58:296567 ProxyService::CreateFixed("https://proxy:70"));
6568
6569 HttpRequestInfo request;
6570 request.method = "GET";
bncce36dca22015-04-21 22:11:236571 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:296572 request.load_flags = 0;
6573
lgarrona91df87f2014-12-05 00:51:346574 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:236575 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]c10b20852013-05-15 21:29:206576 scoped_ptr<SpdyFrame> goaway(
6577 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:296578 MockWrite data_writes[] = {
rch8e6c6c42015-05-01 14:05:136579 CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
6580 CreateMockWrite(*goaway.get(), 2, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:296581 };
6582
6583 static const char* const kExtraHeaders[] = {
6584 "location",
6585 "http://login.example.com/",
6586 };
[email protected]ff98d7f02012-03-22 21:44:196587 scoped_ptr<SpdyFrame> resp(
[email protected]23e482282013-06-14 16:08:026588 spdy_util_.ConstructSpdySynReplyError("302 Redirect", kExtraHeaders,
[email protected]511f6f52010-12-17 03:58:296589 arraysize(kExtraHeaders)/2, 1));
6590 MockRead data_reads[] = {
rch8e6c6c42015-05-01 14:05:136591 CreateMockRead(*resp.get(), 1), MockRead(ASYNC, 0, 3), // EOF
[email protected]511f6f52010-12-17 03:58:296592 };
6593
rch8e6c6c42015-05-01 14:05:136594 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
6595 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066596 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]23e482282013-06-14 16:08:026597 proxy_ssl.SetNextProto(GetParam());
[email protected]511f6f52010-12-17 03:58:296598
[email protected]bb88e1d32013-05-03 23:11:076599 session_deps_.socket_factory->AddSocketDataProvider(&data);
6600 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296601
[email protected]49639fa2011-12-20 23:22:416602 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296603
[email protected]3fe8d2f82013-10-17 08:56:076604 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296605 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416606 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:296607
[email protected]49639fa2011-12-20 23:22:416608 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296609 EXPECT_EQ(ERR_IO_PENDING, rv);
6610
6611 rv = callback.WaitForResult();
6612 EXPECT_EQ(OK, rv);
6613 const HttpResponseInfo* response = trans->GetResponseInfo();
6614
[email protected]fe2255a2011-09-20 19:37:506615 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:296616
6617 EXPECT_EQ(302, response->headers->response_code());
6618 std::string url;
6619 EXPECT_TRUE(response->headers->IsRedirect(&url));
6620 EXPECT_EQ("http://login.example.com/", url);
6621}
6622
[email protected]4eddbc732012-08-09 05:40:176623// Test that an HTTPS proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:026624TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:176625 ErrorResponseToHttpsConnectViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076626 session_deps_.proxy_service.reset(
[email protected]511f6f52010-12-17 03:58:296627 ProxyService::CreateFixed("https://proxy:70"));
6628
6629 HttpRequestInfo request;
6630 request.method = "GET";
bncce36dca22015-04-21 22:11:236631 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:296632 request.load_flags = 0;
6633
6634 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236635 MockWrite(
6636 "CONNECT www.example.org:443 HTTP/1.1\r\n"
6637 "Host: www.example.org\r\n"
6638 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:296639 };
6640
6641 MockRead data_reads[] = {
6642 MockRead("HTTP/1.1 404 Not Found\r\n"),
6643 MockRead("Content-Length: 23\r\n\r\n"),
6644 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:066645 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:296646 };
6647
6648 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6649 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066650 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:296651
[email protected]bb88e1d32013-05-03 23:11:076652 session_deps_.socket_factory->AddSocketDataProvider(&data);
6653 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296654
[email protected]49639fa2011-12-20 23:22:416655 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296656
[email protected]3fe8d2f82013-10-17 08:56:076657 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296658 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416659 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:296660
[email protected]49639fa2011-12-20 23:22:416661 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296662 EXPECT_EQ(ERR_IO_PENDING, rv);
6663
6664 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:176665 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:296666
[email protected]4eddbc732012-08-09 05:40:176667 // TODO(ttuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:296668}
6669
[email protected]4eddbc732012-08-09 05:40:176670// Test that a SPDY proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:026671TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:176672 ErrorResponseToHttpsConnectViaSpdyProxy) {
[email protected]bb88e1d32013-05-03 23:11:076673 session_deps_.proxy_service.reset(
6674 ProxyService::CreateFixed("https://proxy:70"));
[email protected]511f6f52010-12-17 03:58:296675
6676 HttpRequestInfo request;
6677 request.method = "GET";
bncce36dca22015-04-21 22:11:236678 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:296679 request.load_flags = 0;
6680
lgarrona91df87f2014-12-05 00:51:346681 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:236682 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]c10b20852013-05-15 21:29:206683 scoped_ptr<SpdyFrame> rst(
6684 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:296685 MockWrite data_writes[] = {
rch8e6c6c42015-05-01 14:05:136686 CreateMockWrite(*conn.get(), 0), CreateMockWrite(*rst.get(), 3),
[email protected]511f6f52010-12-17 03:58:296687 };
6688
6689 static const char* const kExtraHeaders[] = {
6690 "location",
6691 "http://login.example.com/",
6692 };
[email protected]ff98d7f02012-03-22 21:44:196693 scoped_ptr<SpdyFrame> resp(
[email protected]23e482282013-06-14 16:08:026694 spdy_util_.ConstructSpdySynReplyError("404 Not Found", kExtraHeaders,
[email protected]511f6f52010-12-17 03:58:296695 arraysize(kExtraHeaders)/2, 1));
[email protected]ff98d7f02012-03-22 21:44:196696 scoped_ptr<SpdyFrame> body(
[email protected]23e482282013-06-14 16:08:026697 spdy_util_.ConstructSpdyBodyFrame(
6698 1, "The host does not exist", 23, true));
[email protected]511f6f52010-12-17 03:58:296699 MockRead data_reads[] = {
rch8e6c6c42015-05-01 14:05:136700 CreateMockRead(*resp.get(), 1),
6701 CreateMockRead(*body.get(), 2),
6702 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:296703 };
6704
rch8e6c6c42015-05-01 14:05:136705 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
6706 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066707 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]23e482282013-06-14 16:08:026708 proxy_ssl.SetNextProto(GetParam());
[email protected]511f6f52010-12-17 03:58:296709
[email protected]bb88e1d32013-05-03 23:11:076710 session_deps_.socket_factory->AddSocketDataProvider(&data);
6711 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296712
[email protected]49639fa2011-12-20 23:22:416713 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296714
[email protected]3fe8d2f82013-10-17 08:56:076715 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296716 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416717 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:296718
[email protected]49639fa2011-12-20 23:22:416719 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296720 EXPECT_EQ(ERR_IO_PENDING, rv);
6721
6722 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:176723 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:296724
[email protected]4eddbc732012-08-09 05:40:176725 // TODO(ttuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:296726}
6727
[email protected]0c5fb722012-02-28 11:50:356728// Test the request-challenge-retry sequence for basic auth, through
6729// a SPDY proxy over a single SPDY session.
[email protected]23e482282013-06-14 16:08:026730TEST_P(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:356731 HttpRequestInfo request;
6732 request.method = "GET";
bncce36dca22015-04-21 22:11:236733 request.url = GURL("https://www.example.org/");
[email protected]0c5fb722012-02-28 11:50:356734 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:296735 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]0c5fb722012-02-28 11:50:356736
6737 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076738 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206739 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
vishal.b62985ca92015-04-17 08:45:516740 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076741 session_deps_.net_log = log.bound().net_log();
6742 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:356743
6744 // Since we have proxy, should try to establish tunnel.
lgarrona91df87f2014-12-05 00:51:346745 scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:236746 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]c10b20852013-05-15 21:29:206747 scoped_ptr<SpdyFrame> rst(
6748 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]0c5fb722012-02-28 11:50:356749
6750 // After calling trans->RestartWithAuth(), this is the request we should
6751 // be issuing -- the final header line contains the credentials.
6752 const char* const kAuthCredentials[] = {
6753 "proxy-authorization", "Basic Zm9vOmJhcg==",
6754 };
[email protected]fba2dbde2013-05-24 16:09:016755 scoped_ptr<SpdyFrame> connect2(spdy_util_.ConstructSpdyConnect(
lgarrona91df87f2014-12-05 00:51:346756 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST,
bncce36dca22015-04-21 22:11:236757 HostPortPair("www.example.org", 443)));
6758 // fetch https://www.example.org/ via HTTP
6759 const char get[] =
6760 "GET / HTTP/1.1\r\n"
6761 "Host: www.example.org\r\n"
6762 "Connection: keep-alive\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:196763 scoped_ptr<SpdyFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:026764 spdy_util_.ConstructSpdyBodyFrame(3, get, strlen(get), false));
[email protected]0c5fb722012-02-28 11:50:356765
6766 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:136767 CreateMockWrite(*req, 0, ASYNC),
6768 CreateMockWrite(*rst, 2, ASYNC),
6769 CreateMockWrite(*connect2, 3),
6770 CreateMockWrite(*wrapped_get, 5),
[email protected]0c5fb722012-02-28 11:50:356771 };
6772
6773 // The proxy responds to the connect with a 407, using a persistent
6774 // connection.
thestig9d3bb0c2015-01-24 00:49:516775 const char kAuthStatus[] = "407";
[email protected]0c5fb722012-02-28 11:50:356776 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:356777 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
6778 };
[email protected]745aa9c2014-06-27 02:21:296779 scoped_ptr<SpdyFrame> conn_auth_resp(spdy_util_.ConstructSpdySynReplyError(
6780 kAuthStatus, kAuthChallenge, arraysize(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:356781
[email protected]23e482282013-06-14 16:08:026782 scoped_ptr<SpdyFrame> conn_resp(
6783 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:356784 const char resp[] = "HTTP/1.1 200 OK\r\n"
6785 "Content-Length: 5\r\n\r\n";
6786
[email protected]ff98d7f02012-03-22 21:44:196787 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:026788 spdy_util_.ConstructSpdyBodyFrame(3, resp, strlen(resp), false));
[email protected]ff98d7f02012-03-22 21:44:196789 scoped_ptr<SpdyFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:026790 spdy_util_.ConstructSpdyBodyFrame(3, "hello", 5, false));
[email protected]0c5fb722012-02-28 11:50:356791 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:136792 CreateMockRead(*conn_auth_resp, 1, ASYNC),
6793 CreateMockRead(*conn_resp, 4, ASYNC),
6794 CreateMockRead(*wrapped_get_resp, 6, ASYNC),
6795 CreateMockRead(*wrapped_body, 7, ASYNC),
6796 MockRead(ASYNC, OK, 8), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:356797 };
6798
rch8e6c6c42015-05-01 14:05:136799 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
6800 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:076801 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:356802 // Negotiate SPDY to the proxy
6803 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:026804 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:076805 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:356806 // Vanilla SSL to the server
6807 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076808 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:356809
6810 TestCompletionCallback callback1;
6811
[email protected]262eec82013-03-19 21:01:366812 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506813 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0c5fb722012-02-28 11:50:356814
6815 int rv = trans->Start(&request, callback1.callback(), log.bound());
6816 EXPECT_EQ(ERR_IO_PENDING, rv);
6817
6818 rv = callback1.WaitForResult();
6819 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:466820 TestNetLogEntry::List entries;
[email protected]0c5fb722012-02-28 11:50:356821 log.GetEntries(&entries);
6822 size_t pos = ExpectLogContainsSomewhere(
6823 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
6824 NetLog::PHASE_NONE);
6825 ExpectLogContainsSomewhere(
6826 entries, pos,
6827 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
6828 NetLog::PHASE_NONE);
6829
6830 const HttpResponseInfo* response = trans->GetResponseInfo();
6831 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:506832 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]0c5fb722012-02-28 11:50:356833 EXPECT_EQ(407, response->headers->response_code());
6834 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6835 EXPECT_TRUE(response->auth_challenge.get() != NULL);
6836 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
6837
6838 TestCompletionCallback callback2;
6839
6840 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
6841 callback2.callback());
6842 EXPECT_EQ(ERR_IO_PENDING, rv);
6843
6844 rv = callback2.WaitForResult();
6845 EXPECT_EQ(OK, rv);
6846
6847 response = trans->GetResponseInfo();
6848 ASSERT_TRUE(response != NULL);
6849
6850 EXPECT_TRUE(response->headers->IsKeepAlive());
6851 EXPECT_EQ(200, response->headers->response_code());
6852 EXPECT_EQ(5, response->headers->GetContentLength());
6853 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6854
6855 // The password prompt info should not be set.
6856 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6857
[email protected]029c83b62013-01-24 05:28:206858 LoadTimingInfo load_timing_info;
6859 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6860 TestLoadTimingNotReusedWithPac(load_timing_info,
6861 CONNECT_TIMING_HAS_SSL_TIMES);
6862
[email protected]0c5fb722012-02-28 11:50:356863 trans.reset();
6864 session->CloseAllConnections();
6865}
6866
[email protected]7c6f7ba2012-04-03 04:09:296867// Test that an explicitly trusted SPDY proxy can push a resource from an
6868// origin that is different from that of its associated resource.
[email protected]23e482282013-06-14 16:08:026869TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPush) {
[email protected]7c6f7ba2012-04-03 04:09:296870 HttpRequestInfo request;
6871 HttpRequestInfo push_request;
6872
[email protected]7c6f7ba2012-04-03 04:09:296873 request.method = "GET";
bncce36dca22015-04-21 22:11:236874 request.url = GURL("http://www.example.org/");
[email protected]7c6f7ba2012-04-03 04:09:296875 push_request.method = "GET";
6876 push_request.url = GURL("http://www.another-origin.com/foo.dat");
6877
[email protected]7c6f7ba2012-04-03 04:09:296878 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076879 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206880 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
vishal.b62985ca92015-04-17 08:45:516881 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076882 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:506883
6884 // Enable cross-origin push.
[email protected]bb88e1d32013-05-03 23:11:076885 session_deps_.trusted_spdy_proxy = "myproxy:70";
[email protected]61b4efc2012-04-27 18:12:506886
[email protected]bb88e1d32013-05-03 23:11:076887 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:296888
[email protected]cdf8f7e72013-05-23 10:56:466889 scoped_ptr<SpdyFrame> stream1_syn(
6890 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]7c6f7ba2012-04-03 04:09:296891
6892 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:136893 CreateMockWrite(*stream1_syn, 0, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:296894 };
6895
6896 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026897 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:296898
6899 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026900 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:296901
6902 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026903 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
[email protected]7c6f7ba2012-04-03 04:09:296904 0,
6905 2,
6906 1,
6907 "http://www.another-origin.com/foo.dat"));
[email protected]8a0fc822013-06-27 20:52:436908 const char kPushedData[] = "pushed";
6909 scoped_ptr<SpdyFrame> stream2_body(
6910 spdy_util_.ConstructSpdyBodyFrame(
6911 2, kPushedData, strlen(kPushedData), true));
[email protected]7c6f7ba2012-04-03 04:09:296912
6913 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:136914 CreateMockRead(*stream1_reply, 1, ASYNC),
6915 CreateMockRead(*stream2_syn, 2, ASYNC),
6916 CreateMockRead(*stream1_body, 3, ASYNC),
6917 CreateMockRead(*stream2_body, 4, ASYNC),
6918 MockRead(ASYNC, ERR_IO_PENDING, 5), // Force a pause
[email protected]7c6f7ba2012-04-03 04:09:296919 };
6920
rch8e6c6c42015-05-01 14:05:136921 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
6922 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:076923 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:296924 // Negotiate SPDY to the proxy
6925 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:026926 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:076927 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:296928
[email protected]262eec82013-03-19 21:01:366929 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506930 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7c6f7ba2012-04-03 04:09:296931 TestCompletionCallback callback;
6932 int rv = trans->Start(&request, callback.callback(), log.bound());
6933 EXPECT_EQ(ERR_IO_PENDING, rv);
6934
6935 rv = callback.WaitForResult();
6936 EXPECT_EQ(OK, rv);
6937 const HttpResponseInfo* response = trans->GetResponseInfo();
6938
[email protected]262eec82013-03-19 21:01:366939 scoped_ptr<HttpTransaction> push_trans(
[email protected]90499482013-06-01 00:39:506940 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
6941 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
[email protected]7c6f7ba2012-04-03 04:09:296942 EXPECT_EQ(ERR_IO_PENDING, rv);
6943
6944 rv = callback.WaitForResult();
6945 EXPECT_EQ(OK, rv);
6946 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
6947
6948 ASSERT_TRUE(response != NULL);
6949 EXPECT_TRUE(response->headers->IsKeepAlive());
6950
6951 EXPECT_EQ(200, response->headers->response_code());
6952 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6953
6954 std::string response_data;
6955 rv = ReadTransaction(trans.get(), &response_data);
6956 EXPECT_EQ(OK, rv);
6957 EXPECT_EQ("hello!", response_data);
6958
[email protected]029c83b62013-01-24 05:28:206959 LoadTimingInfo load_timing_info;
6960 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6961 TestLoadTimingNotReusedWithPac(load_timing_info,
6962 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6963
[email protected]7c6f7ba2012-04-03 04:09:296964 // Verify the pushed stream.
[email protected]90499482013-06-01 00:39:506965 EXPECT_TRUE(push_response->headers.get() != NULL);
[email protected]7c6f7ba2012-04-03 04:09:296966 EXPECT_EQ(200, push_response->headers->response_code());
6967
6968 rv = ReadTransaction(push_trans.get(), &response_data);
6969 EXPECT_EQ(OK, rv);
6970 EXPECT_EQ("pushed", response_data);
6971
[email protected]029c83b62013-01-24 05:28:206972 LoadTimingInfo push_load_timing_info;
6973 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
6974 TestLoadTimingReusedWithPac(push_load_timing_info);
6975 // The transactions should share a socket ID, despite being for different
6976 // origins.
6977 EXPECT_EQ(load_timing_info.socket_log_id,
6978 push_load_timing_info.socket_log_id);
6979
[email protected]7c6f7ba2012-04-03 04:09:296980 trans.reset();
6981 push_trans.reset();
6982 session->CloseAllConnections();
6983}
6984
[email protected]8c843192012-04-05 07:15:006985// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
[email protected]23e482282013-06-14 16:08:026986TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
[email protected]8c843192012-04-05 07:15:006987 HttpRequestInfo request;
6988
6989 request.method = "GET";
bncce36dca22015-04-21 22:11:236990 request.url = GURL("http://www.example.org/");
[email protected]8c843192012-04-05 07:15:006991
[email protected]8c843192012-04-05 07:15:006992 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076993 session_deps_.proxy_service.reset(
[email protected]8c843192012-04-05 07:15:006994 ProxyService::CreateFixed("https://myproxy:70"));
vishal.b62985ca92015-04-17 08:45:516995 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076996 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:506997
6998 // Enable cross-origin push.
[email protected]bb88e1d32013-05-03 23:11:076999 session_deps_.trusted_spdy_proxy = "myproxy:70";
[email protected]61b4efc2012-04-27 18:12:507000
[email protected]bb88e1d32013-05-03 23:11:077001 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:007002
[email protected]cdf8f7e72013-05-23 10:56:467003 scoped_ptr<SpdyFrame> stream1_syn(
7004 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]8c843192012-04-05 07:15:007005
7006 scoped_ptr<SpdyFrame> push_rst(
[email protected]c10b20852013-05-15 21:29:207007 spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:007008
7009 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:137010 CreateMockWrite(*stream1_syn, 0, ASYNC), CreateMockWrite(*push_rst, 3),
[email protected]8c843192012-04-05 07:15:007011 };
7012
7013 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:027014 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:007015
7016 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:027017 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8c843192012-04-05 07:15:007018
7019 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:027020 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
[email protected]8c843192012-04-05 07:15:007021 0,
7022 2,
7023 1,
7024 "https://www.another-origin.com/foo.dat"));
7025
7026 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:137027 CreateMockRead(*stream1_reply, 1, ASYNC),
7028 CreateMockRead(*stream2_syn, 2, ASYNC),
7029 CreateMockRead(*stream1_body, 4, ASYNC),
7030 MockRead(ASYNC, ERR_IO_PENDING, 5), // Force a pause
[email protected]8c843192012-04-05 07:15:007031 };
7032
rch8e6c6c42015-05-01 14:05:137033 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
7034 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:077035 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:007036 // Negotiate SPDY to the proxy
7037 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:027038 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:077039 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:007040
[email protected]262eec82013-03-19 21:01:367041 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507042 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c843192012-04-05 07:15:007043 TestCompletionCallback callback;
7044 int rv = trans->Start(&request, callback.callback(), log.bound());
7045 EXPECT_EQ(ERR_IO_PENDING, rv);
7046
7047 rv = callback.WaitForResult();
7048 EXPECT_EQ(OK, rv);
7049 const HttpResponseInfo* response = trans->GetResponseInfo();
7050
7051 ASSERT_TRUE(response != NULL);
7052 EXPECT_TRUE(response->headers->IsKeepAlive());
7053
7054 EXPECT_EQ(200, response->headers->response_code());
7055 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
7056
7057 std::string response_data;
7058 rv = ReadTransaction(trans.get(), &response_data);
7059 EXPECT_EQ(OK, rv);
7060 EXPECT_EQ("hello!", response_data);
7061
7062 trans.reset();
7063 session->CloseAllConnections();
7064}
7065
[email protected]2df19bb2010-08-25 20:13:467066// Test HTTPS connections to a site with a bad certificate, going through an
7067// HTTPS proxy
[email protected]23e482282013-06-14 16:08:027068TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:077069 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:117070 "https://proxy:70"));
[email protected]2df19bb2010-08-25 20:13:467071
7072 HttpRequestInfo request;
7073 request.method = "GET";
bncce36dca22015-04-21 22:11:237074 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:467075 request.load_flags = 0;
7076
7077 // Attempt to fetch the URL from a server with a bad cert
7078 MockWrite bad_cert_writes[] = {
bncce36dca22015-04-21 22:11:237079 MockWrite(
7080 "CONNECT www.example.org:443 HTTP/1.1\r\n"
7081 "Host: www.example.org\r\n"
7082 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:467083 };
7084
7085 MockRead bad_cert_reads[] = {
7086 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067087 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:467088 };
7089
7090 // Attempt to fetch the URL with a good cert
7091 MockWrite good_data_writes[] = {
bncce36dca22015-04-21 22:11:237092 MockWrite(
7093 "CONNECT www.example.org:443 HTTP/1.1\r\n"
7094 "Host: www.example.org\r\n"
7095 "Proxy-Connection: keep-alive\r\n\r\n"),
7096 MockWrite(
7097 "GET / HTTP/1.1\r\n"
7098 "Host: www.example.org\r\n"
7099 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:467100 };
7101
7102 MockRead good_cert_reads[] = {
7103 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
7104 MockRead("HTTP/1.0 200 OK\r\n"),
7105 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7106 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067107 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:467108 };
7109
7110 StaticSocketDataProvider ssl_bad_certificate(
7111 bad_cert_reads, arraysize(bad_cert_reads),
7112 bad_cert_writes, arraysize(bad_cert_writes));
7113 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
7114 good_data_writes, arraysize(good_data_writes));
[email protected]8ddf8322012-02-23 18:08:067115 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
7116 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:467117
7118 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:077119 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7120 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
7121 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:467122
7123 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:077124 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7125 session_deps_.socket_factory->AddSocketDataProvider(&data);
7126 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:467127
[email protected]49639fa2011-12-20 23:22:417128 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:467129
[email protected]3fe8d2f82013-10-17 08:56:077130 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:467131 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417132 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2df19bb2010-08-25 20:13:467133
[email protected]49639fa2011-12-20 23:22:417134 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:467135 EXPECT_EQ(ERR_IO_PENDING, rv);
7136
7137 rv = callback.WaitForResult();
7138 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
7139
[email protected]49639fa2011-12-20 23:22:417140 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]2df19bb2010-08-25 20:13:467141 EXPECT_EQ(ERR_IO_PENDING, rv);
7142
7143 rv = callback.WaitForResult();
7144 EXPECT_EQ(OK, rv);
7145
7146 const HttpResponseInfo* response = trans->GetResponseInfo();
7147
[email protected]fe2255a2011-09-20 19:37:507148 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:467149 EXPECT_EQ(100, response->headers->GetContentLength());
7150}
7151
[email protected]23e482282013-06-14 16:08:027152TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:427153 HttpRequestInfo request;
7154 request.method = "GET";
bncce36dca22015-04-21 22:11:237155 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:437156 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
7157 "Chromium Ultra Awesome X Edition");
[email protected]1c773ea12009-04-28 19:58:427158
[email protected]3fe8d2f82013-10-17 08:56:077159 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277160 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417161 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277162
[email protected]1c773ea12009-04-28 19:58:427163 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237164 MockWrite(
7165 "GET / HTTP/1.1\r\n"
7166 "Host: www.example.org\r\n"
7167 "Connection: keep-alive\r\n"
7168 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427169 };
7170
7171 // Lastly, the server responds with the actual content.
7172 MockRead data_reads[] = {
7173 MockRead("HTTP/1.0 200 OK\r\n"),
7174 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7175 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067176 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427177 };
7178
[email protected]31a2bfe2010-02-09 08:03:397179 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7180 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077181 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427182
[email protected]49639fa2011-12-20 23:22:417183 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427184
[email protected]49639fa2011-12-20 23:22:417185 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427186 EXPECT_EQ(ERR_IO_PENDING, rv);
7187
7188 rv = callback.WaitForResult();
7189 EXPECT_EQ(OK, rv);
7190}
7191
[email protected]23e482282013-06-14 16:08:027192TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:297193 HttpRequestInfo request;
7194 request.method = "GET";
bncce36dca22015-04-21 22:11:237195 request.url = GURL("https://www.example.org/");
[email protected]da81f132010-08-18 23:39:297196 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
7197 "Chromium Ultra Awesome X Edition");
7198
[email protected]bb88e1d32013-05-03 23:11:077199 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]3fe8d2f82013-10-17 08:56:077200 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277201 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417202 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277203
[email protected]da81f132010-08-18 23:39:297204 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237205 MockWrite(
7206 "CONNECT www.example.org:443 HTTP/1.1\r\n"
7207 "Host: www.example.org\r\n"
7208 "Proxy-Connection: keep-alive\r\n"
7209 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]da81f132010-08-18 23:39:297210 };
7211 MockRead data_reads[] = {
7212 // Return an error, so the transaction stops here (this test isn't
7213 // interested in the rest).
7214 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
7215 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7216 MockRead("Proxy-Connection: close\r\n\r\n"),
7217 };
7218
7219 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7220 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077221 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:297222
[email protected]49639fa2011-12-20 23:22:417223 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:297224
[email protected]49639fa2011-12-20 23:22:417225 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]da81f132010-08-18 23:39:297226 EXPECT_EQ(ERR_IO_PENDING, rv);
7227
7228 rv = callback.WaitForResult();
7229 EXPECT_EQ(OK, rv);
7230}
7231
[email protected]23e482282013-06-14 16:08:027232TEST_P(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:427233 HttpRequestInfo request;
7234 request.method = "GET";
bncce36dca22015-04-21 22:11:237235 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427236 request.load_flags = 0;
[email protected]c10450102011-06-27 09:06:167237 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
7238 "http://the.previous.site.com/");
[email protected]1c773ea12009-04-28 19:58:427239
[email protected]3fe8d2f82013-10-17 08:56:077240 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277241 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417242 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277243
[email protected]1c773ea12009-04-28 19:58:427244 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237245 MockWrite(
7246 "GET / HTTP/1.1\r\n"
7247 "Host: www.example.org\r\n"
7248 "Connection: keep-alive\r\n"
7249 "Referer: http://the.previous.site.com/\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427250 };
7251
7252 // Lastly, the server responds with the actual content.
7253 MockRead data_reads[] = {
7254 MockRead("HTTP/1.0 200 OK\r\n"),
7255 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7256 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067257 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427258 };
7259
[email protected]31a2bfe2010-02-09 08:03:397260 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7261 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077262 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427263
[email protected]49639fa2011-12-20 23:22:417264 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427265
[email protected]49639fa2011-12-20 23:22:417266 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427267 EXPECT_EQ(ERR_IO_PENDING, rv);
7268
7269 rv = callback.WaitForResult();
7270 EXPECT_EQ(OK, rv);
7271}
7272
[email protected]23e482282013-06-14 16:08:027273TEST_P(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:427274 HttpRequestInfo request;
7275 request.method = "POST";
bncce36dca22015-04-21 22:11:237276 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427277
[email protected]3fe8d2f82013-10-17 08:56:077278 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277279 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417280 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277281
[email protected]1c773ea12009-04-28 19:58:427282 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237283 MockWrite(
7284 "POST / HTTP/1.1\r\n"
7285 "Host: www.example.org\r\n"
7286 "Connection: keep-alive\r\n"
7287 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427288 };
7289
7290 // Lastly, the server responds with the actual content.
7291 MockRead data_reads[] = {
7292 MockRead("HTTP/1.0 200 OK\r\n"),
7293 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7294 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067295 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427296 };
7297
[email protected]31a2bfe2010-02-09 08:03:397298 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7299 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077300 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427301
[email protected]49639fa2011-12-20 23:22:417302 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427303
[email protected]49639fa2011-12-20 23:22:417304 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427305 EXPECT_EQ(ERR_IO_PENDING, rv);
7306
7307 rv = callback.WaitForResult();
7308 EXPECT_EQ(OK, rv);
7309}
7310
[email protected]23e482282013-06-14 16:08:027311TEST_P(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:427312 HttpRequestInfo request;
7313 request.method = "PUT";
bncce36dca22015-04-21 22:11:237314 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427315
[email protected]3fe8d2f82013-10-17 08:56:077316 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277317 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417318 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277319
[email protected]1c773ea12009-04-28 19:58:427320 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237321 MockWrite(
7322 "PUT / HTTP/1.1\r\n"
7323 "Host: www.example.org\r\n"
7324 "Connection: keep-alive\r\n"
7325 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427326 };
7327
7328 // Lastly, the server responds with the actual content.
7329 MockRead data_reads[] = {
7330 MockRead("HTTP/1.0 200 OK\r\n"),
7331 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7332 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067333 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427334 };
7335
[email protected]31a2bfe2010-02-09 08:03:397336 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7337 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077338 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427339
[email protected]49639fa2011-12-20 23:22:417340 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427341
[email protected]49639fa2011-12-20 23:22:417342 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427343 EXPECT_EQ(ERR_IO_PENDING, rv);
7344
7345 rv = callback.WaitForResult();
7346 EXPECT_EQ(OK, rv);
7347}
7348
[email protected]23e482282013-06-14 16:08:027349TEST_P(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:427350 HttpRequestInfo request;
7351 request.method = "HEAD";
bncce36dca22015-04-21 22:11:237352 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427353
[email protected]3fe8d2f82013-10-17 08:56:077354 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277355 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417356 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277357
[email protected]1c773ea12009-04-28 19:58:427358 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237359 MockWrite(
7360 "HEAD / HTTP/1.1\r\n"
7361 "Host: www.example.org\r\n"
7362 "Connection: keep-alive\r\n"
7363 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427364 };
7365
7366 // Lastly, the server responds with the actual content.
7367 MockRead data_reads[] = {
7368 MockRead("HTTP/1.0 200 OK\r\n"),
7369 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7370 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067371 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427372 };
7373
[email protected]31a2bfe2010-02-09 08:03:397374 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7375 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077376 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427377
[email protected]49639fa2011-12-20 23:22:417378 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427379
[email protected]49639fa2011-12-20 23:22:417380 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427381 EXPECT_EQ(ERR_IO_PENDING, rv);
7382
7383 rv = callback.WaitForResult();
7384 EXPECT_EQ(OK, rv);
7385}
7386
[email protected]23e482282013-06-14 16:08:027387TEST_P(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:427388 HttpRequestInfo request;
7389 request.method = "GET";
bncce36dca22015-04-21 22:11:237390 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427391 request.load_flags = LOAD_BYPASS_CACHE;
7392
[email protected]3fe8d2f82013-10-17 08:56:077393 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277394 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417395 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277396
[email protected]1c773ea12009-04-28 19:58:427397 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237398 MockWrite(
7399 "GET / HTTP/1.1\r\n"
7400 "Host: www.example.org\r\n"
7401 "Connection: keep-alive\r\n"
7402 "Pragma: no-cache\r\n"
7403 "Cache-Control: no-cache\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427404 };
7405
7406 // Lastly, the server responds with the actual content.
7407 MockRead data_reads[] = {
7408 MockRead("HTTP/1.0 200 OK\r\n"),
7409 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7410 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067411 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427412 };
7413
[email protected]31a2bfe2010-02-09 08:03:397414 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7415 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077416 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427417
[email protected]49639fa2011-12-20 23:22:417418 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427419
[email protected]49639fa2011-12-20 23:22:417420 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427421 EXPECT_EQ(ERR_IO_PENDING, rv);
7422
7423 rv = callback.WaitForResult();
7424 EXPECT_EQ(OK, rv);
7425}
7426
[email protected]23e482282013-06-14 16:08:027427TEST_P(HttpNetworkTransactionTest,
[email protected]1c773ea12009-04-28 19:58:427428 BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:427429 HttpRequestInfo request;
7430 request.method = "GET";
bncce36dca22015-04-21 22:11:237431 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427432 request.load_flags = LOAD_VALIDATE_CACHE;
7433
[email protected]3fe8d2f82013-10-17 08:56:077434 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277435 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417436 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277437
[email protected]1c773ea12009-04-28 19:58:427438 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237439 MockWrite(
7440 "GET / HTTP/1.1\r\n"
7441 "Host: www.example.org\r\n"
7442 "Connection: keep-alive\r\n"
7443 "Cache-Control: max-age=0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427444 };
7445
7446 // Lastly, the server responds with the actual content.
7447 MockRead data_reads[] = {
7448 MockRead("HTTP/1.0 200 OK\r\n"),
7449 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7450 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067451 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427452 };
7453
[email protected]31a2bfe2010-02-09 08:03:397454 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7455 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077456 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427457
[email protected]49639fa2011-12-20 23:22:417458 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427459
[email protected]49639fa2011-12-20 23:22:417460 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427461 EXPECT_EQ(ERR_IO_PENDING, rv);
7462
7463 rv = callback.WaitForResult();
7464 EXPECT_EQ(OK, rv);
7465}
7466
[email protected]23e482282013-06-14 16:08:027467TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:427468 HttpRequestInfo request;
7469 request.method = "GET";
bncce36dca22015-04-21 22:11:237470 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:437471 request.extra_headers.SetHeader("FooHeader", "Bar");
[email protected]1c773ea12009-04-28 19:58:427472
[email protected]3fe8d2f82013-10-17 08:56:077473 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277474 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417475 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277476
[email protected]1c773ea12009-04-28 19:58:427477 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237478 MockWrite(
7479 "GET / HTTP/1.1\r\n"
7480 "Host: www.example.org\r\n"
7481 "Connection: keep-alive\r\n"
7482 "FooHeader: Bar\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427483 };
7484
7485 // Lastly, the server responds with the actual content.
7486 MockRead data_reads[] = {
7487 MockRead("HTTP/1.0 200 OK\r\n"),
7488 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7489 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067490 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427491 };
7492
[email protected]31a2bfe2010-02-09 08:03:397493 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7494 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077495 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427496
[email protected]49639fa2011-12-20 23:22:417497 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427498
[email protected]49639fa2011-12-20 23:22:417499 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427500 EXPECT_EQ(ERR_IO_PENDING, rv);
7501
7502 rv = callback.WaitForResult();
7503 EXPECT_EQ(OK, rv);
7504}
7505
[email protected]23e482282013-06-14 16:08:027506TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:477507 HttpRequestInfo request;
7508 request.method = "GET";
bncce36dca22015-04-21 22:11:237509 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:437510 request.extra_headers.SetHeader("referer", "www.foo.com");
7511 request.extra_headers.SetHeader("hEllo", "Kitty");
7512 request.extra_headers.SetHeader("FoO", "bar");
[email protected]270c6412010-03-29 22:02:477513
[email protected]3fe8d2f82013-10-17 08:56:077514 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277515 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417516 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277517
[email protected]270c6412010-03-29 22:02:477518 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237519 MockWrite(
7520 "GET / HTTP/1.1\r\n"
7521 "Host: www.example.org\r\n"
7522 "Connection: keep-alive\r\n"
7523 "referer: www.foo.com\r\n"
7524 "hEllo: Kitty\r\n"
7525 "FoO: bar\r\n\r\n"),
[email protected]270c6412010-03-29 22:02:477526 };
7527
7528 // Lastly, the server responds with the actual content.
7529 MockRead data_reads[] = {
7530 MockRead("HTTP/1.0 200 OK\r\n"),
7531 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7532 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067533 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:477534 };
7535
7536 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7537 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077538 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:477539
[email protected]49639fa2011-12-20 23:22:417540 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:477541
[email protected]49639fa2011-12-20 23:22:417542 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]270c6412010-03-29 22:02:477543 EXPECT_EQ(ERR_IO_PENDING, rv);
7544
7545 rv = callback.WaitForResult();
7546 EXPECT_EQ(OK, rv);
7547}
7548
[email protected]23e482282013-06-14 16:08:027549TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277550 HttpRequestInfo request;
7551 request.method = "GET";
bncce36dca22015-04-21 22:11:237552 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:277553 request.load_flags = 0;
7554
[email protected]bb88e1d32013-05-03 23:11:077555 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207556 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
vishal.b62985ca92015-04-17 08:45:517557 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077558 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:027559
[email protected]3fe8d2f82013-10-17 08:56:077560 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3cd17242009-06-23 02:59:027561 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417562 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3cd17242009-06-23 02:59:027563
[email protected]3cd17242009-06-23 02:59:027564 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
7565 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7566
7567 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237568 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
7569 MockWrite(
7570 "GET / HTTP/1.1\r\n"
7571 "Host: www.example.org\r\n"
7572 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:027573
7574 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:067575 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:027576 MockRead("HTTP/1.0 200 OK\r\n"),
7577 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7578 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067579 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:027580 };
7581
[email protected]31a2bfe2010-02-09 08:03:397582 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7583 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077584 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:027585
[email protected]49639fa2011-12-20 23:22:417586 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:027587
[email protected]49639fa2011-12-20 23:22:417588 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:027589 EXPECT_EQ(ERR_IO_PENDING, rv);
7590
7591 rv = callback.WaitForResult();
7592 EXPECT_EQ(OK, rv);
7593
7594 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507595 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:027596
[email protected]029c83b62013-01-24 05:28:207597 LoadTimingInfo load_timing_info;
7598 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7599 TestLoadTimingNotReusedWithPac(load_timing_info,
7600 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7601
[email protected]3cd17242009-06-23 02:59:027602 std::string response_text;
7603 rv = ReadTransaction(trans.get(), &response_text);
7604 EXPECT_EQ(OK, rv);
7605 EXPECT_EQ("Payload", response_text);
7606}
7607
[email protected]23e482282013-06-14 16:08:027608TEST_P(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277609 HttpRequestInfo request;
7610 request.method = "GET";
bncce36dca22015-04-21 22:11:237611 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:277612 request.load_flags = 0;
7613
[email protected]bb88e1d32013-05-03 23:11:077614 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207615 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
vishal.b62985ca92015-04-17 08:45:517616 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077617 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:027618
[email protected]3fe8d2f82013-10-17 08:56:077619 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3cd17242009-06-23 02:59:027620 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417621 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3cd17242009-06-23 02:59:027622
[email protected]3cd17242009-06-23 02:59:027623 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
7624 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7625
7626 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237627 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
7628 arraysize(write_buffer)),
7629 MockWrite(
7630 "GET / HTTP/1.1\r\n"
7631 "Host: www.example.org\r\n"
7632 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:027633
7634 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:017635 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
7636 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:357637 MockRead("HTTP/1.0 200 OK\r\n"),
7638 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7639 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067640 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:357641 };
7642
[email protected]31a2bfe2010-02-09 08:03:397643 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7644 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077645 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:357646
[email protected]8ddf8322012-02-23 18:08:067647 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077648 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:357649
[email protected]49639fa2011-12-20 23:22:417650 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:357651
[email protected]49639fa2011-12-20 23:22:417652 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:357653 EXPECT_EQ(ERR_IO_PENDING, rv);
7654
7655 rv = callback.WaitForResult();
7656 EXPECT_EQ(OK, rv);
7657
[email protected]029c83b62013-01-24 05:28:207658 LoadTimingInfo load_timing_info;
7659 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7660 TestLoadTimingNotReusedWithPac(load_timing_info,
7661 CONNECT_TIMING_HAS_SSL_TIMES);
7662
[email protected]e0c27be2009-07-15 13:09:357663 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507664 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:357665
7666 std::string response_text;
7667 rv = ReadTransaction(trans.get(), &response_text);
7668 EXPECT_EQ(OK, rv);
7669 EXPECT_EQ("Payload", response_text);
7670}
7671
[email protected]23e482282013-06-14 16:08:027672TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:207673 HttpRequestInfo request;
7674 request.method = "GET";
bncce36dca22015-04-21 22:11:237675 request.url = GURL("http://www.example.org/");
[email protected]029c83b62013-01-24 05:28:207676 request.load_flags = 0;
7677
[email protected]bb88e1d32013-05-03 23:11:077678 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207679 ProxyService::CreateFixed("socks4://myproxy:1080"));
vishal.b62985ca92015-04-17 08:45:517680 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077681 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:207682
[email protected]3fe8d2f82013-10-17 08:56:077683 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:207684 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417685 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:207686
7687 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
7688 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7689
7690 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237691 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
7692 MockWrite(
7693 "GET / HTTP/1.1\r\n"
7694 "Host: www.example.org\r\n"
7695 "Connection: keep-alive\r\n\r\n")};
[email protected]029c83b62013-01-24 05:28:207696
7697 MockRead data_reads[] = {
7698 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
7699 MockRead("HTTP/1.0 200 OK\r\n"),
7700 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7701 MockRead("Payload"),
7702 MockRead(SYNCHRONOUS, OK)
7703 };
7704
7705 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7706 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077707 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:207708
7709 TestCompletionCallback callback;
7710
7711 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7712 EXPECT_EQ(ERR_IO_PENDING, rv);
7713
7714 rv = callback.WaitForResult();
7715 EXPECT_EQ(OK, rv);
7716
7717 const HttpResponseInfo* response = trans->GetResponseInfo();
7718 ASSERT_TRUE(response != NULL);
7719
7720 LoadTimingInfo load_timing_info;
7721 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7722 TestLoadTimingNotReused(load_timing_info,
7723 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7724
7725 std::string response_text;
7726 rv = ReadTransaction(trans.get(), &response_text);
7727 EXPECT_EQ(OK, rv);
7728 EXPECT_EQ("Payload", response_text);
7729}
7730
[email protected]23e482282013-06-14 16:08:027731TEST_P(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277732 HttpRequestInfo request;
7733 request.method = "GET";
bncce36dca22015-04-21 22:11:237734 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:277735 request.load_flags = 0;
7736
[email protected]bb88e1d32013-05-03 23:11:077737 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207738 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
vishal.b62985ca92015-04-17 08:45:517739 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077740 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:357741
[email protected]3fe8d2f82013-10-17 08:56:077742 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e0c27be2009-07-15 13:09:357743 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417744 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]e0c27be2009-07-15 13:09:357745
[email protected]e0c27be2009-07-15 13:09:357746 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
7747 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:377748 const char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:237749 0x05, // Version
7750 0x01, // Command (CONNECT)
7751 0x00, // Reserved.
7752 0x03, // Address type (DOMAINNAME).
7753 0x0F, // Length of domain (15)
7754 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
7755 '.', 'o', 'r', 'g', 0x00, 0x50, // 16-bit port (80)
[email protected]f209dba2009-12-18 00:24:377756 };
[email protected]e0c27be2009-07-15 13:09:357757 const char kSOCKS5OkResponse[] =
7758 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
7759
7760 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237761 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
7762 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
7763 MockWrite(
7764 "GET / HTTP/1.1\r\n"
7765 "Host: www.example.org\r\n"
7766 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:357767
7768 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:017769 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
7770 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:357771 MockRead("HTTP/1.0 200 OK\r\n"),
7772 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7773 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067774 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:357775 };
7776
[email protected]31a2bfe2010-02-09 08:03:397777 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7778 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077779 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:357780
[email protected]49639fa2011-12-20 23:22:417781 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:357782
[email protected]49639fa2011-12-20 23:22:417783 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:357784 EXPECT_EQ(ERR_IO_PENDING, rv);
7785
7786 rv = callback.WaitForResult();
7787 EXPECT_EQ(OK, rv);
7788
7789 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507790 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:357791
[email protected]029c83b62013-01-24 05:28:207792 LoadTimingInfo load_timing_info;
7793 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7794 TestLoadTimingNotReusedWithPac(load_timing_info,
7795 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7796
[email protected]e0c27be2009-07-15 13:09:357797 std::string response_text;
7798 rv = ReadTransaction(trans.get(), &response_text);
7799 EXPECT_EQ(OK, rv);
7800 EXPECT_EQ("Payload", response_text);
7801}
7802
[email protected]23e482282013-06-14 16:08:027803TEST_P(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277804 HttpRequestInfo request;
7805 request.method = "GET";
bncce36dca22015-04-21 22:11:237806 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:277807 request.load_flags = 0;
7808
[email protected]bb88e1d32013-05-03 23:11:077809 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207810 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
vishal.b62985ca92015-04-17 08:45:517811 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077812 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:357813
[email protected]3fe8d2f82013-10-17 08:56:077814 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e0c27be2009-07-15 13:09:357815 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417816 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]e0c27be2009-07-15 13:09:357817
[email protected]e0c27be2009-07-15 13:09:357818 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
7819 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:377820 const unsigned char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:237821 0x05, // Version
7822 0x01, // Command (CONNECT)
7823 0x00, // Reserved.
7824 0x03, // Address type (DOMAINNAME).
7825 0x0F, // Length of domain (15)
7826 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
7827 '.', 'o', 'r', 'g', 0x01, 0xBB, // 16-bit port (443)
[email protected]f209dba2009-12-18 00:24:377828 };
7829
[email protected]e0c27be2009-07-15 13:09:357830 const char kSOCKS5OkResponse[] =
7831 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
7832
7833 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237834 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
7835 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
7836 arraysize(kSOCKS5OkRequest)),
7837 MockWrite(
7838 "GET / HTTP/1.1\r\n"
7839 "Host: www.example.org\r\n"
7840 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:357841
7842 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:017843 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
7844 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:027845 MockRead("HTTP/1.0 200 OK\r\n"),
7846 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7847 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067848 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:027849 };
7850
[email protected]31a2bfe2010-02-09 08:03:397851 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7852 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077853 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:027854
[email protected]8ddf8322012-02-23 18:08:067855 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077856 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:027857
[email protected]49639fa2011-12-20 23:22:417858 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:027859
[email protected]49639fa2011-12-20 23:22:417860 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:027861 EXPECT_EQ(ERR_IO_PENDING, rv);
7862
7863 rv = callback.WaitForResult();
7864 EXPECT_EQ(OK, rv);
7865
7866 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507867 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:027868
[email protected]029c83b62013-01-24 05:28:207869 LoadTimingInfo load_timing_info;
7870 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7871 TestLoadTimingNotReusedWithPac(load_timing_info,
7872 CONNECT_TIMING_HAS_SSL_TIMES);
7873
[email protected]3cd17242009-06-23 02:59:027874 std::string response_text;
7875 rv = ReadTransaction(trans.get(), &response_text);
7876 EXPECT_EQ(OK, rv);
7877 EXPECT_EQ("Payload", response_text);
7878}
7879
[email protected]448d4ca52012-03-04 04:12:237880namespace {
7881
[email protected]04e5be32009-06-26 20:00:317882// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:067883
7884struct GroupNameTest {
7885 std::string proxy_server;
7886 std::string url;
7887 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:187888 bool ssl;
[email protected]2d731a32010-04-29 01:04:067889};
7890
7891scoped_refptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]8a0fc822013-06-27 20:52:437892 NextProto next_proto,
[email protected]bb88e1d32013-05-03 23:11:077893 SpdySessionDependencies* session_deps_) {
7894 scoped_refptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:067895
[email protected]30d4c022013-07-18 22:58:167896 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:537897 session->http_server_properties();
bnccacc0992015-03-20 20:22:227898 AlternativeService alternative_service(
bnc4988e432015-03-31 03:06:257899 AlternateProtocolFromNextProto(next_proto), "", 443);
bnccacc0992015-03-20 20:22:227900 http_server_properties->SetAlternativeService(
7901 HostPortPair("host.with.alternate", 80), alternative_service, 1.0);
[email protected]2d731a32010-04-29 01:04:067902
7903 return session;
7904}
7905
7906int GroupNameTransactionHelper(
7907 const std::string& url,
7908 const scoped_refptr<HttpNetworkSession>& session) {
[email protected]2d731a32010-04-29 01:04:067909 HttpRequestInfo request;
7910 request.method = "GET";
7911 request.url = GURL(url);
7912 request.load_flags = 0;
7913
[email protected]262eec82013-03-19 21:01:367914 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507915 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277916
[email protected]49639fa2011-12-20 23:22:417917 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:067918
7919 // We do not complete this request, the dtor will clean the transaction up.
[email protected]49639fa2011-12-20 23:22:417920 return trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d731a32010-04-29 01:04:067921}
7922
[email protected]448d4ca52012-03-04 04:12:237923} // namespace
7924
[email protected]23e482282013-06-14 16:08:027925TEST_P(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:067926 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:237927 {
7928 "", // unused
7929 "http://www.example.org/direct",
7930 "www.example.org:80",
7931 false,
7932 },
7933 {
7934 "", // unused
7935 "http://[2001:1418:13:1::25]/direct",
7936 "[2001:1418:13:1::25]:80",
7937 false,
7938 },
[email protected]04e5be32009-06-26 20:00:317939
bncce36dca22015-04-21 22:11:237940 // SSL Tests
7941 {
7942 "", // unused
7943 "https://www.example.org/direct_ssl",
7944 "ssl/www.example.org:443",
7945 true,
7946 },
7947 {
7948 "", // unused
7949 "https://[2001:1418:13:1::25]/direct",
7950 "ssl/[2001:1418:13:1::25]:443",
7951 true,
7952 },
7953 {
7954 "", // unused
7955 "http://host.with.alternate/direct",
7956 "ssl/host.with.alternate:443",
7957 true,
7958 },
[email protected]2d731a32010-04-29 01:04:067959 };
[email protected]2ff8b312010-04-26 22:20:547960
[email protected]d7599122014-05-24 03:37:237961 session_deps_.use_alternate_protocols = true;
[email protected]2d731a32010-04-29 01:04:067962
viettrungluue4a8b882014-10-16 06:17:387963 for (size_t i = 0; i < arraysize(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:077964 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:027965 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:067966 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:437967 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:067968
7969 HttpNetworkSessionPeer peer(session);
[email protected]ab739042011-04-07 15:22:287970 CaptureGroupNameTransportSocketPool* transport_conn_pool =
7971 new CaptureGroupNameTransportSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:137972 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347973 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]831e4a32013-11-14 02:14:447974 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
7975 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:027976 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
7977 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
dchenge3d1ddc2014-10-15 19:30:517978 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]2d731a32010-04-29 01:04:067979
7980 EXPECT_EQ(ERR_IO_PENDING,
7981 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:187982 if (tests[i].ssl)
7983 EXPECT_EQ(tests[i].expected_group_name,
7984 ssl_conn_pool->last_group_name_received());
7985 else
7986 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:287987 transport_conn_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:067988 }
7989
[email protected]2d731a32010-04-29 01:04:067990}
7991
[email protected]23e482282013-06-14 16:08:027992TEST_P(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:067993 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:237994 {
7995 "http_proxy",
7996 "http://www.example.org/http_proxy_normal",
7997 "www.example.org:80",
7998 false,
7999 },
[email protected]2d731a32010-04-29 01:04:068000
bncce36dca22015-04-21 22:11:238001 // SSL Tests
8002 {
8003 "http_proxy",
8004 "https://www.example.org/http_connect_ssl",
8005 "ssl/www.example.org:443",
8006 true,
8007 },
[email protected]af3490e2010-10-16 21:02:298008
bncce36dca22015-04-21 22:11:238009 {
8010 "http_proxy",
8011 "http://host.with.alternate/direct",
8012 "ssl/host.with.alternate:443",
8013 true,
8014 },
[email protected]45499252013-01-23 17:12:568015
bncce36dca22015-04-21 22:11:238016 {
8017 "http_proxy",
8018 "ftp://ftp.google.com/http_proxy_normal",
8019 "ftp/ftp.google.com:21",
8020 false,
8021 },
[email protected]2d731a32010-04-29 01:04:068022 };
8023
[email protected]d7599122014-05-24 03:37:238024 session_deps_.use_alternate_protocols = true;
[email protected]2d731a32010-04-29 01:04:068025
viettrungluue4a8b882014-10-16 06:17:388026 for (size_t i = 0; i < arraysize(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:078027 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:028028 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:068029 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:438030 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:068031
8032 HttpNetworkSessionPeer peer(session);
8033
[email protected]e60e47a2010-07-14 03:37:188034 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:138035 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:348036 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:138037 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:348038 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:028039
[email protected]831e4a32013-11-14 02:14:448040 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
8041 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:028042 mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool);
8043 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
dchenge3d1ddc2014-10-15 19:30:518044 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]2d731a32010-04-29 01:04:068045
8046 EXPECT_EQ(ERR_IO_PENDING,
8047 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:188048 if (tests[i].ssl)
8049 EXPECT_EQ(tests[i].expected_group_name,
8050 ssl_conn_pool->last_group_name_received());
8051 else
8052 EXPECT_EQ(tests[i].expected_group_name,
8053 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:068054 }
[email protected]2d731a32010-04-29 01:04:068055}
8056
[email protected]23e482282013-06-14 16:08:028057TEST_P(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:068058 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:238059 {
8060 "socks4://socks_proxy:1080",
8061 "http://www.example.org/socks4_direct",
8062 "socks4/www.example.org:80",
8063 false,
8064 },
8065 {
8066 "socks5://socks_proxy:1080",
8067 "http://www.example.org/socks5_direct",
8068 "socks5/www.example.org:80",
8069 false,
8070 },
[email protected]2d731a32010-04-29 01:04:068071
bncce36dca22015-04-21 22:11:238072 // SSL Tests
8073 {
8074 "socks4://socks_proxy:1080",
8075 "https://www.example.org/socks4_ssl",
8076 "socks4/ssl/www.example.org:443",
8077 true,
8078 },
8079 {
8080 "socks5://socks_proxy:1080",
8081 "https://www.example.org/socks5_ssl",
8082 "socks5/ssl/www.example.org:443",
8083 true,
8084 },
[email protected]af3490e2010-10-16 21:02:298085
bncce36dca22015-04-21 22:11:238086 {
8087 "socks4://socks_proxy:1080",
8088 "http://host.with.alternate/direct",
8089 "socks4/ssl/host.with.alternate:443",
8090 true,
8091 },
[email protected]04e5be32009-06-26 20:00:318092 };
8093
[email protected]d7599122014-05-24 03:37:238094 session_deps_.use_alternate_protocols = true;
[email protected]2ff8b312010-04-26 22:20:548095
viettrungluue4a8b882014-10-16 06:17:388096 for (size_t i = 0; i < arraysize(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:078097 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:028098 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:068099 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:438100 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]8b114dd72011-03-25 05:33:028101
[email protected]2d731a32010-04-29 01:04:068102 HttpNetworkSessionPeer peer(session);
[email protected]04e5be32009-06-26 20:00:318103
[email protected]e60e47a2010-07-14 03:37:188104 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:138105 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:348106 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:138107 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:348108 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:028109
[email protected]831e4a32013-11-14 02:14:448110 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
8111 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:028112 mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_conn_pool);
8113 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
dchenge3d1ddc2014-10-15 19:30:518114 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]04e5be32009-06-26 20:00:318115
[email protected]262eec82013-03-19 21:01:368116 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508117 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]04e5be32009-06-26 20:00:318118
[email protected]2d731a32010-04-29 01:04:068119 EXPECT_EQ(ERR_IO_PENDING,
8120 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:188121 if (tests[i].ssl)
8122 EXPECT_EQ(tests[i].expected_group_name,
8123 ssl_conn_pool->last_group_name_received());
8124 else
8125 EXPECT_EQ(tests[i].expected_group_name,
8126 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:318127 }
8128}
8129
[email protected]23e482282013-06-14 16:08:028130TEST_P(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:278131 HttpRequestInfo request;
8132 request.method = "GET";
bncce36dca22015-04-21 22:11:238133 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278134
[email protected]bb88e1d32013-05-03 23:11:078135 session_deps_.proxy_service.reset(
[email protected]81cdfcd2010-10-16 00:49:008136 ProxyService::CreateFixed("myproxy:70;foobar:80"));
[email protected]b59ff372009-07-15 22:04:328137
[email protected]69719062010-01-05 20:09:218138 // This simulates failure resolving all hostnames; that means we will fail
8139 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:078140 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:328141
[email protected]3fe8d2f82013-10-17 08:56:078142 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]9172a982009-06-06 00:30:258143 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418144 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]9172a982009-06-06 00:30:258145
[email protected]49639fa2011-12-20 23:22:418146 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:258147
[email protected]49639fa2011-12-20 23:22:418148 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9172a982009-06-06 00:30:258149 EXPECT_EQ(ERR_IO_PENDING, rv);
8150
[email protected]9172a982009-06-06 00:30:258151 rv = callback.WaitForResult();
[email protected]f7fccee2010-09-16 20:53:018152 EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
[email protected]9172a982009-06-06 00:30:258153}
8154
[email protected]685af592010-05-11 19:31:248155// Base test to make sure that when the load flags for a request specify to
8156// bypass the cache, the DNS cache is not used.
[email protected]23e482282013-06-14 16:08:028157void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
[email protected]bb88e1d32013-05-03 23:11:078158 int load_flags) {
[email protected]cb9bf6ca2011-01-28 13:15:278159 // Issue a request, asking to bypass the cache(s).
8160 HttpRequestInfo request;
8161 request.method = "GET";
8162 request.load_flags = load_flags;
bncce36dca22015-04-21 22:11:238163 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278164
[email protected]a2c2fb92009-07-18 07:31:048165 // Select a host resolver that does caching.
[email protected]bb88e1d32013-05-03 23:11:078166 session_deps_.host_resolver.reset(new MockCachingHostResolver);
[email protected]b59ff372009-07-15 22:04:328167
[email protected]3fe8d2f82013-10-17 08:56:078168 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8169 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418170 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3b9cca42009-06-16 01:08:288171
bncce36dca22015-04-21 22:11:238172 // Warm up the host cache so it has an entry for "www.example.org".
[email protected]3b9cca42009-06-16 01:08:288173 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:298174 TestCompletionCallback callback;
[email protected]bb88e1d32013-05-03 23:11:078175 int rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:238176 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
8177 DEFAULT_PRIORITY, &addrlist, callback.callback(), NULL, BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:478178 EXPECT_EQ(ERR_IO_PENDING, rv);
8179 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:288180 EXPECT_EQ(OK, rv);
8181
8182 // Verify that it was added to host cache, by doing a subsequent async lookup
8183 // and confirming it completes synchronously.
[email protected]bb88e1d32013-05-03 23:11:078184 rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:238185 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
8186 DEFAULT_PRIORITY, &addrlist, callback.callback(), NULL, BoundNetLog());
[email protected]b59ff372009-07-15 22:04:328187 ASSERT_EQ(OK, rv);
[email protected]3b9cca42009-06-16 01:08:288188
bncce36dca22015-04-21 22:11:238189 // Inject a failure the next time that "www.example.org" is resolved. This way
[email protected]3b9cca42009-06-16 01:08:288190 // we can tell if the next lookup hit the cache, or the "network".
8191 // (cache --> success, "network" --> failure).
bncce36dca22015-04-21 22:11:238192 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.example.org");
[email protected]3b9cca42009-06-16 01:08:288193
8194 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
8195 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:068196 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
[email protected]31a2bfe2010-02-09 08:03:398197 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078198 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:288199
[email protected]3b9cca42009-06-16 01:08:288200 // Run the request.
[email protected]49639fa2011-12-20 23:22:418201 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3b9cca42009-06-16 01:08:288202 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:418203 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:288204
8205 // If we bypassed the cache, we would have gotten a failure while resolving
bncce36dca22015-04-21 22:11:238206 // "www.example.org".
[email protected]3b9cca42009-06-16 01:08:288207 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
8208}
8209
[email protected]685af592010-05-11 19:31:248210// There are multiple load flags that should trigger the host cache bypass.
8211// Test each in isolation:
[email protected]23e482282013-06-14 16:08:028212TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
[email protected]685af592010-05-11 19:31:248213 BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
8214}
8215
[email protected]23e482282013-06-14 16:08:028216TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
[email protected]685af592010-05-11 19:31:248217 BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
8218}
8219
[email protected]23e482282013-06-14 16:08:028220TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
[email protected]685af592010-05-11 19:31:248221 BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
8222}
8223
[email protected]0877e3d2009-10-17 22:29:578224// Make sure we can handle an error when writing the request.
[email protected]23e482282013-06-14 16:08:028225TEST_P(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:578226 HttpRequestInfo request;
8227 request.method = "GET";
8228 request.url = GURL("http://www.foo.com/");
8229 request.load_flags = 0;
8230
8231 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:068232 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:578233 };
[email protected]31a2bfe2010-02-09 08:03:398234 StaticSocketDataProvider data(NULL, 0,
8235 write_failure, arraysize(write_failure));
[email protected]bb88e1d32013-05-03 23:11:078236 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3fe8d2f82013-10-17 08:56:078237 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578238
[email protected]49639fa2011-12-20 23:22:418239 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:578240
8241 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418242 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:578243
[email protected]49639fa2011-12-20 23:22:418244 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578245 EXPECT_EQ(ERR_IO_PENDING, rv);
8246
8247 rv = callback.WaitForResult();
8248 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
8249}
8250
8251// Check that a connection closed after the start of the headers finishes ok.
[email protected]23e482282013-06-14 16:08:028252TEST_P(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:578253 HttpRequestInfo request;
8254 request.method = "GET";
8255 request.url = GURL("http://www.foo.com/");
8256 request.load_flags = 0;
8257
8258 MockRead data_reads[] = {
8259 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:068260 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:578261 };
8262
[email protected]31a2bfe2010-02-09 08:03:398263 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078264 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3fe8d2f82013-10-17 08:56:078265 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578266
[email protected]49639fa2011-12-20 23:22:418267 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:578268
8269 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418270 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:578271
[email protected]49639fa2011-12-20 23:22:418272 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578273 EXPECT_EQ(ERR_IO_PENDING, rv);
8274
8275 rv = callback.WaitForResult();
8276 EXPECT_EQ(OK, rv);
8277
8278 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508279 ASSERT_TRUE(response != NULL);
[email protected]0877e3d2009-10-17 22:29:578280
[email protected]90499482013-06-01 00:39:508281 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]0877e3d2009-10-17 22:29:578282 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
8283
8284 std::string response_data;
8285 rv = ReadTransaction(trans.get(), &response_data);
8286 EXPECT_EQ(OK, rv);
8287 EXPECT_EQ("", response_data);
8288}
8289
8290// Make sure that a dropped connection while draining the body for auth
8291// restart does the right thing.
[email protected]23e482282013-06-14 16:08:028292TEST_P(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:578293 HttpRequestInfo request;
8294 request.method = "GET";
bncce36dca22015-04-21 22:11:238295 request.url = GURL("http://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:578296 request.load_flags = 0;
8297
8298 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238299 MockWrite(
8300 "GET / HTTP/1.1\r\n"
8301 "Host: www.example.org\r\n"
8302 "Connection: keep-alive\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:578303 };
8304
8305 MockRead data_reads1[] = {
8306 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
8307 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8308 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8309 MockRead("Content-Length: 14\r\n\r\n"),
8310 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:068311 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:578312 };
8313
[email protected]31a2bfe2010-02-09 08:03:398314 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8315 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:078316 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:578317
8318 // After calling trans->RestartWithAuth(), this is the request we should
8319 // be issuing -- the final header line contains the credentials.
8320 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238321 MockWrite(
8322 "GET / HTTP/1.1\r\n"
8323 "Host: www.example.org\r\n"
8324 "Connection: keep-alive\r\n"
8325 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:578326 };
8327
8328 // Lastly, the server responds with the actual content.
8329 MockRead data_reads2[] = {
8330 MockRead("HTTP/1.1 200 OK\r\n"),
8331 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8332 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068333 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:578334 };
8335
[email protected]31a2bfe2010-02-09 08:03:398336 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8337 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:078338 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3fe8d2f82013-10-17 08:56:078339 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578340
[email protected]49639fa2011-12-20 23:22:418341 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:578342
[email protected]262eec82013-03-19 21:01:368343 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508344 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:508345
[email protected]49639fa2011-12-20 23:22:418346 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578347 EXPECT_EQ(ERR_IO_PENDING, rv);
8348
8349 rv = callback1.WaitForResult();
8350 EXPECT_EQ(OK, rv);
8351
8352 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508353 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048354 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:578355
[email protected]49639fa2011-12-20 23:22:418356 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:578357
[email protected]49639fa2011-12-20 23:22:418358 rv = trans->RestartWithAuth(
8359 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]0877e3d2009-10-17 22:29:578360 EXPECT_EQ(ERR_IO_PENDING, rv);
8361
8362 rv = callback2.WaitForResult();
8363 EXPECT_EQ(OK, rv);
8364
8365 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508366 ASSERT_TRUE(response != NULL);
[email protected]0877e3d2009-10-17 22:29:578367 EXPECT_TRUE(response->auth_challenge.get() == NULL);
8368 EXPECT_EQ(100, response->headers->GetContentLength());
8369}
8370
8371// Test HTTPS connections going through a proxy that sends extra data.
[email protected]23e482282013-06-14 16:08:028372TEST_P(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
[email protected]bb88e1d32013-05-03 23:11:078373 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]0877e3d2009-10-17 22:29:578374
8375 HttpRequestInfo request;
8376 request.method = "GET";
bncce36dca22015-04-21 22:11:238377 request.url = GURL("https://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:578378 request.load_flags = 0;
8379
8380 MockRead proxy_reads[] = {
8381 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:068382 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:578383 };
8384
[email protected]31a2bfe2010-02-09 08:03:398385 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
[email protected]8ddf8322012-02-23 18:08:068386 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:578387
[email protected]bb88e1d32013-05-03 23:11:078388 session_deps_.socket_factory->AddSocketDataProvider(&data);
8389 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:578390
[email protected]49639fa2011-12-20 23:22:418391 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:578392
[email protected]bb88e1d32013-05-03 23:11:078393 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:578394
[email protected]3fe8d2f82013-10-17 08:56:078395 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578396 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418397 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:578398
[email protected]49639fa2011-12-20 23:22:418399 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578400 EXPECT_EQ(ERR_IO_PENDING, rv);
8401
8402 rv = callback.WaitForResult();
8403 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
8404}
8405
[email protected]23e482282013-06-14 16:08:028406TEST_P(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:468407 HttpRequestInfo request;
8408 request.method = "GET";
bncce36dca22015-04-21 22:11:238409 request.url = GURL("http://www.example.org/");
[email protected]9492e4a2010-02-24 00:58:468410 request.load_flags = 0;
8411
[email protected]3fe8d2f82013-10-17 08:56:078412 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:278413 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418414 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278415
[email protected]e22e1362009-11-23 21:31:128416 MockRead data_reads[] = {
8417 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068418 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:128419 };
[email protected]9492e4a2010-02-24 00:58:468420
8421 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078422 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:468423
[email protected]49639fa2011-12-20 23:22:418424 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:468425
[email protected]49639fa2011-12-20 23:22:418426 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9492e4a2010-02-24 00:58:468427 EXPECT_EQ(ERR_IO_PENDING, rv);
8428
8429 EXPECT_EQ(OK, callback.WaitForResult());
8430
8431 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508432 ASSERT_TRUE(response != NULL);
[email protected]9492e4a2010-02-24 00:58:468433
[email protected]90499482013-06-01 00:39:508434 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]9492e4a2010-02-24 00:58:468435 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
8436
8437 std::string response_data;
8438 rv = ReadTransaction(trans.get(), &response_data);
[email protected]5543cbb2012-04-20 16:35:238439 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
[email protected]e22e1362009-11-23 21:31:128440}
8441
[email protected]23e482282013-06-14 16:08:028442TEST_P(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:158443 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:528444 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
[email protected]95d88ffe2010-02-04 21:25:338445 const uint64 kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:218446 UploadFileElementReader::ScopedOverridingContentLengthForTests
8447 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:338448
[email protected]b2d26cfd2012-12-11 10:36:068449 ScopedVector<UploadElementReader> element_readers;
8450 element_readers.push_back(
[email protected]cadac622013-06-11 16:46:368451 new UploadFileElementReader(base::MessageLoopProxy::current().get(),
8452 temp_file_path,
8453 0,
8454 kuint64max,
8455 base::Time()));
mmenkecbc2b712014-10-09 20:29:078456 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:278457
8458 HttpRequestInfo request;
8459 request.method = "POST";
bncce36dca22015-04-21 22:11:238460 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:278461 request.upload_data_stream = &upload_data_stream;
8462 request.load_flags = 0;
8463
[email protected]3fe8d2f82013-10-17 08:56:078464 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]329b68b2012-11-14 17:54:278465 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418466 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]95d88ffe2010-02-04 21:25:338467
8468 MockRead data_reads[] = {
8469 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
8470 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068471 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:338472 };
[email protected]31a2bfe2010-02-09 08:03:398473 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078474 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:338475
[email protected]49639fa2011-12-20 23:22:418476 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:338477
[email protected]49639fa2011-12-20 23:22:418478 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]95d88ffe2010-02-04 21:25:338479 EXPECT_EQ(ERR_IO_PENDING, rv);
8480
8481 rv = callback.WaitForResult();
8482 EXPECT_EQ(OK, rv);
8483
8484 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508485 ASSERT_TRUE(response != NULL);
[email protected]95d88ffe2010-02-04 21:25:338486
[email protected]90499482013-06-01 00:39:508487 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]95d88ffe2010-02-04 21:25:338488 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
8489
8490 std::string response_data;
8491 rv = ReadTransaction(trans.get(), &response_data);
8492 EXPECT_EQ(OK, rv);
8493 EXPECT_EQ("hello world", response_data);
8494
[email protected]dd3aa792013-07-16 19:10:238495 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:338496}
8497
[email protected]23e482282013-06-14 16:08:028498TEST_P(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:158499 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:528500 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:368501 std::string temp_file_content("Unreadable file.");
[email protected]e5c2a22e2014-03-06 20:42:308502 ASSERT_TRUE(base::WriteFile(temp_file, temp_file_content.c_str(),
[email protected]6624b4622010-03-29 19:58:368503 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:118504 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:368505
[email protected]b2d26cfd2012-12-11 10:36:068506 ScopedVector<UploadElementReader> element_readers;
8507 element_readers.push_back(
[email protected]cadac622013-06-11 16:46:368508 new UploadFileElementReader(base::MessageLoopProxy::current().get(),
8509 temp_file,
8510 0,
8511 kuint64max,
8512 base::Time()));
mmenkecbc2b712014-10-09 20:29:078513 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:278514
8515 HttpRequestInfo request;
8516 request.method = "POST";
bncce36dca22015-04-21 22:11:238517 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:278518 request.upload_data_stream = &upload_data_stream;
8519 request.load_flags = 0;
8520
[email protected]999dd8c2013-11-12 06:45:548521 // If we try to upload an unreadable file, the transaction should fail.
[email protected]3fe8d2f82013-10-17 08:56:078522 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]329b68b2012-11-14 17:54:278523 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418524 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]6624b4622010-03-29 19:58:368525
[email protected]999dd8c2013-11-12 06:45:548526 StaticSocketDataProvider data(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078527 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:368528
[email protected]49639fa2011-12-20 23:22:418529 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:368530
[email protected]49639fa2011-12-20 23:22:418531 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]6624b4622010-03-29 19:58:368532 EXPECT_EQ(ERR_IO_PENDING, rv);
8533
8534 rv = callback.WaitForResult();
[email protected]999dd8c2013-11-12 06:45:548535 EXPECT_EQ(ERR_ACCESS_DENIED, rv);
[email protected]6624b4622010-03-29 19:58:368536
8537 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]999dd8c2013-11-12 06:45:548538 EXPECT_FALSE(response);
[email protected]6624b4622010-03-29 19:58:368539
[email protected]dd3aa792013-07-16 19:10:238540 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:368541}
8542
[email protected]02cad5d2013-10-02 08:14:038543TEST_P(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
8544 class FakeUploadElementReader : public UploadElementReader {
8545 public:
8546 FakeUploadElementReader() {}
dchengb03027d2014-10-21 12:00:208547 ~FakeUploadElementReader() override {}
[email protected]02cad5d2013-10-02 08:14:038548
8549 const CompletionCallback& callback() const { return callback_; }
8550
8551 // UploadElementReader overrides:
dchengb03027d2014-10-21 12:00:208552 int Init(const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:038553 callback_ = callback;
8554 return ERR_IO_PENDING;
8555 }
dchengb03027d2014-10-21 12:00:208556 uint64 GetContentLength() const override { return 0; }
8557 uint64 BytesRemaining() const override { return 0; }
8558 int Read(IOBuffer* buf,
8559 int buf_length,
8560 const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:038561 return ERR_FAILED;
8562 }
8563
8564 private:
8565 CompletionCallback callback_;
8566 };
8567
8568 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
8569 ScopedVector<UploadElementReader> element_readers;
8570 element_readers.push_back(fake_reader);
mmenkecbc2b712014-10-09 20:29:078571 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02cad5d2013-10-02 08:14:038572
8573 HttpRequestInfo request;
8574 request.method = "POST";
bncce36dca22015-04-21 22:11:238575 request.url = GURL("http://www.example.org/upload");
[email protected]02cad5d2013-10-02 08:14:038576 request.upload_data_stream = &upload_data_stream;
8577 request.load_flags = 0;
8578
[email protected]3fe8d2f82013-10-17 08:56:078579 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02cad5d2013-10-02 08:14:038580 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418581 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02cad5d2013-10-02 08:14:038582
8583 StaticSocketDataProvider data;
8584 session_deps_.socket_factory->AddSocketDataProvider(&data);
8585
8586 TestCompletionCallback callback;
8587 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8588 EXPECT_EQ(ERR_IO_PENDING, rv);
8589 base::MessageLoop::current()->RunUntilIdle();
8590
8591 // Transaction is pending on request body initialization.
8592 ASSERT_FALSE(fake_reader->callback().is_null());
8593
8594 // Return Init()'s result after the transaction gets destroyed.
8595 trans.reset();
8596 fake_reader->callback().Run(OK); // Should not crash.
8597}
8598
[email protected]aeefc9e82010-02-19 16:18:278599// Tests that changes to Auth realms are treated like auth rejections.
[email protected]23e482282013-06-14 16:08:028600TEST_P(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:278601
8602 HttpRequestInfo request;
8603 request.method = "GET";
bncce36dca22015-04-21 22:11:238604 request.url = GURL("http://www.example.org/");
[email protected]aeefc9e82010-02-19 16:18:278605 request.load_flags = 0;
8606
8607 // First transaction will request a resource and receive a Basic challenge
8608 // with realm="first_realm".
8609 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238610 MockWrite(
8611 "GET / HTTP/1.1\r\n"
8612 "Host: www.example.org\r\n"
8613 "Connection: keep-alive\r\n"
8614 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:278615 };
8616 MockRead data_reads1[] = {
8617 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8618 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
8619 "\r\n"),
8620 };
8621
8622 // After calling trans->RestartWithAuth(), provide an Authentication header
8623 // for first_realm. The server will reject and provide a challenge with
8624 // second_realm.
8625 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238626 MockWrite(
8627 "GET / HTTP/1.1\r\n"
8628 "Host: www.example.org\r\n"
8629 "Connection: keep-alive\r\n"
8630 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
8631 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:278632 };
8633 MockRead data_reads2[] = {
8634 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8635 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
8636 "\r\n"),
8637 };
8638
8639 // This again fails, and goes back to first_realm. Make sure that the
8640 // entry is removed from cache.
8641 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:238642 MockWrite(
8643 "GET / HTTP/1.1\r\n"
8644 "Host: www.example.org\r\n"
8645 "Connection: keep-alive\r\n"
8646 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
8647 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:278648 };
8649 MockRead data_reads3[] = {
8650 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8651 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
8652 "\r\n"),
8653 };
8654
8655 // Try one last time (with the correct password) and get the resource.
8656 MockWrite data_writes4[] = {
bncce36dca22015-04-21 22:11:238657 MockWrite(
8658 "GET / HTTP/1.1\r\n"
8659 "Host: www.example.org\r\n"
8660 "Connection: keep-alive\r\n"
8661 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
8662 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:278663 };
8664 MockRead data_reads4[] = {
8665 MockRead("HTTP/1.1 200 OK\r\n"
8666 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:508667 "Content-Length: 5\r\n"
8668 "\r\n"
8669 "hello"),
[email protected]aeefc9e82010-02-19 16:18:278670 };
8671
8672 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8673 data_writes1, arraysize(data_writes1));
8674 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8675 data_writes2, arraysize(data_writes2));
8676 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
8677 data_writes3, arraysize(data_writes3));
8678 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
8679 data_writes4, arraysize(data_writes4));
[email protected]bb88e1d32013-05-03 23:11:078680 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8681 session_deps_.socket_factory->AddSocketDataProvider(&data2);
8682 session_deps_.socket_factory->AddSocketDataProvider(&data3);
8683 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:278684
[email protected]49639fa2011-12-20 23:22:418685 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:278686
[email protected]3fe8d2f82013-10-17 08:56:078687 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0b0bf032010-09-21 18:08:508688 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418689 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:508690
[email protected]aeefc9e82010-02-19 16:18:278691 // Issue the first request with Authorize headers. There should be a
8692 // password prompt for first_realm waiting to be filled in after the
8693 // transaction completes.
[email protected]49639fa2011-12-20 23:22:418694 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]aeefc9e82010-02-19 16:18:278695 EXPECT_EQ(ERR_IO_PENDING, rv);
8696 rv = callback1.WaitForResult();
8697 EXPECT_EQ(OK, rv);
8698 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508699 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048700 const AuthChallengeInfo* challenge = response->auth_challenge.get();
8701 ASSERT_FALSE(challenge == NULL);
8702 EXPECT_FALSE(challenge->is_proxy);
bncce36dca22015-04-21 22:11:238703 EXPECT_EQ("www.example.org:80", challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:048704 EXPECT_EQ("first_realm", challenge->realm);
8705 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278706
8707 // Issue the second request with an incorrect password. There should be a
8708 // password prompt for second_realm waiting to be filled in after the
8709 // transaction completes.
[email protected]49639fa2011-12-20 23:22:418710 TestCompletionCallback callback2;
8711 rv = trans->RestartWithAuth(
8712 AuthCredentials(kFirst, kBaz), callback2.callback());
[email protected]aeefc9e82010-02-19 16:18:278713 EXPECT_EQ(ERR_IO_PENDING, rv);
8714 rv = callback2.WaitForResult();
8715 EXPECT_EQ(OK, rv);
8716 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508717 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048718 challenge = response->auth_challenge.get();
8719 ASSERT_FALSE(challenge == NULL);
8720 EXPECT_FALSE(challenge->is_proxy);
bncce36dca22015-04-21 22:11:238721 EXPECT_EQ("www.example.org:80", challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:048722 EXPECT_EQ("second_realm", challenge->realm);
8723 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278724
8725 // Issue the third request with another incorrect password. There should be
8726 // a password prompt for first_realm waiting to be filled in. If the password
8727 // prompt is not present, it indicates that the HttpAuthCacheEntry for
8728 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:418729 TestCompletionCallback callback3;
8730 rv = trans->RestartWithAuth(
8731 AuthCredentials(kSecond, kFou), callback3.callback());
[email protected]aeefc9e82010-02-19 16:18:278732 EXPECT_EQ(ERR_IO_PENDING, rv);
8733 rv = callback3.WaitForResult();
8734 EXPECT_EQ(OK, rv);
8735 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508736 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048737 challenge = response->auth_challenge.get();
8738 ASSERT_FALSE(challenge == NULL);
8739 EXPECT_FALSE(challenge->is_proxy);
bncce36dca22015-04-21 22:11:238740 EXPECT_EQ("www.example.org:80", challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:048741 EXPECT_EQ("first_realm", challenge->realm);
8742 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278743
8744 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:418745 TestCompletionCallback callback4;
8746 rv = trans->RestartWithAuth(
8747 AuthCredentials(kFirst, kBar), callback4.callback());
[email protected]aeefc9e82010-02-19 16:18:278748 EXPECT_EQ(ERR_IO_PENDING, rv);
8749 rv = callback4.WaitForResult();
8750 EXPECT_EQ(OK, rv);
8751 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508752 ASSERT_TRUE(response != NULL);
[email protected]aeefc9e82010-02-19 16:18:278753 EXPECT_TRUE(response->auth_challenge.get() == NULL);
8754}
8755
[email protected]23e482282013-06-14 16:08:028756TEST_P(HttpNetworkTransactionTest, HonorAlternateProtocolHeader) {
[email protected]d7599122014-05-24 03:37:238757 session_deps_.next_protos = SpdyNextProtos();
8758 session_deps_.use_alternate_protocols = true;
[email protected]a2cb8122010-03-10 17:22:428759
[email protected]8a0fc822013-06-27 20:52:438760 std::string alternate_protocol_http_header =
8761 GetAlternateProtocolHttpHeader();
8762
[email protected]564b4912010-03-09 16:30:428763 MockRead data_reads[] = {
8764 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438765 MockRead(alternate_protocol_http_header.c_str()),
[email protected]564b4912010-03-09 16:30:428766 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068767 MockRead(SYNCHRONOUS, OK),
[email protected]564b4912010-03-09 16:30:428768 };
8769
8770 HttpRequestInfo request;
8771 request.method = "GET";
bncce36dca22015-04-21 22:11:238772 request.url = GURL("http://www.example.org/");
[email protected]564b4912010-03-09 16:30:428773 request.load_flags = 0;
8774
8775 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
8776
[email protected]bb88e1d32013-05-03 23:11:078777 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]564b4912010-03-09 16:30:428778
[email protected]49639fa2011-12-20 23:22:418779 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:428780
[email protected]bb88e1d32013-05-03 23:11:078781 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:368782 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508783 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]564b4912010-03-09 16:30:428784
[email protected]49639fa2011-12-20 23:22:418785 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:428786 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]9e743cd2010-03-16 07:03:538787
bncce36dca22015-04-21 22:11:238788 HostPortPair http_host_port_pair("www.example.org", 80);
[email protected]9801e3702014-03-07 09:33:558789 HttpServerProperties& http_server_properties =
[email protected]17291a022011-10-10 07:32:538790 *session->http_server_properties();
bnc181b39a2015-03-17 21:36:478791 AlternativeService alternative_service =
8792 http_server_properties.GetAlternativeService(http_host_port_pair);
8793 EXPECT_EQ(alternative_service.protocol, UNINITIALIZED_ALTERNATE_PROTOCOL);
[email protected]564b4912010-03-09 16:30:428794
8795 EXPECT_EQ(OK, callback.WaitForResult());
8796
8797 const HttpResponseInfo* response = trans->GetResponseInfo();
8798 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508799 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:428800 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:538801 EXPECT_FALSE(response->was_fetched_via_spdy);
8802 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]564b4912010-03-09 16:30:428803
8804 std::string response_data;
8805 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8806 EXPECT_EQ("hello world", response_data);
8807
bnc181b39a2015-03-17 21:36:478808 alternative_service =
8809 http_server_properties.GetAlternativeService(http_host_port_pair);
8810 EXPECT_EQ(443, alternative_service.port);
8811 EXPECT_EQ(AlternateProtocolFromNextProto(GetParam()),
8812 alternative_service.protocol);
[email protected]564b4912010-03-09 16:30:428813}
8814
rch89c6e102015-03-18 18:56:528815TEST_P(HttpNetworkTransactionTest, EmptyAlternateProtocolHeader) {
8816 session_deps_.next_protos = SpdyNextProtos();
8817 session_deps_.use_alternate_protocols = true;
8818
8819 MockRead data_reads[] = {
8820 MockRead("HTTP/1.1 200 OK\r\n"),
8821 MockRead("Alternate-Protocol: \r\n\r\n"),
8822 MockRead("hello world"),
8823 MockRead(SYNCHRONOUS, OK),
8824 };
8825
8826 HttpRequestInfo request;
8827 request.method = "GET";
bncce36dca22015-04-21 22:11:238828 request.url = GURL("http://www.example.org/");
rch89c6e102015-03-18 18:56:528829 request.load_flags = 0;
8830
8831 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
8832
8833 session_deps_.socket_factory->AddSocketDataProvider(&data);
8834
8835 TestCompletionCallback callback;
8836
8837 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8838
bncce36dca22015-04-21 22:11:238839 HostPortPair http_host_port_pair("www.example.org", 80);
rch89c6e102015-03-18 18:56:528840 HttpServerProperties& http_server_properties =
8841 *session->http_server_properties();
bnccacc0992015-03-20 20:22:228842 AlternativeService alternative_service(QUIC, "", 80);
8843 http_server_properties.SetAlternativeService(http_host_port_pair,
8844 alternative_service, 1.0);
8845
8846 alternative_service =
rch89c6e102015-03-18 18:56:528847 http_server_properties.GetAlternativeService(http_host_port_pair);
8848 EXPECT_EQ(alternative_service.protocol, QUIC);
8849
8850 scoped_ptr<HttpTransaction> trans(
8851 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8852
8853 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8854 EXPECT_EQ(ERR_IO_PENDING, rv);
8855
8856 EXPECT_EQ(OK, callback.WaitForResult());
8857
8858 const HttpResponseInfo* response = trans->GetResponseInfo();
8859 ASSERT_TRUE(response != NULL);
8860 ASSERT_TRUE(response->headers.get() != NULL);
8861 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8862 EXPECT_FALSE(response->was_fetched_via_spdy);
8863 EXPECT_FALSE(response->was_npn_negotiated);
8864
8865 std::string response_data;
8866 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8867 EXPECT_EQ("hello world", response_data);
8868
8869 alternative_service =
8870 http_server_properties.GetAlternativeService(http_host_port_pair);
8871 EXPECT_EQ(alternative_service.protocol, UNINITIALIZED_ALTERNATE_PROTOCOL);
8872}
8873
[email protected]23e482282013-06-14 16:08:028874TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238875 MarkBrokenAlternateProtocolAndFallback) {
[email protected]d7599122014-05-24 03:37:238876 session_deps_.use_alternate_protocols = true;
[email protected]564b4912010-03-09 16:30:428877
8878 HttpRequestInfo request;
8879 request.method = "GET";
bncce36dca22015-04-21 22:11:238880 request.url = GURL("http://www.example.org/");
[email protected]564b4912010-03-09 16:30:428881 request.load_flags = 0;
8882
[email protected]d973e99a2012-02-17 21:02:368883 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:428884 StaticSocketDataProvider first_data;
8885 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078886 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]564b4912010-03-09 16:30:428887
8888 MockRead data_reads[] = {
8889 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8890 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068891 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:428892 };
8893 StaticSocketDataProvider second_data(
8894 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078895 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:428896
[email protected]bb88e1d32013-05-03 23:11:078897 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:428898
[email protected]30d4c022013-07-18 22:58:168899 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538900 session->http_server_properties();
bnc8445b3002015-03-13 01:57:098901 const HostPortPair host_port_pair = HostPortPair::FromURL(request.url);
[email protected]3912662a32011-10-04 00:51:118902 // Port must be < 1024, or the header will be ignored (since initial port was
8903 // port 80 (another restricted port).
bnccacc0992015-03-20 20:22:228904 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:238905 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:228906 666); /* port is ignored by MockConnect anyway */
8907 http_server_properties->SetAlternativeService(host_port_pair,
8908 alternative_service, 1.0);
[email protected]564b4912010-03-09 16:30:428909
[email protected]262eec82013-03-19 21:01:368910 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508911 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418912 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:428913
[email protected]49639fa2011-12-20 23:22:418914 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:428915 EXPECT_EQ(ERR_IO_PENDING, rv);
8916 EXPECT_EQ(OK, callback.WaitForResult());
8917
8918 const HttpResponseInfo* response = trans->GetResponseInfo();
8919 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508920 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:428921 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8922
8923 std::string response_data;
8924 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8925 EXPECT_EQ("hello world", response_data);
8926
bnccacc0992015-03-20 20:22:228927 alternative_service =
bnc181b39a2015-03-17 21:36:478928 http_server_properties->GetAlternativeService(host_port_pair);
8929 EXPECT_NE(UNINITIALIZED_ALTERNATE_PROTOCOL, alternative_service.protocol);
bnc8445b3002015-03-13 01:57:098930 EXPECT_TRUE(
8931 http_server_properties->IsAlternativeServiceBroken(alternative_service));
[email protected]564b4912010-03-09 16:30:428932}
8933
[email protected]23e482282013-06-14 16:08:028934TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238935 AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:118936 // Ensure that we're not allowed to redirect traffic via an alternate
8937 // protocol to an unrestricted (port >= 1024) when the original traffic was
8938 // on a restricted port (port < 1024). Ensure that we can redirect in all
8939 // other cases.
[email protected]d7599122014-05-24 03:37:238940 session_deps_.use_alternate_protocols = true;
[email protected]3912662a32011-10-04 00:51:118941
8942 HttpRequestInfo restricted_port_request;
8943 restricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:238944 restricted_port_request.url = GURL("http://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:118945 restricted_port_request.load_flags = 0;
8946
[email protected]d973e99a2012-02-17 21:02:368947 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118948 StaticSocketDataProvider first_data;
8949 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078950 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118951
8952 MockRead data_reads[] = {
8953 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8954 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068955 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118956 };
8957 StaticSocketDataProvider second_data(
8958 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078959 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118960
[email protected]bb88e1d32013-05-03 23:11:078961 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118962
[email protected]30d4c022013-07-18 22:58:168963 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538964 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118965 const int kUnrestrictedAlternatePort = 1024;
bnccacc0992015-03-20 20:22:228966 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:238967 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:228968 kUnrestrictedAlternatePort);
8969 http_server_properties->SetAlternativeService(
8970 HostPortPair::FromURL(restricted_port_request.url), alternative_service,
bnc1102b552015-01-30 20:11:018971 1.0);
[email protected]3912662a32011-10-04 00:51:118972
[email protected]262eec82013-03-19 21:01:368973 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508974 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418975 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118976
[email protected]49639fa2011-12-20 23:22:418977 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:368978 &restricted_port_request,
8979 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118980 EXPECT_EQ(ERR_IO_PENDING, rv);
8981 // Invalid change to unrestricted port should fail.
8982 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.WaitForResult());
[email protected]c54c6962013-02-01 04:53:198983}
[email protected]3912662a32011-10-04 00:51:118984
[email protected]23e482282013-06-14 16:08:028985TEST_P(HttpNetworkTransactionTest,
[email protected]c54c6962013-02-01 04:53:198986 AlternateProtocolPortRestrictedPermitted) {
8987 // Ensure that we're allowed to redirect traffic via an alternate
8988 // protocol to an unrestricted (port >= 1024) when the original traffic was
8989 // on a restricted port (port < 1024) if we set
8990 // enable_user_alternate_protocol_ports.
8991
[email protected]d7599122014-05-24 03:37:238992 session_deps_.use_alternate_protocols = true;
[email protected]bb88e1d32013-05-03 23:11:078993 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:198994
8995 HttpRequestInfo restricted_port_request;
8996 restricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:238997 restricted_port_request.url = GURL("http://www.example.org:1023/");
[email protected]c54c6962013-02-01 04:53:198998 restricted_port_request.load_flags = 0;
8999
9000 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
9001 StaticSocketDataProvider first_data;
9002 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079003 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:199004
9005 MockRead data_reads[] = {
9006 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9007 MockRead("hello world"),
9008 MockRead(ASYNC, OK),
9009 };
9010 StaticSocketDataProvider second_data(
9011 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079012 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]c54c6962013-02-01 04:53:199013
[email protected]bb88e1d32013-05-03 23:11:079014 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:199015
[email protected]30d4c022013-07-18 22:58:169016 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]c54c6962013-02-01 04:53:199017 session->http_server_properties();
9018 const int kUnrestrictedAlternatePort = 1024;
bnccacc0992015-03-20 20:22:229019 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239020 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229021 kUnrestrictedAlternatePort);
9022 http_server_properties->SetAlternativeService(
9023 HostPortPair::FromURL(restricted_port_request.url), alternative_service,
bnc1102b552015-01-30 20:11:019024 1.0);
[email protected]c54c6962013-02-01 04:53:199025
[email protected]262eec82013-03-19 21:01:369026 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509027 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]c54c6962013-02-01 04:53:199028 TestCompletionCallback callback;
9029
9030 EXPECT_EQ(ERR_IO_PENDING, trans->Start(
[email protected]262eec82013-03-19 21:01:369031 &restricted_port_request,
9032 callback.callback(), BoundNetLog()));
[email protected]c54c6962013-02-01 04:53:199033 // Change to unrestricted port should succeed.
9034 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:119035}
9036
[email protected]23e482282013-06-14 16:08:029037TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239038 AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:119039 // Ensure that we're not allowed to redirect traffic via an alternate
9040 // protocol to an unrestricted (port >= 1024) when the original traffic was
9041 // on a restricted port (port < 1024). Ensure that we can redirect in all
9042 // other cases.
[email protected]d7599122014-05-24 03:37:239043 session_deps_.use_alternate_protocols = true;
[email protected]3912662a32011-10-04 00:51:119044
9045 HttpRequestInfo restricted_port_request;
9046 restricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:239047 restricted_port_request.url = GURL("http://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:119048 restricted_port_request.load_flags = 0;
9049
[email protected]d973e99a2012-02-17 21:02:369050 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:119051 StaticSocketDataProvider first_data;
9052 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079053 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:119054
9055 MockRead data_reads[] = {
9056 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9057 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069058 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:119059 };
9060 StaticSocketDataProvider second_data(
9061 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079062 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:119063
[email protected]bb88e1d32013-05-03 23:11:079064 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:119065
[email protected]30d4c022013-07-18 22:58:169066 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:539067 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:119068 const int kRestrictedAlternatePort = 80;
bnccacc0992015-03-20 20:22:229069 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239070 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229071 kRestrictedAlternatePort);
9072 http_server_properties->SetAlternativeService(
9073 HostPortPair::FromURL(restricted_port_request.url), alternative_service,
bnc1102b552015-01-30 20:11:019074 1.0);
[email protected]3912662a32011-10-04 00:51:119075
[email protected]262eec82013-03-19 21:01:369076 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509077 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419078 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:119079
[email protected]49639fa2011-12-20 23:22:419080 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:369081 &restricted_port_request,
9082 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:119083 EXPECT_EQ(ERR_IO_PENDING, rv);
9084 // Valid change to restricted port should pass.
9085 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:119086}
9087
[email protected]23e482282013-06-14 16:08:029088TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239089 AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:119090 // Ensure that we're not allowed to redirect traffic via an alternate
9091 // protocol to an unrestricted (port >= 1024) when the original traffic was
9092 // on a restricted port (port < 1024). Ensure that we can redirect in all
9093 // other cases.
[email protected]d7599122014-05-24 03:37:239094 session_deps_.use_alternate_protocols = true;
[email protected]3912662a32011-10-04 00:51:119095
9096 HttpRequestInfo unrestricted_port_request;
9097 unrestricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:239098 unrestricted_port_request.url = GURL("http://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:119099 unrestricted_port_request.load_flags = 0;
9100
[email protected]d973e99a2012-02-17 21:02:369101 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:119102 StaticSocketDataProvider first_data;
9103 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079104 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:119105
9106 MockRead data_reads[] = {
9107 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9108 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069109 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:119110 };
9111 StaticSocketDataProvider second_data(
9112 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079113 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:119114
[email protected]bb88e1d32013-05-03 23:11:079115 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:119116
[email protected]30d4c022013-07-18 22:58:169117 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:539118 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:119119 const int kRestrictedAlternatePort = 80;
bnccacc0992015-03-20 20:22:229120 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239121 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229122 kRestrictedAlternatePort);
9123 http_server_properties->SetAlternativeService(
9124 HostPortPair::FromURL(unrestricted_port_request.url), alternative_service,
bnc1102b552015-01-30 20:11:019125 1.0);
[email protected]3912662a32011-10-04 00:51:119126
[email protected]262eec82013-03-19 21:01:369127 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509128 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419129 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:119130
[email protected]49639fa2011-12-20 23:22:419131 int rv = trans->Start(
9132 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:119133 EXPECT_EQ(ERR_IO_PENDING, rv);
9134 // Valid change to restricted port should pass.
9135 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:119136}
9137
[email protected]23e482282013-06-14 16:08:029138TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239139 AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:119140 // Ensure that we're not allowed to redirect traffic via an alternate
9141 // protocol to an unrestricted (port >= 1024) when the original traffic was
9142 // on a restricted port (port < 1024). Ensure that we can redirect in all
9143 // other cases.
[email protected]d7599122014-05-24 03:37:239144 session_deps_.use_alternate_protocols = true;
[email protected]3912662a32011-10-04 00:51:119145
9146 HttpRequestInfo unrestricted_port_request;
9147 unrestricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:239148 unrestricted_port_request.url = GURL("http://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:119149 unrestricted_port_request.load_flags = 0;
9150
[email protected]d973e99a2012-02-17 21:02:369151 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:119152 StaticSocketDataProvider first_data;
9153 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079154 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:119155
9156 MockRead data_reads[] = {
9157 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9158 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069159 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:119160 };
9161 StaticSocketDataProvider second_data(
9162 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079163 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:119164
[email protected]bb88e1d32013-05-03 23:11:079165 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:119166
[email protected]30d4c022013-07-18 22:58:169167 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:539168 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:119169 const int kUnrestrictedAlternatePort = 1024;
bnccacc0992015-03-20 20:22:229170 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239171 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229172 kUnrestrictedAlternatePort);
9173 http_server_properties->SetAlternativeService(
9174 HostPortPair::FromURL(unrestricted_port_request.url), alternative_service,
bnc1102b552015-01-30 20:11:019175 1.0);
[email protected]3912662a32011-10-04 00:51:119176
[email protected]262eec82013-03-19 21:01:369177 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509178 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419179 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:119180
[email protected]49639fa2011-12-20 23:22:419181 int rv = trans->Start(
9182 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:119183 EXPECT_EQ(ERR_IO_PENDING, rv);
9184 // Valid change to an unrestricted port should pass.
9185 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:119186}
9187
[email protected]d7599122014-05-24 03:37:239188TEST_P(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:029189 // Ensure that we're not allowed to redirect traffic via an alternate
9190 // protocol to an unsafe port, and that we resume the second
9191 // HttpStreamFactoryImpl::Job once the alternate protocol request fails.
[email protected]d7599122014-05-24 03:37:239192 session_deps_.use_alternate_protocols = true;
[email protected]eb6234e2012-01-19 01:50:029193
9194 HttpRequestInfo request;
9195 request.method = "GET";
bncce36dca22015-04-21 22:11:239196 request.url = GURL("http://www.example.org/");
[email protected]eb6234e2012-01-19 01:50:029197 request.load_flags = 0;
9198
9199 // The alternate protocol request will error out before we attempt to connect,
9200 // so only the standard HTTP request will try to connect.
9201 MockRead data_reads[] = {
9202 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9203 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069204 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:029205 };
9206 StaticSocketDataProvider data(
9207 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079208 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:029209
[email protected]bb88e1d32013-05-03 23:11:079210 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:029211
[email protected]30d4c022013-07-18 22:58:169212 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]eb6234e2012-01-19 01:50:029213 session->http_server_properties();
9214 const int kUnsafePort = 7;
bnccacc0992015-03-20 20:22:229215 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239216 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229217 kUnsafePort);
9218 http_server_properties->SetAlternativeService(
9219 HostPortPair::FromURL(request.url), alternative_service, 1.0);
[email protected]eb6234e2012-01-19 01:50:029220
[email protected]262eec82013-03-19 21:01:369221 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509222 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]eb6234e2012-01-19 01:50:029223 TestCompletionCallback callback;
9224
9225 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9226 EXPECT_EQ(ERR_IO_PENDING, rv);
9227 // The HTTP request should succeed.
9228 EXPECT_EQ(OK, callback.WaitForResult());
9229
9230 // Disable alternate protocol before the asserts.
[email protected]d7599122014-05-24 03:37:239231 // HttpStreamFactory::set_use_alternate_protocols(false);
[email protected]eb6234e2012-01-19 01:50:029232
9233 const HttpResponseInfo* response = trans->GetResponseInfo();
9234 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509235 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]eb6234e2012-01-19 01:50:029236 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9237
9238 std::string response_data;
9239 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9240 EXPECT_EQ("hello world", response_data);
9241}
9242
[email protected]23e482282013-06-14 16:08:029243TEST_P(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]d7599122014-05-24 03:37:239244 session_deps_.use_alternate_protocols = true;
9245 session_deps_.next_protos = SpdyNextProtos();
[email protected]2ff8b312010-04-26 22:20:549246
9247 HttpRequestInfo request;
9248 request.method = "GET";
bncce36dca22015-04-21 22:11:239249 request.url = GURL("http://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:549250 request.load_flags = 0;
9251
[email protected]8a0fc822013-06-27 20:52:439252 std::string alternate_protocol_http_header =
9253 GetAlternateProtocolHttpHeader();
9254
[email protected]2ff8b312010-04-26 22:20:549255 MockRead data_reads[] = {
9256 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439257 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2ff8b312010-04-26 22:20:549258 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:179259 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
9260 MockRead(ASYNC, OK)
[email protected]2ff8b312010-04-26 22:20:549261 };
9262
9263 StaticSocketDataProvider first_transaction(
9264 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079265 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:549266
[email protected]8ddf8322012-02-23 18:08:069267 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029268 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:239269 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
9270 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:079271 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:549272
[email protected]cdf8f7e72013-05-23 10:56:469273 scoped_ptr<SpdyFrame> req(
9274 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
rch8e6c6c42015-05-01 14:05:139275 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]2ff8b312010-04-26 22:20:549276
[email protected]23e482282013-06-14 16:08:029277 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9278 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:549279 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:139280 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:549281 };
9282
rch8e6c6c42015-05-01 14:05:139283 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9284 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079285 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:549286
[email protected]d973e99a2012-02-17 21:02:369287 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559288 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
9289 NULL, 0, NULL, 0);
9290 hanging_non_alternate_protocol_socket.set_connect_data(
9291 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:079292 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:559293 &hanging_non_alternate_protocol_socket);
9294
[email protected]49639fa2011-12-20 23:22:419295 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:549296
[email protected]bb88e1d32013-05-03 23:11:079297 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369298 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509299 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:549300
[email protected]49639fa2011-12-20 23:22:419301 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:549302 EXPECT_EQ(ERR_IO_PENDING, rv);
9303 EXPECT_EQ(OK, callback.WaitForResult());
9304
9305 const HttpResponseInfo* response = trans->GetResponseInfo();
9306 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509307 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:549308 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9309
9310 std::string response_data;
9311 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9312 EXPECT_EQ("hello world", response_data);
9313
[email protected]90499482013-06-01 00:39:509314 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:549315
[email protected]49639fa2011-12-20 23:22:419316 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:549317 EXPECT_EQ(ERR_IO_PENDING, rv);
9318 EXPECT_EQ(OK, callback.WaitForResult());
9319
9320 response = trans->GetResponseInfo();
9321 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509322 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:549323 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539324 EXPECT_TRUE(response->was_fetched_via_spdy);
9325 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:549326
9327 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9328 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:549329}
9330
[email protected]23e482282013-06-14 16:08:029331TEST_P(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]d7599122014-05-24 03:37:239332 session_deps_.use_alternate_protocols = true;
9333 session_deps_.next_protos = SpdyNextProtos();
[email protected]2d6728692011-03-12 01:39:559334
9335 HttpRequestInfo request;
9336 request.method = "GET";
bncce36dca22015-04-21 22:11:239337 request.url = GURL("http://www.example.org/");
[email protected]2d6728692011-03-12 01:39:559338 request.load_flags = 0;
9339
[email protected]8a0fc822013-06-27 20:52:439340 std::string alternate_protocol_http_header =
9341 GetAlternateProtocolHttpHeader();
9342
[email protected]2d6728692011-03-12 01:39:559343 MockRead data_reads[] = {
9344 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439345 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2d6728692011-03-12 01:39:559346 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:179347 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:069348 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:559349 };
9350
9351 StaticSocketDataProvider first_transaction(
9352 data_reads, arraysize(data_reads), NULL, 0);
9353 // Socket 1 is the HTTP transaction with the Alternate-Protocol header.
[email protected]bb88e1d32013-05-03 23:11:079354 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:559355
[email protected]d973e99a2012-02-17 21:02:369356 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559357 StaticSocketDataProvider hanging_socket(
9358 NULL, 0, NULL, 0);
9359 hanging_socket.set_connect_data(never_finishing_connect);
9360 // Socket 2 and 3 are the hanging Alternate-Protocol and
9361 // non-Alternate-Protocol jobs from the 2nd transaction.
[email protected]bb88e1d32013-05-03 23:11:079362 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
9363 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
[email protected]2d6728692011-03-12 01:39:559364
[email protected]8ddf8322012-02-23 18:08:069365 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029366 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:239367 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
9368 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:079369 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:559370
[email protected]cdf8f7e72013-05-23 10:56:469371 scoped_ptr<SpdyFrame> req1(
9372 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
9373 scoped_ptr<SpdyFrame> req2(
9374 spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
[email protected]2d6728692011-03-12 01:39:559375 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:139376 CreateMockWrite(*req1, 0), CreateMockWrite(*req2, 1),
[email protected]2d6728692011-03-12 01:39:559377 };
[email protected]23e482282013-06-14 16:08:029378 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9379 scoped_ptr<SpdyFrame> data1(spdy_util_.ConstructSpdyBodyFrame(1, true));
9380 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
9381 scoped_ptr<SpdyFrame> data2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]2d6728692011-03-12 01:39:559382 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:139383 CreateMockRead(*resp1, 2),
9384 CreateMockRead(*data1, 3),
9385 CreateMockRead(*resp2, 4),
9386 CreateMockRead(*data2, 5),
9387 MockRead(ASYNC, 0, 6),
[email protected]2d6728692011-03-12 01:39:559388 };
9389
rch8e6c6c42015-05-01 14:05:139390 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9391 arraysize(spdy_writes));
[email protected]2d6728692011-03-12 01:39:559392 // Socket 4 is the successful Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:079393 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:559394
9395 // Socket 5 is the unsuccessful non-Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:079396 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
[email protected]2d6728692011-03-12 01:39:559397
[email protected]bb88e1d32013-05-03 23:11:079398 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:419399 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:509400 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:559401
[email protected]49639fa2011-12-20 23:22:419402 int rv = trans1.Start(&request, callback1.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559403 EXPECT_EQ(ERR_IO_PENDING, rv);
9404 EXPECT_EQ(OK, callback1.WaitForResult());
9405
9406 const HttpResponseInfo* response = trans1.GetResponseInfo();
9407 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509408 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559409 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9410
9411 std::string response_data;
9412 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
9413 EXPECT_EQ("hello world", response_data);
9414
[email protected]49639fa2011-12-20 23:22:419415 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:509416 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:419417 rv = trans2.Start(&request, callback2.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559418 EXPECT_EQ(ERR_IO_PENDING, rv);
9419
[email protected]49639fa2011-12-20 23:22:419420 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:509421 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:419422 rv = trans3.Start(&request, callback3.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559423 EXPECT_EQ(ERR_IO_PENDING, rv);
9424
9425 EXPECT_EQ(OK, callback2.WaitForResult());
9426 EXPECT_EQ(OK, callback3.WaitForResult());
9427
9428 response = trans2.GetResponseInfo();
9429 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509430 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559431 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9432 EXPECT_TRUE(response->was_fetched_via_spdy);
9433 EXPECT_TRUE(response->was_npn_negotiated);
9434 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
9435 EXPECT_EQ("hello!", response_data);
9436
9437 response = trans3.GetResponseInfo();
9438 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509439 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559440 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9441 EXPECT_TRUE(response->was_fetched_via_spdy);
9442 EXPECT_TRUE(response->was_npn_negotiated);
9443 ASSERT_EQ(OK, ReadTransaction(&trans3, &response_data));
9444 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:559445}
9446
[email protected]23e482282013-06-14 16:08:029447TEST_P(HttpNetworkTransactionTest, StallAlternateProtocolForNpnSpdy) {
[email protected]d7599122014-05-24 03:37:239448 session_deps_.use_alternate_protocols = true;
9449 session_deps_.next_protos = SpdyNextProtos();
[email protected]2d6728692011-03-12 01:39:559450
9451 HttpRequestInfo request;
9452 request.method = "GET";
bncce36dca22015-04-21 22:11:239453 request.url = GURL("http://www.example.org/");
[email protected]2d6728692011-03-12 01:39:559454 request.load_flags = 0;
9455
[email protected]8a0fc822013-06-27 20:52:439456 std::string alternate_protocol_http_header =
9457 GetAlternateProtocolHttpHeader();
9458
[email protected]2d6728692011-03-12 01:39:559459 MockRead data_reads[] = {
9460 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439461 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2d6728692011-03-12 01:39:559462 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:179463 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:069464 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:559465 };
9466
9467 StaticSocketDataProvider first_transaction(
9468 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079469 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:559470
[email protected]8ddf8322012-02-23 18:08:069471 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029472 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:079473 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:559474
[email protected]d973e99a2012-02-17 21:02:369475 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559476 StaticSocketDataProvider hanging_alternate_protocol_socket(
9477 NULL, 0, NULL, 0);
9478 hanging_alternate_protocol_socket.set_connect_data(
9479 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:079480 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:559481 &hanging_alternate_protocol_socket);
9482
9483 // 2nd request is just a copy of the first one, over HTTP again.
[email protected]bb88e1d32013-05-03 23:11:079484 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:559485
[email protected]49639fa2011-12-20 23:22:419486 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:559487
[email protected]bb88e1d32013-05-03 23:11:079488 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369489 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509490 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:559491
[email protected]49639fa2011-12-20 23:22:419492 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559493 EXPECT_EQ(ERR_IO_PENDING, rv);
9494 EXPECT_EQ(OK, callback.WaitForResult());
9495
9496 const HttpResponseInfo* response = trans->GetResponseInfo();
9497 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509498 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559499 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9500
9501 std::string response_data;
9502 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9503 EXPECT_EQ("hello world", response_data);
9504
[email protected]90499482013-06-01 00:39:509505 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:559506
[email protected]49639fa2011-12-20 23:22:419507 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559508 EXPECT_EQ(ERR_IO_PENDING, rv);
9509 EXPECT_EQ(OK, callback.WaitForResult());
9510
9511 response = trans->GetResponseInfo();
9512 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509513 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559514 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9515 EXPECT_FALSE(response->was_fetched_via_spdy);
9516 EXPECT_FALSE(response->was_npn_negotiated);
9517
9518 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9519 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:559520}
9521
[email protected]631f1322010-04-30 17:59:119522class CapturingProxyResolver : public ProxyResolver {
9523 public:
9524 CapturingProxyResolver() : ProxyResolver(false /* expects_pac_bytes */) {}
dchengb03027d2014-10-21 12:00:209525 ~CapturingProxyResolver() override {}
[email protected]631f1322010-04-30 17:59:119526
dchengb03027d2014-10-21 12:00:209527 int GetProxyForURL(const GURL& url,
9528 ProxyInfo* results,
9529 const CompletionCallback& callback,
9530 RequestHandle* request,
9531 const BoundNetLog& net_log) override {
[email protected]fae7669f2010-08-02 21:49:409532 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
9533 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:429534 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:119535 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:429536 return OK;
[email protected]631f1322010-04-30 17:59:119537 }
9538
dchengb03027d2014-10-21 12:00:209539 void CancelRequest(RequestHandle request) override { NOTREACHED(); }
[email protected]631f1322010-04-30 17:59:119540
dchengb03027d2014-10-21 12:00:209541 LoadState GetLoadState(RequestHandle request) const override {
[email protected]f2c971f2011-11-08 00:33:179542 NOTREACHED();
9543 return LOAD_STATE_IDLE;
9544 }
9545
dchengb03027d2014-10-21 12:00:209546 void CancelSetPacScript() override { NOTREACHED(); }
[email protected]1e605472010-12-16 21:41:409547
dchengb03027d2014-10-21 12:00:209548 int SetPacScript(const scoped_refptr<ProxyResolverScriptData>&,
9549 const CompletionCallback& /*callback*/) override {
[email protected]d911f1b2010-05-05 22:39:429550 return OK;
[email protected]631f1322010-04-30 17:59:119551 }
9552
[email protected]24476402010-07-20 20:55:179553 const std::vector<GURL>& resolved() const { return resolved_; }
9554
9555 private:
[email protected]631f1322010-04-30 17:59:119556 std::vector<GURL> resolved_;
9557
9558 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
9559};
9560
sammce64b2362015-04-29 03:50:239561class CapturingProxyResolverFactory : public ProxyResolverFactory {
9562 public:
9563 explicit CapturingProxyResolverFactory(CapturingProxyResolver* resolver)
9564 : ProxyResolverFactory(false), resolver_(resolver) {}
9565
9566 int CreateProxyResolver(
9567 const scoped_refptr<ProxyResolverScriptData>& pac_script,
9568 scoped_ptr<ProxyResolver>* resolver,
9569 const net::CompletionCallback& callback,
9570 scoped_ptr<Request>* request) override {
9571 resolver->reset(new ForwardingProxyResolver(resolver_));
9572 return OK;
9573 }
9574
9575 private:
9576 ProxyResolver* resolver_;
9577};
9578
[email protected]23e482282013-06-14 16:08:029579TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239580 UseAlternateProtocolForTunneledNpnSpdy) {
[email protected]d7599122014-05-24 03:37:239581 session_deps_.use_alternate_protocols = true;
9582 session_deps_.next_protos = SpdyNextProtos();
[email protected]631f1322010-04-30 17:59:119583
9584 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:429585 proxy_config.set_auto_detect(true);
9586 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:119587
sammc5dd160c2015-04-02 02:43:139588 CapturingProxyResolver capturing_proxy_resolver;
[email protected]bb88e1d32013-05-03 23:11:079589 session_deps_.proxy_service.reset(new ProxyService(
sammc5dd160c2015-04-02 02:43:139590 new ProxyConfigServiceFixed(proxy_config),
9591 make_scoped_ptr(
sammce64b2362015-04-29 03:50:239592 new CapturingProxyResolverFactory(&capturing_proxy_resolver)),
[email protected]66761b952010-06-25 21:30:389593 NULL));
vishal.b62985ca92015-04-17 08:45:519594 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079595 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:119596
9597 HttpRequestInfo request;
9598 request.method = "GET";
bncce36dca22015-04-21 22:11:239599 request.url = GURL("http://www.example.org/");
[email protected]631f1322010-04-30 17:59:119600 request.load_flags = 0;
9601
[email protected]8a0fc822013-06-27 20:52:439602 std::string alternate_protocol_http_header =
9603 GetAlternateProtocolHttpHeader();
9604
[email protected]631f1322010-04-30 17:59:119605 MockRead data_reads[] = {
9606 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439607 MockRead(alternate_protocol_http_header.c_str()),
[email protected]631f1322010-04-30 17:59:119608 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:179609 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:069610 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:119611 };
9612
9613 StaticSocketDataProvider first_transaction(
9614 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079615 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]631f1322010-04-30 17:59:119616
[email protected]8ddf8322012-02-23 18:08:069617 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029618 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:239619 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
9620 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:079621 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]631f1322010-04-30 17:59:119622
[email protected]cdf8f7e72013-05-23 10:56:469623 scoped_ptr<SpdyFrame> req(
9624 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]631f1322010-04-30 17:59:119625 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:139626 MockWrite(ASYNC, 0,
9627 "CONNECT www.example.org:443 HTTP/1.1\r\n"
9628 "Host: www.example.org\r\n"
9629 "Proxy-Connection: keep-alive\r\n\r\n"),
9630 CreateMockWrite(*req, 2),
[email protected]631f1322010-04-30 17:59:119631 };
9632
[email protected]d911f1b2010-05-05 22:39:429633 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
9634
[email protected]23e482282013-06-14 16:08:029635 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9636 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]631f1322010-04-30 17:59:119637 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:139638 MockRead(ASYNC, 1, kCONNECTResponse),
9639 CreateMockRead(*resp.get(), 3),
9640 CreateMockRead(*data.get(), 4),
9641 MockRead(ASYNC, ERR_IO_PENDING, 5),
[email protected]631f1322010-04-30 17:59:119642 };
9643
rch8e6c6c42015-05-01 14:05:139644 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9645 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079646 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:119647
[email protected]d973e99a2012-02-17 21:02:369648 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559649 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
9650 NULL, 0, NULL, 0);
9651 hanging_non_alternate_protocol_socket.set_connect_data(
9652 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:079653 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:559654 &hanging_non_alternate_protocol_socket);
9655
[email protected]49639fa2011-12-20 23:22:419656 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:119657
[email protected]bb88e1d32013-05-03 23:11:079658 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369659 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509660 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:119661
[email protected]49639fa2011-12-20 23:22:419662 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:119663 EXPECT_EQ(ERR_IO_PENDING, rv);
9664 EXPECT_EQ(OK, callback.WaitForResult());
9665
9666 const HttpResponseInfo* response = trans->GetResponseInfo();
9667 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509668 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]631f1322010-04-30 17:59:119669 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539670 EXPECT_FALSE(response->was_fetched_via_spdy);
9671 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:119672
9673 std::string response_data;
9674 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9675 EXPECT_EQ("hello world", response_data);
9676
[email protected]90499482013-06-01 00:39:509677 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:119678
[email protected]49639fa2011-12-20 23:22:419679 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:119680 EXPECT_EQ(ERR_IO_PENDING, rv);
9681 EXPECT_EQ(OK, callback.WaitForResult());
9682
9683 response = trans->GetResponseInfo();
9684 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509685 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]631f1322010-04-30 17:59:119686 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539687 EXPECT_TRUE(response->was_fetched_via_spdy);
9688 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:119689
9690 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9691 EXPECT_EQ("hello!", response_data);
sammc5dd160c2015-04-02 02:43:139692 ASSERT_EQ(3u, capturing_proxy_resolver.resolved().size());
bncce36dca22015-04-21 22:11:239693 EXPECT_EQ("http://www.example.org/",
sammc5dd160c2015-04-02 02:43:139694 capturing_proxy_resolver.resolved()[0].spec());
bncce36dca22015-04-21 22:11:239695 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:139696 capturing_proxy_resolver.resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:119697
[email protected]029c83b62013-01-24 05:28:209698 LoadTimingInfo load_timing_info;
9699 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
9700 TestLoadTimingNotReusedWithPac(load_timing_info,
9701 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:119702}
[email protected]631f1322010-04-30 17:59:119703
[email protected]23e482282013-06-14 16:08:029704TEST_P(HttpNetworkTransactionTest,
[email protected]2ff8b312010-04-26 22:20:549705 UseAlternateProtocolForNpnSpdyWithExistingSpdySession) {
[email protected]d7599122014-05-24 03:37:239706 session_deps_.use_alternate_protocols = true;
9707 session_deps_.next_protos = SpdyNextProtos();
[email protected]2ff8b312010-04-26 22:20:549708
9709 HttpRequestInfo request;
9710 request.method = "GET";
bncce36dca22015-04-21 22:11:239711 request.url = GURL("http://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:549712 request.load_flags = 0;
9713
[email protected]8a0fc822013-06-27 20:52:439714 std::string alternate_protocol_http_header =
9715 GetAlternateProtocolHttpHeader();
9716
[email protected]2ff8b312010-04-26 22:20:549717 MockRead data_reads[] = {
9718 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439719 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2ff8b312010-04-26 22:20:549720 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069721 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:549722 };
9723
9724 StaticSocketDataProvider first_transaction(
9725 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079726 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:549727
[email protected]8ddf8322012-02-23 18:08:069728 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029729 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:239730 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
9731 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:079732 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:549733
[email protected]cdf8f7e72013-05-23 10:56:469734 scoped_ptr<SpdyFrame> req(
9735 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
rch8e6c6c42015-05-01 14:05:139736 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]2ff8b312010-04-26 22:20:549737
[email protected]23e482282013-06-14 16:08:029738 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9739 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:549740 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:139741 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:549742 };
9743
rch8e6c6c42015-05-01 14:05:139744 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9745 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079746 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:549747
[email protected]83039bb2011-12-09 18:43:559748 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:549749
[email protected]bb88e1d32013-05-03 23:11:079750 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:549751
[email protected]262eec82013-03-19 21:01:369752 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509753 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:549754
[email protected]49639fa2011-12-20 23:22:419755 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:549756 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:419757 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:549758
9759 const HttpResponseInfo* response = trans->GetResponseInfo();
9760 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509761 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:549762 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9763
9764 std::string response_data;
9765 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9766 EXPECT_EQ("hello world", response_data);
9767
9768 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:239769 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:409770 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:539771 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:279772 base::WeakPtr<SpdySession> spdy_session =
[email protected]41d64e82013-07-03 22:44:269773 CreateSecureSpdySession(session, key, BoundNetLog());
[email protected]02b0c342010-09-25 21:09:389774
[email protected]90499482013-06-01 00:39:509775 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:549776
[email protected]49639fa2011-12-20 23:22:419777 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:549778 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:419779 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:549780
9781 response = trans->GetResponseInfo();
9782 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509783 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:549784 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539785 EXPECT_TRUE(response->was_fetched_via_spdy);
9786 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:549787
9788 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9789 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:429790}
9791
[email protected]044de0642010-06-17 10:42:159792// GenerateAuthToken is a mighty big test.
9793// It tests all permutation of GenerateAuthToken behavior:
9794// - Synchronous and Asynchronous completion.
9795// - OK or error on completion.
9796// - Direct connection, non-authenticating proxy, and authenticating proxy.
9797// - HTTP or HTTPS backend (to include proxy tunneling).
9798// - Non-authenticating and authenticating backend.
9799//
[email protected]fe3b7dc2012-02-03 19:52:099800// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:159801// problems generating an auth token for an authenticating proxy, we don't
9802// need to test all permutations of the backend server).
9803//
9804// The test proceeds by going over each of the configuration cases, and
9805// potentially running up to three rounds in each of the tests. The TestConfig
9806// specifies both the configuration for the test as well as the expectations
9807// for the results.
[email protected]23e482282013-06-14 16:08:029808TEST_P(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:509809 static const char kServer[] = "http://www.example.com";
9810 static const char kSecureServer[] = "https://www.example.com";
9811 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:159812 const int kAuthErr = ERR_INVALID_AUTH_CREDENTIALS;
9813
9814 enum AuthTiming {
9815 AUTH_NONE,
9816 AUTH_SYNC,
9817 AUTH_ASYNC,
9818 };
9819
9820 const MockWrite kGet(
9821 "GET / HTTP/1.1\r\n"
9822 "Host: www.example.com\r\n"
9823 "Connection: keep-alive\r\n\r\n");
9824 const MockWrite kGetProxy(
9825 "GET http://www.example.com/ HTTP/1.1\r\n"
9826 "Host: www.example.com\r\n"
9827 "Proxy-Connection: keep-alive\r\n\r\n");
9828 const MockWrite kGetAuth(
9829 "GET / HTTP/1.1\r\n"
9830 "Host: www.example.com\r\n"
9831 "Connection: keep-alive\r\n"
9832 "Authorization: auth_token\r\n\r\n");
9833 const MockWrite kGetProxyAuth(
9834 "GET http://www.example.com/ HTTP/1.1\r\n"
9835 "Host: www.example.com\r\n"
9836 "Proxy-Connection: keep-alive\r\n"
9837 "Proxy-Authorization: auth_token\r\n\r\n");
9838 const MockWrite kGetAuthThroughProxy(
9839 "GET http://www.example.com/ HTTP/1.1\r\n"
9840 "Host: www.example.com\r\n"
9841 "Proxy-Connection: keep-alive\r\n"
9842 "Authorization: auth_token\r\n\r\n");
9843 const MockWrite kGetAuthWithProxyAuth(
9844 "GET http://www.example.com/ HTTP/1.1\r\n"
9845 "Host: www.example.com\r\n"
9846 "Proxy-Connection: keep-alive\r\n"
9847 "Proxy-Authorization: auth_token\r\n"
9848 "Authorization: auth_token\r\n\r\n");
9849 const MockWrite kConnect(
9850 "CONNECT www.example.com:443 HTTP/1.1\r\n"
9851 "Host: www.example.com\r\n"
9852 "Proxy-Connection: keep-alive\r\n\r\n");
9853 const MockWrite kConnectProxyAuth(
9854 "CONNECT www.example.com:443 HTTP/1.1\r\n"
9855 "Host: www.example.com\r\n"
9856 "Proxy-Connection: keep-alive\r\n"
9857 "Proxy-Authorization: auth_token\r\n\r\n");
9858
9859 const MockRead kSuccess(
9860 "HTTP/1.1 200 OK\r\n"
9861 "Content-Type: text/html; charset=iso-8859-1\r\n"
9862 "Content-Length: 3\r\n\r\n"
9863 "Yes");
9864 const MockRead kFailure(
9865 "Should not be called.");
9866 const MockRead kServerChallenge(
9867 "HTTP/1.1 401 Unauthorized\r\n"
9868 "WWW-Authenticate: Mock realm=server\r\n"
9869 "Content-Type: text/html; charset=iso-8859-1\r\n"
9870 "Content-Length: 14\r\n\r\n"
9871 "Unauthorized\r\n");
9872 const MockRead kProxyChallenge(
9873 "HTTP/1.1 407 Unauthorized\r\n"
9874 "Proxy-Authenticate: Mock realm=proxy\r\n"
9875 "Proxy-Connection: close\r\n"
9876 "Content-Type: text/html; charset=iso-8859-1\r\n"
9877 "Content-Length: 14\r\n\r\n"
9878 "Unauthorized\r\n");
9879 const MockRead kProxyConnected(
9880 "HTTP/1.1 200 Connection Established\r\n\r\n");
9881
9882 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
9883 // no constructors, but the C++ compiler on Windows warns about
9884 // unspecified data in compound literals. So, moved to using constructors,
9885 // and TestRound's created with the default constructor should not be used.
9886 struct TestRound {
9887 TestRound()
9888 : expected_rv(ERR_UNEXPECTED),
9889 extra_write(NULL),
9890 extra_read(NULL) {
9891 }
9892 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
9893 int expected_rv_arg)
9894 : write(write_arg),
9895 read(read_arg),
9896 expected_rv(expected_rv_arg),
9897 extra_write(NULL),
9898 extra_read(NULL) {
9899 }
9900 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
9901 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:019902 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:159903 : write(write_arg),
9904 read(read_arg),
9905 expected_rv(expected_rv_arg),
9906 extra_write(extra_write_arg),
9907 extra_read(extra_read_arg) {
9908 }
9909 MockWrite write;
9910 MockRead read;
9911 int expected_rv;
9912 const MockWrite* extra_write;
9913 const MockRead* extra_read;
9914 };
9915
9916 static const int kNoSSL = 500;
9917
9918 struct TestConfig {
thestig9d3bb0c2015-01-24 00:49:519919 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:159920 AuthTiming proxy_auth_timing;
9921 int proxy_auth_rv;
thestig9d3bb0c2015-01-24 00:49:519922 const char* const server_url;
[email protected]044de0642010-06-17 10:42:159923 AuthTiming server_auth_timing;
9924 int server_auth_rv;
9925 int num_auth_rounds;
9926 int first_ssl_round;
9927 TestRound rounds[3];
9928 } test_configs[] = {
9929 // Non-authenticating HTTP server with a direct connection.
9930 { NULL, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
9931 { TestRound(kGet, kSuccess, OK)}},
9932 // Authenticating HTTP server with a direct connection.
9933 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
9934 { TestRound(kGet, kServerChallenge, OK),
9935 TestRound(kGetAuth, kSuccess, OK)}},
9936 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
9937 { TestRound(kGet, kServerChallenge, OK),
9938 TestRound(kGetAuth, kFailure, kAuthErr)}},
9939 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
9940 { TestRound(kGet, kServerChallenge, OK),
9941 TestRound(kGetAuth, kSuccess, OK)}},
9942 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
9943 { TestRound(kGet, kServerChallenge, OK),
9944 TestRound(kGetAuth, kFailure, kAuthErr)}},
9945 // Non-authenticating HTTP server through a non-authenticating proxy.
9946 { kProxy, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
9947 { TestRound(kGetProxy, kSuccess, OK)}},
9948 // Authenticating HTTP server through a non-authenticating proxy.
9949 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
9950 { TestRound(kGetProxy, kServerChallenge, OK),
9951 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
9952 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
9953 { TestRound(kGetProxy, kServerChallenge, OK),
9954 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
9955 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
9956 { TestRound(kGetProxy, kServerChallenge, OK),
9957 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
9958 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
9959 { TestRound(kGetProxy, kServerChallenge, OK),
9960 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
9961 // Non-authenticating HTTP server through an authenticating proxy.
9962 { kProxy, AUTH_SYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
9963 { TestRound(kGetProxy, kProxyChallenge, OK),
9964 TestRound(kGetProxyAuth, kSuccess, OK)}},
9965 { kProxy, AUTH_SYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
9966 { TestRound(kGetProxy, kProxyChallenge, OK),
9967 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
9968 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
9969 { TestRound(kGetProxy, kProxyChallenge, OK),
9970 TestRound(kGetProxyAuth, kSuccess, OK)}},
9971 { kProxy, AUTH_ASYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
9972 { TestRound(kGetProxy, kProxyChallenge, OK),
9973 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
9974 // Authenticating HTTP server through an authenticating proxy.
9975 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
9976 { TestRound(kGetProxy, kProxyChallenge, OK),
9977 TestRound(kGetProxyAuth, kServerChallenge, OK),
9978 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9979 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
9980 { TestRound(kGetProxy, kProxyChallenge, OK),
9981 TestRound(kGetProxyAuth, kServerChallenge, OK),
9982 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9983 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
9984 { TestRound(kGetProxy, kProxyChallenge, OK),
9985 TestRound(kGetProxyAuth, kServerChallenge, OK),
9986 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9987 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
9988 { TestRound(kGetProxy, kProxyChallenge, OK),
9989 TestRound(kGetProxyAuth, kServerChallenge, OK),
9990 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9991 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
9992 { TestRound(kGetProxy, kProxyChallenge, OK),
9993 TestRound(kGetProxyAuth, kServerChallenge, OK),
9994 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9995 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
9996 { TestRound(kGetProxy, kProxyChallenge, OK),
9997 TestRound(kGetProxyAuth, kServerChallenge, OK),
9998 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9999 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
10000 { TestRound(kGetProxy, kProxyChallenge, OK),
10001 TestRound(kGetProxyAuth, kServerChallenge, OK),
10002 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
10003 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
10004 { TestRound(kGetProxy, kProxyChallenge, OK),
10005 TestRound(kGetProxyAuth, kServerChallenge, OK),
10006 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
10007 // Non-authenticating HTTPS server with a direct connection.
10008 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
10009 { TestRound(kGet, kSuccess, OK)}},
10010 // Authenticating HTTPS server with a direct connection.
10011 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
10012 { TestRound(kGet, kServerChallenge, OK),
10013 TestRound(kGetAuth, kSuccess, OK)}},
10014 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
10015 { TestRound(kGet, kServerChallenge, OK),
10016 TestRound(kGetAuth, kFailure, kAuthErr)}},
10017 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
10018 { TestRound(kGet, kServerChallenge, OK),
10019 TestRound(kGetAuth, kSuccess, OK)}},
10020 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
10021 { TestRound(kGet, kServerChallenge, OK),
10022 TestRound(kGetAuth, kFailure, kAuthErr)}},
10023 // Non-authenticating HTTPS server with a non-authenticating proxy.
10024 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
10025 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
10026 // Authenticating HTTPS server through a non-authenticating proxy.
10027 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
10028 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
10029 TestRound(kGetAuth, kSuccess, OK)}},
10030 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
10031 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
10032 TestRound(kGetAuth, kFailure, kAuthErr)}},
10033 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
10034 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
10035 TestRound(kGetAuth, kSuccess, OK)}},
10036 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
10037 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
10038 TestRound(kGetAuth, kFailure, kAuthErr)}},
10039 // Non-Authenticating HTTPS server through an authenticating proxy.
10040 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
10041 { TestRound(kConnect, kProxyChallenge, OK),
10042 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
10043 { kProxy, AUTH_SYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
10044 { TestRound(kConnect, kProxyChallenge, OK),
10045 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
10046 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
10047 { TestRound(kConnect, kProxyChallenge, OK),
10048 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
10049 { kProxy, AUTH_ASYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
10050 { TestRound(kConnect, kProxyChallenge, OK),
10051 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
10052 // Authenticating HTTPS server through an authenticating proxy.
10053 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
10054 { TestRound(kConnect, kProxyChallenge, OK),
10055 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10056 &kGet, &kServerChallenge),
10057 TestRound(kGetAuth, kSuccess, OK)}},
10058 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
10059 { TestRound(kConnect, kProxyChallenge, OK),
10060 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10061 &kGet, &kServerChallenge),
10062 TestRound(kGetAuth, kFailure, kAuthErr)}},
10063 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
10064 { TestRound(kConnect, kProxyChallenge, OK),
10065 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10066 &kGet, &kServerChallenge),
10067 TestRound(kGetAuth, kSuccess, OK)}},
10068 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
10069 { TestRound(kConnect, kProxyChallenge, OK),
10070 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10071 &kGet, &kServerChallenge),
10072 TestRound(kGetAuth, kFailure, kAuthErr)}},
10073 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
10074 { TestRound(kConnect, kProxyChallenge, OK),
10075 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10076 &kGet, &kServerChallenge),
10077 TestRound(kGetAuth, kSuccess, OK)}},
10078 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
10079 { TestRound(kConnect, kProxyChallenge, OK),
10080 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10081 &kGet, &kServerChallenge),
10082 TestRound(kGetAuth, kFailure, kAuthErr)}},
10083 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
10084 { TestRound(kConnect, kProxyChallenge, OK),
10085 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10086 &kGet, &kServerChallenge),
10087 TestRound(kGetAuth, kSuccess, OK)}},
10088 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
10089 { TestRound(kConnect, kProxyChallenge, OK),
10090 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10091 &kGet, &kServerChallenge),
10092 TestRound(kGetAuth, kFailure, kAuthErr)}},
10093 };
10094
viettrungluue4a8b882014-10-16 06:17:3810095 for (size_t i = 0; i < arraysize(test_configs); ++i) {
[email protected]2d01c262011-08-11 23:07:0810096 HttpAuthHandlerMock::Factory* auth_factory(
10097 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0710098 session_deps_.http_auth_handler_factory.reset(auth_factory);
[email protected]044de0642010-06-17 10:42:1510099 const TestConfig& test_config = test_configs[i];
[email protected]65d34382010-07-01 18:12:2610100
10101 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:1510102 if (test_config.proxy_auth_timing != AUTH_NONE) {
[email protected]2d01c262011-08-11 23:07:0810103 for (int n = 0; n < 2; n++) {
10104 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
10105 std::string auth_challenge = "Mock realm=proxy";
10106 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:2410107 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
10108 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:0810109 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
10110 origin, BoundNetLog());
10111 auth_handler->SetGenerateExpectation(
10112 test_config.proxy_auth_timing == AUTH_ASYNC,
10113 test_config.proxy_auth_rv);
10114 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
10115 }
[email protected]044de0642010-06-17 10:42:1510116 }
10117 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:0010118 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:1510119 std::string auth_challenge = "Mock realm=server";
10120 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:2410121 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
10122 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:1510123 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
10124 origin, BoundNetLog());
10125 auth_handler->SetGenerateExpectation(
10126 test_config.server_auth_timing == AUTH_ASYNC,
10127 test_config.server_auth_rv);
[email protected]2d01c262011-08-11 23:07:0810128 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:1510129 }
10130 if (test_config.proxy_url) {
[email protected]bb88e1d32013-05-03 23:11:0710131 session_deps_.proxy_service.reset(
[email protected]6104ea5d2011-04-27 21:37:1210132 ProxyService::CreateFixed(test_config.proxy_url));
[email protected]044de0642010-06-17 10:42:1510133 } else {
[email protected]bb88e1d32013-05-03 23:11:0710134 session_deps_.proxy_service.reset(ProxyService::CreateDirect());
[email protected]044de0642010-06-17 10:42:1510135 }
10136
10137 HttpRequestInfo request;
10138 request.method = "GET";
10139 request.url = GURL(test_config.server_url);
10140 request.load_flags = 0;
10141
[email protected]bb88e1d32013-05-03 23:11:0710142 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
dcheng48459ac22014-08-26 00:46:4110143 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]044de0642010-06-17 10:42:1510144
10145 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
10146 const TestRound& read_write_round = test_config.rounds[round];
10147
10148 // Set up expected reads and writes.
10149 MockRead reads[2];
10150 reads[0] = read_write_round.read;
10151 size_t length_reads = 1;
10152 if (read_write_round.extra_read) {
10153 reads[1] = *read_write_round.extra_read;
10154 length_reads = 2;
10155 }
10156
10157 MockWrite writes[2];
10158 writes[0] = read_write_round.write;
10159 size_t length_writes = 1;
10160 if (read_write_round.extra_write) {
10161 writes[1] = *read_write_round.extra_write;
10162 length_writes = 2;
10163 }
10164 StaticSocketDataProvider data_provider(
10165 reads, length_reads, writes, length_writes);
[email protected]bb88e1d32013-05-03 23:11:0710166 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]044de0642010-06-17 10:42:1510167
10168 // Add an SSL sequence if necessary.
[email protected]8ddf8322012-02-23 18:08:0610169 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
[email protected]044de0642010-06-17 10:42:1510170 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0710171 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1510172 &ssl_socket_data_provider);
10173
10174 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4110175 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1510176 int rv;
10177 if (round == 0) {
[email protected]49639fa2011-12-20 23:22:4110178 rv = trans.Start(&request, callback.callback(), BoundNetLog());
[email protected]044de0642010-06-17 10:42:1510179 } else {
[email protected]49639fa2011-12-20 23:22:4110180 rv = trans.RestartWithAuth(
10181 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1510182 }
10183 if (rv == ERR_IO_PENDING)
10184 rv = callback.WaitForResult();
10185
10186 // Compare results with expected data.
10187 EXPECT_EQ(read_write_round.expected_rv, rv);
[email protected]0b0bf032010-09-21 18:08:5010188 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]044de0642010-06-17 10:42:1510189 if (read_write_round.expected_rv == OK) {
[email protected]fe2255a2011-09-20 19:37:5010190 ASSERT_TRUE(response != NULL);
[email protected]044de0642010-06-17 10:42:1510191 } else {
10192 EXPECT_TRUE(response == NULL);
10193 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
10194 continue;
10195 }
10196 if (round + 1 < test_config.num_auth_rounds) {
10197 EXPECT_FALSE(response->auth_challenge.get() == NULL);
10198 } else {
10199 EXPECT_TRUE(response->auth_challenge.get() == NULL);
10200 }
10201 }
[email protected]e5ae96a2010-04-14 20:12:4510202 }
10203}
10204
[email protected]23e482282013-06-14 16:08:0210205TEST_P(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1410206 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1410207 HttpAuthHandlerMock::Factory* auth_factory(
10208 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0710209 session_deps_.http_auth_handler_factory.reset(auth_factory);
10210 session_deps_.proxy_service.reset(ProxyService::CreateDirect());
10211 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
10212 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:1410213
10214 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
10215 auth_handler->set_connection_based(true);
10216 std::string auth_challenge = "Mock realm=server";
10217 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2410218 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
10219 auth_challenge.end());
[email protected]c871bce92010-07-15 21:51:1410220 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
10221 origin, BoundNetLog());
[email protected]2d01c262011-08-11 23:07:0810222 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1410223
[email protected]c871bce92010-07-15 21:51:1410224 int rv = OK;
10225 const HttpResponseInfo* response = NULL;
10226 HttpRequestInfo request;
10227 request.method = "GET";
10228 request.url = origin;
10229 request.load_flags = 0;
[email protected]cb9bf6ca2011-01-28 13:15:2710230
[email protected]bb88e1d32013-05-03 23:11:0710231 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1010232
10233 // Use a TCP Socket Pool with only one connection per group. This is used
10234 // to validate that the TCP socket is not released to the pool between
10235 // each round of multi-round authentication.
10236 HttpNetworkSessionPeer session_peer(session);
[email protected]ab739042011-04-07 15:22:2810237 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:1010238 50, // Max sockets for pool
10239 1, // Max sockets per group
[email protected]bb88e1d32013-05-03 23:11:0710240 session_deps_.host_resolver.get(),
10241 session_deps_.socket_factory.get(),
10242 session_deps_.net_log);
[email protected]831e4a32013-11-14 02:14:4410243 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
10244 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:0210245 mock_pool_manager->SetTransportSocketPool(transport_pool);
dchenge3d1ddc2014-10-15 19:30:5110246 session_peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]7ef4cbbb2011-02-06 11:19:1010247
[email protected]262eec82013-03-19 21:01:3610248 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010249 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110250 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1410251
10252 const MockWrite kGet(
10253 "GET / HTTP/1.1\r\n"
10254 "Host: www.example.com\r\n"
10255 "Connection: keep-alive\r\n\r\n");
10256 const MockWrite kGetAuth(
10257 "GET / HTTP/1.1\r\n"
10258 "Host: www.example.com\r\n"
10259 "Connection: keep-alive\r\n"
10260 "Authorization: auth_token\r\n\r\n");
10261
10262 const MockRead kServerChallenge(
10263 "HTTP/1.1 401 Unauthorized\r\n"
10264 "WWW-Authenticate: Mock realm=server\r\n"
10265 "Content-Type: text/html; charset=iso-8859-1\r\n"
10266 "Content-Length: 14\r\n\r\n"
10267 "Unauthorized\r\n");
10268 const MockRead kSuccess(
10269 "HTTP/1.1 200 OK\r\n"
10270 "Content-Type: text/html; charset=iso-8859-1\r\n"
10271 "Content-Length: 3\r\n\r\n"
10272 "Yes");
10273
10274 MockWrite writes[] = {
10275 // First round
10276 kGet,
10277 // Second round
10278 kGetAuth,
10279 // Third round
10280 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3010281 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1010282 kGetAuth,
10283 // Competing request
10284 kGet,
[email protected]c871bce92010-07-15 21:51:1410285 };
10286 MockRead reads[] = {
10287 // First round
10288 kServerChallenge,
10289 // Second round
10290 kServerChallenge,
10291 // Third round
[email protected]eca50e122010-09-11 14:03:3010292 kServerChallenge,
10293 // Fourth round
[email protected]c871bce92010-07-15 21:51:1410294 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1010295 // Competing response
10296 kSuccess,
[email protected]c871bce92010-07-15 21:51:1410297 };
10298 StaticSocketDataProvider data_provider(reads, arraysize(reads),
10299 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:0710300 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1410301
thestig9d3bb0c2015-01-24 00:49:5110302 const char kSocketGroup[] = "www.example.com:80";
[email protected]7ef4cbbb2011-02-06 11:19:1010303
10304 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1410305 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4110306 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]c871bce92010-07-15 21:51:1410307 if (rv == ERR_IO_PENDING)
10308 rv = callback.WaitForResult();
10309 EXPECT_EQ(OK, rv);
10310 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010311 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:1410312 EXPECT_FALSE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2810313 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1410314
[email protected]7ef4cbbb2011-02-06 11:19:1010315 // In between rounds, another request comes in for the same domain.
10316 // It should not be able to grab the TCP socket that trans has already
10317 // claimed.
10318 scoped_ptr<HttpTransaction> trans_compete(
[email protected]90499482013-06-01 00:39:5010319 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110320 TestCompletionCallback callback_compete;
10321 rv = trans_compete->Start(
10322 &request, callback_compete.callback(), BoundNetLog());
[email protected]7ef4cbbb2011-02-06 11:19:1010323 EXPECT_EQ(ERR_IO_PENDING, rv);
10324 // callback_compete.WaitForResult at this point would stall forever,
10325 // since the HttpNetworkTransaction does not release the request back to
10326 // the pool until after authentication completes.
10327
10328 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1410329 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4110330 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1410331 if (rv == ERR_IO_PENDING)
10332 rv = callback.WaitForResult();
10333 EXPECT_EQ(OK, rv);
10334 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010335 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:1410336 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2810337 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1410338
[email protected]7ef4cbbb2011-02-06 11:19:1010339 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1410340 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4110341 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1410342 if (rv == ERR_IO_PENDING)
10343 rv = callback.WaitForResult();
10344 EXPECT_EQ(OK, rv);
10345 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010346 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:1410347 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2810348 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]eca50e122010-09-11 14:03:3010349
[email protected]7ef4cbbb2011-02-06 11:19:1010350 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3010351 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4110352 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3010353 if (rv == ERR_IO_PENDING)
10354 rv = callback.WaitForResult();
10355 EXPECT_EQ(OK, rv);
10356 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010357 ASSERT_TRUE(response != NULL);
[email protected]eca50e122010-09-11 14:03:3010358 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2810359 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1010360
10361 // Read the body since the fourth round was successful. This will also
10362 // release the socket back to the pool.
10363 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
[email protected]90499482013-06-01 00:39:5010364 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1010365 if (rv == ERR_IO_PENDING)
10366 rv = callback.WaitForResult();
10367 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:5010368 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1010369 EXPECT_EQ(0, rv);
10370 // There are still 0 idle sockets, since the trans_compete transaction
10371 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:2810372 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1010373
10374 // The competing request can now finish. Wait for the headers and then
10375 // read the body.
10376 rv = callback_compete.WaitForResult();
10377 EXPECT_EQ(OK, rv);
[email protected]90499482013-06-01 00:39:5010378 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1010379 if (rv == ERR_IO_PENDING)
10380 rv = callback.WaitForResult();
10381 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:5010382 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1010383 EXPECT_EQ(0, rv);
10384
10385 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:2810386 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1410387}
10388
[email protected]65041fa2010-05-21 06:56:5310389// This tests the case that a request is issued via http instead of spdy after
10390// npn is negotiated.
[email protected]23e482282013-06-14 16:08:0210391TEST_P(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]d7599122014-05-24 03:37:2310392 session_deps_.use_alternate_protocols = true;
10393 NextProtoVector next_protos;
[email protected]0ce3af82013-07-22 16:17:1610394 next_protos.push_back(kProtoHTTP11);
[email protected]d7599122014-05-24 03:37:2310395 session_deps_.next_protos = next_protos;
10396
[email protected]65041fa2010-05-21 06:56:5310397 HttpRequestInfo request;
10398 request.method = "GET";
bncce36dca22015-04-21 22:11:2310399 request.url = GURL("https://www.example.org/");
[email protected]65041fa2010-05-21 06:56:5310400 request.load_flags = 0;
10401
10402 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310403 MockWrite(
10404 "GET / HTTP/1.1\r\n"
10405 "Host: www.example.org\r\n"
10406 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5310407 };
10408
[email protected]8a0fc822013-06-27 20:52:4310409 std::string alternate_protocol_http_header =
10410 GetAlternateProtocolHttpHeader();
10411
[email protected]65041fa2010-05-21 06:56:5310412 MockRead data_reads[] = {
10413 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:4310414 MockRead(alternate_protocol_http_header.c_str()),
[email protected]65041fa2010-05-21 06:56:5310415 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610416 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5310417 };
10418
[email protected]8ddf8322012-02-23 18:08:0610419 SSLSocketDataProvider ssl(ASYNC, OK);
davidben6974bf72015-04-27 17:52:4810420 ssl.SetNextProto(kProtoHTTP11);
[email protected]65041fa2010-05-21 06:56:5310421
[email protected]bb88e1d32013-05-03 23:11:0710422 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5310423
10424 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
10425 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0710426 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5310427
[email protected]49639fa2011-12-20 23:22:4110428 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5310429
[email protected]bb88e1d32013-05-03 23:11:0710430 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610431 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010432 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]65041fa2010-05-21 06:56:5310433
[email protected]49639fa2011-12-20 23:22:4110434 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]65041fa2010-05-21 06:56:5310435
10436 EXPECT_EQ(ERR_IO_PENDING, rv);
10437 EXPECT_EQ(OK, callback.WaitForResult());
10438
10439 const HttpResponseInfo* response = trans->GetResponseInfo();
10440 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010441 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]65041fa2010-05-21 06:56:5310442 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10443
10444 std::string response_data;
10445 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10446 EXPECT_EQ("hello world", response_data);
10447
10448 EXPECT_FALSE(response->was_fetched_via_spdy);
10449 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]65041fa2010-05-21 06:56:5310450}
[email protected]26ef6582010-06-24 02:30:4710451
[email protected]23e482282013-06-14 16:08:0210452TEST_P(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:4710453 // Simulate the SSL handshake completing with an NPN negotiation
10454 // followed by an immediate server closing of the socket.
10455 // Fix crash: http://crbug.com/46369
[email protected]d7599122014-05-24 03:37:2310456 session_deps_.use_alternate_protocols = true;
10457 session_deps_.next_protos = SpdyNextProtos();
[email protected]26ef6582010-06-24 02:30:4710458
10459 HttpRequestInfo request;
10460 request.method = "GET";
bncce36dca22015-04-21 22:11:2310461 request.url = GURL("https://www.example.org/");
[email protected]26ef6582010-06-24 02:30:4710462 request.load_flags = 0;
10463
[email protected]8ddf8322012-02-23 18:08:0610464 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210465 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710466 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4710467
[email protected]cdf8f7e72013-05-23 10:56:4610468 scoped_ptr<SpdyFrame> req(
10469 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
rch8e6c6c42015-05-01 14:05:1310470 MockWrite spdy_writes[] = {CreateMockWrite(*req, 1)};
[email protected]26ef6582010-06-24 02:30:4710471
10472 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0610473 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4710474 };
10475
rch8e6c6c42015-05-01 14:05:1310476 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10477 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710478 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4710479
[email protected]49639fa2011-12-20 23:22:4110480 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4710481
[email protected]bb88e1d32013-05-03 23:11:0710482 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610483 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010484 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]26ef6582010-06-24 02:30:4710485
[email protected]49639fa2011-12-20 23:22:4110486 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]26ef6582010-06-24 02:30:4710487 EXPECT_EQ(ERR_IO_PENDING, rv);
10488 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult());
[email protected]26ef6582010-06-24 02:30:4710489}
[email protected]65d34382010-07-01 18:12:2610490
[email protected]795cbf82013-07-22 09:37:2710491// A subclass of HttpAuthHandlerMock that records the request URL when
10492// it gets it. This is needed since the auth handler may get destroyed
10493// before we get a chance to query it.
10494class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
10495 public:
10496 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
10497
dchengb03027d2014-10-21 12:00:2010498 ~UrlRecordingHttpAuthHandlerMock() override {}
[email protected]795cbf82013-07-22 09:37:2710499
10500 protected:
dchengb03027d2014-10-21 12:00:2010501 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
10502 const HttpRequestInfo* request,
10503 const CompletionCallback& callback,
10504 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2710505 *url_ = request->url;
10506 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
10507 credentials, request, callback, auth_token);
10508 }
10509
10510 private:
10511 GURL* url_;
10512};
10513
[email protected]23e482282013-06-14 16:08:0210514TEST_P(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) {
[email protected]f45c1ee2010-08-03 00:54:3010515 // This test ensures that the URL passed into the proxy is upgraded
10516 // to https when doing an Alternate Protocol upgrade.
[email protected]d7599122014-05-24 03:37:2310517 session_deps_.use_alternate_protocols = true;
10518 session_deps_.next_protos = SpdyNextProtos();
[email protected]f45c1ee2010-08-03 00:54:3010519
[email protected]bb88e1d32013-05-03 23:11:0710520 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:2010521 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
vishal.b62985ca92015-04-17 08:45:5110522 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710523 session_deps_.net_log = &net_log;
[email protected]795cbf82013-07-22 09:37:2710524 GURL request_url;
10525 {
10526 HttpAuthHandlerMock::Factory* auth_factory =
10527 new HttpAuthHandlerMock::Factory();
10528 UrlRecordingHttpAuthHandlerMock* auth_handler =
10529 new UrlRecordingHttpAuthHandlerMock(&request_url);
10530 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
10531 auth_factory->set_do_init_from_challenge(true);
10532 session_deps_.http_auth_handler_factory.reset(auth_factory);
10533 }
[email protected]f45c1ee2010-08-03 00:54:3010534
10535 HttpRequestInfo request;
10536 request.method = "GET";
bncce36dca22015-04-21 22:11:2310537 request.url = GURL("http://www.example.org");
[email protected]f45c1ee2010-08-03 00:54:3010538 request.load_flags = 0;
10539
10540 // First round goes unauthenticated through the proxy.
10541 MockWrite data_writes_1[] = {
bncce36dca22015-04-21 22:11:2310542 MockWrite(
10543 "GET http://www.example.org/ HTTP/1.1\r\n"
10544 "Host: www.example.org\r\n"
10545 "Proxy-Connection: keep-alive\r\n"
10546 "\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3010547 };
10548 MockRead data_reads_1[] = {
[email protected]8ddf8322012-02-23 18:08:0610549 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
bnc33b8cef42014-11-19 17:30:3810550 MockRead("HTTP/1.1 200 OK\r\n"),
10551 MockRead("Alternate-Protocol: 443:"),
10552 MockRead(GetAlternateProtocolFromParam()),
10553 MockRead("\r\n"),
10554 MockRead("Proxy-Connection: close\r\n"),
10555 MockRead("\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3010556 };
10557 StaticSocketDataProvider data_1(data_reads_1, arraysize(data_reads_1),
10558 data_writes_1, arraysize(data_writes_1));
10559
bncce36dca22015-04-21 22:11:2310560 // Second round tries to tunnel to www.example.org due to the
[email protected]f45c1ee2010-08-03 00:54:3010561 // Alternate-Protocol announcement in the first round. It fails due
10562 // to a proxy authentication challenge.
bncce36dca22015-04-21 22:11:2310563 // After the failure, a tunnel is established to www.example.org using
[email protected]394816e92010-08-03 07:38:5910564 // Proxy-Authorization headers. There is then a SPDY request round.
10565 //
[email protected]fe3b7dc2012-02-03 19:52:0910566 // NOTE: Despite the "Proxy-Connection: Close", these are done on the
10567 // same MockTCPClientSocket since the underlying HttpNetworkClientSocket
10568 // does a Disconnect and Connect on the same socket, rather than trying
10569 // to obtain a new one.
10570 //
[email protected]394816e92010-08-03 07:38:5910571 // NOTE: Originally, the proxy response to the second CONNECT request
10572 // simply returned another 407 so the unit test could skip the SSL connection
10573 // establishment and SPDY framing issues. Alas, the
10574 // retry-http-when-alternate-protocol fails logic kicks in, which was more
[email protected]f45c1ee2010-08-03 00:54:3010575 // complicated to set up expectations for than the SPDY session.
[email protected]394816e92010-08-03 07:38:5910576
[email protected]cdf8f7e72013-05-23 10:56:4610577 scoped_ptr<SpdyFrame> req(
10578 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]23e482282013-06-14 16:08:0210579 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10580 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]f45c1ee2010-08-03 00:54:3010581
[email protected]394816e92010-08-03 07:38:5910582 MockWrite data_writes_2[] = {
bncce36dca22015-04-21 22:11:2310583 // First connection attempt without Proxy-Authorization.
rch8e6c6c42015-05-01 14:05:1310584 MockWrite(ASYNC, 0,
10585 "CONNECT www.example.org:443 HTTP/1.1\r\n"
10586 "Host: www.example.org\r\n"
10587 "Proxy-Connection: keep-alive\r\n"
10588 "\r\n"),
[email protected]394816e92010-08-03 07:38:5910589
bncce36dca22015-04-21 22:11:2310590 // Second connection attempt with Proxy-Authorization.
rch8e6c6c42015-05-01 14:05:1310591 MockWrite(ASYNC, 2,
10592 "CONNECT www.example.org:443 HTTP/1.1\r\n"
10593 "Host: www.example.org\r\n"
10594 "Proxy-Connection: keep-alive\r\n"
10595 "Proxy-Authorization: auth_token\r\n"
10596 "\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3010597
bncce36dca22015-04-21 22:11:2310598 // SPDY request
rch8e6c6c42015-05-01 14:05:1310599 CreateMockWrite(*req, 4),
[email protected]f45c1ee2010-08-03 00:54:3010600 };
[email protected]394816e92010-08-03 07:38:5910601 const char kRejectConnectResponse[] = ("HTTP/1.1 407 Unauthorized\r\n"
10602 "Proxy-Authenticate: Mock\r\n"
10603 "Proxy-Connection: close\r\n"
10604 "\r\n");
10605 const char kAcceptConnectResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
10606 MockRead data_reads_2[] = {
rch8e6c6c42015-05-01 14:05:1310607 // First connection attempt fails
10608 MockRead(ASYNC, kRejectConnectResponse,
10609 arraysize(kRejectConnectResponse) - 1, 1),
[email protected]394816e92010-08-03 07:38:5910610
rch8e6c6c42015-05-01 14:05:1310611 // Second connection attempt passes
10612 MockRead(ASYNC, kAcceptConnectResponse,
10613 arraysize(kAcceptConnectResponse) - 1, 3),
[email protected]394816e92010-08-03 07:38:5910614
rch8e6c6c42015-05-01 14:05:1310615 // SPDY response
10616 CreateMockRead(*resp.get(), 5),
10617 CreateMockRead(*data.get(), 6),
10618 MockRead(ASYNC, 0, 0, 7),
[email protected]394816e92010-08-03 07:38:5910619 };
rch8e6c6c42015-05-01 14:05:1310620 SequencedSocketData data_2(data_reads_2, arraysize(data_reads_2),
10621 data_writes_2, arraysize(data_writes_2));
[email protected]f45c1ee2010-08-03 00:54:3010622
[email protected]8ddf8322012-02-23 18:08:0610623 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210624 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:2310625 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
10626 ASSERT_TRUE(ssl.cert.get());
[email protected]f45c1ee2010-08-03 00:54:3010627
[email protected]d973e99a2012-02-17 21:02:3610628 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5510629 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
10630 NULL, 0, NULL, 0);
10631 hanging_non_alternate_protocol_socket.set_connect_data(
10632 never_finishing_connect);
10633
[email protected]bb88e1d32013-05-03 23:11:0710634 session_deps_.socket_factory->AddSocketDataProvider(&data_1);
10635 session_deps_.socket_factory->AddSocketDataProvider(&data_2);
10636 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10637 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5510638 &hanging_non_alternate_protocol_socket);
[email protected]bb88e1d32013-05-03 23:11:0710639 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f45c1ee2010-08-03 00:54:3010640
10641 // First round should work and provide the Alternate-Protocol state.
[email protected]49639fa2011-12-20 23:22:4110642 TestCompletionCallback callback_1;
[email protected]262eec82013-03-19 21:01:3610643 scoped_ptr<HttpTransaction> trans_1(
[email protected]90499482013-06-01 00:39:5010644 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110645 int rv = trans_1->Start(&request, callback_1.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:3010646 EXPECT_EQ(ERR_IO_PENDING, rv);
10647 EXPECT_EQ(OK, callback_1.WaitForResult());
10648
10649 // Second round should attempt a tunnel connect and get an auth challenge.
[email protected]49639fa2011-12-20 23:22:4110650 TestCompletionCallback callback_2;
[email protected]262eec82013-03-19 21:01:3610651 scoped_ptr<HttpTransaction> trans_2(
[email protected]90499482013-06-01 00:39:5010652 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110653 rv = trans_2->Start(&request, callback_2.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:3010654 EXPECT_EQ(ERR_IO_PENDING, rv);
10655 EXPECT_EQ(OK, callback_2.WaitForResult());
10656 const HttpResponseInfo* response = trans_2->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010657 ASSERT_TRUE(response != NULL);
[email protected]f45c1ee2010-08-03 00:54:3010658 ASSERT_FALSE(response->auth_challenge.get() == NULL);
10659
10660 // Restart with auth. Tunnel should work and response received.
[email protected]49639fa2011-12-20 23:22:4110661 TestCompletionCallback callback_3;
10662 rv = trans_2->RestartWithAuth(
10663 AuthCredentials(kFoo, kBar), callback_3.callback());
[email protected]f45c1ee2010-08-03 00:54:3010664 EXPECT_EQ(ERR_IO_PENDING, rv);
10665 EXPECT_EQ(OK, callback_3.WaitForResult());
10666
10667 // After all that work, these two lines (or actually, just the scheme) are
10668 // what this test is all about. Make sure it happens correctly.
[email protected]f45c1ee2010-08-03 00:54:3010669 EXPECT_EQ("https", request_url.scheme());
bncce36dca22015-04-21 22:11:2310670 EXPECT_EQ("www.example.org", request_url.host());
[email protected]f45c1ee2010-08-03 00:54:3010671
[email protected]029c83b62013-01-24 05:28:2010672 LoadTimingInfo load_timing_info;
10673 EXPECT_TRUE(trans_2->GetLoadTimingInfo(&load_timing_info));
10674 TestLoadTimingNotReusedWithPac(load_timing_info,
10675 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]8e6441ca2010-08-19 05:56:3810676}
10677
10678// Test that if we cancel the transaction as the connection is completing, that
10679// everything tears down correctly.
[email protected]23e482282013-06-14 16:08:0210680TEST_P(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3810681 // Setup everything about the connection to complete synchronously, so that
10682 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
10683 // for is the callback from the HttpStreamRequest.
10684 // Then cancel the transaction.
10685 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3610686 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3810687 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0610688 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
10689 MockRead(SYNCHRONOUS, "hello world"),
10690 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3810691 };
10692
[email protected]8e6441ca2010-08-19 05:56:3810693 HttpRequestInfo request;
10694 request.method = "GET";
bncce36dca22015-04-21 22:11:2310695 request.url = GURL("http://www.example.org/");
[email protected]8e6441ca2010-08-19 05:56:3810696 request.load_flags = 0;
10697
[email protected]bb88e1d32013-05-03 23:11:0710698 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]3fe8d2f82013-10-17 08:56:0710699 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:2710700 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4110701 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:2710702
[email protected]8e6441ca2010-08-19 05:56:3810703 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10704 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710705 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3810706
[email protected]49639fa2011-12-20 23:22:4110707 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3810708
vishal.b62985ca92015-04-17 08:45:5110709 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4110710 int rv = trans->Start(&request, callback.callback(), log.bound());
[email protected]8e6441ca2010-08-19 05:56:3810711 EXPECT_EQ(ERR_IO_PENDING, rv);
10712 trans.reset(); // Cancel the transaction here.
10713
[email protected]2da659e2013-05-23 20:51:3410714 base::MessageLoop::current()->RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3010715}
10716
[email protected]ecab6e052014-05-16 14:58:1210717// Test that if a transaction is cancelled after receiving the headers, the
10718// stream is drained properly and added back to the socket pool. The main
10719// purpose of this test is to make sure that an HttpStreamParser can be read
10720// from after the HttpNetworkTransaction and the objects it owns have been
10721// deleted.
10722// See http://crbug.com/368418
10723TEST_P(HttpNetworkTransactionTest, CancelAfterHeaders) {
10724 MockRead data_reads[] = {
10725 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
10726 MockRead(ASYNC, "Content-Length: 2\r\n"),
10727 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
10728 MockRead(ASYNC, "1"),
10729 // 2 async reads are necessary to trigger a ReadResponseBody call after the
10730 // HttpNetworkTransaction has been deleted.
10731 MockRead(ASYNC, "2"),
10732 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
10733 };
10734 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10735 session_deps_.socket_factory->AddSocketDataProvider(&data);
10736
10737 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10738
10739 {
10740 HttpRequestInfo request;
10741 request.method = "GET";
bncce36dca22015-04-21 22:11:2310742 request.url = GURL("http://www.example.org/");
[email protected]ecab6e052014-05-16 14:58:1210743 request.load_flags = 0;
10744
dcheng48459ac22014-08-26 00:46:4110745 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1210746 TestCompletionCallback callback;
10747
10748 int rv = trans.Start(&request, callback.callback(), BoundNetLog());
10749 EXPECT_EQ(ERR_IO_PENDING, rv);
10750 callback.WaitForResult();
10751
10752 const HttpResponseInfo* response = trans.GetResponseInfo();
10753 ASSERT_TRUE(response != NULL);
10754 EXPECT_TRUE(response->headers.get() != NULL);
10755 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10756
10757 // The transaction and HttpRequestInfo are deleted.
10758 }
10759
10760 // Let the HttpResponseBodyDrainer drain the socket.
10761 base::MessageLoop::current()->RunUntilIdle();
10762
10763 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4110764 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1210765}
10766
[email protected]76a505b2010-08-25 06:23:0010767// Test a basic GET request through a proxy.
[email protected]23e482282013-06-14 16:08:0210768TEST_P(HttpNetworkTransactionTest, ProxyGet) {
[email protected]bb88e1d32013-05-03 23:11:0710769 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:2010770 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
vishal.b62985ca92015-04-17 08:45:5110771 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710772 session_deps_.net_log = log.bound().net_log();
10773 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0010774
[email protected]76a505b2010-08-25 06:23:0010775 HttpRequestInfo request;
10776 request.method = "GET";
bncce36dca22015-04-21 22:11:2310777 request.url = GURL("http://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0010778
10779 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2310780 MockWrite(
10781 "GET http://www.example.org/ HTTP/1.1\r\n"
10782 "Host: www.example.org\r\n"
10783 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0010784 };
10785
10786 MockRead data_reads1[] = {
10787 MockRead("HTTP/1.1 200 OK\r\n"),
10788 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10789 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610790 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0010791 };
10792
10793 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10794 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710795 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0010796
[email protected]49639fa2011-12-20 23:22:4110797 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0010798
[email protected]262eec82013-03-19 21:01:3610799 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010800 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]597a1ab2014-06-26 08:12:2710801 BeforeProxyHeadersSentHandler proxy_headers_handler;
10802 trans->SetBeforeProxyHeadersSentCallback(
10803 base::Bind(&BeforeProxyHeadersSentHandler::OnBeforeProxyHeadersSent,
10804 base::Unretained(&proxy_headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5010805
[email protected]49639fa2011-12-20 23:22:4110806 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0010807 EXPECT_EQ(ERR_IO_PENDING, rv);
10808
10809 rv = callback1.WaitForResult();
10810 EXPECT_EQ(OK, rv);
10811
10812 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010813 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:0010814
10815 EXPECT_TRUE(response->headers->IsKeepAlive());
10816 EXPECT_EQ(200, response->headers->response_code());
10817 EXPECT_EQ(100, response->headers->GetContentLength());
10818 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]d8fc4722014-06-13 13:17:1510819 EXPECT_TRUE(
10820 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
[email protected]597a1ab2014-06-26 08:12:2710821 EXPECT_TRUE(proxy_headers_handler.observed_before_proxy_headers_sent());
10822 EXPECT_EQ("myproxy:70", proxy_headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0010823 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2010824
10825 LoadTimingInfo load_timing_info;
10826 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10827 TestLoadTimingNotReusedWithPac(load_timing_info,
10828 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0010829}
10830
10831// Test a basic HTTPS GET request through a proxy.
[email protected]23e482282013-06-14 16:08:0210832TEST_P(HttpNetworkTransactionTest, ProxyTunnelGet) {
[email protected]bb88e1d32013-05-03 23:11:0710833 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:2010834 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
vishal.b62985ca92015-04-17 08:45:5110835 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710836 session_deps_.net_log = log.bound().net_log();
10837 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0010838
[email protected]76a505b2010-08-25 06:23:0010839 HttpRequestInfo request;
10840 request.method = "GET";
bncce36dca22015-04-21 22:11:2310841 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0010842
10843 // Since we have proxy, should try to establish tunnel.
10844 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2310845 MockWrite(
10846 "CONNECT www.example.org:443 HTTP/1.1\r\n"
10847 "Host: www.example.org\r\n"
10848 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0010849
bncce36dca22015-04-21 22:11:2310850 MockWrite(
10851 "GET / HTTP/1.1\r\n"
10852 "Host: www.example.org\r\n"
10853 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0010854 };
10855
10856 MockRead data_reads1[] = {
10857 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
10858
10859 MockRead("HTTP/1.1 200 OK\r\n"),
10860 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10861 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610862 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0010863 };
10864
10865 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10866 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710867 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0610868 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710869 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0010870
[email protected]49639fa2011-12-20 23:22:4110871 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0010872
[email protected]262eec82013-03-19 21:01:3610873 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010874 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5010875
[email protected]49639fa2011-12-20 23:22:4110876 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0010877 EXPECT_EQ(ERR_IO_PENDING, rv);
10878
10879 rv = callback1.WaitForResult();
10880 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:4610881 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4010882 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0010883 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010884 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0010885 NetLog::PHASE_NONE);
10886 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010887 entries, pos,
[email protected]76a505b2010-08-25 06:23:0010888 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
10889 NetLog::PHASE_NONE);
10890
10891 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010892 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:0010893
10894 EXPECT_TRUE(response->headers->IsKeepAlive());
10895 EXPECT_EQ(200, response->headers->response_code());
10896 EXPECT_EQ(100, response->headers->GetContentLength());
10897 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10898 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]d8fc4722014-06-13 13:17:1510899 EXPECT_TRUE(
10900 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
[email protected]029c83b62013-01-24 05:28:2010901
10902 LoadTimingInfo load_timing_info;
10903 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10904 TestLoadTimingNotReusedWithPac(load_timing_info,
10905 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0010906}
10907
10908// Test a basic HTTPS GET request through a proxy, but the server hangs up
10909// while establishing the tunnel.
[email protected]23e482282013-06-14 16:08:0210910TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
[email protected]bb88e1d32013-05-03 23:11:0710911 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
vishal.b62985ca92015-04-17 08:45:5110912 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710913 session_deps_.net_log = log.bound().net_log();
10914 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0010915
[email protected]76a505b2010-08-25 06:23:0010916 HttpRequestInfo request;
10917 request.method = "GET";
bncce36dca22015-04-21 22:11:2310918 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0010919
10920 // Since we have proxy, should try to establish tunnel.
10921 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2310922 MockWrite(
10923 "CONNECT www.example.org:443 HTTP/1.1\r\n"
10924 "Host: www.example.org\r\n"
10925 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0010926
bncce36dca22015-04-21 22:11:2310927 MockWrite(
10928 "GET / HTTP/1.1\r\n"
10929 "Host: www.example.org\r\n"
10930 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0010931 };
10932
10933 MockRead data_reads1[] = {
[email protected]8ddf8322012-02-23 18:08:0610934 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:0010935 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610936 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0010937 };
10938
10939 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10940 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710941 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0610942 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710943 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0010944
[email protected]49639fa2011-12-20 23:22:4110945 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0010946
[email protected]262eec82013-03-19 21:01:3610947 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010948 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5010949
[email protected]49639fa2011-12-20 23:22:4110950 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0010951 EXPECT_EQ(ERR_IO_PENDING, rv);
10952
10953 rv = callback1.WaitForResult();
10954 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
mmenke43758e62015-05-04 21:09:4610955 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4010956 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0010957 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010958 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0010959 NetLog::PHASE_NONE);
10960 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010961 entries, pos,
[email protected]76a505b2010-08-25 06:23:0010962 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
10963 NetLog::PHASE_NONE);
10964}
10965
[email protected]749eefa82010-09-13 22:14:0310966// Test for crbug.com/55424.
[email protected]23e482282013-06-14 16:08:0210967TEST_P(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
[email protected]cdf8f7e72013-05-23 10:56:4610968 scoped_ptr<SpdyFrame> req(
bncce36dca22015-04-21 22:11:2310969 spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
rch8e6c6c42015-05-01 14:05:1310970 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]749eefa82010-09-13 22:14:0310971
[email protected]23e482282013-06-14 16:08:0210972 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10973 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0310974 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1310975 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0310976 };
10977
rch8e6c6c42015-05-01 14:05:1310978 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10979 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710980 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0310981
[email protected]8ddf8322012-02-23 18:08:0610982 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210983 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710984 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0310985
[email protected]bb88e1d32013-05-03 23:11:0710986 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0310987
10988 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2310989 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4010990 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5310991 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2710992 base::WeakPtr<SpdySession> spdy_session =
[email protected]41d64e82013-07-03 22:44:2610993 CreateInsecureSpdySession(session, key, BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0310994
10995 HttpRequestInfo request;
10996 request.method = "GET";
bncce36dca22015-04-21 22:11:2310997 request.url = GURL("https://www.example.org/");
[email protected]749eefa82010-09-13 22:14:0310998 request.load_flags = 0;
10999
11000 // This is the important line that marks this as a preconnect.
11001 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
11002
[email protected]262eec82013-03-19 21:01:3611003 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011004 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]749eefa82010-09-13 22:14:0311005
[email protected]41d64e82013-07-03 22:44:2611006 TestCompletionCallback callback;
[email protected]49639fa2011-12-20 23:22:4111007 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0311008 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111009 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]749eefa82010-09-13 22:14:0311010}
11011
[email protected]73b8dd222010-11-11 19:55:2411012// Given a net error, cause that error to be returned from the first Write()
11013// call and verify that the HttpTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0211014void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0711015 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2911016 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2711017 request_info.url = GURL("https://www.example.com/");
11018 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2911019 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2711020
[email protected]8ddf8322012-02-23 18:08:0611021 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2911022 MockWrite data_writes[] = {
11023 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2411024 };
ttuttle859dc7a2015-04-23 19:42:2911025 StaticSocketDataProvider data(NULL, 0, data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0711026 session_deps_.socket_factory->AddSocketDataProvider(&data);
11027 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2411028
[email protected]bb88e1d32013-05-03 23:11:0711029 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3611030 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011031 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]73b8dd222010-11-11 19:55:2411032
[email protected]49639fa2011-12-20 23:22:4111033 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2911034 int rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
11035 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2411036 rv = callback.WaitForResult();
11037 ASSERT_EQ(error, rv);
11038}
11039
[email protected]23e482282013-06-14 16:08:0211040TEST_P(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2411041 // Just check a grab bag of cert errors.
11042 static const int kErrors[] = {
11043 ERR_CERT_COMMON_NAME_INVALID,
11044 ERR_CERT_AUTHORITY_INVALID,
11045 ERR_CERT_DATE_INVALID,
11046 };
11047 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0611048 CheckErrorIsPassedBack(kErrors[i], ASYNC);
11049 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2411050 }
11051}
11052
[email protected]bd0b6772011-01-11 19:59:3011053// Ensure that a client certificate is removed from the SSL client auth
11054// cache when:
11055// 1) No proxy is involved.
11056// 2) TLS False Start is disabled.
11057// 3) The initial TLS handshake requests a client certificate.
11058// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0211059TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2311060 ClientAuthCertCache_Direct_NoFalseStart) {
ttuttle859dc7a2015-04-23 19:42:2911061 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2711062 request_info.url = GURL("https://www.example.com/");
11063 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2911064 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2711065
[email protected]bd0b6772011-01-11 19:59:3011066 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4111067 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3011068
11069 // [ssl_]data1 contains the data for the first SSL handshake. When a
11070 // CertificateRequest is received for the first time, the handshake will
11071 // be aborted to allow the caller to provide a certificate.
ttuttle859dc7a2015-04-23 19:42:2911072 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3011073 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711074 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2911075 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711076 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3011077
11078 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
11079 // False Start is not being used, the result of the SSL handshake will be
11080 // returned as part of the SSLClientSocket::Connect() call. This test
11081 // matches the result of a server sending a handshake_failure alert,
11082 // rather than a Finished message, because it requires a client
11083 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2911084 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3011085 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711086 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2911087 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711088 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3011089
11090 // [ssl_]data3 contains the data for the third SSL handshake. When a
11091 // connection to a server fails during an SSL handshake,
[email protected]80c75f682012-05-26 16:22:1711092 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
11093 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3011094 // of the HttpNetworkTransaction. Because this test failure is due to
11095 // requiring a client certificate, this fallback handshake should also
11096 // fail.
ttuttle859dc7a2015-04-23 19:42:2911097 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3011098 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711099 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2911100 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711101 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3011102
[email protected]80c75f682012-05-26 16:22:1711103 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
11104 // connection to a server fails during an SSL handshake,
11105 // HttpNetworkTransaction will attempt to fallback to SSLv3 if the previous
11106 // connection was attempted with TLSv1. This is transparent to the caller
11107 // of the HttpNetworkTransaction. Because this test failure is due to
11108 // requiring a client certificate, this fallback handshake should also
11109 // fail.
ttuttle859dc7a2015-04-23 19:42:2911110 SSLSocketDataProvider ssl_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1711111 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711112 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2911113 StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711114 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1711115
[email protected]7799de12013-05-30 05:52:5111116 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2911117 SSLSocketDataProvider ssl_data5(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]7799de12013-05-30 05:52:5111118 ssl_data5.cert_request_info = cert_request.get();
11119 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
ttuttle859dc7a2015-04-23 19:42:2911120 StaticSocketDataProvider data5(NULL, 0, NULL, 0);
[email protected]7799de12013-05-30 05:52:5111121 session_deps_.socket_factory->AddSocketDataProvider(&data5);
11122
[email protected]bb88e1d32013-05-03 23:11:0711123 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3611124 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011125 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3011126
[email protected]bd0b6772011-01-11 19:59:3011127 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4111128 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2911129 int rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
11130 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3011131
11132 // Complete the SSL handshake, which should abort due to requiring a
11133 // client certificate.
11134 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911135 ASSERT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
[email protected]bd0b6772011-01-11 19:59:3011136
11137 // Indicate that no certificate should be supplied. From the perspective
11138 // of SSLClientCertCache, NULL is just as meaningful as a real
11139 // certificate, so this is the same as supply a
11140 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4111141 rv = trans->RestartWithCertificate(NULL, callback.callback());
ttuttle859dc7a2015-04-23 19:42:2911142 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3011143
11144 // Ensure the certificate was added to the client auth cache before
11145 // allowing the connection to continue restarting.
11146 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4111147 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
11148 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3011149 ASSERT_EQ(NULL, client_cert.get());
11150
11151 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1711152 // then consume ssl_data3 and ssl_data4, both of which should also fail.
11153 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3011154 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911155 ASSERT_EQ(ERR_SSL_PROTOCOL_ERROR, rv);
[email protected]bd0b6772011-01-11 19:59:3011156
11157 // Ensure that the client certificate is removed from the cache on a
11158 // handshake failure.
[email protected]791879c2013-12-17 07:22:4111159 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11160 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3011161}
11162
11163// Ensure that a client certificate is removed from the SSL client auth
11164// cache when:
11165// 1) No proxy is involved.
11166// 2) TLS False Start is enabled.
11167// 3) The initial TLS handshake requests a client certificate.
11168// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0211169TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2311170 ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2911171 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2711172 request_info.url = GURL("https://www.example.com/");
11173 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2911174 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2711175
[email protected]bd0b6772011-01-11 19:59:3011176 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4111177 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3011178
11179 // When TLS False Start is used, SSLClientSocket::Connect() calls will
11180 // return successfully after reading up to the peer's Certificate message.
11181 // This is to allow the caller to call SSLClientSocket::Write(), which can
11182 // enqueue application data to be sent in the same packet as the
11183 // ChangeCipherSpec and Finished messages.
11184 // The actual handshake will be finished when SSLClientSocket::Read() is
11185 // called, which expects to process the peer's ChangeCipherSpec and
11186 // Finished messages. If there was an error negotiating with the peer,
11187 // such as due to the peer requiring a client certificate when none was
11188 // supplied, the alert sent by the peer won't be processed until Read() is
11189 // called.
11190
11191 // Like the non-False Start case, when a client certificate is requested by
11192 // the peer, the handshake is aborted during the Connect() call.
11193 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2911194 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3011195 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711196 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2911197 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711198 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3011199
11200 // When a client certificate is supplied, Connect() will not be aborted
11201 // when the peer requests the certificate. Instead, the handshake will
11202 // artificially succeed, allowing the caller to write the HTTP request to
11203 // the socket. The handshake messages are not processed until Read() is
11204 // called, which then detects that the handshake was aborted, due to the
11205 // peer sending a handshake_failure because it requires a client
11206 // certificate.
ttuttle859dc7a2015-04-23 19:42:2911207 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3011208 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711209 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2911210 MockRead data2_reads[] = {
11211 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3011212 };
ttuttle859dc7a2015-04-23 19:42:2911213 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711214 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3011215
11216 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1711217 // the data for the SSL handshake once the TLSv1.1 connection falls back to
11218 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2911219 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3011220 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711221 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2911222 StaticSocketDataProvider data3(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711223 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3011224
[email protected]80c75f682012-05-26 16:22:1711225 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
11226 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2911227 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1711228 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711229 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2911230 StaticSocketDataProvider data4(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711231 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1711232
[email protected]7799de12013-05-30 05:52:5111233 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2911234 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5111235 ssl_data5.cert_request_info = cert_request.get();
11236 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
ttuttle859dc7a2015-04-23 19:42:2911237 StaticSocketDataProvider data5(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]7799de12013-05-30 05:52:5111238 session_deps_.socket_factory->AddSocketDataProvider(&data5);
11239
[email protected]bb88e1d32013-05-03 23:11:0711240 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3611241 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011242 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3011243
[email protected]bd0b6772011-01-11 19:59:3011244 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4111245 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2911246 int rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
11247 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3011248
11249 // Complete the SSL handshake, which should abort due to requiring a
11250 // client certificate.
11251 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911252 ASSERT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
[email protected]bd0b6772011-01-11 19:59:3011253
11254 // Indicate that no certificate should be supplied. From the perspective
11255 // of SSLClientCertCache, NULL is just as meaningful as a real
11256 // certificate, so this is the same as supply a
11257 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4111258 rv = trans->RestartWithCertificate(NULL, callback.callback());
ttuttle859dc7a2015-04-23 19:42:2911259 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3011260
11261 // Ensure the certificate was added to the client auth cache before
11262 // allowing the connection to continue restarting.
11263 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4111264 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
11265 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3011266 ASSERT_EQ(NULL, client_cert.get());
11267
[email protected]bd0b6772011-01-11 19:59:3011268 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1711269 // then consume ssl_data3 and ssl_data4, both of which should also fail.
11270 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3011271 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911272 ASSERT_EQ(ERR_SSL_PROTOCOL_ERROR, rv);
[email protected]bd0b6772011-01-11 19:59:3011273
11274 // Ensure that the client certificate is removed from the cache on a
11275 // handshake failure.
[email protected]791879c2013-12-17 07:22:4111276 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11277 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3011278}
11279
[email protected]8c405132011-01-11 22:03:1811280// Ensure that a client certificate is removed from the SSL client auth
11281// cache when:
11282// 1) An HTTPS proxy is involved.
11283// 3) The HTTPS proxy requests a client certificate.
11284// 4) The client supplies an invalid/unacceptable certificate for the
11285// proxy.
11286// The test is repeated twice, first for connecting to an HTTPS endpoint,
11287// then for connecting to an HTTP endpoint.
[email protected]23e482282013-06-14 16:08:0211288TEST_P(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
[email protected]bb88e1d32013-05-03 23:11:0711289 session_deps_.proxy_service.reset(
[email protected]8c405132011-01-11 22:03:1811290 ProxyService::CreateFixed("https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:5111291 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0711292 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1811293
11294 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4111295 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1811296
11297 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
11298 // [ssl_]data[1-3]. Rather than represending the endpoint
11299 // (www.example.com:443), they represent failures with the HTTPS proxy
11300 // (proxy:70).
ttuttle859dc7a2015-04-23 19:42:2911301 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1811302 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711303 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2911304 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711305 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1811306
ttuttle859dc7a2015-04-23 19:42:2911307 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1811308 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711309 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2911310 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711311 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1811312
[email protected]80c75f682012-05-26 16:22:1711313 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
11314#if 0
ttuttle859dc7a2015-04-23 19:42:2911315 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1811316 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711317 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2911318 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711319 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1711320#endif
[email protected]8c405132011-01-11 22:03:1811321
ttuttle859dc7a2015-04-23 19:42:2911322 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1811323 requests[0].url = GURL("https://www.example.com/");
11324 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2911325 requests[0].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1811326
11327 requests[1].url = GURL("http://www.example.com/");
11328 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2911329 requests[1].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1811330
11331 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0711332 session_deps_.socket_factory->ResetNextMockIndexes();
11333 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c405132011-01-11 22:03:1811334 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5011335 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c405132011-01-11 22:03:1811336
11337 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4111338 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2911339 int rv = trans->Start(&requests[i], callback.callback(), BoundNetLog());
11340 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]8c405132011-01-11 22:03:1811341
11342 // Complete the SSL handshake, which should abort due to requiring a
11343 // client certificate.
11344 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911345 ASSERT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
[email protected]8c405132011-01-11 22:03:1811346
11347 // Indicate that no certificate should be supplied. From the perspective
11348 // of SSLClientCertCache, NULL is just as meaningful as a real
11349 // certificate, so this is the same as supply a
11350 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4111351 rv = trans->RestartWithCertificate(NULL, callback.callback());
ttuttle859dc7a2015-04-23 19:42:2911352 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]8c405132011-01-11 22:03:1811353
11354 // Ensure the certificate was added to the client auth cache before
11355 // allowing the connection to continue restarting.
11356 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4111357 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
11358 HostPortPair("proxy", 70), &client_cert));
[email protected]8c405132011-01-11 22:03:1811359 ASSERT_EQ(NULL, client_cert.get());
11360 // Ensure the certificate was NOT cached for the endpoint. This only
11361 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4111362 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11363 HostPortPair("www.example.com", 443), &client_cert));
[email protected]8c405132011-01-11 22:03:1811364
11365 // Restart the handshake. This will consume ssl_data2, which fails, and
11366 // then consume ssl_data3, which should also fail. The result code is
11367 // checked against what ssl_data3 should return.
11368 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911369 ASSERT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
[email protected]8c405132011-01-11 22:03:1811370
11371 // Now that the new handshake has failed, ensure that the client
11372 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4111373 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11374 HostPortPair("proxy", 70), &client_cert));
11375 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11376 HostPortPair("www.example.com", 443), &client_cert));
[email protected]8c405132011-01-11 22:03:1811377 }
11378}
11379
[email protected]23e482282013-06-14 16:08:0211380// Unlike TEST/TEST_F, which are macros that expand to further macros,
11381// TEST_P is a macro that expands directly to code that stringizes the
11382// arguments. As a result, macros passed as parameters (such as prefix
11383// or test_case_name) will not be expanded by the preprocessor. To
11384// work around this, indirect the macro for TEST_P, so that the
11385// pre-processor will expand macros such as MAYBE_test_name before
11386// instantiating the test.
11387#define WRAPPED_TEST_P(test_case_name, test_name) \
11388 TEST_P(test_case_name, test_name)
11389
[email protected]45b170822012-05-04 21:18:1411390// Times out on Win7 dbg(2) bot. http://crbug.com/124776
11391#if defined(OS_WIN)
11392#define MAYBE_UseIPConnectionPooling DISABLED_UseIPConnectionPooling
11393#else
11394#define MAYBE_UseIPConnectionPooling UseIPConnectionPooling
11395#endif
[email protected]23e482282013-06-14 16:08:0211396WRAPPED_TEST_P(HttpNetworkTransactionTest, MAYBE_UseIPConnectionPooling) {
[email protected]d7599122014-05-24 03:37:2311397 session_deps_.use_alternate_protocols = true;
11398 session_deps_.next_protos = SpdyNextProtos();
[email protected]e3ceb682011-06-28 23:55:4611399
11400 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0711401 session_deps_.host_resolver.reset(new MockCachingHostResolver());
11402 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2611403 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
11404 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4611405
[email protected]8ddf8322012-02-23 18:08:0611406 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211407 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711408 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4611409
[email protected]cdf8f7e72013-05-23 10:56:4611410 scoped_ptr<SpdyFrame> host1_req(
bncce36dca22015-04-21 22:11:2311411 spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
[email protected]cdf8f7e72013-05-23 10:56:4611412 scoped_ptr<SpdyFrame> host2_req(
11413 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4611414 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1311415 CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4611416 };
[email protected]23e482282013-06-14 16:08:0211417 scoped_ptr<SpdyFrame> host1_resp(
11418 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11419 scoped_ptr<SpdyFrame> host1_resp_body(
11420 spdy_util_.ConstructSpdyBodyFrame(1, true));
11421 scoped_ptr<SpdyFrame> host2_resp(
11422 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11423 scoped_ptr<SpdyFrame> host2_resp_body(
11424 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4611425 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1311426 CreateMockRead(*host1_resp, 1),
11427 CreateMockRead(*host1_resp_body, 2),
11428 CreateMockRead(*host2_resp, 4),
11429 CreateMockRead(*host2_resp_body, 5),
11430 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4611431 };
11432
[email protected]d2b5f092012-06-08 23:55:0211433 IPAddressNumber ip;
11434 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
11435 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11436 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1311437 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
11438 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711439 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4611440
[email protected]aa22b242011-11-16 18:58:2911441 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4611442 HttpRequestInfo request1;
11443 request1.method = "GET";
bncce36dca22015-04-21 22:11:2311444 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4611445 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011446 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611447
[email protected]49639fa2011-12-20 23:22:4111448 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611449 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111450 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611451
11452 const HttpResponseInfo* response = trans1.GetResponseInfo();
11453 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011454 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611455 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11456
11457 std::string response_data;
11458 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
11459 EXPECT_EQ("hello!", response_data);
11460
11461 // Preload www.gmail.com into HostCache.
11462 HostPortPair host_port("www.gmail.com", 443);
[email protected]5109c1952013-08-20 18:44:1011463 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4611464 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1011465 rv = session_deps_.host_resolver->Resolve(resolve_info,
11466 DEFAULT_PRIORITY,
11467 &ignored,
11468 callback.callback(),
11469 NULL,
11470 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4711471 EXPECT_EQ(ERR_IO_PENDING, rv);
11472 rv = callback.WaitForResult();
11473 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4611474
11475 HttpRequestInfo request2;
11476 request2.method = "GET";
11477 request2.url = GURL("https://www.gmail.com/");
11478 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011479 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611480
[email protected]49639fa2011-12-20 23:22:4111481 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611482 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111483 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611484
11485 response = trans2.GetResponseInfo();
11486 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011487 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611488 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11489 EXPECT_TRUE(response->was_fetched_via_spdy);
11490 EXPECT_TRUE(response->was_npn_negotiated);
11491 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
11492 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4611493}
[email protected]45b170822012-05-04 21:18:1411494#undef MAYBE_UseIPConnectionPooling
[email protected]e3ceb682011-06-28 23:55:4611495
[email protected]23e482282013-06-14 16:08:0211496TEST_P(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d7599122014-05-24 03:37:2311497 session_deps_.use_alternate_protocols = true;
11498 session_deps_.next_protos = SpdyNextProtos();
[email protected]d2b5f092012-06-08 23:55:0211499
11500 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0711501 session_deps_.host_resolver.reset(new MockCachingHostResolver());
11502 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0211503 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
11504 pool_peer.DisableDomainAuthenticationVerification();
11505
11506 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211507 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711508 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]d2b5f092012-06-08 23:55:0211509
[email protected]cdf8f7e72013-05-23 10:56:4611510 scoped_ptr<SpdyFrame> host1_req(
bncce36dca22015-04-21 22:11:2311511 spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
[email protected]cdf8f7e72013-05-23 10:56:4611512 scoped_ptr<SpdyFrame> host2_req(
11513 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0211514 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1311515 CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0211516 };
[email protected]23e482282013-06-14 16:08:0211517 scoped_ptr<SpdyFrame> host1_resp(
11518 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11519 scoped_ptr<SpdyFrame> host1_resp_body(
11520 spdy_util_.ConstructSpdyBodyFrame(1, true));
11521 scoped_ptr<SpdyFrame> host2_resp(
11522 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11523 scoped_ptr<SpdyFrame> host2_resp_body(
11524 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0211525 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1311526 CreateMockRead(*host1_resp, 1),
11527 CreateMockRead(*host1_resp_body, 2),
11528 CreateMockRead(*host2_resp, 4),
11529 CreateMockRead(*host2_resp_body, 5),
11530 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0211531 };
11532
11533 IPAddressNumber ip;
11534 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
11535 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11536 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1311537 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
11538 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711539 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0211540
11541 TestCompletionCallback callback;
11542 HttpRequestInfo request1;
11543 request1.method = "GET";
bncce36dca22015-04-21 22:11:2311544 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0211545 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011546 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0211547
11548 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
11549 EXPECT_EQ(ERR_IO_PENDING, rv);
11550 EXPECT_EQ(OK, callback.WaitForResult());
11551
11552 const HttpResponseInfo* response = trans1.GetResponseInfo();
11553 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011554 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d2b5f092012-06-08 23:55:0211555 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11556
11557 std::string response_data;
11558 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
11559 EXPECT_EQ("hello!", response_data);
11560
11561 HttpRequestInfo request2;
11562 request2.method = "GET";
11563 request2.url = GURL("https://www.gmail.com/");
11564 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011565 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0211566
11567 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
11568 EXPECT_EQ(ERR_IO_PENDING, rv);
11569 EXPECT_EQ(OK, callback.WaitForResult());
11570
11571 response = trans2.GetResponseInfo();
11572 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011573 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d2b5f092012-06-08 23:55:0211574 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11575 EXPECT_TRUE(response->was_fetched_via_spdy);
11576 EXPECT_TRUE(response->was_npn_negotiated);
11577 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
11578 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0211579}
11580
ttuttle859dc7a2015-04-23 19:42:2911581class OneTimeCachingHostResolver : public HostResolver {
[email protected]e3ceb682011-06-28 23:55:4611582 public:
11583 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
11584 : host_port_(host_port) {}
dchengb03027d2014-10-21 12:00:2011585 ~OneTimeCachingHostResolver() override {}
[email protected]e3ceb682011-06-28 23:55:4611586
11587 RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); }
11588
11589 // HostResolver methods:
dchengb03027d2014-10-21 12:00:2011590 int Resolve(const RequestInfo& info,
11591 RequestPriority priority,
11592 AddressList* addresses,
11593 const CompletionCallback& callback,
11594 RequestHandle* out_req,
11595 const BoundNetLog& net_log) override {
[email protected]95a214c2011-08-04 21:50:4011596 return host_resolver_.Resolve(
[email protected]5109c1952013-08-20 18:44:1011597 info, priority, addresses, callback, out_req, net_log);
[email protected]95a214c2011-08-04 21:50:4011598 }
11599
dchengb03027d2014-10-21 12:00:2011600 int ResolveFromCache(const RequestInfo& info,
11601 AddressList* addresses,
11602 const BoundNetLog& net_log) override {
[email protected]95a214c2011-08-04 21:50:4011603 int rv = host_resolver_.ResolveFromCache(info, addresses, net_log);
11604 if (rv == OK && info.host_port_pair().Equals(host_port_))
[email protected]98e1cd012011-11-08 15:33:0911605 host_resolver_.GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4611606 return rv;
11607 }
11608
dchengb03027d2014-10-21 12:00:2011609 void CancelRequest(RequestHandle req) override {
[email protected]e3ceb682011-06-28 23:55:4611610 host_resolver_.CancelRequest(req);
11611 }
11612
[email protected]46da33be2011-07-19 21:58:0411613 MockCachingHostResolver* GetMockHostResolver() {
11614 return &host_resolver_;
11615 }
11616
[email protected]e3ceb682011-06-28 23:55:4611617 private:
11618 MockCachingHostResolver host_resolver_;
11619 const HostPortPair host_port_;
11620};
11621
[email protected]45b170822012-05-04 21:18:1411622// Times out on Win7 dbg(2) bot. http://crbug.com/124776
11623#if defined(OS_WIN)
[email protected]bb88e1d32013-05-03 23:11:0711624#define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \
11625 DISABLED_UseIPConnectionPoolingWithHostCacheExpiration
[email protected]45b170822012-05-04 21:18:1411626#else
[email protected]bb88e1d32013-05-03 23:11:0711627#define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \
11628 UseIPConnectionPoolingWithHostCacheExpiration
[email protected]45b170822012-05-04 21:18:1411629#endif
[email protected]23e482282013-06-14 16:08:0211630WRAPPED_TEST_P(HttpNetworkTransactionTest,
11631 MAYBE_UseIPConnectionPoolingWithHostCacheExpiration) {
[email protected]23e482282013-06-14 16:08:0211632// Times out on Win7 dbg(2) bot. http://crbug.com/124776 . (MAYBE_
11633// prefix doesn't work with parametrized tests).
11634#if defined(OS_WIN)
11635 return;
[email protected]88c7b4be2014-03-19 23:04:0111636#else
[email protected]d7599122014-05-24 03:37:2311637 session_deps_.use_alternate_protocols = true;
11638 session_deps_.next_protos = SpdyNextProtos();
[email protected]e3ceb682011-06-28 23:55:4611639
11640 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
[email protected]e3ceb682011-06-28 23:55:4611641 OneTimeCachingHostResolver host_resolver(HostPortPair("www.gmail.com", 443));
[email protected]c6bf8152012-12-02 07:43:3411642 HttpNetworkSession::Params params =
[email protected]bb88e1d32013-05-03 23:11:0711643 SpdySessionDependencies::CreateSessionParams(&session_deps_);
[email protected]e3ceb682011-06-28 23:55:4611644 params.host_resolver = &host_resolver;
[email protected]bb88e1d32013-05-03 23:11:0711645 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2611646 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
11647 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4611648
[email protected]8ddf8322012-02-23 18:08:0611649 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211650 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711651 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4611652
[email protected]cdf8f7e72013-05-23 10:56:4611653 scoped_ptr<SpdyFrame> host1_req(
bncce36dca22015-04-21 22:11:2311654 spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
[email protected]cdf8f7e72013-05-23 10:56:4611655 scoped_ptr<SpdyFrame> host2_req(
11656 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4611657 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1311658 CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4611659 };
[email protected]23e482282013-06-14 16:08:0211660 scoped_ptr<SpdyFrame> host1_resp(
11661 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11662 scoped_ptr<SpdyFrame> host1_resp_body(
11663 spdy_util_.ConstructSpdyBodyFrame(1, true));
11664 scoped_ptr<SpdyFrame> host2_resp(
11665 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11666 scoped_ptr<SpdyFrame> host2_resp_body(
11667 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4611668 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1311669 CreateMockRead(*host1_resp, 1),
11670 CreateMockRead(*host1_resp_body, 2),
11671 CreateMockRead(*host2_resp, 4),
11672 CreateMockRead(*host2_resp_body, 5),
11673 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4611674 };
11675
[email protected]d2b5f092012-06-08 23:55:0211676 IPAddressNumber ip;
11677 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
11678 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11679 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1311680 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
11681 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711682 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4611683
[email protected]aa22b242011-11-16 18:58:2911684 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4611685 HttpRequestInfo request1;
11686 request1.method = "GET";
bncce36dca22015-04-21 22:11:2311687 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4611688 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011689 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611690
[email protected]49639fa2011-12-20 23:22:4111691 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611692 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111693 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611694
11695 const HttpResponseInfo* response = trans1.GetResponseInfo();
11696 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011697 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611698 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11699
11700 std::string response_data;
11701 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
11702 EXPECT_EQ("hello!", response_data);
11703
11704 // Preload cache entries into HostCache.
[email protected]5109c1952013-08-20 18:44:1011705 HostResolver::RequestInfo resolve_info(HostPortPair("www.gmail.com", 443));
[email protected]e3ceb682011-06-28 23:55:4611706 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1011707 rv = host_resolver.Resolve(resolve_info,
11708 DEFAULT_PRIORITY,
11709 &ignored,
11710 callback.callback(),
11711 NULL,
11712 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4711713 EXPECT_EQ(ERR_IO_PENDING, rv);
11714 rv = callback.WaitForResult();
11715 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4611716
11717 HttpRequestInfo request2;
11718 request2.method = "GET";
11719 request2.url = GURL("https://www.gmail.com/");
11720 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011721 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611722
[email protected]49639fa2011-12-20 23:22:4111723 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611724 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111725 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611726
11727 response = trans2.GetResponseInfo();
11728 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011729 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611730 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11731 EXPECT_TRUE(response->was_fetched_via_spdy);
11732 EXPECT_TRUE(response->was_npn_negotiated);
11733 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
11734 EXPECT_EQ("hello!", response_data);
[email protected]88c7b4be2014-03-19 23:04:0111735#endif
[email protected]e3ceb682011-06-28 23:55:4611736}
[email protected]45b170822012-05-04 21:18:1411737#undef MAYBE_UseIPConnectionPoolingWithHostCacheExpiration
[email protected]e3ceb682011-06-28 23:55:4611738
[email protected]23e482282013-06-14 16:08:0211739TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2311740 const std::string https_url = "https://www.example.org:8080/";
11741 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0411742
11743 // SPDY GET for HTTPS URL
[email protected]cdf8f7e72013-05-23 10:56:4611744 scoped_ptr<SpdyFrame> req1(
11745 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0411746
11747 MockWrite writes1[] = {
11748 CreateMockWrite(*req1, 0),
11749 };
11750
[email protected]23e482282013-06-14 16:08:0211751 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11752 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8450d722012-07-02 19:14:0411753 MockRead reads1[] = {
11754 CreateMockRead(*resp1, 1),
11755 CreateMockRead(*body1, 2),
11756 MockRead(ASYNC, ERR_IO_PENDING, 3)
11757 };
11758
rch8e6c6c42015-05-01 14:05:1311759 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
11760 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0411761 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5711762 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0411763
11764 // HTTP GET for the HTTP URL
11765 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1311766 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3411767 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2311768 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3411769 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0411770 };
11771
11772 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1311773 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
11774 MockRead(ASYNC, 2, "hello"),
11775 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0411776 };
11777
rch8e6c6c42015-05-01 14:05:1311778 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
11779 arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0411780
[email protected]8450d722012-07-02 19:14:0411781 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211782 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711783 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11784 session_deps_.socket_factory->AddSocketDataProvider(&data1);
11785 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0411786
[email protected]bb88e1d32013-05-03 23:11:0711787 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0411788
11789 // Start the first transaction to set up the SpdySession
11790 HttpRequestInfo request1;
11791 request1.method = "GET";
11792 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0411793 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011794 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0411795 TestCompletionCallback callback1;
11796 EXPECT_EQ(ERR_IO_PENDING,
11797 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411798 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411799
11800 EXPECT_EQ(OK, callback1.WaitForResult());
11801 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11802
11803 // Now, start the HTTP request
11804 HttpRequestInfo request2;
11805 request2.method = "GET";
11806 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0411807 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011808 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0411809 TestCompletionCallback callback2;
11810 EXPECT_EQ(ERR_IO_PENDING,
11811 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411812 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411813
11814 EXPECT_EQ(OK, callback2.WaitForResult());
11815 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11816}
11817
bnc1b0e36852015-04-28 15:32:5911818class AltSvcCertificateVerificationTest : public HttpNetworkTransactionTest {
11819 public:
11820 void Run(bool pooling, bool valid) {
11821 HostPortPair origin(valid ? "mail.example.org" : "invalid.example.org",
11822 443);
11823 HostPortPair alternative("www.example.org", 443);
11824
11825 base::FilePath certs_dir = GetTestCertsDirectory();
11826 scoped_refptr<X509Certificate> cert(
11827 ImportCertFromFile(certs_dir, "spdy_pooling.pem"));
11828 ASSERT_TRUE(cert.get());
11829 bool common_name_fallback_used;
11830 EXPECT_EQ(valid,
11831 cert->VerifyNameMatch(origin.host(), &common_name_fallback_used));
11832 EXPECT_TRUE(
11833 cert->VerifyNameMatch(alternative.host(), &common_name_fallback_used));
11834 SSLSocketDataProvider ssl(ASYNC, OK);
11835 ssl.SetNextProto(GetParam());
11836 ssl.cert = cert;
11837 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11838
11839 // If pooling, then start a request to alternative first to create a
11840 // SpdySession.
11841 std::string url0 = "https://www.example.org:443";
11842 // Second request to origin, which has an alternative service, and could
11843 // open a connection to the alternative host or pool to the existing one.
11844 std::string url1("https://");
11845 url1.append(origin.host());
11846 url1.append(":443");
11847
11848 scoped_ptr<SpdyFrame> req0;
11849 scoped_ptr<SpdyFrame> req1;
11850 scoped_ptr<SpdyFrame> resp0;
11851 scoped_ptr<SpdyFrame> body0;
11852 scoped_ptr<SpdyFrame> resp1;
11853 scoped_ptr<SpdyFrame> body1;
11854 std::vector<MockWrite> writes;
11855 std::vector<MockRead> reads;
11856
11857 if (pooling) {
11858 req0.reset(spdy_util_.ConstructSpdyGet(url0.c_str(), false, 1, LOWEST));
11859 req1.reset(spdy_util_.ConstructSpdyGet(url1.c_str(), false, 3, LOWEST));
11860
11861 writes.push_back(CreateMockWrite(*req0, 0));
11862 writes.push_back(CreateMockWrite(*req1, 3));
11863
11864 resp0.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11865 body0.reset(spdy_util_.ConstructSpdyBodyFrame(1, true));
11866 resp1.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11867 body1.reset(spdy_util_.ConstructSpdyBodyFrame(3, true));
11868
11869 reads.push_back(CreateMockRead(*resp0, 1));
11870 reads.push_back(CreateMockRead(*body0, 2));
11871 reads.push_back(MockRead(ASYNC, ERR_IO_PENDING, 4));
11872 reads.push_back(CreateMockRead(*resp1, 5));
11873 reads.push_back(CreateMockRead(*body1, 6));
11874 reads.push_back(MockRead(ASYNC, OK, 7));
11875 } else {
11876 req1.reset(spdy_util_.ConstructSpdyGet(url1.c_str(), false, 1, LOWEST));
11877
11878 writes.push_back(CreateMockWrite(*req1, 0));
11879
11880 resp1.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11881 body1.reset(spdy_util_.ConstructSpdyBodyFrame(1, true));
11882
11883 reads.push_back(CreateMockRead(*resp1, 1));
11884 reads.push_back(CreateMockRead(*body1, 2));
11885 reads.push_back(MockRead(ASYNC, OK, 3));
11886 }
11887
dbeamcd6674c72015-05-05 01:57:5411888 OrderedSocketData data(vector_as_array(&reads), reads.size(),
11889 vector_as_array(&writes), writes.size());
bnc1b0e36852015-04-28 15:32:5911890 session_deps_.socket_factory->AddSocketDataProvider(&data);
11891
11892 // Connection to the origin fails.
11893 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11894 StaticSocketDataProvider data_refused;
11895 data_refused.set_connect_data(mock_connect);
11896 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
11897
11898 session_deps_.use_alternate_protocols = true;
11899 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11900 base::WeakPtr<HttpServerProperties> http_server_properties =
11901 session->http_server_properties();
11902 AlternativeService alternative_service(
11903 AlternateProtocolFromNextProto(GetParam()), alternative);
11904 http_server_properties->SetAlternativeService(origin, alternative_service,
11905 1.0);
11906
11907 // First request to alternative.
11908 if (pooling) {
11909 scoped_ptr<HttpTransaction> trans0(
11910 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
11911 HttpRequestInfo request0;
11912 request0.method = "GET";
11913 request0.url = GURL(url0);
11914 request0.load_flags = 0;
11915 TestCompletionCallback callback0;
11916
11917 int rv = trans0->Start(&request0, callback0.callback(), BoundNetLog());
11918 EXPECT_EQ(ERR_IO_PENDING, rv);
11919 rv = callback0.WaitForResult();
11920 EXPECT_EQ(OK, rv);
11921 }
11922
11923 // Second request to origin.
11924 scoped_ptr<HttpTransaction> trans1(
11925 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
11926 HttpRequestInfo request1;
11927 request1.method = "GET";
11928 request1.url = GURL(url1);
11929 request1.load_flags = 0;
11930 TestCompletionCallback callback1;
11931
11932 int rv = trans1->Start(&request1, callback1.callback(), BoundNetLog());
11933 EXPECT_EQ(ERR_IO_PENDING, rv);
11934 rv = callback1.WaitForResult();
11935 if (valid) {
11936 EXPECT_EQ(OK, rv);
11937 } else {
11938 if (pooling) {
11939 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
11940 } else {
11941 EXPECT_EQ(ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN, rv);
11942 }
11943 }
11944 }
11945};
11946
11947INSTANTIATE_TEST_CASE_P(NextProto,
11948 AltSvcCertificateVerificationTest,
11949 testing::Values(kProtoSPDY31,
11950 kProtoSPDY4_14,
11951 kProtoSPDY4));
11952
11953// The alternative service host must exhibit a certificate that is valid for the
11954// origin host. Test that this is enforced when pooling to an existing
11955// connection.
11956TEST_P(AltSvcCertificateVerificationTest, PoolingValid) {
11957 Run(true, true);
11958}
11959
11960TEST_P(AltSvcCertificateVerificationTest, PoolingInvalid) {
11961 Run(true, false);
11962}
11963
11964// The alternative service host must exhibit a certificate that is valid for the
11965// origin host. Test that this is enforced when opening a new connection.
11966TEST_P(AltSvcCertificateVerificationTest, NewConnectionValid) {
11967 Run(false, true);
11968}
11969
11970TEST_P(AltSvcCertificateVerificationTest, NewConnectionInvalid) {
11971 Run(false, false);
11972}
11973
[email protected]23e482282013-06-14 16:08:0211974TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2311975 const std::string https_url = "https://www.example.org:8080/";
11976 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0411977
11978 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2311979 const HostPortPair host_port_pair("www.example.org", 8080);
lgarrona91df87f2014-12-05 00:51:3411980 scoped_ptr<SpdyFrame> connect(
11981 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
[email protected]cdf8f7e72013-05-23 10:56:4611982 scoped_ptr<SpdyFrame> req1(
11983 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]23e482282013-06-14 16:08:0211984 scoped_ptr<SpdyFrame> wrapped_req1(
11985 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3911986
11987 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
[email protected]745aa9c2014-06-27 02:21:2911988 SpdyHeaderBlock req2_block;
11989 req2_block[spdy_util_.GetMethodKey()] = "GET";
bnc33b8cef42014-11-19 17:30:3811990 req2_block[spdy_util_.GetPathKey()] = "/";
bncce36dca22015-04-21 22:11:2311991 req2_block[spdy_util_.GetHostKey()] = "www.example.org:8080";
[email protected]745aa9c2014-06-27 02:21:2911992 req2_block[spdy_util_.GetSchemeKey()] = "http";
11993 spdy_util_.MaybeAddVersionHeader(&req2_block);
[email protected]601e03f12014-04-06 16:26:3911994 scoped_ptr<SpdyFrame> req2(
[email protected]745aa9c2014-06-27 02:21:2911995 spdy_util_.ConstructSpdySyn(3, req2_block, MEDIUM, false, true));
[email protected]8450d722012-07-02 19:14:0411996
11997 MockWrite writes1[] = {
11998 CreateMockWrite(*connect, 0),
11999 CreateMockWrite(*wrapped_req1, 2),
12000 CreateMockWrite(*req2, 5),
12001 };
12002
[email protected]23e482282013-06-14 16:08:0212003 scoped_ptr<SpdyFrame> conn_resp(
12004 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12005 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12006 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
12007 scoped_ptr<SpdyFrame> wrapped_resp1(
12008 spdy_util_.ConstructWrappedSpdyFrame(resp1, 1));
12009 scoped_ptr<SpdyFrame> wrapped_body1(
12010 spdy_util_.ConstructWrappedSpdyFrame(body1, 1));
12011 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
12012 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]8450d722012-07-02 19:14:0412013 MockRead reads1[] = {
12014 CreateMockRead(*conn_resp, 1),
12015 CreateMockRead(*wrapped_resp1, 3),
12016 CreateMockRead(*wrapped_body1, 4),
12017 CreateMockRead(*resp2, 6),
12018 CreateMockRead(*body2, 7),
12019 MockRead(ASYNC, ERR_IO_PENDING, 8)
12020 };
12021
[email protected]dd54bd82012-07-19 23:44:5712022 DeterministicSocketData data1(reads1, arraysize(reads1),
12023 writes1, arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0412024 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5712025 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0412026
[email protected]bb88e1d32013-05-03 23:11:0712027 session_deps_.proxy_service.reset(
[email protected]f6c63db52013-02-02 00:35:2212028 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
vishal.b62985ca92015-04-17 08:45:5112029 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712030 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0412031 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
[email protected]23e482282013-06-14 16:08:0212032 ssl1.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0712033 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0412034 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
[email protected]23e482282013-06-14 16:08:0212035 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0712036 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
12037 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0412038
12039 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0712040 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]8450d722012-07-02 19:14:0412041
12042 // Start the first transaction to set up the SpdySession
12043 HttpRequestInfo request1;
12044 request1.method = "GET";
12045 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0412046 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012047 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0412048 TestCompletionCallback callback1;
12049 EXPECT_EQ(ERR_IO_PENDING,
12050 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412051 base::MessageLoop::current()->RunUntilIdle();
[email protected]dd54bd82012-07-19 23:44:5712052 data1.RunFor(4);
[email protected]8450d722012-07-02 19:14:0412053
12054 EXPECT_EQ(OK, callback1.WaitForResult());
12055 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
12056
[email protected]f6c63db52013-02-02 00:35:2212057 LoadTimingInfo load_timing_info1;
12058 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
12059 TestLoadTimingNotReusedWithPac(load_timing_info1,
12060 CONNECT_TIMING_HAS_SSL_TIMES);
12061
[email protected]8450d722012-07-02 19:14:0412062 // Now, start the HTTP request
12063 HttpRequestInfo request2;
12064 request2.method = "GET";
12065 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0412066 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012067 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0412068 TestCompletionCallback callback2;
12069 EXPECT_EQ(ERR_IO_PENDING,
12070 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412071 base::MessageLoop::current()->RunUntilIdle();
[email protected]dd54bd82012-07-19 23:44:5712072 data1.RunFor(3);
[email protected]8450d722012-07-02 19:14:0412073
12074 EXPECT_EQ(OK, callback2.WaitForResult());
12075 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2212076
12077 LoadTimingInfo load_timing_info2;
12078 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
12079 // The established SPDY sessions is considered reused by the HTTP request.
12080 TestLoadTimingReusedWithPac(load_timing_info2);
12081 // HTTP requests over a SPDY session should have a different connection
12082 // socket_log_id than requests over a tunnel.
12083 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0412084}
12085
[email protected]2d88e7d2012-07-19 17:55:1712086// Test that in the case where we have a SPDY session to a SPDY proxy
12087// that we do not pool other origins that resolve to the same IP when
12088// the certificate does not match the new origin.
12089// http://crbug.com/134690
[email protected]23e482282013-06-14 16:08:0212090TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2312091 const std::string url1 = "http://www.example.org/";
12092 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1712093 const std::string ip_addr = "1.2.3.4";
12094
12095 // SPDY GET for HTTP URL (through SPDY proxy)
[email protected]23e482282013-06-14 16:08:0212096 scoped_ptr<SpdyHeaderBlock> headers(
bncce36dca22015-04-21 22:11:2312097 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
[email protected]745aa9c2014-06-27 02:21:2912098 scoped_ptr<SpdyFrame> req1(
12099 spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, false, true));
[email protected]2d88e7d2012-07-19 17:55:1712100
12101 MockWrite writes1[] = {
12102 CreateMockWrite(*req1, 0),
12103 };
12104
[email protected]23e482282013-06-14 16:08:0212105 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12106 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1712107 MockRead reads1[] = {
12108 CreateMockRead(*resp1, 1),
12109 CreateMockRead(*body1, 2),
12110 MockRead(ASYNC, OK, 3) // EOF
12111 };
12112
12113 scoped_ptr<DeterministicSocketData> data1(
12114 new DeterministicSocketData(reads1, arraysize(reads1),
12115 writes1, arraysize(writes1)));
12116 IPAddressNumber ip;
12117 ASSERT_TRUE(ParseIPLiteralToNumber(ip_addr, &ip));
12118 IPEndPoint peer_addr = IPEndPoint(ip, 443);
12119 MockConnect connect_data1(ASYNC, OK, peer_addr);
12120 data1->set_connect_data(connect_data1);
12121
12122 // SPDY GET for HTTPS URL (direct)
[email protected]cdf8f7e72013-05-23 10:56:4612123 scoped_ptr<SpdyFrame> req2(
12124 spdy_util_.ConstructSpdyGet(url2.c_str(), false, 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1712125
12126 MockWrite writes2[] = {
12127 CreateMockWrite(*req2, 0),
12128 };
12129
[email protected]23e482282013-06-14 16:08:0212130 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12131 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1712132 MockRead reads2[] = {
12133 CreateMockRead(*resp2, 1),
12134 CreateMockRead(*body2, 2),
12135 MockRead(ASYNC, OK, 3) // EOF
12136 };
12137
12138 scoped_ptr<DeterministicSocketData> data2(
12139 new DeterministicSocketData(reads2, arraysize(reads2),
12140 writes2, arraysize(writes2)));
12141 MockConnect connect_data2(ASYNC, OK);
12142 data2->set_connect_data(connect_data2);
12143
12144 // Set up a proxy config that sends HTTP requests to a proxy, and
12145 // all others direct.
12146 ProxyConfig proxy_config;
12147 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
[email protected]bb88e1d32013-05-03 23:11:0712148 session_deps_.proxy_service.reset(new ProxyService(
sammc5dd160c2015-04-02 02:43:1312149 new ProxyConfigServiceFixed(proxy_config), nullptr, NULL));
[email protected]2d88e7d2012-07-19 17:55:1712150
bncce36dca22015-04-21 22:11:2312151 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
12152 ssl1.SetNextProto(GetParam());
[email protected]2d88e7d2012-07-19 17:55:1712153 // Load a valid cert. Note, that this does not need to
12154 // be valid for proxy because the MockSSLClientSocket does
12155 // not actually verify it. But SpdySession will use this
12156 // to see if it is valid for the new origin
bncce36dca22015-04-21 22:11:2312157 ssl1.cert = ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
12158 ASSERT_TRUE(ssl1.cert.get());
[email protected]bb88e1d32013-05-03 23:11:0712159 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
12160 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
12161 data1.get());
[email protected]2d88e7d2012-07-19 17:55:1712162
12163 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
[email protected]23e482282013-06-14 16:08:0212164 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0712165 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
12166 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
12167 data2.get());
[email protected]2d88e7d2012-07-19 17:55:1712168
[email protected]bb88e1d32013-05-03 23:11:0712169 session_deps_.host_resolver.reset(new MockCachingHostResolver());
bncce36dca22015-04-21 22:11:2312170 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0712171 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1712172
12173 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0712174 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]2d88e7d2012-07-19 17:55:1712175
12176 // Start the first transaction to set up the SpdySession
12177 HttpRequestInfo request1;
12178 request1.method = "GET";
12179 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1712180 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012181 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1712182 TestCompletionCallback callback1;
12183 ASSERT_EQ(ERR_IO_PENDING,
12184 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
12185 data1->RunFor(3);
12186
12187 ASSERT_TRUE(callback1.have_result());
12188 EXPECT_EQ(OK, callback1.WaitForResult());
12189 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
12190
12191 // Now, start the HTTP request
12192 HttpRequestInfo request2;
12193 request2.method = "GET";
12194 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1712195 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012196 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1712197 TestCompletionCallback callback2;
12198 EXPECT_EQ(ERR_IO_PENDING,
12199 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412200 base::MessageLoop::current()->RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1712201 data2->RunFor(3);
12202
12203 ASSERT_TRUE(callback2.have_result());
12204 EXPECT_EQ(OK, callback2.WaitForResult());
12205 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
12206}
12207
[email protected]85f97342013-04-17 06:12:2412208// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
12209// error) in SPDY session, removes the socket from pool and closes the SPDY
12210// session. Verify that new url's from the same HttpNetworkSession (and a new
12211// SpdySession) do work. http://crbug.com/224701
[email protected]23e482282013-06-14 16:08:0212212TEST_P(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2312213 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2412214
12215 MockRead reads1[] = {
12216 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
12217 };
12218
12219 scoped_ptr<DeterministicSocketData> data1(
12220 new DeterministicSocketData(reads1, arraysize(reads1), NULL, 0));
12221 data1->SetStop(1);
12222
[email protected]cdf8f7e72013-05-23 10:56:4612223 scoped_ptr<SpdyFrame> req2(
12224 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2412225 MockWrite writes2[] = {
12226 CreateMockWrite(*req2, 0),
12227 };
12228
[email protected]23e482282013-06-14 16:08:0212229 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12230 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]85f97342013-04-17 06:12:2412231 MockRead reads2[] = {
12232 CreateMockRead(*resp2, 1),
12233 CreateMockRead(*body2, 2),
12234 MockRead(ASYNC, OK, 3) // EOF
12235 };
12236
12237 scoped_ptr<DeterministicSocketData> data2(
12238 new DeterministicSocketData(reads2, arraysize(reads2),
12239 writes2, arraysize(writes2)));
12240
[email protected]85f97342013-04-17 06:12:2412241 SSLSocketDataProvider ssl1(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212242 ssl1.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0712243 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
12244 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
12245 data1.get());
[email protected]85f97342013-04-17 06:12:2412246
12247 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212248 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0712249 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
12250 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
12251 data2.get());
[email protected]85f97342013-04-17 06:12:2412252
12253 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0712254 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]85f97342013-04-17 06:12:2412255
12256 // Start the first transaction to set up the SpdySession and verify that
12257 // connection was closed.
12258 HttpRequestInfo request1;
12259 request1.method = "GET";
12260 request1.url = GURL(https_url);
12261 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012262 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2412263 TestCompletionCallback callback1;
12264 EXPECT_EQ(ERR_IO_PENDING,
12265 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412266 base::MessageLoop::current()->RunUntilIdle();
[email protected]85f97342013-04-17 06:12:2412267 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback1.WaitForResult());
12268
12269 // Now, start the second request and make sure it succeeds.
12270 HttpRequestInfo request2;
12271 request2.method = "GET";
12272 request2.url = GURL(https_url);
12273 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012274 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2412275 TestCompletionCallback callback2;
12276 EXPECT_EQ(ERR_IO_PENDING,
12277 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412278 base::MessageLoop::current()->RunUntilIdle();
[email protected]85f97342013-04-17 06:12:2412279 data2->RunFor(3);
12280
12281 ASSERT_TRUE(callback2.have_result());
12282 EXPECT_EQ(OK, callback2.WaitForResult());
12283 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
12284}
12285
[email protected]23e482282013-06-14 16:08:0212286TEST_P(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]d7599122014-05-24 03:37:2312287 session_deps_.next_protos = SpdyNextProtos();
[email protected]483fa202013-05-14 01:07:0312288 ClientSocketPoolManager::set_max_sockets_per_group(
12289 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12290 ClientSocketPoolManager::set_max_sockets_per_pool(
12291 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12292
12293 // Use two different hosts with different IPs so they don't get pooled.
12294 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
12295 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
12296 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12297
12298 SSLSocketDataProvider ssl1(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212299 ssl1.SetNextProto(GetParam());
[email protected]483fa202013-05-14 01:07:0312300 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212301 ssl2.SetNextProto(GetParam());
[email protected]483fa202013-05-14 01:07:0312302 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
12303 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
12304
[email protected]cdf8f7e72013-05-23 10:56:4612305 scoped_ptr<SpdyFrame> host1_req(spdy_util_.ConstructSpdyGet(
[email protected]483fa202013-05-14 01:07:0312306 "https://www.a.com", false, 1, DEFAULT_PRIORITY));
12307 MockWrite spdy1_writes[] = {
rch8e6c6c42015-05-01 14:05:1312308 CreateMockWrite(*host1_req, 0),
[email protected]483fa202013-05-14 01:07:0312309 };
[email protected]23e482282013-06-14 16:08:0212310 scoped_ptr<SpdyFrame> host1_resp(
12311 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12312 scoped_ptr<SpdyFrame> host1_resp_body(
12313 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0312314 MockRead spdy1_reads[] = {
rch8e6c6c42015-05-01 14:05:1312315 CreateMockRead(*host1_resp, 1),
12316 CreateMockRead(*host1_resp_body, 2),
12317 MockRead(ASYNC, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0312318 };
12319
rch8e6c6c42015-05-01 14:05:1312320 scoped_ptr<SequencedSocketData> spdy1_data(
12321 new SequencedSocketData(spdy1_reads, arraysize(spdy1_reads), spdy1_writes,
12322 arraysize(spdy1_writes)));
[email protected]483fa202013-05-14 01:07:0312323 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
12324
[email protected]cdf8f7e72013-05-23 10:56:4612325 scoped_ptr<SpdyFrame> host2_req(spdy_util_.ConstructSpdyGet(
[email protected]483fa202013-05-14 01:07:0312326 "https://www.b.com", false, 1, DEFAULT_PRIORITY));
12327 MockWrite spdy2_writes[] = {
rch8e6c6c42015-05-01 14:05:1312328 CreateMockWrite(*host2_req, 0),
[email protected]483fa202013-05-14 01:07:0312329 };
[email protected]23e482282013-06-14 16:08:0212330 scoped_ptr<SpdyFrame> host2_resp(
12331 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12332 scoped_ptr<SpdyFrame> host2_resp_body(
12333 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0312334 MockRead spdy2_reads[] = {
rch8e6c6c42015-05-01 14:05:1312335 CreateMockRead(*host2_resp, 1),
12336 CreateMockRead(*host2_resp_body, 2),
12337 MockRead(ASYNC, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0312338 };
12339
rch8e6c6c42015-05-01 14:05:1312340 scoped_ptr<SequencedSocketData> spdy2_data(
12341 new SequencedSocketData(spdy2_reads, arraysize(spdy2_reads), spdy2_writes,
12342 arraysize(spdy2_writes)));
[email protected]483fa202013-05-14 01:07:0312343 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
12344
12345 MockWrite http_write[] = {
12346 MockWrite("GET / HTTP/1.1\r\n"
12347 "Host: www.a.com\r\n"
12348 "Connection: keep-alive\r\n\r\n"),
12349 };
12350
12351 MockRead http_read[] = {
12352 MockRead("HTTP/1.1 200 OK\r\n"),
12353 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12354 MockRead("Content-Length: 6\r\n\r\n"),
12355 MockRead("hello!"),
12356 };
12357 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
12358 http_write, arraysize(http_write));
12359 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12360
12361 HostPortPair host_port_pair_a("www.a.com", 443);
[email protected]e6d017652013-05-17 18:01:4012362 SpdySessionKey spdy_session_key_a(
[email protected]314b03992014-04-01 01:28:5312363 host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0312364 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2612365 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0312366
12367 TestCompletionCallback callback;
12368 HttpRequestInfo request1;
12369 request1.method = "GET";
12370 request1.url = GURL("https://www.a.com/");
12371 request1.load_flags = 0;
12372 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5012373 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0312374
12375 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
12376 EXPECT_EQ(ERR_IO_PENDING, rv);
12377 EXPECT_EQ(OK, callback.WaitForResult());
12378
12379 const HttpResponseInfo* response = trans->GetResponseInfo();
12380 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5012381 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0312382 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12383 EXPECT_TRUE(response->was_fetched_via_spdy);
12384 EXPECT_TRUE(response->was_npn_negotiated);
12385
12386 std::string response_data;
12387 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
12388 EXPECT_EQ("hello!", response_data);
12389 trans.reset();
12390 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2612391 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0312392
12393 HostPortPair host_port_pair_b("www.b.com", 443);
[email protected]e6d017652013-05-17 18:01:4012394 SpdySessionKey spdy_session_key_b(
[email protected]314b03992014-04-01 01:28:5312395 host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0312396 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2612397 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0312398 HttpRequestInfo request2;
12399 request2.method = "GET";
12400 request2.url = GURL("https://www.b.com/");
12401 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012402 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0312403
12404 rv = trans->Start(&request2, callback.callback(), BoundNetLog());
12405 EXPECT_EQ(ERR_IO_PENDING, rv);
12406 EXPECT_EQ(OK, callback.WaitForResult());
12407
12408 response = trans->GetResponseInfo();
12409 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5012410 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0312411 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12412 EXPECT_TRUE(response->was_fetched_via_spdy);
12413 EXPECT_TRUE(response->was_npn_negotiated);
12414 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
12415 EXPECT_EQ("hello!", response_data);
12416 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2612417 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0312418 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2612419 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0312420
12421 HostPortPair host_port_pair_a1("www.a.com", 80);
[email protected]e6d017652013-05-17 18:01:4012422 SpdySessionKey spdy_session_key_a1(
[email protected]314b03992014-04-01 01:28:5312423 host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0312424 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2612425 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0312426 HttpRequestInfo request3;
12427 request3.method = "GET";
12428 request3.url = GURL("http://www.a.com/");
12429 request3.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012430 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0312431
12432 rv = trans->Start(&request3, callback.callback(), BoundNetLog());
12433 EXPECT_EQ(ERR_IO_PENDING, rv);
12434 EXPECT_EQ(OK, callback.WaitForResult());
12435
12436 response = trans->GetResponseInfo();
12437 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5012438 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0312439 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12440 EXPECT_FALSE(response->was_fetched_via_spdy);
12441 EXPECT_FALSE(response->was_npn_negotiated);
12442 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
12443 EXPECT_EQ("hello!", response_data);
12444 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2612445 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0312446 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2612447 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0312448}
12449
[email protected]79e1fd62013-06-20 06:50:0412450TEST_P(HttpNetworkTransactionTest, HttpSyncConnectError) {
12451 HttpRequestInfo request;
12452 request.method = "GET";
bncce36dca22015-04-21 22:11:2312453 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0412454 request.load_flags = 0;
12455
[email protected]3fe8d2f82013-10-17 08:56:0712456 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412457 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112458 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412459
12460 MockConnect mock_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
12461 StaticSocketDataProvider data;
12462 data.set_connect_data(mock_connect);
12463 session_deps_.socket_factory->AddSocketDataProvider(&data);
12464
12465 TestCompletionCallback callback;
12466
12467 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12468 EXPECT_EQ(ERR_IO_PENDING, rv);
12469
12470 rv = callback.WaitForResult();
12471 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
12472
12473 EXPECT_EQ(NULL, trans->GetResponseInfo());
12474
12475 // We don't care whether this succeeds or fails, but it shouldn't crash.
12476 HttpRequestHeaders request_headers;
12477 trans->GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4712478
12479 ConnectionAttempts attempts;
12480 trans->GetConnectionAttempts(&attempts);
12481 ASSERT_EQ(1u, attempts.size());
12482 EXPECT_EQ(ERR_CONNECTION_REFUSED, attempts[0].result);
[email protected]79e1fd62013-06-20 06:50:0412483}
12484
12485TEST_P(HttpNetworkTransactionTest, HttpAsyncConnectError) {
12486 HttpRequestInfo request;
12487 request.method = "GET";
bncce36dca22015-04-21 22:11:2312488 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0412489 request.load_flags = 0;
12490
[email protected]3fe8d2f82013-10-17 08:56:0712491 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412492 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112493 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412494
12495 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
12496 StaticSocketDataProvider data;
12497 data.set_connect_data(mock_connect);
12498 session_deps_.socket_factory->AddSocketDataProvider(&data);
12499
12500 TestCompletionCallback callback;
12501
12502 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12503 EXPECT_EQ(ERR_IO_PENDING, rv);
12504
12505 rv = callback.WaitForResult();
12506 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
12507
12508 EXPECT_EQ(NULL, trans->GetResponseInfo());
12509
12510 // We don't care whether this succeeds or fails, but it shouldn't crash.
12511 HttpRequestHeaders request_headers;
12512 trans->GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4712513
12514 ConnectionAttempts attempts;
12515 trans->GetConnectionAttempts(&attempts);
12516 ASSERT_EQ(1u, attempts.size());
12517 EXPECT_EQ(ERR_CONNECTION_REFUSED, attempts[0].result);
[email protected]79e1fd62013-06-20 06:50:0412518}
12519
12520TEST_P(HttpNetworkTransactionTest, HttpSyncWriteError) {
12521 HttpRequestInfo request;
12522 request.method = "GET";
bncce36dca22015-04-21 22:11:2312523 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0412524 request.load_flags = 0;
12525
[email protected]3fe8d2f82013-10-17 08:56:0712526 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412527 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112528 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412529
12530 MockWrite data_writes[] = {
12531 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
12532 };
12533 MockRead data_reads[] = {
12534 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
12535 };
12536
12537 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12538 data_writes, arraysize(data_writes));
12539 session_deps_.socket_factory->AddSocketDataProvider(&data);
12540
12541 TestCompletionCallback callback;
12542
12543 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12544 EXPECT_EQ(ERR_IO_PENDING, rv);
12545
12546 rv = callback.WaitForResult();
12547 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12548
12549 EXPECT_EQ(NULL, trans->GetResponseInfo());
12550
12551 HttpRequestHeaders request_headers;
12552 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12553 EXPECT_TRUE(request_headers.HasHeader("Host"));
12554}
12555
12556TEST_P(HttpNetworkTransactionTest, HttpAsyncWriteError) {
12557 HttpRequestInfo request;
12558 request.method = "GET";
bncce36dca22015-04-21 22:11:2312559 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0412560 request.load_flags = 0;
12561
[email protected]3fe8d2f82013-10-17 08:56:0712562 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412563 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112564 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412565
12566 MockWrite data_writes[] = {
12567 MockWrite(ASYNC, ERR_CONNECTION_RESET),
12568 };
12569 MockRead data_reads[] = {
12570 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
12571 };
12572
12573 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12574 data_writes, arraysize(data_writes));
12575 session_deps_.socket_factory->AddSocketDataProvider(&data);
12576
12577 TestCompletionCallback callback;
12578
12579 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12580 EXPECT_EQ(ERR_IO_PENDING, rv);
12581
12582 rv = callback.WaitForResult();
12583 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12584
12585 EXPECT_EQ(NULL, trans->GetResponseInfo());
12586
12587 HttpRequestHeaders request_headers;
12588 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12589 EXPECT_TRUE(request_headers.HasHeader("Host"));
12590}
12591
12592TEST_P(HttpNetworkTransactionTest, HttpSyncReadError) {
12593 HttpRequestInfo request;
12594 request.method = "GET";
bncce36dca22015-04-21 22:11:2312595 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0412596 request.load_flags = 0;
12597
[email protected]3fe8d2f82013-10-17 08:56:0712598 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412599 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112600 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412601
12602 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2312603 MockWrite(
12604 "GET / HTTP/1.1\r\n"
12605 "Host: www.example.org\r\n"
12606 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0412607 };
12608 MockRead data_reads[] = {
12609 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
12610 };
12611
12612 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12613 data_writes, arraysize(data_writes));
12614 session_deps_.socket_factory->AddSocketDataProvider(&data);
12615
12616 TestCompletionCallback callback;
12617
12618 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12619 EXPECT_EQ(ERR_IO_PENDING, rv);
12620
12621 rv = callback.WaitForResult();
12622 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12623
12624 EXPECT_EQ(NULL, trans->GetResponseInfo());
12625
12626 HttpRequestHeaders request_headers;
12627 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12628 EXPECT_TRUE(request_headers.HasHeader("Host"));
12629}
12630
12631TEST_P(HttpNetworkTransactionTest, HttpAsyncReadError) {
12632 HttpRequestInfo request;
12633 request.method = "GET";
bncce36dca22015-04-21 22:11:2312634 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0412635 request.load_flags = 0;
12636
[email protected]3fe8d2f82013-10-17 08:56:0712637 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412638 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112639 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412640
12641 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2312642 MockWrite(
12643 "GET / HTTP/1.1\r\n"
12644 "Host: www.example.org\r\n"
12645 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0412646 };
12647 MockRead data_reads[] = {
12648 MockRead(ASYNC, ERR_CONNECTION_RESET),
12649 };
12650
12651 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12652 data_writes, arraysize(data_writes));
12653 session_deps_.socket_factory->AddSocketDataProvider(&data);
12654
12655 TestCompletionCallback callback;
12656
12657 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12658 EXPECT_EQ(ERR_IO_PENDING, rv);
12659
12660 rv = callback.WaitForResult();
12661 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12662
12663 EXPECT_EQ(NULL, trans->GetResponseInfo());
12664
12665 HttpRequestHeaders request_headers;
12666 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12667 EXPECT_TRUE(request_headers.HasHeader("Host"));
12668}
12669
12670TEST_P(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
12671 HttpRequestInfo request;
12672 request.method = "GET";
bncce36dca22015-04-21 22:11:2312673 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0412674 request.load_flags = 0;
12675 request.extra_headers.SetHeader("X-Foo", "bar");
12676
[email protected]3fe8d2f82013-10-17 08:56:0712677 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412678 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112679 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412680
12681 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2312682 MockWrite(
12683 "GET / HTTP/1.1\r\n"
12684 "Host: www.example.org\r\n"
12685 "Connection: keep-alive\r\n"
12686 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0412687 };
12688 MockRead data_reads[] = {
12689 MockRead("HTTP/1.1 200 OK\r\n"
12690 "Content-Length: 5\r\n\r\n"
12691 "hello"),
12692 MockRead(ASYNC, ERR_UNEXPECTED),
12693 };
12694
12695 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12696 data_writes, arraysize(data_writes));
12697 session_deps_.socket_factory->AddSocketDataProvider(&data);
12698
12699 TestCompletionCallback callback;
12700
12701 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12702 EXPECT_EQ(ERR_IO_PENDING, rv);
12703
12704 rv = callback.WaitForResult();
12705 EXPECT_EQ(OK, rv);
12706
12707 HttpRequestHeaders request_headers;
12708 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12709 std::string foo;
12710 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
12711 EXPECT_EQ("bar", foo);
12712}
12713
[email protected]bf828982013-08-14 18:01:4712714namespace {
12715
yhiranoa7e05bb2014-11-06 05:40:3912716// Fake HttpStream that simply records calls to SetPriority().
12717class FakeStream : public HttpStream,
[email protected]e86839fd2013-08-14 18:29:0312718 public base::SupportsWeakPtr<FakeStream> {
12719 public:
12720 explicit FakeStream(RequestPriority priority) : priority_(priority) {}
dchengb03027d2014-10-21 12:00:2012721 ~FakeStream() override {}
[email protected]e86839fd2013-08-14 18:29:0312722
12723 RequestPriority priority() const { return priority_; }
12724
dchengb03027d2014-10-21 12:00:2012725 int InitializeStream(const HttpRequestInfo* request_info,
12726 RequestPriority priority,
12727 const BoundNetLog& net_log,
12728 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0312729 return ERR_IO_PENDING;
12730 }
12731
dchengb03027d2014-10-21 12:00:2012732 int SendRequest(const HttpRequestHeaders& request_headers,
12733 HttpResponseInfo* response,
12734 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0312735 ADD_FAILURE();
12736 return ERR_UNEXPECTED;
12737 }
12738
dchengb03027d2014-10-21 12:00:2012739 int ReadResponseHeaders(const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0312740 ADD_FAILURE();
12741 return ERR_UNEXPECTED;
12742 }
12743
dchengb03027d2014-10-21 12:00:2012744 int ReadResponseBody(IOBuffer* buf,
12745 int buf_len,
12746 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0312747 ADD_FAILURE();
12748 return ERR_UNEXPECTED;
12749 }
12750
dchengb03027d2014-10-21 12:00:2012751 void Close(bool not_reusable) override {}
[email protected]e86839fd2013-08-14 18:29:0312752
dchengb03027d2014-10-21 12:00:2012753 bool IsResponseBodyComplete() const override {
[email protected]e86839fd2013-08-14 18:29:0312754 ADD_FAILURE();
12755 return false;
12756 }
12757
dchengb03027d2014-10-21 12:00:2012758 bool CanFindEndOfResponse() const override { return false; }
[email protected]e86839fd2013-08-14 18:29:0312759
dchengb03027d2014-10-21 12:00:2012760 bool IsConnectionReused() const override {
[email protected]e86839fd2013-08-14 18:29:0312761 ADD_FAILURE();
12762 return false;
12763 }
12764
dchengb03027d2014-10-21 12:00:2012765 void SetConnectionReused() override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0312766
dchengb03027d2014-10-21 12:00:2012767 bool IsConnectionReusable() const override {
[email protected]e86839fd2013-08-14 18:29:0312768 ADD_FAILURE();
12769 return false;
12770 }
12771
dchengb03027d2014-10-21 12:00:2012772 int64 GetTotalReceivedBytes() const override {
[email protected]bc92bc972013-12-13 08:32:5912773 ADD_FAILURE();
12774 return 0;
12775 }
12776
dchengb03027d2014-10-21 12:00:2012777 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
[email protected]e86839fd2013-08-14 18:29:0312778 ADD_FAILURE();
12779 return false;
12780 }
12781
dchengb03027d2014-10-21 12:00:2012782 void GetSSLInfo(SSLInfo* ssl_info) override { ADD_FAILURE(); }
12783
12784 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
[email protected]e86839fd2013-08-14 18:29:0312785 ADD_FAILURE();
12786 }
12787
dchengb03027d2014-10-21 12:00:2012788 bool IsSpdyHttpStream() const override {
[email protected]e86839fd2013-08-14 18:29:0312789 ADD_FAILURE();
12790 return false;
12791 }
12792
dchengb03027d2014-10-21 12:00:2012793 void Drain(HttpNetworkSession* session) override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0312794
dchengb03027d2014-10-21 12:00:2012795 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]e86839fd2013-08-14 18:29:0312796
yhiranoa7e05bb2014-11-06 05:40:3912797 UploadProgress GetUploadProgress() const override { return UploadProgress(); }
12798
12799 HttpStream* RenewStreamForAuth() override { return NULL; }
12800
[email protected]e86839fd2013-08-14 18:29:0312801 private:
12802 RequestPriority priority_;
12803
12804 DISALLOW_COPY_AND_ASSIGN(FakeStream);
12805};
12806
12807// Fake HttpStreamRequest that simply records calls to SetPriority()
12808// and vends FakeStreams with its current priority.
[email protected]bf828982013-08-14 18:01:4712809class FakeStreamRequest : public HttpStreamRequest,
12810 public base::SupportsWeakPtr<FakeStreamRequest> {
12811 public:
[email protected]e86839fd2013-08-14 18:29:0312812 FakeStreamRequest(RequestPriority priority,
12813 HttpStreamRequest::Delegate* delegate)
12814 : priority_(priority),
[email protected]831e4a32013-11-14 02:14:4412815 delegate_(delegate),
12816 websocket_stream_create_helper_(NULL) {}
12817
12818 FakeStreamRequest(RequestPriority priority,
12819 HttpStreamRequest::Delegate* delegate,
12820 WebSocketHandshakeStreamBase::CreateHelper* create_helper)
12821 : priority_(priority),
12822 delegate_(delegate),
12823 websocket_stream_create_helper_(create_helper) {}
[email protected]e86839fd2013-08-14 18:29:0312824
dchengb03027d2014-10-21 12:00:2012825 ~FakeStreamRequest() override {}
[email protected]bf828982013-08-14 18:01:4712826
12827 RequestPriority priority() const { return priority_; }
12828
[email protected]831e4a32013-11-14 02:14:4412829 const WebSocketHandshakeStreamBase::CreateHelper*
12830 websocket_stream_create_helper() const {
12831 return websocket_stream_create_helper_;
12832 }
12833
[email protected]e86839fd2013-08-14 18:29:0312834 // Create a new FakeStream and pass it to the request's
12835 // delegate. Returns a weak pointer to the FakeStream.
12836 base::WeakPtr<FakeStream> FinishStreamRequest() {
12837 FakeStream* fake_stream = new FakeStream(priority_);
12838 // Do this before calling OnStreamReady() as OnStreamReady() may
12839 // immediately delete |fake_stream|.
12840 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
12841 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), fake_stream);
12842 return weak_stream;
12843 }
12844
dchengb03027d2014-10-21 12:00:2012845 int RestartTunnelWithProxyAuth(const AuthCredentials& credentials) override {
[email protected]bf828982013-08-14 18:01:4712846 ADD_FAILURE();
12847 return ERR_UNEXPECTED;
12848 }
12849
dchengb03027d2014-10-21 12:00:2012850 LoadState GetLoadState() const override {
[email protected]bf828982013-08-14 18:01:4712851 ADD_FAILURE();
12852 return LoadState();
12853 }
12854
dchengb03027d2014-10-21 12:00:2012855 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]bf828982013-08-14 18:01:4712856
dchengb03027d2014-10-21 12:00:2012857 bool was_npn_negotiated() const override { return false; }
[email protected]bf828982013-08-14 18:01:4712858
dchengb03027d2014-10-21 12:00:2012859 NextProto protocol_negotiated() const override { return kProtoUnknown; }
[email protected]bf828982013-08-14 18:01:4712860
dchengb03027d2014-10-21 12:00:2012861 bool using_spdy() const override { return false; }
[email protected]bf828982013-08-14 18:01:4712862
ttuttle1f2d7e92015-04-28 16:17:4712863 const ConnectionAttempts& connection_attempts() const override {
12864 static ConnectionAttempts no_attempts;
12865 return no_attempts;
12866 }
12867
[email protected]bf828982013-08-14 18:01:4712868 private:
12869 RequestPriority priority_;
[email protected]e86839fd2013-08-14 18:29:0312870 HttpStreamRequest::Delegate* const delegate_;
[email protected]831e4a32013-11-14 02:14:4412871 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
[email protected]bf828982013-08-14 18:01:4712872
12873 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
12874};
12875
12876// Fake HttpStreamFactory that vends FakeStreamRequests.
12877class FakeStreamFactory : public HttpStreamFactory {
12878 public:
12879 FakeStreamFactory() {}
dchengb03027d2014-10-21 12:00:2012880 ~FakeStreamFactory() override {}
[email protected]bf828982013-08-14 18:01:4712881
12882 // Returns a WeakPtr<> to the last HttpStreamRequest returned by
12883 // RequestStream() (which may be NULL if it was destroyed already).
12884 base::WeakPtr<FakeStreamRequest> last_stream_request() {
12885 return last_stream_request_;
12886 }
12887
dchengb03027d2014-10-21 12:00:2012888 HttpStreamRequest* RequestStream(const HttpRequestInfo& info,
12889 RequestPriority priority,
12890 const SSLConfig& server_ssl_config,
12891 const SSLConfig& proxy_ssl_config,
12892 HttpStreamRequest::Delegate* delegate,
12893 const BoundNetLog& net_log) override {
[email protected]e86839fd2013-08-14 18:29:0312894 FakeStreamRequest* fake_request = new FakeStreamRequest(priority, delegate);
[email protected]bf828982013-08-14 18:01:4712895 last_stream_request_ = fake_request->AsWeakPtr();
12896 return fake_request;
12897 }
12898
dchengb03027d2014-10-21 12:00:2012899 HttpStreamRequest* RequestWebSocketHandshakeStream(
[email protected]bf828982013-08-14 18:01:4712900 const HttpRequestInfo& info,
12901 RequestPriority priority,
12902 const SSLConfig& server_ssl_config,
12903 const SSLConfig& proxy_ssl_config,
12904 HttpStreamRequest::Delegate* delegate,
[email protected]467086b2013-11-12 08:19:4612905 WebSocketHandshakeStreamBase::CreateHelper* create_helper,
mostynbba063d6032014-10-09 11:01:1312906 const BoundNetLog& net_log) override {
[email protected]831e4a32013-11-14 02:14:4412907 FakeStreamRequest* fake_request =
12908 new FakeStreamRequest(priority, delegate, create_helper);
12909 last_stream_request_ = fake_request->AsWeakPtr();
12910 return fake_request;
[email protected]bf828982013-08-14 18:01:4712911 }
12912
dchengb03027d2014-10-21 12:00:2012913 void PreconnectStreams(int num_streams,
12914 const HttpRequestInfo& info,
12915 RequestPriority priority,
12916 const SSLConfig& server_ssl_config,
12917 const SSLConfig& proxy_ssl_config) override {
[email protected]bf828982013-08-14 18:01:4712918 ADD_FAILURE();
12919 }
12920
dchengb03027d2014-10-21 12:00:2012921 const HostMappingRules* GetHostMappingRules() const override {
[email protected]bf828982013-08-14 18:01:4712922 ADD_FAILURE();
12923 return NULL;
12924 }
12925
12926 private:
12927 base::WeakPtr<FakeStreamRequest> last_stream_request_;
12928
12929 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
12930};
12931
Adam Rice425cf122015-01-19 06:18:2412932// TODO(ricea): Maybe unify this with the one in
12933// url_request_http_job_unittest.cc ?
12934class FakeWebSocketBasicHandshakeStream : public WebSocketHandshakeStreamBase {
12935 public:
12936 FakeWebSocketBasicHandshakeStream(scoped_ptr<ClientSocketHandle> connection,
12937 bool using_proxy)
12938 : state_(connection.release(), using_proxy) {}
12939
12940 // Fake implementation of HttpStreamBase methods.
12941 // This ends up being quite "real" because this object has to really send data
12942 // on the mock socket. It might be easier to use the real implementation, but
12943 // the fact that the WebSocket code is not compiled on iOS makes that
12944 // difficult.
12945 int InitializeStream(const HttpRequestInfo* request_info,
12946 RequestPriority priority,
12947 const BoundNetLog& net_log,
12948 const CompletionCallback& callback) override {
12949 state_.Initialize(request_info, priority, net_log, callback);
12950 return OK;
12951 }
12952
12953 int SendRequest(const HttpRequestHeaders& request_headers,
12954 HttpResponseInfo* response,
12955 const CompletionCallback& callback) override {
12956 return parser()->SendRequest(state_.GenerateRequestLine(), request_headers,
12957 response, callback);
12958 }
12959
12960 int ReadResponseHeaders(const CompletionCallback& callback) override {
12961 return parser()->ReadResponseHeaders(callback);
12962 }
12963
12964 int ReadResponseBody(IOBuffer* buf,
12965 int buf_len,
12966 const CompletionCallback& callback) override {
12967 NOTREACHED();
12968 return ERR_IO_PENDING;
12969 }
12970
12971 void Close(bool not_reusable) override {
12972 if (parser())
12973 parser()->Close(true);
12974 }
12975
12976 bool IsResponseBodyComplete() const override {
12977 NOTREACHED();
12978 return false;
12979 }
12980
12981 bool CanFindEndOfResponse() const override {
12982 return parser()->CanFindEndOfResponse();
12983 }
12984
12985 bool IsConnectionReused() const override {
12986 NOTREACHED();
12987 return false;
12988 }
12989 void SetConnectionReused() override { NOTREACHED(); }
12990
12991 bool IsConnectionReusable() const override {
12992 NOTREACHED();
12993 return false;
12994 }
12995
12996 int64 GetTotalReceivedBytes() const override {
12997 NOTREACHED();
12998 return 0;
12999 }
13000
13001 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
13002 NOTREACHED();
13003 return false;
13004 }
13005
Adam Ricecb76ac62015-02-20 05:33:2513006 void GetSSLInfo(SSLInfo* ssl_info) override {}
Adam Rice425cf122015-01-19 06:18:2413007
13008 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
13009 NOTREACHED();
13010 }
13011
13012 bool IsSpdyHttpStream() const override {
13013 NOTREACHED();
13014 return false;
13015 }
13016
13017 void Drain(HttpNetworkSession* session) override { NOTREACHED(); }
13018
13019 void SetPriority(RequestPriority priority) override { NOTREACHED(); }
13020
13021 UploadProgress GetUploadProgress() const override {
13022 NOTREACHED();
13023 return UploadProgress();
13024 }
13025
13026 HttpStream* RenewStreamForAuth() override {
13027 NOTREACHED();
13028 return nullptr;
13029 }
13030
13031 // Fake implementation of WebSocketHandshakeStreamBase method(s)
13032 scoped_ptr<WebSocketStream> Upgrade() override {
13033 NOTREACHED();
13034 return scoped_ptr<WebSocketStream>();
13035 }
13036
13037 private:
13038 HttpStreamParser* parser() const { return state_.parser(); }
13039 HttpBasicState state_;
13040
13041 DISALLOW_COPY_AND_ASSIGN(FakeWebSocketBasicHandshakeStream);
13042};
13043
[email protected]831e4a32013-11-14 02:14:4413044// TODO(yhirano): Split this class out into a net/websockets file, if it is
13045// worth doing.
13046class FakeWebSocketStreamCreateHelper :
13047 public WebSocketHandshakeStreamBase::CreateHelper {
13048 public:
dchengb03027d2014-10-21 12:00:2013049 WebSocketHandshakeStreamBase* CreateBasicStream(
[email protected]7e841a52013-11-22 09:04:2113050 scoped_ptr<ClientSocketHandle> connection,
mostynbba063d6032014-10-09 11:01:1313051 bool using_proxy) override {
Adam Rice425cf122015-01-19 06:18:2413052 return new FakeWebSocketBasicHandshakeStream(connection.Pass(),
13053 using_proxy);
[email protected]831e4a32013-11-14 02:14:4413054 }
13055
dchengb03027d2014-10-21 12:00:2013056 WebSocketHandshakeStreamBase* CreateSpdyStream(
[email protected]831e4a32013-11-14 02:14:4413057 const base::WeakPtr<SpdySession>& session,
mostynbba063d6032014-10-09 11:01:1313058 bool use_relative_url) override {
[email protected]831e4a32013-11-14 02:14:4413059 NOTREACHED();
13060 return NULL;
13061 };
13062
dchengb03027d2014-10-21 12:00:2013063 ~FakeWebSocketStreamCreateHelper() override {}
[email protected]831e4a32013-11-14 02:14:4413064
13065 virtual scoped_ptr<WebSocketStream> Upgrade() {
13066 NOTREACHED();
13067 return scoped_ptr<WebSocketStream>();
13068 }
13069};
13070
[email protected]bf828982013-08-14 18:01:4713071} // namespace
13072
13073// Make sure that HttpNetworkTransaction passes on its priority to its
13074// stream request on start.
13075TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
13076 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13077 HttpNetworkSessionPeer peer(session);
13078 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4413079 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4713080
dcheng48459ac22014-08-26 00:46:4113081 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4713082
13083 ASSERT_TRUE(fake_factory->last_stream_request() == NULL);
13084
13085 HttpRequestInfo request;
13086 TestCompletionCallback callback;
13087 EXPECT_EQ(ERR_IO_PENDING,
13088 trans.Start(&request, callback.callback(), BoundNetLog()));
13089
13090 base::WeakPtr<FakeStreamRequest> fake_request =
13091 fake_factory->last_stream_request();
13092 ASSERT_TRUE(fake_request != NULL);
13093 EXPECT_EQ(LOW, fake_request->priority());
13094}
13095
13096// Make sure that HttpNetworkTransaction passes on its priority
13097// updates to its stream request.
13098TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriority) {
13099 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13100 HttpNetworkSessionPeer peer(session);
13101 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4413102 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4713103
dcheng48459ac22014-08-26 00:46:4113104 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4713105
13106 HttpRequestInfo request;
13107 TestCompletionCallback callback;
13108 EXPECT_EQ(ERR_IO_PENDING,
13109 trans.Start(&request, callback.callback(), BoundNetLog()));
13110
13111 base::WeakPtr<FakeStreamRequest> fake_request =
13112 fake_factory->last_stream_request();
13113 ASSERT_TRUE(fake_request != NULL);
13114 EXPECT_EQ(LOW, fake_request->priority());
13115
13116 trans.SetPriority(LOWEST);
13117 ASSERT_TRUE(fake_request != NULL);
13118 EXPECT_EQ(LOWEST, fake_request->priority());
13119}
13120
[email protected]e86839fd2013-08-14 18:29:0313121// Make sure that HttpNetworkTransaction passes on its priority
13122// updates to its stream.
13123TEST_P(HttpNetworkTransactionTest, SetStreamPriority) {
13124 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13125 HttpNetworkSessionPeer peer(session);
13126 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4413127 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]e86839fd2013-08-14 18:29:0313128
dcheng48459ac22014-08-26 00:46:4113129 HttpNetworkTransaction trans(LOW, session.get());
[email protected]e86839fd2013-08-14 18:29:0313130
13131 HttpRequestInfo request;
13132 TestCompletionCallback callback;
13133 EXPECT_EQ(ERR_IO_PENDING,
13134 trans.Start(&request, callback.callback(), BoundNetLog()));
13135
13136 base::WeakPtr<FakeStreamRequest> fake_request =
13137 fake_factory->last_stream_request();
13138 ASSERT_TRUE(fake_request != NULL);
13139 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
13140 ASSERT_TRUE(fake_stream != NULL);
13141 EXPECT_EQ(LOW, fake_stream->priority());
13142
13143 trans.SetPriority(LOWEST);
13144 EXPECT_EQ(LOWEST, fake_stream->priority());
13145}
13146
[email protected]831e4a32013-11-14 02:14:4413147TEST_P(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
13148 // The same logic needs to be tested for both ws: and wss: schemes, but this
13149 // test is already parameterised on NextProto, so it uses a loop to verify
13150 // that the different schemes work.
bncce36dca22015-04-21 22:11:2313151 std::string test_cases[] = {"ws://www.example.org/",
13152 "wss://www.example.org/"};
[email protected]831e4a32013-11-14 02:14:4413153 for (size_t i = 0; i < arraysize(test_cases); ++i) {
13154 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13155 HttpNetworkSessionPeer peer(session);
13156 FakeStreamFactory* fake_factory = new FakeStreamFactory();
13157 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
[email protected]0191b51c2013-11-18 10:55:2313158 peer.SetHttpStreamFactoryForWebSocket(
[email protected]831e4a32013-11-14 02:14:4413159 scoped_ptr<HttpStreamFactory>(fake_factory));
13160
dcheng48459ac22014-08-26 00:46:4113161 HttpNetworkTransaction trans(LOW, session.get());
[email protected]831e4a32013-11-14 02:14:4413162 trans.SetWebSocketHandshakeStreamCreateHelper(
13163 &websocket_stream_create_helper);
13164
13165 HttpRequestInfo request;
13166 TestCompletionCallback callback;
13167 request.method = "GET";
13168 request.url = GURL(test_cases[i]);
13169
13170 EXPECT_EQ(ERR_IO_PENDING,
13171 trans.Start(&request, callback.callback(), BoundNetLog()));
13172
13173 base::WeakPtr<FakeStreamRequest> fake_request =
13174 fake_factory->last_stream_request();
13175 ASSERT_TRUE(fake_request != NULL);
13176 EXPECT_EQ(&websocket_stream_create_helper,
13177 fake_request->websocket_stream_create_helper());
13178 }
13179}
13180
[email protected]043b68c82013-08-22 23:41:5213181// Tests that when a used socket is returned to the SSL socket pool, it's closed
13182// if the transport socket pool is stalled on the global socket limit.
13183TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
13184 ClientSocketPoolManager::set_max_sockets_per_group(
13185 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13186 ClientSocketPoolManager::set_max_sockets_per_pool(
13187 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13188
13189 // Set up SSL request.
13190
13191 HttpRequestInfo ssl_request;
13192 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2313193 ssl_request.url = GURL("https://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5213194
13195 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2313196 MockWrite(
13197 "GET / HTTP/1.1\r\n"
13198 "Host: www.example.org\r\n"
13199 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5213200 };
13201 MockRead ssl_reads[] = {
13202 MockRead("HTTP/1.1 200 OK\r\n"),
13203 MockRead("Content-Length: 11\r\n\r\n"),
13204 MockRead("hello world"),
13205 MockRead(SYNCHRONOUS, OK),
13206 };
13207 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
13208 ssl_writes, arraysize(ssl_writes));
13209 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
13210
13211 SSLSocketDataProvider ssl(ASYNC, OK);
13212 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13213
13214 // Set up HTTP request.
13215
13216 HttpRequestInfo http_request;
13217 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2313218 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5213219
13220 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2313221 MockWrite(
13222 "GET / HTTP/1.1\r\n"
13223 "Host: www.example.org\r\n"
13224 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5213225 };
13226 MockRead http_reads[] = {
13227 MockRead("HTTP/1.1 200 OK\r\n"),
13228 MockRead("Content-Length: 7\r\n\r\n"),
13229 MockRead("falafel"),
13230 MockRead(SYNCHRONOUS, OK),
13231 };
13232 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
13233 http_writes, arraysize(http_writes));
13234 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13235
13236 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13237
13238 // Start the SSL request.
13239 TestCompletionCallback ssl_callback;
13240 scoped_ptr<HttpTransaction> ssl_trans(
13241 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13242 ASSERT_EQ(ERR_IO_PENDING,
13243 ssl_trans->Start(&ssl_request, ssl_callback.callback(),
13244 BoundNetLog()));
13245
13246 // Start the HTTP request. Pool should stall.
13247 TestCompletionCallback http_callback;
13248 scoped_ptr<HttpTransaction> http_trans(
13249 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13250 ASSERT_EQ(ERR_IO_PENDING,
13251 http_trans->Start(&http_request, http_callback.callback(),
13252 BoundNetLog()));
dcheng48459ac22014-08-26 00:46:4113253 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5213254
13255 // Wait for response from SSL request.
13256 ASSERT_EQ(OK, ssl_callback.WaitForResult());
13257 std::string response_data;
13258 ASSERT_EQ(OK, ReadTransaction(ssl_trans.get(), &response_data));
13259 EXPECT_EQ("hello world", response_data);
13260
13261 // The SSL socket should automatically be closed, so the HTTP request can
13262 // start.
dcheng48459ac22014-08-26 00:46:4113263 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
13264 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5213265
13266 // The HTTP request can now complete.
13267 ASSERT_EQ(OK, http_callback.WaitForResult());
13268 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
13269 EXPECT_EQ("falafel", response_data);
13270
dcheng48459ac22014-08-26 00:46:4113271 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5213272}
13273
13274// Tests that when a SSL connection is established but there's no corresponding
13275// request that needs it, the new socket is closed if the transport socket pool
13276// is stalled on the global socket limit.
13277TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
13278 ClientSocketPoolManager::set_max_sockets_per_group(
13279 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13280 ClientSocketPoolManager::set_max_sockets_per_pool(
13281 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13282
13283 // Set up an ssl request.
13284
13285 HttpRequestInfo ssl_request;
13286 ssl_request.method = "GET";
13287 ssl_request.url = GURL("https://www.foopy.com/");
13288
13289 // No data will be sent on the SSL socket.
13290 StaticSocketDataProvider ssl_data;
13291 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
13292
13293 SSLSocketDataProvider ssl(ASYNC, OK);
13294 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13295
13296 // Set up HTTP request.
13297
13298 HttpRequestInfo http_request;
13299 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2313300 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5213301
13302 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2313303 MockWrite(
13304 "GET / HTTP/1.1\r\n"
13305 "Host: www.example.org\r\n"
13306 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5213307 };
13308 MockRead http_reads[] = {
13309 MockRead("HTTP/1.1 200 OK\r\n"),
13310 MockRead("Content-Length: 7\r\n\r\n"),
13311 MockRead("falafel"),
13312 MockRead(SYNCHRONOUS, OK),
13313 };
13314 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
13315 http_writes, arraysize(http_writes));
13316 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13317
13318 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13319
13320 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
13321 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2913322 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
13323 SSLConfig ssl_config;
[email protected]043b68c82013-08-22 23:41:5213324 session->ssl_config_service()->GetSSLConfig(&ssl_config);
13325 http_stream_factory->PreconnectStreams(1, ssl_request, DEFAULT_PRIORITY,
13326 ssl_config, ssl_config);
dcheng48459ac22014-08-26 00:46:4113327 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5213328
13329 // Start the HTTP request. Pool should stall.
13330 TestCompletionCallback http_callback;
13331 scoped_ptr<HttpTransaction> http_trans(
13332 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13333 ASSERT_EQ(ERR_IO_PENDING,
13334 http_trans->Start(&http_request, http_callback.callback(),
13335 BoundNetLog()));
dcheng48459ac22014-08-26 00:46:4113336 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5213337
13338 // The SSL connection will automatically be closed once the connection is
13339 // established, to let the HTTP request start.
13340 ASSERT_EQ(OK, http_callback.WaitForResult());
13341 std::string response_data;
13342 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
13343 EXPECT_EQ("falafel", response_data);
13344
dcheng48459ac22014-08-26 00:46:4113345 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5213346}
13347
[email protected]02d74a02014-04-23 18:10:5413348TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
13349 ScopedVector<UploadElementReader> element_readers;
13350 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713351 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413352
13353 HttpRequestInfo request;
13354 request.method = "POST";
13355 request.url = GURL("http://www.foo.com/");
13356 request.upload_data_stream = &upload_data_stream;
13357 request.load_flags = 0;
13358
13359 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13360 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113361 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413362 // Send headers successfully, but get an error while sending the body.
13363 MockWrite data_writes[] = {
13364 MockWrite("POST / HTTP/1.1\r\n"
13365 "Host: www.foo.com\r\n"
13366 "Connection: keep-alive\r\n"
13367 "Content-Length: 3\r\n\r\n"),
13368 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13369 };
13370
13371 MockRead data_reads[] = {
13372 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
13373 MockRead("hello world"),
13374 MockRead(SYNCHRONOUS, OK),
13375 };
13376 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13377 arraysize(data_writes));
13378 session_deps_.socket_factory->AddSocketDataProvider(&data);
13379
13380 TestCompletionCallback callback;
13381
13382 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13383 EXPECT_EQ(ERR_IO_PENDING, rv);
13384
13385 rv = callback.WaitForResult();
13386 EXPECT_EQ(OK, rv);
13387
13388 const HttpResponseInfo* response = trans->GetResponseInfo();
13389 ASSERT_TRUE(response != NULL);
13390
13391 EXPECT_TRUE(response->headers.get() != NULL);
13392 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
13393
13394 std::string response_data;
13395 rv = ReadTransaction(trans.get(), &response_data);
13396 EXPECT_EQ(OK, rv);
13397 EXPECT_EQ("hello world", response_data);
13398}
13399
13400// This test makes sure the retry logic doesn't trigger when reading an error
13401// response from a server that rejected a POST with a CONNECTION_RESET.
13402TEST_P(HttpNetworkTransactionTest,
13403 PostReadsErrorResponseAfterResetOnReusedSocket) {
13404 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13405 MockWrite data_writes[] = {
13406 MockWrite("GET / HTTP/1.1\r\n"
13407 "Host: www.foo.com\r\n"
13408 "Connection: keep-alive\r\n\r\n"),
13409 MockWrite("POST / HTTP/1.1\r\n"
13410 "Host: www.foo.com\r\n"
13411 "Connection: keep-alive\r\n"
13412 "Content-Length: 3\r\n\r\n"),
13413 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13414 };
13415
13416 MockRead data_reads[] = {
13417 MockRead("HTTP/1.1 200 Peachy\r\n"
13418 "Content-Length: 14\r\n\r\n"),
13419 MockRead("first response"),
13420 MockRead("HTTP/1.1 400 Not OK\r\n"
13421 "Content-Length: 15\r\n\r\n"),
13422 MockRead("second response"),
13423 MockRead(SYNCHRONOUS, OK),
13424 };
13425 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13426 arraysize(data_writes));
13427 session_deps_.socket_factory->AddSocketDataProvider(&data);
13428
13429 TestCompletionCallback callback;
13430 HttpRequestInfo request1;
13431 request1.method = "GET";
13432 request1.url = GURL("http://www.foo.com/");
13433 request1.load_flags = 0;
13434
13435 scoped_ptr<HttpTransaction> trans1(
dcheng48459ac22014-08-26 00:46:4113436 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413437 int rv = trans1->Start(&request1, callback.callback(), BoundNetLog());
13438 EXPECT_EQ(ERR_IO_PENDING, rv);
13439
13440 rv = callback.WaitForResult();
13441 EXPECT_EQ(OK, rv);
13442
13443 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
13444 ASSERT_TRUE(response1 != NULL);
13445
13446 EXPECT_TRUE(response1->headers.get() != NULL);
13447 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
13448
13449 std::string response_data1;
13450 rv = ReadTransaction(trans1.get(), &response_data1);
13451 EXPECT_EQ(OK, rv);
13452 EXPECT_EQ("first response", response_data1);
13453 // Delete the transaction to release the socket back into the socket pool.
13454 trans1.reset();
13455
13456 ScopedVector<UploadElementReader> element_readers;
13457 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713458 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413459
13460 HttpRequestInfo request2;
13461 request2.method = "POST";
13462 request2.url = GURL("http://www.foo.com/");
13463 request2.upload_data_stream = &upload_data_stream;
13464 request2.load_flags = 0;
13465
13466 scoped_ptr<HttpTransaction> trans2(
dcheng48459ac22014-08-26 00:46:4113467 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413468 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
13469 EXPECT_EQ(ERR_IO_PENDING, rv);
13470
13471 rv = callback.WaitForResult();
13472 EXPECT_EQ(OK, rv);
13473
13474 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
13475 ASSERT_TRUE(response2 != NULL);
13476
13477 EXPECT_TRUE(response2->headers.get() != NULL);
13478 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
13479
13480 std::string response_data2;
13481 rv = ReadTransaction(trans2.get(), &response_data2);
13482 EXPECT_EQ(OK, rv);
13483 EXPECT_EQ("second response", response_data2);
13484}
13485
13486TEST_P(HttpNetworkTransactionTest,
13487 PostReadsErrorResponseAfterResetPartialBodySent) {
13488 ScopedVector<UploadElementReader> element_readers;
13489 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713490 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413491
13492 HttpRequestInfo request;
13493 request.method = "POST";
13494 request.url = GURL("http://www.foo.com/");
13495 request.upload_data_stream = &upload_data_stream;
13496 request.load_flags = 0;
13497
13498 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13499 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113500 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413501 // Send headers successfully, but get an error while sending the body.
13502 MockWrite data_writes[] = {
13503 MockWrite("POST / HTTP/1.1\r\n"
13504 "Host: www.foo.com\r\n"
13505 "Connection: keep-alive\r\n"
13506 "Content-Length: 3\r\n\r\n"
13507 "fo"),
13508 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13509 };
13510
13511 MockRead data_reads[] = {
13512 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
13513 MockRead("hello world"),
13514 MockRead(SYNCHRONOUS, OK),
13515 };
13516 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13517 arraysize(data_writes));
13518 session_deps_.socket_factory->AddSocketDataProvider(&data);
13519
13520 TestCompletionCallback callback;
13521
13522 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13523 EXPECT_EQ(ERR_IO_PENDING, rv);
13524
13525 rv = callback.WaitForResult();
13526 EXPECT_EQ(OK, rv);
13527
13528 const HttpResponseInfo* response = trans->GetResponseInfo();
13529 ASSERT_TRUE(response != NULL);
13530
13531 EXPECT_TRUE(response->headers.get() != NULL);
13532 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
13533
13534 std::string response_data;
13535 rv = ReadTransaction(trans.get(), &response_data);
13536 EXPECT_EQ(OK, rv);
13537 EXPECT_EQ("hello world", response_data);
13538}
13539
13540// This tests the more common case than the previous test, where headers and
13541// body are not merged into a single request.
13542TEST_P(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
13543 ScopedVector<UploadElementReader> element_readers;
13544 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713545 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5413546
13547 HttpRequestInfo request;
13548 request.method = "POST";
13549 request.url = GURL("http://www.foo.com/");
13550 request.upload_data_stream = &upload_data_stream;
13551 request.load_flags = 0;
13552
13553 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13554 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113555 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413556 // Send headers successfully, but get an error while sending the body.
13557 MockWrite data_writes[] = {
13558 MockWrite("POST / HTTP/1.1\r\n"
13559 "Host: www.foo.com\r\n"
13560 "Connection: keep-alive\r\n"
13561 "Transfer-Encoding: chunked\r\n\r\n"),
13562 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13563 };
13564
13565 MockRead data_reads[] = {
13566 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
13567 MockRead("hello world"),
13568 MockRead(SYNCHRONOUS, OK),
13569 };
13570 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13571 arraysize(data_writes));
13572 session_deps_.socket_factory->AddSocketDataProvider(&data);
13573
13574 TestCompletionCallback callback;
13575
13576 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13577 EXPECT_EQ(ERR_IO_PENDING, rv);
13578 // Make sure the headers are sent before adding a chunk. This ensures that
13579 // they can't be merged with the body in a single send. Not currently
13580 // necessary since a chunked body is never merged with headers, but this makes
13581 // the test more future proof.
13582 base::RunLoop().RunUntilIdle();
13583
mmenkecbc2b712014-10-09 20:29:0713584 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5413585
13586 rv = callback.WaitForResult();
13587 EXPECT_EQ(OK, rv);
13588
13589 const HttpResponseInfo* response = trans->GetResponseInfo();
13590 ASSERT_TRUE(response != NULL);
13591
13592 EXPECT_TRUE(response->headers.get() != NULL);
13593 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
13594
13595 std::string response_data;
13596 rv = ReadTransaction(trans.get(), &response_data);
13597 EXPECT_EQ(OK, rv);
13598 EXPECT_EQ("hello world", response_data);
13599}
13600
13601TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
13602 ScopedVector<UploadElementReader> element_readers;
13603 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713604 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413605
13606 HttpRequestInfo request;
13607 request.method = "POST";
13608 request.url = GURL("http://www.foo.com/");
13609 request.upload_data_stream = &upload_data_stream;
13610 request.load_flags = 0;
13611
13612 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13613 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113614 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413615
13616 MockWrite data_writes[] = {
13617 MockWrite("POST / HTTP/1.1\r\n"
13618 "Host: www.foo.com\r\n"
13619 "Connection: keep-alive\r\n"
13620 "Content-Length: 3\r\n\r\n"),
13621 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13622 };
13623
13624 MockRead data_reads[] = {
13625 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
13626 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
13627 MockRead("hello world"),
13628 MockRead(SYNCHRONOUS, OK),
13629 };
13630 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13631 arraysize(data_writes));
13632 session_deps_.socket_factory->AddSocketDataProvider(&data);
13633
13634 TestCompletionCallback callback;
13635
13636 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13637 EXPECT_EQ(ERR_IO_PENDING, rv);
13638
13639 rv = callback.WaitForResult();
13640 EXPECT_EQ(OK, rv);
13641
13642 const HttpResponseInfo* response = trans->GetResponseInfo();
13643 ASSERT_TRUE(response != NULL);
13644
13645 EXPECT_TRUE(response->headers.get() != NULL);
13646 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
13647
13648 std::string response_data;
13649 rv = ReadTransaction(trans.get(), &response_data);
13650 EXPECT_EQ(OK, rv);
13651 EXPECT_EQ("hello world", response_data);
13652}
13653
13654TEST_P(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
13655 ScopedVector<UploadElementReader> element_readers;
13656 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713657 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413658
13659 HttpRequestInfo request;
13660 request.method = "POST";
13661 request.url = GURL("http://www.foo.com/");
13662 request.upload_data_stream = &upload_data_stream;
13663 request.load_flags = 0;
13664
13665 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13666 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113667 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413668 // Send headers successfully, but get an error while sending the body.
13669 MockWrite data_writes[] = {
13670 MockWrite("POST / HTTP/1.1\r\n"
13671 "Host: www.foo.com\r\n"
13672 "Connection: keep-alive\r\n"
13673 "Content-Length: 3\r\n\r\n"),
13674 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13675 };
13676
13677 MockRead data_reads[] = {
13678 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
13679 MockRead("hello world"),
13680 MockRead(SYNCHRONOUS, OK),
13681 };
13682 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13683 arraysize(data_writes));
13684 session_deps_.socket_factory->AddSocketDataProvider(&data);
13685
13686 TestCompletionCallback callback;
13687
13688 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13689 EXPECT_EQ(ERR_IO_PENDING, rv);
13690
13691 rv = callback.WaitForResult();
13692 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13693
13694 const HttpResponseInfo* response = trans->GetResponseInfo();
13695 EXPECT_TRUE(response == NULL);
13696}
13697
13698TEST_P(HttpNetworkTransactionTest,
13699 PostIgnoresNonErrorResponseAfterResetAnd100) {
13700 ScopedVector<UploadElementReader> element_readers;
13701 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713702 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413703
13704 HttpRequestInfo request;
13705 request.method = "POST";
13706 request.url = GURL("http://www.foo.com/");
13707 request.upload_data_stream = &upload_data_stream;
13708 request.load_flags = 0;
13709
13710 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13711 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113712 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413713 // Send headers successfully, but get an error while sending the body.
13714 MockWrite data_writes[] = {
13715 MockWrite("POST / HTTP/1.1\r\n"
13716 "Host: www.foo.com\r\n"
13717 "Connection: keep-alive\r\n"
13718 "Content-Length: 3\r\n\r\n"),
13719 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13720 };
13721
13722 MockRead data_reads[] = {
13723 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
13724 MockRead("HTTP/1.0 302 Redirect\r\n"),
13725 MockRead("Location: http://somewhere-else.com/\r\n"),
13726 MockRead("Content-Length: 0\r\n\r\n"),
13727 MockRead(SYNCHRONOUS, OK),
13728 };
13729 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13730 arraysize(data_writes));
13731 session_deps_.socket_factory->AddSocketDataProvider(&data);
13732
13733 TestCompletionCallback callback;
13734
13735 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13736 EXPECT_EQ(ERR_IO_PENDING, rv);
13737
13738 rv = callback.WaitForResult();
13739 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13740
13741 const HttpResponseInfo* response = trans->GetResponseInfo();
13742 EXPECT_TRUE(response == NULL);
13743}
13744
13745TEST_P(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
13746 ScopedVector<UploadElementReader> element_readers;
13747 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713748 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413749
13750 HttpRequestInfo request;
13751 request.method = "POST";
13752 request.url = GURL("http://www.foo.com/");
13753 request.upload_data_stream = &upload_data_stream;
13754 request.load_flags = 0;
13755
13756 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13757 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113758 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413759 // Send headers successfully, but get an error while sending the body.
13760 MockWrite data_writes[] = {
13761 MockWrite("POST / HTTP/1.1\r\n"
13762 "Host: www.foo.com\r\n"
13763 "Connection: keep-alive\r\n"
13764 "Content-Length: 3\r\n\r\n"),
13765 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13766 };
13767
13768 MockRead data_reads[] = {
13769 MockRead("HTTP 0.9 rocks!"),
13770 MockRead(SYNCHRONOUS, OK),
13771 };
13772 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13773 arraysize(data_writes));
13774 session_deps_.socket_factory->AddSocketDataProvider(&data);
13775
13776 TestCompletionCallback callback;
13777
13778 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13779 EXPECT_EQ(ERR_IO_PENDING, rv);
13780
13781 rv = callback.WaitForResult();
13782 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13783
13784 const HttpResponseInfo* response = trans->GetResponseInfo();
13785 EXPECT_TRUE(response == NULL);
13786}
13787
13788TEST_P(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
13789 ScopedVector<UploadElementReader> element_readers;
13790 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713791 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413792
13793 HttpRequestInfo request;
13794 request.method = "POST";
13795 request.url = GURL("http://www.foo.com/");
13796 request.upload_data_stream = &upload_data_stream;
13797 request.load_flags = 0;
13798
13799 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13800 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113801 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413802 // Send headers successfully, but get an error while sending the body.
13803 MockWrite data_writes[] = {
13804 MockWrite("POST / HTTP/1.1\r\n"
13805 "Host: www.foo.com\r\n"
13806 "Connection: keep-alive\r\n"
13807 "Content-Length: 3\r\n\r\n"),
13808 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13809 };
13810
13811 MockRead data_reads[] = {
13812 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
13813 MockRead(SYNCHRONOUS, OK),
13814 };
13815 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13816 arraysize(data_writes));
13817 session_deps_.socket_factory->AddSocketDataProvider(&data);
13818
13819 TestCompletionCallback callback;
13820
13821 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13822 EXPECT_EQ(ERR_IO_PENDING, rv);
13823
13824 rv = callback.WaitForResult();
13825 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13826
13827 const HttpResponseInfo* response = trans->GetResponseInfo();
13828 EXPECT_TRUE(response == NULL);
13829}
13830
Adam Rice425cf122015-01-19 06:18:2413831// Verify that proxy headers are not sent to the destination server when
13832// establishing a tunnel for a secure WebSocket connection.
13833TEST_P(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
13834 HttpRequestInfo request;
13835 request.method = "GET";
bncce36dca22015-04-21 22:11:2313836 request.url = GURL("wss://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2413837 AddWebSocketHeaders(&request.extra_headers);
13838
13839 // Configure against proxy server "myproxy:70".
13840 session_deps_.proxy_service.reset(
13841 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
13842
13843 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13844
13845 // Since a proxy is configured, try to establish a tunnel.
13846 MockWrite data_writes[] = {
13847 MockWrite(
bncce36dca22015-04-21 22:11:2313848 "CONNECT www.example.org:443 HTTP/1.1\r\n"
13849 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2413850 "Proxy-Connection: keep-alive\r\n\r\n"),
13851
13852 // After calling trans->RestartWithAuth(), this is the request we should
13853 // be issuing -- the final header line contains the credentials.
13854 MockWrite(
bncce36dca22015-04-21 22:11:2313855 "CONNECT www.example.org:443 HTTP/1.1\r\n"
13856 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2413857 "Proxy-Connection: keep-alive\r\n"
13858 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
13859
13860 MockWrite(
13861 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2313862 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2413863 "Connection: Upgrade\r\n"
13864 "Upgrade: websocket\r\n"
bncce36dca22015-04-21 22:11:2313865 "Origin: http://www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2413866 "Sec-WebSocket-Version: 13\r\n"
13867 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
13868 };
13869
13870 // The proxy responds to the connect with a 407, using a persistent
13871 // connection.
13872 MockRead data_reads[] = {
13873 // No credentials.
13874 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
13875 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
13876 MockRead("Proxy-Connection: close\r\n\r\n"),
13877
13878 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
13879
13880 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
13881 MockRead("Upgrade: websocket\r\n"),
13882 MockRead("Connection: Upgrade\r\n"),
13883 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
13884 };
13885
13886 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13887 arraysize(data_writes));
13888 session_deps_.socket_factory->AddSocketDataProvider(&data);
13889 SSLSocketDataProvider ssl(ASYNC, OK);
13890 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13891
13892 scoped_ptr<HttpTransaction> trans(
13893 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13894 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
13895 trans->SetWebSocketHandshakeStreamCreateHelper(
13896 &websocket_stream_create_helper);
13897
13898 {
13899 TestCompletionCallback callback;
13900
13901 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13902 EXPECT_EQ(ERR_IO_PENDING, rv);
13903
13904 rv = callback.WaitForResult();
13905 EXPECT_EQ(OK, rv);
13906 }
13907
13908 const HttpResponseInfo* response = trans->GetResponseInfo();
13909 ASSERT_TRUE(response);
13910 ASSERT_TRUE(response->headers.get());
13911 EXPECT_EQ(407, response->headers->response_code());
13912
13913 {
13914 TestCompletionCallback callback;
13915
13916 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
13917 callback.callback());
13918 EXPECT_EQ(ERR_IO_PENDING, rv);
13919
13920 rv = callback.WaitForResult();
13921 EXPECT_EQ(OK, rv);
13922 }
13923
13924 response = trans->GetResponseInfo();
13925 ASSERT_TRUE(response);
13926 ASSERT_TRUE(response->headers.get());
13927
13928 EXPECT_EQ(101, response->headers->response_code());
13929
13930 trans.reset();
13931 session->CloseAllConnections();
13932}
13933
13934// Verify that proxy headers are not sent to the destination server when
13935// establishing a tunnel for an insecure WebSocket connection.
13936// This requires the authentication info to be injected into the auth cache
13937// due to crbug.com/395064
13938// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
13939TEST_P(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
13940 HttpRequestInfo request;
13941 request.method = "GET";
bncce36dca22015-04-21 22:11:2313942 request.url = GURL("ws://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2413943 AddWebSocketHeaders(&request.extra_headers);
13944
13945 // Configure against proxy server "myproxy:70".
13946 session_deps_.proxy_service.reset(
13947 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
13948
13949 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13950
13951 MockWrite data_writes[] = {
13952 // Try to establish a tunnel for the WebSocket connection, with
13953 // credentials. Because WebSockets have a separate set of socket pools,
13954 // they cannot and will not use the same TCP/IP connection as the
13955 // preflight HTTP request.
13956 MockWrite(
bncce36dca22015-04-21 22:11:2313957 "CONNECT www.example.org:80 HTTP/1.1\r\n"
13958 "Host: www.example.org:80\r\n"
Adam Rice425cf122015-01-19 06:18:2413959 "Proxy-Connection: keep-alive\r\n"
13960 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
13961
13962 MockWrite(
13963 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2313964 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2413965 "Connection: Upgrade\r\n"
13966 "Upgrade: websocket\r\n"
bncce36dca22015-04-21 22:11:2313967 "Origin: http://www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2413968 "Sec-WebSocket-Version: 13\r\n"
13969 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
13970 };
13971
13972 MockRead data_reads[] = {
13973 // HTTP CONNECT with credentials.
13974 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
13975
13976 // WebSocket connection established inside tunnel.
13977 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
13978 MockRead("Upgrade: websocket\r\n"),
13979 MockRead("Connection: Upgrade\r\n"),
13980 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
13981 };
13982
13983 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13984 arraysize(data_writes));
13985 session_deps_.socket_factory->AddSocketDataProvider(&data);
13986
13987 session->http_auth_cache()->Add(
13988 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
13989 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
13990
13991 scoped_ptr<HttpTransaction> trans(
13992 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13993 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
13994 trans->SetWebSocketHandshakeStreamCreateHelper(
13995 &websocket_stream_create_helper);
13996
13997 TestCompletionCallback callback;
13998
13999 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14000 EXPECT_EQ(ERR_IO_PENDING, rv);
14001
14002 rv = callback.WaitForResult();
14003 EXPECT_EQ(OK, rv);
14004
14005 const HttpResponseInfo* response = trans->GetResponseInfo();
14006 ASSERT_TRUE(response);
14007 ASSERT_TRUE(response->headers.get());
14008
14009 EXPECT_EQ(101, response->headers->response_code());
14010
14011 trans.reset();
14012 session->CloseAllConnections();
14013}
14014
[email protected]89ceba9a2009-03-21 03:46:0614015} // namespace net