blob: d318cad726158d3b094962b00d5bd6c45e315960 [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;
estade8d046462015-05-16 01:02:34130 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
eroman24bc6a12015-05-06 19:55:48332 EXPECT_TRUE(log.bound().IsCapturing());
[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}
1588
1589// What do various browsers do when the server closes a non-keepalive
1590// connection without sending any response header or body?
1591//
1592// IE7: error page
1593// Safari 3.1.2 (Windows): error page
1594// Firefox 3.0.1: blank page
1595// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:421596// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1597// Us: error page (EMPTY_RESPONSE)
[email protected]23e482282013-06-14 16:08:021598TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:251599 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061600 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:351601 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1602 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061603 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251604 };
[email protected]31a2bfe2010-02-09 08:03:391605 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1606 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:421607 EXPECT_EQ(ERR_EMPTY_RESPONSE, out.rv);
[email protected]3d2a59b2008-09-26 19:44:251608}
[email protected]038e9a32008-10-08 22:40:161609
[email protected]1826a402014-01-08 15:40:481610// Test that network access can be deferred and resumed.
1611TEST_P(HttpNetworkTransactionTest, ThrottleBeforeNetworkStart) {
1612 HttpRequestInfo request;
1613 request.method = "GET";
bncce36dca22015-04-21 22:11:231614 request.url = GURL("http://www.example.org/");
[email protected]1826a402014-01-08 15:40:481615 request.load_flags = 0;
1616
1617 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1618 scoped_ptr<HttpTransaction> trans(
1619 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1620
1621 // Defer on OnBeforeNetworkStart.
1622 BeforeNetworkStartHandler net_start_handler(true); // defer
1623 trans->SetBeforeNetworkStartCallback(
1624 base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
1625 base::Unretained(&net_start_handler)));
1626
1627 MockRead data_reads[] = {
1628 MockRead("HTTP/1.0 200 OK\r\n"),
1629 MockRead("Content-Length: 5\r\n\r\n"),
1630 MockRead("hello"),
1631 MockRead(SYNCHRONOUS, 0),
1632 };
1633 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1634 session_deps_.socket_factory->AddSocketDataProvider(&data);
1635
1636 TestCompletionCallback callback;
1637
1638 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1639 EXPECT_EQ(ERR_IO_PENDING, rv);
1640 base::MessageLoop::current()->RunUntilIdle();
1641
1642 // Should have deferred for network start.
1643 EXPECT_TRUE(net_start_handler.observed_before_network_start());
1644 EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
[email protected]1826a402014-01-08 15:40:481645
1646 trans->ResumeNetworkStart();
1647 rv = callback.WaitForResult();
1648 EXPECT_EQ(OK, rv);
1649 EXPECT_TRUE(trans->GetResponseInfo() != NULL);
1650
1651 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
1652 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
1653 if (rv == ERR_IO_PENDING)
1654 rv = callback.WaitForResult();
1655 EXPECT_EQ(5, rv);
1656 trans.reset();
1657}
1658
1659// Test that network use can be deferred and canceled.
1660TEST_P(HttpNetworkTransactionTest, ThrottleAndCancelBeforeNetworkStart) {
1661 HttpRequestInfo request;
1662 request.method = "GET";
bncce36dca22015-04-21 22:11:231663 request.url = GURL("http://www.example.org/");
[email protected]1826a402014-01-08 15:40:481664 request.load_flags = 0;
1665
1666 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1667 scoped_ptr<HttpTransaction> trans(
1668 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1669
1670 // Defer on OnBeforeNetworkStart.
1671 BeforeNetworkStartHandler net_start_handler(true); // defer
1672 trans->SetBeforeNetworkStartCallback(
1673 base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
1674 base::Unretained(&net_start_handler)));
1675
1676 TestCompletionCallback callback;
1677
1678 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1679 EXPECT_EQ(ERR_IO_PENDING, rv);
1680 base::MessageLoop::current()->RunUntilIdle();
1681
1682 // Should have deferred for network start.
1683 EXPECT_TRUE(net_start_handler.observed_before_network_start());
1684 EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
[email protected]1826a402014-01-08 15:40:481685}
1686
[email protected]7a5378b2012-11-04 03:25:171687// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
1688// tests. There was a bug causing HttpNetworkTransaction to hang in the
1689// destructor in such situations.
1690// See http://crbug.com/154712 and http://crbug.com/156609.
[email protected]23e482282013-06-14 16:08:021691TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:171692 HttpRequestInfo request;
1693 request.method = "GET";
bncce36dca22015-04-21 22:11:231694 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171695 request.load_flags = 0;
1696
[email protected]bb88e1d32013-05-03 23:11:071697 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:361698 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501699 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171700
1701 MockRead data_reads[] = {
1702 MockRead("HTTP/1.0 200 OK\r\n"),
1703 MockRead("Connection: keep-alive\r\n"),
1704 MockRead("Content-Length: 100\r\n\r\n"),
1705 MockRead("hello"),
1706 MockRead(SYNCHRONOUS, 0),
1707 };
1708 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071709 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171710
1711 TestCompletionCallback callback;
1712
1713 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1714 EXPECT_EQ(ERR_IO_PENDING, rv);
1715
1716 rv = callback.WaitForResult();
1717 EXPECT_EQ(OK, rv);
1718
1719 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501720 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171721 if (rv == ERR_IO_PENDING)
1722 rv = callback.WaitForResult();
1723 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:501724 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171725 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1726
1727 trans.reset();
[email protected]2da659e2013-05-23 20:51:341728 base::MessageLoop::current()->RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171729 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1730}
1731
[email protected]23e482282013-06-14 16:08:021732TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:171733 HttpRequestInfo request;
1734 request.method = "GET";
bncce36dca22015-04-21 22:11:231735 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171736 request.load_flags = 0;
1737
[email protected]bb88e1d32013-05-03 23:11:071738 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:361739 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501740 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171741
1742 MockRead data_reads[] = {
1743 MockRead("HTTP/1.0 200 OK\r\n"),
1744 MockRead("Connection: keep-alive\r\n"),
1745 MockRead("Content-Length: 100\r\n\r\n"),
1746 MockRead(SYNCHRONOUS, 0),
1747 };
1748 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071749 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171750
1751 TestCompletionCallback callback;
1752
1753 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1754 EXPECT_EQ(ERR_IO_PENDING, rv);
1755
1756 rv = callback.WaitForResult();
1757 EXPECT_EQ(OK, rv);
1758
1759 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501760 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171761 if (rv == ERR_IO_PENDING)
1762 rv = callback.WaitForResult();
1763 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1764
1765 trans.reset();
[email protected]2da659e2013-05-23 20:51:341766 base::MessageLoop::current()->RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171767 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1768}
1769
[email protected]0b0bf032010-09-21 18:08:501770// Test that we correctly reuse a keep-alive connection after not explicitly
1771// reading the body.
[email protected]23e482282013-06-14 16:08:021772TEST_P(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:131773 HttpRequestInfo request;
1774 request.method = "GET";
1775 request.url = GURL("http://www.foo.com/");
1776 request.load_flags = 0;
1777
vishal.b62985ca92015-04-17 08:45:511778 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071779 session_deps_.net_log = &net_log;
1780 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271781
[email protected]0b0bf032010-09-21 18:08:501782 // Note that because all these reads happen in the same
1783 // StaticSocketDataProvider, it shows that the same socket is being reused for
1784 // all transactions.
[email protected]fc31d6a42010-06-24 18:05:131785 MockRead data1_reads[] = {
[email protected]0b0bf032010-09-21 18:08:501786 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
1787 MockRead("HTTP/1.1 205 Reset Content\r\n\r\n"),
[email protected]fc31d6a42010-06-24 18:05:131788 MockRead("HTTP/1.1 304 Not Modified\r\n\r\n"),
[email protected]0b0bf032010-09-21 18:08:501789 MockRead("HTTP/1.1 302 Found\r\n"
1790 "Content-Length: 0\r\n\r\n"),
1791 MockRead("HTTP/1.1 302 Found\r\n"
1792 "Content-Length: 5\r\n\r\n"
1793 "hello"),
1794 MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1795 "Content-Length: 0\r\n\r\n"),
1796 MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1797 "Content-Length: 5\r\n\r\n"
1798 "hello"),
[email protected]fc31d6a42010-06-24 18:05:131799 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1800 MockRead("hello"),
1801 };
1802 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071803 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]fc31d6a42010-06-24 18:05:131804
1805 MockRead data2_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061806 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]fc31d6a42010-06-24 18:05:131807 };
1808 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071809 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]fc31d6a42010-06-24 18:05:131810
[email protected]0b0bf032010-09-21 18:08:501811 const int kNumUnreadBodies = arraysize(data1_reads) - 2;
1812 std::string response_lines[kNumUnreadBodies];
1813
[email protected]58e32bb2013-01-21 18:23:251814 uint32 first_socket_log_id = NetLog::Source::kInvalidId;
[email protected]0b0bf032010-09-21 18:08:501815 for (size_t i = 0; i < arraysize(data1_reads) - 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411816 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:131817
[email protected]262eec82013-03-19 21:01:361818 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501819 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]fc31d6a42010-06-24 18:05:131820
[email protected]49639fa2011-12-20 23:22:411821 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]fc31d6a42010-06-24 18:05:131822 EXPECT_EQ(ERR_IO_PENDING, rv);
1823
1824 rv = callback.WaitForResult();
1825 EXPECT_EQ(OK, rv);
1826
[email protected]58e32bb2013-01-21 18:23:251827 LoadTimingInfo load_timing_info;
1828 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1829 if (i == 0) {
1830 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1831 first_socket_log_id = load_timing_info.socket_log_id;
1832 } else {
1833 TestLoadTimingReused(load_timing_info);
1834 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
1835 }
1836
[email protected]fc31d6a42010-06-24 18:05:131837 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]0b0bf032010-09-21 18:08:501838 ASSERT_TRUE(response != NULL);
[email protected]fc31d6a42010-06-24 18:05:131839
[email protected]90499482013-06-01 00:39:501840 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]0b0bf032010-09-21 18:08:501841 response_lines[i] = response->headers->GetStatusLine();
1842
1843 // We intentionally don't read the response bodies.
[email protected]fc31d6a42010-06-24 18:05:131844 }
[email protected]0b0bf032010-09-21 18:08:501845
1846 const char* const kStatusLines[] = {
1847 "HTTP/1.1 204 No Content",
1848 "HTTP/1.1 205 Reset Content",
1849 "HTTP/1.1 304 Not Modified",
1850 "HTTP/1.1 302 Found",
1851 "HTTP/1.1 302 Found",
1852 "HTTP/1.1 301 Moved Permanently",
1853 "HTTP/1.1 301 Moved Permanently",
1854 };
1855
mostynb91e0da982015-01-20 19:17:271856 static_assert(kNumUnreadBodies == arraysize(kStatusLines),
1857 "forgot to update kStatusLines");
[email protected]0b0bf032010-09-21 18:08:501858
1859 for (int i = 0; i < kNumUnreadBodies; ++i)
1860 EXPECT_EQ(kStatusLines[i], response_lines[i]);
1861
[email protected]49639fa2011-12-20 23:22:411862 TestCompletionCallback callback;
[email protected]262eec82013-03-19 21:01:361863 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501864 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:411865 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0b0bf032010-09-21 18:08:501866 EXPECT_EQ(ERR_IO_PENDING, rv);
1867 rv = callback.WaitForResult();
1868 EXPECT_EQ(OK, rv);
1869 const HttpResponseInfo* response = trans->GetResponseInfo();
1870 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:501871 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]0b0bf032010-09-21 18:08:501872 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1873 std::string response_data;
1874 rv = ReadTransaction(trans.get(), &response_data);
1875 EXPECT_EQ(OK, rv);
1876 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:131877}
1878
[email protected]038e9a32008-10-08 22:40:161879// Test the request-challenge-retry sequence for basic auth.
1880// (basic auth is the easiest to mock, because it has no randomness).
[email protected]23e482282013-06-14 16:08:021881TEST_P(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:421882 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:161883 request.method = "GET";
bncce36dca22015-04-21 22:11:231884 request.url = GURL("http://www.example.org/");
[email protected]038e9a32008-10-08 22:40:161885 request.load_flags = 0;
1886
vishal.b62985ca92015-04-17 08:45:511887 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:071888 session_deps_.net_log = &log;
[email protected]3fe8d2f82013-10-17 08:56:071889 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271890 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411891 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271892
[email protected]f9ee6b52008-11-08 06:46:231893 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:231894 MockWrite(
1895 "GET / HTTP/1.1\r\n"
1896 "Host: www.example.org\r\n"
1897 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:231898 };
1899
[email protected]038e9a32008-10-08 22:40:161900 MockRead data_reads1[] = {
1901 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
1902 // Give a couple authenticate options (only the middle one is actually
1903 // supported).
[email protected]22927ad2009-09-21 19:56:191904 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:161905 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1906 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
1907 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1908 // Large content-length -- won't matter, as connection will be reset.
1909 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061910 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:161911 };
1912
1913 // After calling trans->RestartWithAuth(), this is the request we should
1914 // be issuing -- the final header line contains the credentials.
1915 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:231916 MockWrite(
1917 "GET / HTTP/1.1\r\n"
1918 "Host: www.example.org\r\n"
1919 "Connection: keep-alive\r\n"
1920 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:161921 };
1922
1923 // Lastly, the server responds with the actual content.
1924 MockRead data_reads2[] = {
1925 MockRead("HTTP/1.0 200 OK\r\n"),
1926 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1927 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061928 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:161929 };
1930
[email protected]31a2bfe2010-02-09 08:03:391931 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1932 data_writes1, arraysize(data_writes1));
1933 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1934 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:071935 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1936 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:161937
[email protected]49639fa2011-12-20 23:22:411938 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:161939
[email protected]49639fa2011-12-20 23:22:411940 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421941 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:161942
1943 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421944 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:161945
[email protected]58e32bb2013-01-21 18:23:251946 LoadTimingInfo load_timing_info1;
1947 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
1948 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
1949
[email protected]b8015c42013-12-24 15:18:191950 int64 reads_size1 = ReadsSize(data_reads1, arraysize(data_reads1));
1951 EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
1952
[email protected]1c773ea12009-04-28 19:58:421953 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501954 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:041955 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:161956
[email protected]49639fa2011-12-20 23:22:411957 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:161958
[email protected]49639fa2011-12-20 23:22:411959 rv = trans->RestartWithAuth(
1960 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:421961 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:161962
1963 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421964 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:161965
[email protected]58e32bb2013-01-21 18:23:251966 LoadTimingInfo load_timing_info2;
1967 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
1968 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
1969 // The load timing after restart should have a new socket ID, and times after
1970 // those of the first load timing.
1971 EXPECT_LE(load_timing_info1.receive_headers_end,
1972 load_timing_info2.connect_timing.connect_start);
1973 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
1974
[email protected]b8015c42013-12-24 15:18:191975 int64 reads_size2 = ReadsSize(data_reads2, arraysize(data_reads2));
1976 EXPECT_EQ(reads_size1 + reads_size2, trans->GetTotalReceivedBytes());
1977
[email protected]038e9a32008-10-08 22:40:161978 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501979 ASSERT_TRUE(response != NULL);
[email protected]038e9a32008-10-08 22:40:161980 EXPECT_TRUE(response->auth_challenge.get() == NULL);
1981 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:161982}
1983
[email protected]23e482282013-06-14 16:08:021984TEST_P(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:461985 HttpRequestInfo request;
1986 request.method = "GET";
bncce36dca22015-04-21 22:11:231987 request.url = GURL("http://www.example.org/");
ttuttle859dc7a2015-04-23 19:42:291988 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]861fcd52009-08-26 02:33:461989
[email protected]3fe8d2f82013-10-17 08:56:071990 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271991 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411992 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271993
[email protected]861fcd52009-08-26 02:33:461994 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:231995 MockWrite(
1996 "GET / HTTP/1.1\r\n"
1997 "Host: www.example.org\r\n"
1998 "Connection: keep-alive\r\n\r\n"),
[email protected]861fcd52009-08-26 02:33:461999 };
2000
2001 MockRead data_reads[] = {
2002 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2003 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2004 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2005 // Large content-length -- won't matter, as connection will be reset.
2006 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062007 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:462008 };
2009
[email protected]31a2bfe2010-02-09 08:03:392010 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2011 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072012 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:412013 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:462014
[email protected]49639fa2011-12-20 23:22:412015 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]861fcd52009-08-26 02:33:462016 EXPECT_EQ(ERR_IO_PENDING, rv);
2017
2018 rv = callback.WaitForResult();
2019 EXPECT_EQ(0, rv);
2020
[email protected]b8015c42013-12-24 15:18:192021 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
2022 EXPECT_EQ(reads_size, trans->GetTotalReceivedBytes());
2023
[email protected]861fcd52009-08-26 02:33:462024 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502025 ASSERT_TRUE(response != NULL);
[email protected]861fcd52009-08-26 02:33:462026 EXPECT_TRUE(response->auth_challenge.get() == NULL);
2027}
2028
[email protected]2d2697f92009-02-18 21:00:322029// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2030// connection.
[email protected]23e482282013-06-14 16:08:022031TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
[email protected]1c773ea12009-04-28 19:58:422032 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322033 request.method = "GET";
bncce36dca22015-04-21 22:11:232034 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322035 request.load_flags = 0;
2036
vishal.b62985ca92015-04-17 08:45:512037 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072038 session_deps_.net_log = &log;
2039 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272040
[email protected]2d2697f92009-02-18 21:00:322041 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232042 MockWrite(
2043 "GET / HTTP/1.1\r\n"
2044 "Host: www.example.org\r\n"
2045 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322046
bncce36dca22015-04-21 22:11:232047 // After calling trans->RestartWithAuth(), this is the request we should
2048 // be issuing -- the final header line contains the credentials.
2049 MockWrite(
2050 "GET / HTTP/1.1\r\n"
2051 "Host: www.example.org\r\n"
2052 "Connection: keep-alive\r\n"
2053 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322054 };
2055
2056 MockRead data_reads1[] = {
2057 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2058 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2059 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2060 MockRead("Content-Length: 14\r\n\r\n"),
2061 MockRead("Unauthorized\r\n"),
2062
2063 // Lastly, the server responds with the actual content.
2064 MockRead("HTTP/1.1 200 OK\r\n"),
2065 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502066 MockRead("Content-Length: 5\r\n\r\n"),
2067 MockRead("Hello"),
[email protected]2d2697f92009-02-18 21:00:322068 };
2069
[email protected]2d0a4f92011-05-05 16:38:462070 // If there is a regression where we disconnect a Keep-Alive
2071 // connection during an auth roundtrip, we'll end up reading this.
2072 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062073 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462074 };
2075
[email protected]31a2bfe2010-02-09 08:03:392076 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2077 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462078 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2079 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072080 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2081 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322082
[email protected]49639fa2011-12-20 23:22:412083 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322084
[email protected]262eec82013-03-19 21:01:362085 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502086 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412087 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422088 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322089
2090 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422091 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322092
[email protected]58e32bb2013-01-21 18:23:252093 LoadTimingInfo load_timing_info1;
2094 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
2095 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2096
[email protected]1c773ea12009-04-28 19:58:422097 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502098 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042099 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322100
[email protected]49639fa2011-12-20 23:22:412101 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322102
[email protected]49639fa2011-12-20 23:22:412103 rv = trans->RestartWithAuth(
2104 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422105 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322106
2107 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422108 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322109
[email protected]58e32bb2013-01-21 18:23:252110 LoadTimingInfo load_timing_info2;
2111 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
2112 TestLoadTimingReused(load_timing_info2);
2113 // The load timing after restart should have the same socket ID, and times
2114 // those of the first load timing.
2115 EXPECT_LE(load_timing_info1.receive_headers_end,
2116 load_timing_info2.send_start);
2117 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2118
[email protected]2d2697f92009-02-18 21:00:322119 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502120 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322121 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502122 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]b8015c42013-12-24 15:18:192123
2124 std::string response_data;
2125 rv = ReadTransaction(trans.get(), &response_data);
2126 EXPECT_EQ(OK, rv);
2127 int64 reads_size1 = ReadsSize(data_reads1, arraysize(data_reads1));
2128 EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
[email protected]2d2697f92009-02-18 21:00:322129}
2130
2131// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2132// connection and with no response body to drain.
[email protected]23e482282013-06-14 16:08:022133TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:422134 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322135 request.method = "GET";
bncce36dca22015-04-21 22:11:232136 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322137 request.load_flags = 0;
2138
[email protected]bb88e1d32013-05-03 23:11:072139 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272140
[email protected]2d2697f92009-02-18 21:00:322141 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232142 MockWrite(
2143 "GET / HTTP/1.1\r\n"
2144 "Host: www.example.org\r\n"
2145 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322146
bncce36dca22015-04-21 22:11:232147 // After calling trans->RestartWithAuth(), this is the request we should
2148 // be issuing -- the final header line contains the credentials.
2149 MockWrite(
2150 "GET / HTTP/1.1\r\n"
2151 "Host: www.example.org\r\n"
2152 "Connection: keep-alive\r\n"
2153 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322154 };
2155
[email protected]2d2697f92009-02-18 21:00:322156 MockRead data_reads1[] = {
2157 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2158 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:312159 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:322160
2161 // Lastly, the server responds with the actual content.
2162 MockRead("HTTP/1.1 200 OK\r\n"),
2163 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502164 MockRead("Content-Length: 5\r\n\r\n"),
2165 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322166 };
2167
[email protected]2d0a4f92011-05-05 16:38:462168 // An incorrect reconnect would cause this to be read.
2169 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062170 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462171 };
2172
[email protected]31a2bfe2010-02-09 08:03:392173 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2174 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462175 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2176 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072177 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2178 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322179
[email protected]49639fa2011-12-20 23:22:412180 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322181
[email protected]262eec82013-03-19 21:01:362182 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502183 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412184 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422185 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322186
2187 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422188 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322189
[email protected]1c773ea12009-04-28 19:58:422190 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502191 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042192 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322193
[email protected]49639fa2011-12-20 23:22:412194 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322195
[email protected]49639fa2011-12-20 23:22:412196 rv = trans->RestartWithAuth(
2197 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422198 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322199
2200 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422201 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322202
2203 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502204 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322205 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502206 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322207}
2208
2209// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2210// connection and with a large response body to drain.
[email protected]23e482282013-06-14 16:08:022211TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:422212 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322213 request.method = "GET";
bncce36dca22015-04-21 22:11:232214 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322215 request.load_flags = 0;
2216
[email protected]bb88e1d32013-05-03 23:11:072217 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272218
[email protected]2d2697f92009-02-18 21:00:322219 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232220 MockWrite(
2221 "GET / HTTP/1.1\r\n"
2222 "Host: www.example.org\r\n"
2223 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322224
bncce36dca22015-04-21 22:11:232225 // After calling trans->RestartWithAuth(), this is the request we should
2226 // be issuing -- the final header line contains the credentials.
2227 MockWrite(
2228 "GET / HTTP/1.1\r\n"
2229 "Host: www.example.org\r\n"
2230 "Connection: keep-alive\r\n"
2231 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322232 };
2233
2234 // Respond with 5 kb of response body.
2235 std::string large_body_string("Unauthorized");
2236 large_body_string.append(5 * 1024, ' ');
2237 large_body_string.append("\r\n");
2238
2239 MockRead data_reads1[] = {
2240 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2241 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2242 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2243 // 5134 = 12 + 5 * 1024 + 2
2244 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062245 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:322246
2247 // Lastly, the server responds with the actual content.
2248 MockRead("HTTP/1.1 200 OK\r\n"),
2249 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502250 MockRead("Content-Length: 5\r\n\r\n"),
2251 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322252 };
2253
[email protected]2d0a4f92011-05-05 16:38:462254 // An incorrect reconnect would cause this to be read.
2255 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062256 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462257 };
2258
[email protected]31a2bfe2010-02-09 08:03:392259 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2260 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462261 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2262 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072263 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2264 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322265
[email protected]49639fa2011-12-20 23:22:412266 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322267
[email protected]262eec82013-03-19 21:01:362268 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502269 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412270 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422271 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322272
2273 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422274 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322275
[email protected]1c773ea12009-04-28 19:58:422276 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502277 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042278 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322279
[email protected]49639fa2011-12-20 23:22:412280 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322281
[email protected]49639fa2011-12-20 23:22:412282 rv = trans->RestartWithAuth(
2283 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422284 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322285
2286 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422287 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322288
2289 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502290 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322291 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502292 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322293}
2294
2295// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:312296// connection, but the server gets impatient and closes the connection.
[email protected]23e482282013-06-14 16:08:022297TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:312298 HttpRequestInfo request;
2299 request.method = "GET";
bncce36dca22015-04-21 22:11:232300 request.url = GURL("http://www.example.org/");
[email protected]11203f012009-11-12 23:02:312301 request.load_flags = 0;
2302
[email protected]bb88e1d32013-05-03 23:11:072303 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272304
[email protected]11203f012009-11-12 23:02:312305 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232306 MockWrite(
2307 "GET / HTTP/1.1\r\n"
2308 "Host: www.example.org\r\n"
2309 "Connection: keep-alive\r\n\r\n"),
2310 // This simulates the seemingly successful write to a closed connection
2311 // if the bug is not fixed.
2312 MockWrite(
2313 "GET / HTTP/1.1\r\n"
2314 "Host: www.example.org\r\n"
2315 "Connection: keep-alive\r\n"
2316 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312317 };
2318
2319 MockRead data_reads1[] = {
2320 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2321 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2322 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2323 MockRead("Content-Length: 14\r\n\r\n"),
2324 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:062325 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:312326 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:062327 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:312328 };
2329
2330 // After calling trans->RestartWithAuth(), this is the request we should
2331 // be issuing -- the final header line contains the credentials.
2332 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232333 MockWrite(
2334 "GET / HTTP/1.1\r\n"
2335 "Host: www.example.org\r\n"
2336 "Connection: keep-alive\r\n"
2337 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312338 };
2339
2340 // Lastly, the server responds with the actual content.
2341 MockRead data_reads2[] = {
2342 MockRead("HTTP/1.1 200 OK\r\n"),
2343 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502344 MockRead("Content-Length: 5\r\n\r\n"),
2345 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:312346 };
2347
[email protected]31a2bfe2010-02-09 08:03:392348 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2349 data_writes1, arraysize(data_writes1));
2350 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2351 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072352 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2353 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:312354
[email protected]49639fa2011-12-20 23:22:412355 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:312356
[email protected]262eec82013-03-19 21:01:362357 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502358 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412359 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]11203f012009-11-12 23:02:312360 EXPECT_EQ(ERR_IO_PENDING, rv);
2361
2362 rv = callback1.WaitForResult();
2363 EXPECT_EQ(OK, rv);
2364
2365 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502366 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042367 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:312368
[email protected]49639fa2011-12-20 23:22:412369 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:312370
[email protected]49639fa2011-12-20 23:22:412371 rv = trans->RestartWithAuth(
2372 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]11203f012009-11-12 23:02:312373 EXPECT_EQ(ERR_IO_PENDING, rv);
2374
2375 rv = callback2.WaitForResult();
2376 EXPECT_EQ(OK, rv);
2377
2378 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502379 ASSERT_TRUE(response != NULL);
[email protected]11203f012009-11-12 23:02:312380 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502381 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:312382}
2383
[email protected]394816e92010-08-03 07:38:592384// Test the request-challenge-retry sequence for basic auth, over a connection
2385// that requires a restart when setting up an SSL tunnel.
ttuttle34f63b52015-03-05 04:33:012386TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
2387 HttpRequestInfo request;
2388 request.method = "GET";
bncce36dca22015-04-21 22:11:232389 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:012390 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292391 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:012392
2393 // Configure against proxy server "myproxy:70".
2394 session_deps_.proxy_service.reset(
2395 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
vishal.b62985ca92015-04-17 08:45:512396 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:012397 session_deps_.net_log = log.bound().net_log();
2398 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2399
2400 // Since we have proxy, should try to establish tunnel.
2401 MockWrite data_writes1[] = {
2402 MockWrite(
bncce36dca22015-04-21 22:11:232403 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2404 "Host: www.example.org\r\n"
ttuttle34f63b52015-03-05 04:33:012405 "Proxy-Connection: keep-alive\r\n\r\n"),
2406
2407 // After calling trans->RestartWithAuth(), this is the request we should
2408 // be issuing -- the final header line contains the credentials.
2409 MockWrite(
bncce36dca22015-04-21 22:11:232410 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2411 "Host: www.example.org\r\n"
ttuttle34f63b52015-03-05 04:33:012412 "Proxy-Connection: keep-alive\r\n"
2413 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2414
2415 MockWrite(
2416 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:232417 "Host: www.example.org\r\n"
ttuttle34f63b52015-03-05 04:33:012418 "Connection: keep-alive\r\n\r\n"),
2419 };
2420
2421 // The proxy responds to the connect with a 407, using a persistent
2422 // connection.
2423 MockRead data_reads1[] = {
2424 // No credentials.
2425 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
2426 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
2427
2428 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
2429
2430 MockRead("HTTP/1.1 200 OK\r\n"),
2431 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2432 MockRead("Content-Length: 5\r\n\r\n"),
2433 MockRead(SYNCHRONOUS, "hello"),
2434 };
2435
2436 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2437 data_writes1, arraysize(data_writes1));
2438 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2439 SSLSocketDataProvider ssl(ASYNC, OK);
2440 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
2441
2442 TestCompletionCallback callback1;
2443
2444 scoped_ptr<HttpTransaction> trans(
2445 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2446
2447 int rv = trans->Start(&request, callback1.callback(), log.bound());
2448 EXPECT_EQ(ERR_IO_PENDING, rv);
2449
2450 rv = callback1.WaitForResult();
2451 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:462452 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:012453 log.GetEntries(&entries);
2454 size_t pos = ExpectLogContainsSomewhere(
2455 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
2456 NetLog::PHASE_NONE);
2457 ExpectLogContainsSomewhere(
2458 entries, pos, NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2459 NetLog::PHASE_NONE);
2460
2461 const HttpResponseInfo* response = trans->GetResponseInfo();
2462 ASSERT_TRUE(response != NULL);
2463 EXPECT_FALSE(response->headers->IsKeepAlive());
2464 ASSERT_FALSE(response->headers.get() == NULL);
2465 EXPECT_EQ(407, response->headers->response_code());
2466 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
2467 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2468
2469 LoadTimingInfo load_timing_info;
2470 // CONNECT requests and responses are handled at the connect job level, so
2471 // the transaction does not yet have a connection.
2472 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
2473
2474 TestCompletionCallback callback2;
2475
2476 rv =
2477 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
2478 EXPECT_EQ(ERR_IO_PENDING, rv);
2479
2480 rv = callback2.WaitForResult();
2481 EXPECT_EQ(OK, rv);
2482
2483 response = trans->GetResponseInfo();
2484 ASSERT_TRUE(response != NULL);
2485
2486 EXPECT_TRUE(response->headers->IsKeepAlive());
2487 EXPECT_EQ(200, response->headers->response_code());
2488 EXPECT_EQ(5, response->headers->GetContentLength());
2489 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2490
2491 // The password prompt info should not be set.
2492 EXPECT_TRUE(response->auth_challenge.get() == NULL);
2493
2494 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2495 TestLoadTimingNotReusedWithPac(load_timing_info,
2496 CONNECT_TIMING_HAS_SSL_TIMES);
2497
2498 trans.reset();
2499 session->CloseAllConnections();
2500}
2501
2502// Test the request-challenge-retry sequence for basic auth, over a connection
2503// that requires a restart when setting up an SSL tunnel.
2504TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) {
[email protected]394816e92010-08-03 07:38:592505 HttpRequestInfo request;
2506 request.method = "GET";
bncce36dca22015-04-21 22:11:232507 request.url = GURL("https://www.example.org/");
[email protected]394816e92010-08-03 07:38:592508 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292509 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]394816e92010-08-03 07:38:592510
[email protected]cb9bf6ca2011-01-28 13:15:272511 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072512 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:202513 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
vishal.b62985ca92015-04-17 08:45:512514 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072515 session_deps_.net_log = log.bound().net_log();
2516 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272517
[email protected]394816e92010-08-03 07:38:592518 // Since we have proxy, should try to establish tunnel.
2519 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232520 MockWrite(
2521 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2522 "Host: www.example.org\r\n"
2523 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]394816e92010-08-03 07:38:592524
bncce36dca22015-04-21 22:11:232525 // After calling trans->RestartWithAuth(), this is the request we should
2526 // be issuing -- the final header line contains the credentials.
2527 MockWrite(
2528 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2529 "Host: www.example.org\r\n"
2530 "Proxy-Connection: keep-alive\r\n"
2531 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]394816e92010-08-03 07:38:592532
bncce36dca22015-04-21 22:11:232533 MockWrite(
2534 "GET / HTTP/1.1\r\n"
2535 "Host: www.example.org\r\n"
2536 "Connection: keep-alive\r\n\r\n"),
[email protected]394816e92010-08-03 07:38:592537 };
2538
2539 // The proxy responds to the connect with a 407, using a persistent
2540 // connection.
2541 MockRead data_reads1[] = {
2542 // No credentials.
2543 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2544 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2545 MockRead("Proxy-Connection: close\r\n\r\n"),
2546
2547 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2548
2549 MockRead("HTTP/1.1 200 OK\r\n"),
2550 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502551 MockRead("Content-Length: 5\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062552 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:592553 };
2554
2555 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2556 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072557 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:062558 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072559 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:592560
[email protected]49639fa2011-12-20 23:22:412561 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:592562
[email protected]262eec82013-03-19 21:01:362563 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502564 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:502565
[email protected]49639fa2011-12-20 23:22:412566 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]394816e92010-08-03 07:38:592567 EXPECT_EQ(ERR_IO_PENDING, rv);
2568
2569 rv = callback1.WaitForResult();
2570 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:462571 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:402572 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:592573 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402574 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]394816e92010-08-03 07:38:592575 NetLog::PHASE_NONE);
2576 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402577 entries, pos,
[email protected]394816e92010-08-03 07:38:592578 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2579 NetLog::PHASE_NONE);
2580
2581 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502582 ASSERT_TRUE(response != NULL);
ttuttle34f63b52015-03-05 04:33:012583 EXPECT_FALSE(response->headers->IsKeepAlive());
[email protected]90499482013-06-01 00:39:502584 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]394816e92010-08-03 07:38:592585 EXPECT_EQ(407, response->headers->response_code());
2586 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042587 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:592588
[email protected]029c83b62013-01-24 05:28:202589 LoadTimingInfo load_timing_info;
2590 // CONNECT requests and responses are handled at the connect job level, so
2591 // the transaction does not yet have a connection.
2592 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
2593
[email protected]49639fa2011-12-20 23:22:412594 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:592595
[email protected]49639fa2011-12-20 23:22:412596 rv = trans->RestartWithAuth(
2597 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]394816e92010-08-03 07:38:592598 EXPECT_EQ(ERR_IO_PENDING, rv);
2599
2600 rv = callback2.WaitForResult();
2601 EXPECT_EQ(OK, rv);
2602
2603 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502604 ASSERT_TRUE(response != NULL);
[email protected]394816e92010-08-03 07:38:592605
2606 EXPECT_TRUE(response->headers->IsKeepAlive());
2607 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:502608 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:592609 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2610
2611 // The password prompt info should not be set.
2612 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502613
[email protected]029c83b62013-01-24 05:28:202614 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2615 TestLoadTimingNotReusedWithPac(load_timing_info,
2616 CONNECT_TIMING_HAS_SSL_TIMES);
2617
[email protected]0b0bf032010-09-21 18:08:502618 trans.reset();
[email protected]102e27c2011-02-23 01:01:312619 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:592620}
2621
[email protected]11203f012009-11-12 23:02:312622// Test the request-challenge-retry sequence for basic auth, over a keep-alive
ttuttle34f63b52015-03-05 04:33:012623// proxy connection with HTTP/1.0 responses, when setting up an SSL tunnel.
2624TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
2625 HttpRequestInfo request;
2626 request.method = "GET";
bncce36dca22015-04-21 22:11:232627 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:012628 // Ensure that proxy authentication is attempted even
2629 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292630 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:012631
2632 // Configure against proxy server "myproxy:70".
2633 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
vishal.b62985ca92015-04-17 08:45:512634 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:012635 session_deps_.net_log = log.bound().net_log();
2636 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2637
2638 scoped_ptr<HttpTransaction> trans(
2639 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2640
2641 // Since we have proxy, should try to establish tunnel.
2642 MockWrite data_writes1[] = {
2643 MockWrite(
bncce36dca22015-04-21 22:11:232644 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2645 "Host: www.example.org\r\n"
ttuttle34f63b52015-03-05 04:33:012646 "Proxy-Connection: keep-alive\r\n\r\n"),
2647
2648 // After calling trans->RestartWithAuth(), this is the request we should
2649 // be issuing -- the final header line contains the credentials.
2650 MockWrite(
bncce36dca22015-04-21 22:11:232651 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2652 "Host: www.example.org\r\n"
ttuttle34f63b52015-03-05 04:33:012653 "Proxy-Connection: keep-alive\r\n"
2654 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
2655 };
2656
2657 // The proxy responds to the connect with a 407, using a persistent
2658 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
2659 MockRead data_reads1[] = {
2660 // No credentials.
2661 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
2662 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2663 MockRead("Proxy-Connection: keep-alive\r\n"),
2664 MockRead("Content-Length: 10\r\n\r\n"),
2665 MockRead("0123456789"),
2666
2667 // Wrong credentials (wrong password).
2668 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
2669 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2670 MockRead("Proxy-Connection: keep-alive\r\n"),
2671 MockRead("Content-Length: 10\r\n\r\n"),
2672 // No response body because the test stops reading here.
2673 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
2674 };
2675
2676 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2677 data_writes1, arraysize(data_writes1));
2678 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2679
2680 TestCompletionCallback callback1;
2681
2682 int rv = trans->Start(&request, callback1.callback(), log.bound());
2683 EXPECT_EQ(ERR_IO_PENDING, rv);
2684
2685 rv = callback1.WaitForResult();
2686 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:462687 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:012688 log.GetEntries(&entries);
2689 size_t pos = ExpectLogContainsSomewhere(
2690 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
2691 NetLog::PHASE_NONE);
2692 ExpectLogContainsSomewhere(
2693 entries, pos, NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2694 NetLog::PHASE_NONE);
2695
2696 const HttpResponseInfo* response = trans->GetResponseInfo();
2697 ASSERT_TRUE(response);
2698 ASSERT_TRUE(response->headers);
2699 EXPECT_TRUE(response->headers->IsKeepAlive());
2700 EXPECT_EQ(407, response->headers->response_code());
2701 EXPECT_EQ(10, response->headers->GetContentLength());
2702 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
2703 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2704
2705 TestCompletionCallback callback2;
2706
2707 // Wrong password (should be "bar").
2708 rv =
2709 trans->RestartWithAuth(AuthCredentials(kFoo, kBaz), callback2.callback());
2710 EXPECT_EQ(ERR_IO_PENDING, rv);
2711
2712 rv = callback2.WaitForResult();
2713 EXPECT_EQ(OK, rv);
2714
2715 response = trans->GetResponseInfo();
2716 ASSERT_TRUE(response);
2717 ASSERT_TRUE(response->headers);
2718 EXPECT_TRUE(response->headers->IsKeepAlive());
2719 EXPECT_EQ(407, response->headers->response_code());
2720 EXPECT_EQ(10, response->headers->GetContentLength());
2721 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
2722 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2723
2724 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
2725 // out of scope.
2726 session->CloseAllConnections();
2727}
2728
2729// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2730// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel.
2731TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
[email protected]cb9bf6ca2011-01-28 13:15:272732 HttpRequestInfo request;
2733 request.method = "GET";
bncce36dca22015-04-21 22:11:232734 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:272735 // Ensure that proxy authentication is attempted even
2736 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292737 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]cb9bf6ca2011-01-28 13:15:272738
[email protected]2d2697f92009-02-18 21:00:322739 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072740 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
vishal.b62985ca92015-04-17 08:45:512741 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072742 session_deps_.net_log = log.bound().net_log();
2743 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:322744
[email protected]262eec82013-03-19 21:01:362745 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502746 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d2697f92009-02-18 21:00:322747
[email protected]2d2697f92009-02-18 21:00:322748 // Since we have proxy, should try to establish tunnel.
2749 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232750 MockWrite(
2751 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2752 "Host: www.example.org\r\n"
2753 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322754
bncce36dca22015-04-21 22:11:232755 // After calling trans->RestartWithAuth(), this is the request we should
2756 // be issuing -- the final header line contains the credentials.
2757 MockWrite(
2758 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2759 "Host: www.example.org\r\n"
2760 "Proxy-Connection: keep-alive\r\n"
2761 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322762 };
2763
2764 // The proxy responds to the connect with a 407, using a persistent
2765 // connection.
2766 MockRead data_reads1[] = {
2767 // No credentials.
2768 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2769 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2770 MockRead("Content-Length: 10\r\n\r\n"),
2771 MockRead("0123456789"),
2772
2773 // Wrong credentials (wrong password).
2774 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2775 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2776 MockRead("Content-Length: 10\r\n\r\n"),
2777 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:062778 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]2d2697f92009-02-18 21:00:322779 };
2780
[email protected]31a2bfe2010-02-09 08:03:392781 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2782 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072783 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d2697f92009-02-18 21:00:322784
[email protected]49639fa2011-12-20 23:22:412785 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322786
[email protected]49639fa2011-12-20 23:22:412787 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]1c773ea12009-04-28 19:58:422788 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322789
2790 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422791 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:462792 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:402793 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:392794 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402795 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]dbb83db2010-05-11 18:13:392796 NetLog::PHASE_NONE);
2797 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402798 entries, pos,
[email protected]dbb83db2010-05-11 18:13:392799 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2800 NetLog::PHASE_NONE);
[email protected]2d2697f92009-02-18 21:00:322801
[email protected]1c773ea12009-04-28 19:58:422802 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:242803 ASSERT_TRUE(response);
2804 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:322805 EXPECT_TRUE(response->headers->IsKeepAlive());
2806 EXPECT_EQ(407, response->headers->response_code());
ttuttle34f63b52015-03-05 04:33:012807 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422808 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042809 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322810
[email protected]49639fa2011-12-20 23:22:412811 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322812
2813 // Wrong password (should be "bar").
[email protected]49639fa2011-12-20 23:22:412814 rv = trans->RestartWithAuth(
2815 AuthCredentials(kFoo, kBaz), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422816 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322817
2818 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422819 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322820
2821 response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:242822 ASSERT_TRUE(response);
2823 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:322824 EXPECT_TRUE(response->headers->IsKeepAlive());
2825 EXPECT_EQ(407, response->headers->response_code());
ttuttle34f63b52015-03-05 04:33:012826 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422827 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042828 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]e772db3f2010-07-12 18:11:132829
[email protected]e60e47a2010-07-14 03:37:182830 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
2831 // out of scope.
[email protected]102e27c2011-02-23 01:01:312832 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:322833}
2834
[email protected]a8e9b162009-03-12 00:06:442835// Test that we don't read the response body when we fail to establish a tunnel,
2836// even if the user cancels the proxy's auth attempt.
[email protected]23e482282013-06-14 16:08:022837TEST_P(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:272838 HttpRequestInfo request;
2839 request.method = "GET";
bncce36dca22015-04-21 22:11:232840 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:272841 request.load_flags = 0;
2842
[email protected]a8e9b162009-03-12 00:06:442843 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072844 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]a8e9b162009-03-12 00:06:442845
[email protected]bb88e1d32013-05-03 23:11:072846 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:442847
[email protected]262eec82013-03-19 21:01:362848 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502849 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]a8e9b162009-03-12 00:06:442850
[email protected]a8e9b162009-03-12 00:06:442851 // Since we have proxy, should try to establish tunnel.
2852 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:232853 MockWrite(
2854 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2855 "Host: www.example.org\r\n"
2856 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:442857 };
2858
2859 // The proxy responds to the connect with a 407.
2860 MockRead data_reads[] = {
ttuttle7933c112015-01-06 00:55:242861 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2862 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2863 MockRead("Content-Length: 10\r\n\r\n"),
2864 MockRead("0123456789"), // Should not be reached.
2865 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]a8e9b162009-03-12 00:06:442866 };
2867
[email protected]31a2bfe2010-02-09 08:03:392868 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2869 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072870 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:442871
[email protected]49639fa2011-12-20 23:22:412872 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:442873
[email protected]49639fa2011-12-20 23:22:412874 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422875 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a8e9b162009-03-12 00:06:442876
2877 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422878 EXPECT_EQ(OK, rv);
[email protected]a8e9b162009-03-12 00:06:442879
[email protected]1c773ea12009-04-28 19:58:422880 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:242881 ASSERT_TRUE(response);
2882 ASSERT_TRUE(response->headers);
[email protected]a8e9b162009-03-12 00:06:442883 EXPECT_TRUE(response->headers->IsKeepAlive());
2884 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:422885 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:442886
2887 std::string response_data;
2888 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:422889 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]e60e47a2010-07-14 03:37:182890
2891 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:312892 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:442893}
2894
ttuttle7933c112015-01-06 00:55:242895// Test that we don't pass extraneous headers from the proxy's response to the
2896// caller when the proxy responds to CONNECT with 407.
2897TEST_P(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
2898 HttpRequestInfo request;
2899 request.method = "GET";
bncce36dca22015-04-21 22:11:232900 request.url = GURL("https://www.example.org/");
ttuttle7933c112015-01-06 00:55:242901 request.load_flags = 0;
2902
2903 // Configure against proxy server "myproxy:70".
2904 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
2905
2906 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2907
2908 scoped_ptr<HttpTransaction> trans(
2909 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2910
2911 // Since we have proxy, should try to establish tunnel.
2912 MockWrite data_writes[] = {
2913 MockWrite(
bncce36dca22015-04-21 22:11:232914 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2915 "Host: www.example.org\r\n"
ttuttle7933c112015-01-06 00:55:242916 "Proxy-Connection: keep-alive\r\n\r\n"),
2917 };
2918
2919 // The proxy responds to the connect with a 407.
2920 MockRead data_reads[] = {
2921 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2922 MockRead("X-Foo: bar\r\n"),
2923 MockRead("Set-Cookie: foo=bar\r\n"),
2924 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2925 MockRead("Content-Length: 10\r\n\r\n"),
2926 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
2927 };
2928
2929 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
2930 arraysize(data_writes));
2931 session_deps_.socket_factory->AddSocketDataProvider(&data);
2932
2933 TestCompletionCallback callback;
2934
2935 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
2936 EXPECT_EQ(ERR_IO_PENDING, rv);
2937
2938 rv = callback.WaitForResult();
2939 EXPECT_EQ(OK, rv);
2940
2941 const HttpResponseInfo* response = trans->GetResponseInfo();
2942 ASSERT_TRUE(response);
2943 ASSERT_TRUE(response->headers);
2944 EXPECT_TRUE(response->headers->IsKeepAlive());
2945 EXPECT_EQ(407, response->headers->response_code());
2946 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2947 EXPECT_FALSE(response->headers->HasHeader("X-Foo"));
2948 EXPECT_FALSE(response->headers->HasHeader("Set-Cookie"));
2949
2950 std::string response_data;
2951 rv = ReadTransaction(trans.get(), &response_data);
2952 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
2953
2954 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
2955 session->CloseAllConnections();
2956}
2957
[email protected]8fdbcd22010-05-05 02:54:522958// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
2959// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
[email protected]23e482282013-06-14 16:08:022960TEST_P(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:522961 HttpRequestInfo request;
2962 request.method = "GET";
bncce36dca22015-04-21 22:11:232963 request.url = GURL("http://www.example.org/");
[email protected]8fdbcd22010-05-05 02:54:522964 request.load_flags = 0;
2965
[email protected]cb9bf6ca2011-01-28 13:15:272966 // We are using a DIRECT connection (i.e. no proxy) for this session.
[email protected]3fe8d2f82013-10-17 08:56:072967 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272968 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:412969 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:272970
[email protected]8fdbcd22010-05-05 02:54:522971 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232972 MockWrite(
2973 "GET / HTTP/1.1\r\n"
2974 "Host: www.example.org\r\n"
2975 "Connection: keep-alive\r\n\r\n"),
[email protected]8fdbcd22010-05-05 02:54:522976 };
2977
2978 MockRead data_reads1[] = {
2979 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
2980 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2981 // Large content-length -- won't matter, as connection will be reset.
2982 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062983 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:522984 };
2985
2986 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2987 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072988 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:522989
[email protected]49639fa2011-12-20 23:22:412990 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:522991
[email protected]49639fa2011-12-20 23:22:412992 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]8fdbcd22010-05-05 02:54:522993 EXPECT_EQ(ERR_IO_PENDING, rv);
2994
2995 rv = callback.WaitForResult();
2996 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
2997}
2998
[email protected]7a67a8152010-11-05 18:31:102999// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
3000// through a non-authenticating proxy. The request should fail with
3001// ERR_UNEXPECTED_PROXY_AUTH.
3002// Note that it is impossible to detect if an HTTP server returns a 407 through
3003// a non-authenticating proxy - there is nothing to indicate whether the
3004// response came from the proxy or the server, so it is treated as if the proxy
3005// issued the challenge.
[email protected]23e482282013-06-14 16:08:023006TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:233007 HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:273008 HttpRequestInfo request;
3009 request.method = "GET";
bncce36dca22015-04-21 22:11:233010 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273011
[email protected]bb88e1d32013-05-03 23:11:073012 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
vishal.b62985ca92015-04-17 08:45:513013 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073014 session_deps_.net_log = log.bound().net_log();
3015 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:103016
[email protected]7a67a8152010-11-05 18:31:103017 // Since we have proxy, should try to establish tunnel.
3018 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233019 MockWrite(
3020 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3021 "Host: www.example.org\r\n"
3022 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103023
bncce36dca22015-04-21 22:11:233024 MockWrite(
3025 "GET / HTTP/1.1\r\n"
3026 "Host: www.example.org\r\n"
3027 "Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103028 };
3029
3030 MockRead data_reads1[] = {
3031 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3032
3033 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
3034 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3035 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:063036 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:103037 };
3038
3039 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3040 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073041 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063042 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073043 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:103044
[email protected]49639fa2011-12-20 23:22:413045 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:103046
[email protected]262eec82013-03-19 21:01:363047 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503048 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a67a8152010-11-05 18:31:103049
[email protected]49639fa2011-12-20 23:22:413050 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7a67a8152010-11-05 18:31:103051 EXPECT_EQ(ERR_IO_PENDING, rv);
3052
3053 rv = callback1.WaitForResult();
3054 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
mmenke43758e62015-05-04 21:09:463055 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403056 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:103057 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403058 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]7a67a8152010-11-05 18:31:103059 NetLog::PHASE_NONE);
3060 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403061 entries, pos,
[email protected]7a67a8152010-11-05 18:31:103062 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3063 NetLog::PHASE_NONE);
3064}
[email protected]2df19bb2010-08-25 20:13:463065
[email protected]029c83b62013-01-24 05:28:203066// Test the load timing for HTTPS requests with an HTTP proxy.
[email protected]23e482282013-06-14 16:08:023067TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:203068 HttpRequestInfo request1;
3069 request1.method = "GET";
bncce36dca22015-04-21 22:11:233070 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:203071
3072 HttpRequestInfo request2;
3073 request2.method = "GET";
bncce36dca22015-04-21 22:11:233074 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:203075
3076 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073077 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:203078 ProxyService::CreateFixed("PROXY myproxy:70"));
vishal.b62985ca92015-04-17 08:45:513079 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073080 session_deps_.net_log = log.bound().net_log();
3081 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:203082
3083 // Since we have proxy, should try to establish tunnel.
3084 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233085 MockWrite(
3086 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3087 "Host: www.example.org\r\n"
3088 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203089
bncce36dca22015-04-21 22:11:233090 MockWrite(
3091 "GET /1 HTTP/1.1\r\n"
3092 "Host: www.example.org\r\n"
3093 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203094
bncce36dca22015-04-21 22:11:233095 MockWrite(
3096 "GET /2 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 };
3100
3101 // The proxy responds to the connect with a 407, using a persistent
3102 // connection.
3103 MockRead data_reads1[] = {
3104 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3105
3106 MockRead("HTTP/1.1 200 OK\r\n"),
3107 MockRead("Content-Length: 1\r\n\r\n"),
3108 MockRead(SYNCHRONOUS, "1"),
3109
3110 MockRead("HTTP/1.1 200 OK\r\n"),
3111 MockRead("Content-Length: 2\r\n\r\n"),
3112 MockRead(SYNCHRONOUS, "22"),
3113 };
3114
3115 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3116 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073117 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:203118 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073119 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:203120
3121 TestCompletionCallback callback1;
[email protected]262eec82013-03-19 21:01:363122 scoped_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:503123 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:203124
3125 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
3126 EXPECT_EQ(ERR_IO_PENDING, rv);
3127
3128 rv = callback1.WaitForResult();
3129 EXPECT_EQ(OK, rv);
3130
3131 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
3132 ASSERT_TRUE(response1 != NULL);
[email protected]90499482013-06-01 00:39:503133 ASSERT_TRUE(response1->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:203134 EXPECT_EQ(1, response1->headers->GetContentLength());
3135
3136 LoadTimingInfo load_timing_info1;
3137 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
3138 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
3139
3140 trans1.reset();
3141
3142 TestCompletionCallback callback2;
[email protected]262eec82013-03-19 21:01:363143 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503144 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:203145
3146 rv = trans2->Start(&request2, callback2.callback(), log.bound());
3147 EXPECT_EQ(ERR_IO_PENDING, rv);
3148
3149 rv = callback2.WaitForResult();
3150 EXPECT_EQ(OK, rv);
3151
3152 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
3153 ASSERT_TRUE(response2 != NULL);
[email protected]90499482013-06-01 00:39:503154 ASSERT_TRUE(response2->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:203155 EXPECT_EQ(2, response2->headers->GetContentLength());
3156
3157 LoadTimingInfo load_timing_info2;
3158 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3159 TestLoadTimingReused(load_timing_info2);
3160
3161 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
3162
3163 trans2.reset();
3164 session->CloseAllConnections();
3165}
3166
3167// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
[email protected]23e482282013-06-14 16:08:023168TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:203169 HttpRequestInfo request1;
3170 request1.method = "GET";
bncce36dca22015-04-21 22:11:233171 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:203172
3173 HttpRequestInfo request2;
3174 request2.method = "GET";
bncce36dca22015-04-21 22:11:233175 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:203176
3177 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073178 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:203179 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
vishal.b62985ca92015-04-17 08:45:513180 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073181 session_deps_.net_log = log.bound().net_log();
3182 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:203183
3184 // Since we have proxy, should try to establish tunnel.
3185 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233186 MockWrite(
3187 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3188 "Host: www.example.org\r\n"
3189 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203190
bncce36dca22015-04-21 22:11:233191 MockWrite(
3192 "GET /1 HTTP/1.1\r\n"
3193 "Host: www.example.org\r\n"
3194 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203195
bncce36dca22015-04-21 22:11:233196 MockWrite(
3197 "GET /2 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 };
3201
3202 // The proxy responds to the connect with a 407, using a persistent
3203 // connection.
3204 MockRead data_reads1[] = {
3205 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3206
3207 MockRead("HTTP/1.1 200 OK\r\n"),
3208 MockRead("Content-Length: 1\r\n\r\n"),
3209 MockRead(SYNCHRONOUS, "1"),
3210
3211 MockRead("HTTP/1.1 200 OK\r\n"),
3212 MockRead("Content-Length: 2\r\n\r\n"),
3213 MockRead(SYNCHRONOUS, "22"),
3214 };
3215
3216 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3217 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073218 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:203219 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073220 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:203221
3222 TestCompletionCallback callback1;
[email protected]262eec82013-03-19 21:01:363223 scoped_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:503224 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:203225
3226 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
3227 EXPECT_EQ(ERR_IO_PENDING, rv);
3228
3229 rv = callback1.WaitForResult();
3230 EXPECT_EQ(OK, rv);
3231
3232 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
3233 ASSERT_TRUE(response1 != NULL);
[email protected]90499482013-06-01 00:39:503234 ASSERT_TRUE(response1->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:203235 EXPECT_EQ(1, response1->headers->GetContentLength());
3236
3237 LoadTimingInfo load_timing_info1;
3238 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
3239 TestLoadTimingNotReusedWithPac(load_timing_info1,
3240 CONNECT_TIMING_HAS_SSL_TIMES);
3241
3242 trans1.reset();
3243
3244 TestCompletionCallback callback2;
[email protected]262eec82013-03-19 21:01:363245 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503246 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:203247
3248 rv = trans2->Start(&request2, callback2.callback(), log.bound());
3249 EXPECT_EQ(ERR_IO_PENDING, rv);
3250
3251 rv = callback2.WaitForResult();
3252 EXPECT_EQ(OK, rv);
3253
3254 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
3255 ASSERT_TRUE(response2 != NULL);
[email protected]90499482013-06-01 00:39:503256 ASSERT_TRUE(response2->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:203257 EXPECT_EQ(2, response2->headers->GetContentLength());
3258
3259 LoadTimingInfo load_timing_info2;
3260 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3261 TestLoadTimingReusedWithPac(load_timing_info2);
3262
3263 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
3264
3265 trans2.reset();
3266 session->CloseAllConnections();
3267}
3268
[email protected]2df19bb2010-08-25 20:13:463269// Test a simple get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023270TEST_P(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:273271 HttpRequestInfo request;
3272 request.method = "GET";
bncce36dca22015-04-21 22:11:233273 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273274
[email protected]2df19bb2010-08-25 20:13:463275 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073276 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113277 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513278 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073279 session_deps_.net_log = log.bound().net_log();
3280 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:463281
[email protected]2df19bb2010-08-25 20:13:463282 // Since we have proxy, should use full url
3283 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233284 MockWrite(
3285 "GET http://www.example.org/ HTTP/1.1\r\n"
3286 "Host: www.example.org\r\n"
3287 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:463288 };
3289
3290 MockRead data_reads1[] = {
3291 MockRead("HTTP/1.1 200 OK\r\n"),
3292 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3293 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063294 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:463295 };
3296
3297 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3298 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073299 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063300 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073301 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:463302
[email protected]49639fa2011-12-20 23:22:413303 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:463304
[email protected]262eec82013-03-19 21:01:363305 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503306 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503307
[email protected]49639fa2011-12-20 23:22:413308 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:463309 EXPECT_EQ(ERR_IO_PENDING, rv);
3310
3311 rv = callback1.WaitForResult();
3312 EXPECT_EQ(OK, rv);
3313
[email protected]58e32bb2013-01-21 18:23:253314 LoadTimingInfo load_timing_info;
3315 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3316 TestLoadTimingNotReused(load_timing_info,
3317 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3318
[email protected]2df19bb2010-08-25 20:13:463319 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503320 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:463321
3322 EXPECT_TRUE(response->headers->IsKeepAlive());
3323 EXPECT_EQ(200, response->headers->response_code());
3324 EXPECT_EQ(100, response->headers->GetContentLength());
3325 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3326
3327 // The password prompt info should not be set.
3328 EXPECT_TRUE(response->auth_challenge.get() == NULL);
3329}
3330
[email protected]7642b5ae2010-09-01 20:55:173331// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023332TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:273333 HttpRequestInfo request;
3334 request.method = "GET";
bncce36dca22015-04-21 22:11:233335 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273336 request.load_flags = 0;
3337
[email protected]7642b5ae2010-09-01 20:55:173338 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073339 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113340 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513341 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073342 session_deps_.net_log = log.bound().net_log();
3343 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:173344
bncce36dca22015-04-21 22:11:233345 // fetch http://www.example.org/ via SPDY
[email protected]cdf8f7e72013-05-23 10:56:463346 scoped_ptr<SpdyFrame> req(
3347 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
rch8e6c6c42015-05-01 14:05:133348 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]7642b5ae2010-09-01 20:55:173349
[email protected]23e482282013-06-14 16:08:023350 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3351 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:173352 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:133353 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]7642b5ae2010-09-01 20:55:173354 };
3355
rch8e6c6c42015-05-01 14:05:133356 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3357 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073358 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:173359
[email protected]8ddf8322012-02-23 18:08:063360 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023361 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073362 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:173363
[email protected]49639fa2011-12-20 23:22:413364 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:173365
[email protected]262eec82013-03-19 21:01:363366 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503367 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503368
[email protected]49639fa2011-12-20 23:22:413369 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7642b5ae2010-09-01 20:55:173370 EXPECT_EQ(ERR_IO_PENDING, rv);
3371
3372 rv = callback1.WaitForResult();
3373 EXPECT_EQ(OK, rv);
3374
[email protected]58e32bb2013-01-21 18:23:253375 LoadTimingInfo load_timing_info;
3376 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3377 TestLoadTimingNotReused(load_timing_info,
3378 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3379
[email protected]7642b5ae2010-09-01 20:55:173380 const HttpResponseInfo* response = trans->GetResponseInfo();
3381 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503382 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]7642b5ae2010-09-01 20:55:173383 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3384
3385 std::string response_data;
3386 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:233387 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:173388}
3389
[email protected]1c173852014-06-19 12:51:503390// Verifies that a session which races and wins against the owning transaction
3391// (completing prior to host resolution), doesn't fail the transaction.
3392// Regression test for crbug.com/334413.
3393TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
3394 HttpRequestInfo request;
3395 request.method = "GET";
bncce36dca22015-04-21 22:11:233396 request.url = GURL("http://www.example.org/");
[email protected]1c173852014-06-19 12:51:503397 request.load_flags = 0;
3398
3399 // Configure SPDY proxy server "proxy:70".
3400 session_deps_.proxy_service.reset(
3401 ProxyService::CreateFixed("https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513402 BoundTestNetLog log;
[email protected]1c173852014-06-19 12:51:503403 session_deps_.net_log = log.bound().net_log();
3404 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3405
bncce36dca22015-04-21 22:11:233406 // Fetch http://www.example.org/ through the SPDY proxy.
[email protected]1c173852014-06-19 12:51:503407 scoped_ptr<SpdyFrame> req(
3408 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
rch8e6c6c42015-05-01 14:05:133409 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]1c173852014-06-19 12:51:503410
3411 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3412 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
3413 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:133414 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]1c173852014-06-19 12:51:503415 };
3416
rch8e6c6c42015-05-01 14:05:133417 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3418 arraysize(spdy_writes));
[email protected]1c173852014-06-19 12:51:503419 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
3420
3421 SSLSocketDataProvider ssl(ASYNC, OK);
3422 ssl.SetNextProto(GetParam());
3423 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3424
3425 TestCompletionCallback callback1;
3426
3427 scoped_ptr<HttpTransaction> trans(
3428 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3429
3430 // Stall the hostname resolution begun by the transaction.
3431 session_deps_.host_resolver->set_synchronous_mode(false);
3432 session_deps_.host_resolver->set_ondemand_mode(true);
3433
3434 int rv = trans->Start(&request, callback1.callback(), log.bound());
3435 EXPECT_EQ(ERR_IO_PENDING, rv);
3436
3437 // Race a session to the proxy, which completes first.
3438 session_deps_.host_resolver->set_ondemand_mode(false);
3439 SpdySessionKey key(
3440 HostPortPair("proxy", 70), ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
3441 base::WeakPtr<SpdySession> spdy_session =
3442 CreateSecureSpdySession(session, key, log.bound());
3443
3444 // Unstall the resolution begun by the transaction.
3445 session_deps_.host_resolver->set_ondemand_mode(true);
3446 session_deps_.host_resolver->ResolveAllPending();
3447
3448 EXPECT_FALSE(callback1.have_result());
3449 rv = callback1.WaitForResult();
3450 EXPECT_EQ(OK, rv);
3451
3452 const HttpResponseInfo* response = trans->GetResponseInfo();
3453 ASSERT_TRUE(response != NULL);
3454 ASSERT_TRUE(response->headers.get() != NULL);
3455 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3456
3457 std::string response_data;
3458 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
3459 EXPECT_EQ(kUploadData, response_data);
3460}
3461
[email protected]dc7bd1c52010-11-12 00:01:133462// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023463TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:273464 HttpRequestInfo request;
3465 request.method = "GET";
bncce36dca22015-04-21 22:11:233466 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273467 request.load_flags = 0;
3468
[email protected]79cb5c12011-09-12 13:12:043469 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073470 session_deps_.proxy_service.reset(
[email protected]79cb5c12011-09-12 13:12:043471 ProxyService::CreateFixed("https://myproxy:70"));
vishal.b62985ca92015-04-17 08:45:513472 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073473 session_deps_.net_log = log.bound().net_log();
3474 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:133475
[email protected]dc7bd1c52010-11-12 00:01:133476 // The first request will be a bare GET, the second request will be a
3477 // GET with a Proxy-Authorization header.
[email protected]ff98d7f02012-03-22 21:44:193478 scoped_ptr<SpdyFrame> req_get(
[email protected]cdf8f7e72013-05-23 10:56:463479 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]dc7bd1c52010-11-12 00:01:133480 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:463481 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:133482 };
[email protected]ff98d7f02012-03-22 21:44:193483 scoped_ptr<SpdyFrame> req_get_authorization(
[email protected]cdf8f7e72013-05-23 10:56:463484 spdy_util_.ConstructSpdyGet(kExtraAuthorizationHeaders,
3485 arraysize(kExtraAuthorizationHeaders) / 2,
3486 false,
3487 3,
3488 LOWEST,
3489 false));
[email protected]dc7bd1c52010-11-12 00:01:133490 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:133491 CreateMockWrite(*req_get, 0), CreateMockWrite(*req_get_authorization, 3),
[email protected]dc7bd1c52010-11-12 00:01:133492 };
3493
3494 // The first response is a 407 proxy authentication challenge, and the second
3495 // response will be a 200 response since the second request includes a valid
3496 // Authorization header.
3497 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:463498 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:133499 };
[email protected]ff98d7f02012-03-22 21:44:193500 scoped_ptr<SpdyFrame> resp_authentication(
[email protected]23e482282013-06-14 16:08:023501 spdy_util_.ConstructSpdySynReplyError(
[email protected]dc7bd1c52010-11-12 00:01:133502 "407 Proxy Authentication Required",
3503 kExtraAuthenticationHeaders, arraysize(kExtraAuthenticationHeaders)/2,
3504 1));
[email protected]ff98d7f02012-03-22 21:44:193505 scoped_ptr<SpdyFrame> body_authentication(
[email protected]23e482282013-06-14 16:08:023506 spdy_util_.ConstructSpdyBodyFrame(1, true));
3507 scoped_ptr<SpdyFrame> resp_data(
3508 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
3509 scoped_ptr<SpdyFrame> body_data(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:133510 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:133511 CreateMockRead(*resp_authentication, 1),
3512 CreateMockRead(*body_authentication, 2),
3513 CreateMockRead(*resp_data, 4),
3514 CreateMockRead(*body_data, 5),
3515 MockRead(ASYNC, 0, 6),
[email protected]dc7bd1c52010-11-12 00:01:133516 };
3517
rch8e6c6c42015-05-01 14:05:133518 SequencedSocketData data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3519 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073520 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:133521
[email protected]8ddf8322012-02-23 18:08:063522 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023523 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073524 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:133525
[email protected]49639fa2011-12-20 23:22:413526 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:133527
[email protected]262eec82013-03-19 21:01:363528 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503529 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]dc7bd1c52010-11-12 00:01:133530
[email protected]49639fa2011-12-20 23:22:413531 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]dc7bd1c52010-11-12 00:01:133532 EXPECT_EQ(ERR_IO_PENDING, rv);
3533
3534 rv = callback1.WaitForResult();
3535 EXPECT_EQ(OK, rv);
3536
3537 const HttpResponseInfo* const response = trans->GetResponseInfo();
3538
3539 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503540 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]dc7bd1c52010-11-12 00:01:133541 EXPECT_EQ(407, response->headers->response_code());
3542 EXPECT_TRUE(response->was_fetched_via_spdy);
[email protected]79cb5c12011-09-12 13:12:043543 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:133544
[email protected]49639fa2011-12-20 23:22:413545 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:133546
[email protected]49639fa2011-12-20 23:22:413547 rv = trans->RestartWithAuth(
3548 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]dc7bd1c52010-11-12 00:01:133549 EXPECT_EQ(ERR_IO_PENDING, rv);
3550
3551 rv = callback2.WaitForResult();
3552 EXPECT_EQ(OK, rv);
3553
3554 const HttpResponseInfo* const response_restart = trans->GetResponseInfo();
3555
3556 ASSERT_TRUE(response_restart != NULL);
[email protected]90499482013-06-01 00:39:503557 ASSERT_TRUE(response_restart->headers.get() != NULL);
[email protected]dc7bd1c52010-11-12 00:01:133558 EXPECT_EQ(200, response_restart->headers->response_code());
3559 // The password prompt info should not be set.
3560 EXPECT_TRUE(response_restart->auth_challenge.get() == NULL);
3561}
3562
[email protected]d9da5fe2010-10-13 22:37:163563// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
[email protected]23e482282013-06-14 16:08:023564TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:273565 HttpRequestInfo request;
3566 request.method = "GET";
bncce36dca22015-04-21 22:11:233567 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273568 request.load_flags = 0;
3569
[email protected]d9da5fe2010-10-13 22:37:163570 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073571 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113572 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513573 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073574 session_deps_.net_log = log.bound().net_log();
3575 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:163576
[email protected]262eec82013-03-19 21:01:363577 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503578 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:163579
bncce36dca22015-04-21 22:11:233580 // CONNECT to www.example.org:443 via SPDY
lgarrona91df87f2014-12-05 00:51:343581 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:233582 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
3583 // fetch https://www.example.org/ via HTTP
[email protected]d9da5fe2010-10-13 22:37:163584
bncce36dca22015-04-21 22:11:233585 const char get[] =
3586 "GET / HTTP/1.1\r\n"
3587 "Host: www.example.org\r\n"
3588 "Connection: keep-alive\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:193589 scoped_ptr<SpdyFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:023590 spdy_util_.ConstructSpdyBodyFrame(1, get, strlen(get), false));
3591 scoped_ptr<SpdyFrame> conn_resp(
3592 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:163593 const char resp[] = "HTTP/1.1 200 OK\r\n"
3594 "Content-Length: 10\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:193595 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:023596 spdy_util_.ConstructSpdyBodyFrame(1, resp, strlen(resp), false));
[email protected]ff98d7f02012-03-22 21:44:193597 scoped_ptr<SpdyFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:023598 spdy_util_.ConstructSpdyBodyFrame(1, "1234567890", 10, false));
[email protected]ff98d7f02012-03-22 21:44:193599 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203600 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
[email protected]8d2f7012012-02-16 00:08:043601
3602 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:133603 CreateMockWrite(*connect, 0),
3604 CreateMockWrite(*wrapped_get, 2),
3605 CreateMockWrite(*window_update, 6),
[email protected]8d2f7012012-02-16 00:08:043606 };
3607
[email protected]d9da5fe2010-10-13 22:37:163608 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:133609 CreateMockRead(*conn_resp, 1, ASYNC),
3610 CreateMockRead(*wrapped_get_resp, 3, ASYNC),
3611 CreateMockRead(*wrapped_body, 4, ASYNC),
3612 CreateMockRead(*wrapped_body, 5, ASYNC),
3613 MockRead(ASYNC, 0, 7),
[email protected]d9da5fe2010-10-13 22:37:163614 };
3615
rch8e6c6c42015-05-01 14:05:133616 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3617 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073618 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163619
[email protected]8ddf8322012-02-23 18:08:063620 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023621 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073622 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063623 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073624 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163625
[email protected]49639fa2011-12-20 23:22:413626 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163627
[email protected]49639fa2011-12-20 23:22:413628 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163629 EXPECT_EQ(ERR_IO_PENDING, rv);
3630
3631 rv = callback1.WaitForResult();
rch8e6c6c42015-05-01 14:05:133632 ASSERT_EQ(OK, rv);
[email protected]d9da5fe2010-10-13 22:37:163633
[email protected]58e32bb2013-01-21 18:23:253634 LoadTimingInfo load_timing_info;
3635 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3636 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3637
[email protected]d9da5fe2010-10-13 22:37:163638 const HttpResponseInfo* response = trans->GetResponseInfo();
3639 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503640 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d9da5fe2010-10-13 22:37:163641 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3642
3643 std::string response_data;
3644 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
3645 EXPECT_EQ("1234567890", response_data);
3646}
3647
3648// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
[email protected]23e482282013-06-14 16:08:023649TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
[email protected]cb9bf6ca2011-01-28 13:15:273650 HttpRequestInfo request;
3651 request.method = "GET";
bncce36dca22015-04-21 22:11:233652 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273653 request.load_flags = 0;
3654
[email protected]d9da5fe2010-10-13 22:37:163655 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073656 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113657 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513658 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073659 session_deps_.net_log = log.bound().net_log();
3660 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:163661
[email protected]262eec82013-03-19 21:01:363662 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503663 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:163664
bncce36dca22015-04-21 22:11:233665 // CONNECT to www.example.org:443 via SPDY
lgarrona91df87f2014-12-05 00:51:343666 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:233667 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
3668 // fetch https://www.example.org/ via SPDY
3669 const char kMyUrl[] = "https://www.example.org/";
[email protected]cdf8f7e72013-05-23 10:56:463670 scoped_ptr<SpdyFrame> get(
3671 spdy_util_.ConstructSpdyGet(kMyUrl, false, 1, LOWEST));
[email protected]23e482282013-06-14 16:08:023672 scoped_ptr<SpdyFrame> wrapped_get(
3673 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
3674 scoped_ptr<SpdyFrame> conn_resp(
3675 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3676 scoped_ptr<SpdyFrame> get_resp(
3677 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]ff98d7f02012-03-22 21:44:193678 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:023679 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
3680 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
3681 scoped_ptr<SpdyFrame> wrapped_body(
3682 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
[email protected]ff98d7f02012-03-22 21:44:193683 scoped_ptr<SpdyFrame> window_update_get_resp(
[email protected]c10b20852013-05-15 21:29:203684 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
[email protected]ff98d7f02012-03-22 21:44:193685 scoped_ptr<SpdyFrame> window_update_body(
[email protected]c10b20852013-05-15 21:29:203686 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body->size()));
[email protected]8d2f7012012-02-16 00:08:043687
3688 MockWrite spdy_writes[] = {
rch32320842015-05-16 15:57:093689 CreateMockWrite(*connect, 0),
3690 CreateMockWrite(*wrapped_get, 2),
3691 CreateMockWrite(*window_update_get_resp, 6),
[email protected]8d2f7012012-02-16 00:08:043692 CreateMockWrite(*window_update_body, 7),
3693 };
3694
[email protected]d9da5fe2010-10-13 22:37:163695 MockRead spdy_reads[] = {
rch32320842015-05-16 15:57:093696 CreateMockRead(*conn_resp, 1, ASYNC),
3697 MockRead(ASYNC, ERR_IO_PENDING, 3),
rch8e6c6c42015-05-01 14:05:133698 CreateMockRead(*wrapped_get_resp, 4, ASYNC),
rch32320842015-05-16 15:57:093699 CreateMockRead(*wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:133700 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:163701 };
3702
rch32320842015-05-16 15:57:093703 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3704 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073705 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163706
[email protected]8ddf8322012-02-23 18:08:063707 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023708 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073709 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063710 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023711 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073712 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163713
[email protected]49639fa2011-12-20 23:22:413714 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163715
[email protected]49639fa2011-12-20 23:22:413716 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163717 EXPECT_EQ(ERR_IO_PENDING, rv);
3718
rch32320842015-05-16 15:57:093719 // Allow the SpdyProxyClientSocket's write callback to complete.
3720 base::MessageLoop::current()->RunUntilIdle();
3721 // Now allow the read of the response to complete.
3722 spdy_data.CompleteRead();
[email protected]d9da5fe2010-10-13 22:37:163723 rv = callback1.WaitForResult();
3724 EXPECT_EQ(OK, rv);
3725
[email protected]58e32bb2013-01-21 18:23:253726 LoadTimingInfo load_timing_info;
3727 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3728 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3729
[email protected]d9da5fe2010-10-13 22:37:163730 const HttpResponseInfo* response = trans->GetResponseInfo();
3731 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503732 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d9da5fe2010-10-13 22:37:163733 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3734
3735 std::string response_data;
3736 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:233737 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:163738}
3739
3740// Test a SPDY CONNECT failure through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023741TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:273742 HttpRequestInfo request;
3743 request.method = "GET";
bncce36dca22015-04-21 22:11:233744 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273745 request.load_flags = 0;
3746
[email protected]d9da5fe2010-10-13 22:37:163747 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073748 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113749 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513750 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073751 session_deps_.net_log = log.bound().net_log();
3752 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:163753
[email protected]262eec82013-03-19 21:01:363754 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503755 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:163756
bncce36dca22015-04-21 22:11:233757 // CONNECT to www.example.org:443 via SPDY
lgarrona91df87f2014-12-05 00:51:343758 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:233759 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]c10b20852013-05-15 21:29:203760 scoped_ptr<SpdyFrame> get(
3761 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:163762
3763 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:133764 CreateMockWrite(*connect, 0), CreateMockWrite(*get, 2),
[email protected]d9da5fe2010-10-13 22:37:163765 };
3766
[email protected]23e482282013-06-14 16:08:023767 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdySynReplyError(1));
3768 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:163769 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:133770 CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 3),
[email protected]d9da5fe2010-10-13 22:37:163771 };
3772
rch8e6c6c42015-05-01 14:05:133773 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3774 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073775 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163776
[email protected]8ddf8322012-02-23 18:08:063777 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023778 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073779 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063780 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023781 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073782 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163783
[email protected]49639fa2011-12-20 23:22:413784 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163785
[email protected]49639fa2011-12-20 23:22:413786 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163787 EXPECT_EQ(ERR_IO_PENDING, rv);
3788
3789 rv = callback1.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:173790 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]d9da5fe2010-10-13 22:37:163791
[email protected]4eddbc732012-08-09 05:40:173792 // TODO(ttuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:163793}
3794
[email protected]f6c63db52013-02-02 00:35:223795// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
3796// HTTPS Proxy to different servers.
[email protected]23e482282013-06-14 16:08:023797TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:223798 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
3799 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073800 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:223801 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513802 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073803 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:223804 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:073805 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:223806
3807 HttpRequestInfo request1;
3808 request1.method = "GET";
bncce36dca22015-04-21 22:11:233809 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:223810 request1.load_flags = 0;
3811
3812 HttpRequestInfo request2;
3813 request2.method = "GET";
bncce36dca22015-04-21 22:11:233814 request2.url = GURL("https://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:223815 request2.load_flags = 0;
3816
bncce36dca22015-04-21 22:11:233817 // CONNECT to www.example.org:443 via SPDY.
lgarrona91df87f2014-12-05 00:51:343818 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:233819 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]23e482282013-06-14 16:08:023820 scoped_ptr<SpdyFrame> conn_resp1(
3821 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:223822
bncce36dca22015-04-21 22:11:233823 // Fetch https://www.example.org/ via HTTP.
3824 const char get1[] =
3825 "GET / HTTP/1.1\r\n"
3826 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:223827 "Connection: keep-alive\r\n\r\n";
3828 scoped_ptr<SpdyFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:023829 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:223830 const char resp1[] = "HTTP/1.1 200 OK\r\n"
3831 "Content-Length: 1\r\n\r\n";
3832 scoped_ptr<SpdyFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:023833 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
3834 scoped_ptr<SpdyFrame> wrapped_body1(
3835 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
[email protected]f6c63db52013-02-02 00:35:223836 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203837 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:223838
bncce36dca22015-04-21 22:11:233839 // CONNECT to mail.example.org:443 via SPDY.
[email protected]745aa9c2014-06-27 02:21:293840 SpdyHeaderBlock connect2_block;
3841 connect2_block[spdy_util_.GetMethodKey()] = "CONNECT";
bncce36dca22015-04-21 22:11:233842 connect2_block[spdy_util_.GetPathKey()] = "mail.example.org:443";
3843 connect2_block[spdy_util_.GetHostKey()] = "mail.example.org";
[email protected]745aa9c2014-06-27 02:21:293844 spdy_util_.MaybeAddVersionHeader(&connect2_block);
[email protected]f6c63db52013-02-02 00:35:223845 scoped_ptr<SpdyFrame> connect2(
[email protected]745aa9c2014-06-27 02:21:293846 spdy_util_.ConstructSpdySyn(3, connect2_block, LOWEST, false, false));
[email protected]601e03f12014-04-06 16:26:393847
[email protected]23e482282013-06-14 16:08:023848 scoped_ptr<SpdyFrame> conn_resp2(
3849 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:223850
bncce36dca22015-04-21 22:11:233851 // Fetch https://mail.example.org/ via HTTP.
3852 const char get2[] =
3853 "GET / HTTP/1.1\r\n"
3854 "Host: mail.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:223855 "Connection: keep-alive\r\n\r\n";
3856 scoped_ptr<SpdyFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:023857 spdy_util_.ConstructSpdyBodyFrame(3, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:223858 const char resp2[] = "HTTP/1.1 200 OK\r\n"
3859 "Content-Length: 2\r\n\r\n";
3860 scoped_ptr<SpdyFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:023861 spdy_util_.ConstructSpdyBodyFrame(3, resp2, strlen(resp2), false));
[email protected]f6c63db52013-02-02 00:35:223862 scoped_ptr<SpdyFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:023863 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:223864
3865 MockWrite spdy_writes[] = {
3866 CreateMockWrite(*connect1, 0),
3867 CreateMockWrite(*wrapped_get1, 2),
3868 CreateMockWrite(*connect2, 5),
3869 CreateMockWrite(*wrapped_get2, 7),
3870 };
3871
3872 MockRead spdy_reads[] = {
3873 CreateMockRead(*conn_resp1, 1, ASYNC),
3874 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
3875 CreateMockRead(*wrapped_body1, 4, ASYNC),
3876 CreateMockRead(*conn_resp2, 6, ASYNC),
3877 CreateMockRead(*wrapped_get_resp2, 8, ASYNC),
3878 CreateMockRead(*wrapped_body2, 9, ASYNC),
3879 MockRead(ASYNC, 0, 10),
3880 };
3881
3882 DeterministicSocketData spdy_data(
3883 spdy_reads, arraysize(spdy_reads),
3884 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073885 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:223886
3887 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023888 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073889 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:223890 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073891 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:223892 SSLSocketDataProvider ssl3(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073893 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:223894
3895 TestCompletionCallback callback;
3896
[email protected]262eec82013-03-19 21:01:363897 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503898 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223899 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
3900 EXPECT_EQ(ERR_IO_PENDING, rv);
3901 // The first connect and request, each of their responses, and the body.
3902 spdy_data.RunFor(5);
3903
3904 rv = callback.WaitForResult();
3905 EXPECT_EQ(OK, rv);
3906
3907 LoadTimingInfo load_timing_info;
3908 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3909 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3910
3911 const HttpResponseInfo* response = trans->GetResponseInfo();
3912 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503913 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:223914 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3915
3916 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:293917 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]90499482013-06-01 00:39:503918 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223919
[email protected]262eec82013-03-19 21:01:363920 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503921 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223922 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
3923 EXPECT_EQ(ERR_IO_PENDING, rv);
3924
3925 // The second connect and request, each of their responses, and the body.
3926 spdy_data.RunFor(5);
3927 rv = callback.WaitForResult();
3928 EXPECT_EQ(OK, rv);
3929
3930 LoadTimingInfo load_timing_info2;
3931 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3932 // Even though the SPDY connection is reused, a new tunnelled connection has
3933 // to be created, so the socket's load timing looks like a fresh connection.
3934 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
3935
3936 // The requests should have different IDs, since they each are using their own
3937 // separate stream.
3938 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
3939
[email protected]90499482013-06-01 00:39:503940 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223941}
3942
3943// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
3944// HTTPS Proxy to the same server.
[email protected]23e482282013-06-14 16:08:023945TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:223946 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
3947 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073948 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:223949 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513950 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073951 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:223952 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:073953 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:223954
3955 HttpRequestInfo request1;
3956 request1.method = "GET";
bncce36dca22015-04-21 22:11:233957 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:223958 request1.load_flags = 0;
3959
3960 HttpRequestInfo request2;
3961 request2.method = "GET";
bncce36dca22015-04-21 22:11:233962 request2.url = GURL("https://www.example.org/2");
[email protected]f6c63db52013-02-02 00:35:223963 request2.load_flags = 0;
3964
bncce36dca22015-04-21 22:11:233965 // CONNECT to www.example.org:443 via SPDY.
lgarrona91df87f2014-12-05 00:51:343966 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:233967 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]23e482282013-06-14 16:08:023968 scoped_ptr<SpdyFrame> conn_resp1(
3969 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:223970
bncce36dca22015-04-21 22:11:233971 // Fetch https://www.example.org/ via HTTP.
3972 const char get1[] =
3973 "GET / HTTP/1.1\r\n"
3974 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:223975 "Connection: keep-alive\r\n\r\n";
3976 scoped_ptr<SpdyFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:023977 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:223978 const char resp1[] = "HTTP/1.1 200 OK\r\n"
3979 "Content-Length: 1\r\n\r\n";
3980 scoped_ptr<SpdyFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:023981 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
3982 scoped_ptr<SpdyFrame> wrapped_body1(
3983 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
[email protected]f6c63db52013-02-02 00:35:223984 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203985 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:223986
bncce36dca22015-04-21 22:11:233987 // Fetch https://www.example.org/2 via HTTP.
3988 const char get2[] =
3989 "GET /2 HTTP/1.1\r\n"
3990 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:223991 "Connection: keep-alive\r\n\r\n";
3992 scoped_ptr<SpdyFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:023993 spdy_util_.ConstructSpdyBodyFrame(1, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:223994 const char resp2[] = "HTTP/1.1 200 OK\r\n"
3995 "Content-Length: 2\r\n\r\n";
3996 scoped_ptr<SpdyFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:023997 spdy_util_.ConstructSpdyBodyFrame(1, resp2, strlen(resp2), false));
[email protected]f6c63db52013-02-02 00:35:223998 scoped_ptr<SpdyFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:023999 spdy_util_.ConstructSpdyBodyFrame(1, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:224000
4001 MockWrite spdy_writes[] = {
4002 CreateMockWrite(*connect1, 0),
4003 CreateMockWrite(*wrapped_get1, 2),
4004 CreateMockWrite(*wrapped_get2, 5),
4005 };
4006
4007 MockRead spdy_reads[] = {
4008 CreateMockRead(*conn_resp1, 1, ASYNC),
4009 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
4010 CreateMockRead(*wrapped_body1, 4, ASYNC),
4011 CreateMockRead(*wrapped_get_resp2, 6, ASYNC),
4012 CreateMockRead(*wrapped_body2, 7, ASYNC),
4013 MockRead(ASYNC, 0, 8),
4014 };
4015
4016 DeterministicSocketData spdy_data(
4017 spdy_reads, arraysize(spdy_reads),
4018 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074019 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:224020
4021 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:024022 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:074023 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:224024 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074025 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:224026
4027 TestCompletionCallback callback;
4028
[email protected]262eec82013-03-19 21:01:364029 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504030 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224031 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
4032 EXPECT_EQ(ERR_IO_PENDING, rv);
4033 // The first connect and request, each of their responses, and the body.
4034 spdy_data.RunFor(5);
4035
4036 rv = callback.WaitForResult();
4037 EXPECT_EQ(OK, rv);
4038
4039 LoadTimingInfo load_timing_info;
4040 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4041 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
4042
4043 const HttpResponseInfo* response = trans->GetResponseInfo();
4044 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504045 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:224046 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4047
4048 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:294049 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]90499482013-06-01 00:39:504050 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:224051 trans.reset();
4052
[email protected]262eec82013-03-19 21:01:364053 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:504054 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224055 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
4056 EXPECT_EQ(ERR_IO_PENDING, rv);
4057
4058 // The second request, response, and body. There should not be a second
4059 // connect.
4060 spdy_data.RunFor(3);
4061 rv = callback.WaitForResult();
4062 EXPECT_EQ(OK, rv);
4063
4064 LoadTimingInfo load_timing_info2;
4065 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4066 TestLoadTimingReused(load_timing_info2);
4067
4068 // The requests should have the same ID.
4069 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
4070
[email protected]90499482013-06-01 00:39:504071 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:224072}
4073
4074// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
4075// Proxy to different servers.
[email protected]23e482282013-06-14 16:08:024076TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:224077 HttpsProxySpdyLoadTimingTwoHttpRequests) {
4078 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:074079 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:224080 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:514081 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074082 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:224083 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:074084 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:224085
4086 HttpRequestInfo request1;
4087 request1.method = "GET";
bncce36dca22015-04-21 22:11:234088 request1.url = GURL("http://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:224089 request1.load_flags = 0;
4090
4091 HttpRequestInfo request2;
4092 request2.method = "GET";
bncce36dca22015-04-21 22:11:234093 request2.url = GURL("http://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:224094 request2.load_flags = 0;
4095
bncce36dca22015-04-21 22:11:234096 // http://www.example.org/
[email protected]23e482282013-06-14 16:08:024097 scoped_ptr<SpdyHeaderBlock> headers(
bncce36dca22015-04-21 22:11:234098 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
[email protected]745aa9c2014-06-27 02:21:294099 scoped_ptr<SpdyFrame> get1(
4100 spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, false, true));
[email protected]23e482282013-06-14 16:08:024101 scoped_ptr<SpdyFrame> get_resp1(
4102 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
4103 scoped_ptr<SpdyFrame> body1(
4104 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, true));
[email protected]f6c63db52013-02-02 00:35:224105
bncce36dca22015-04-21 22:11:234106 // http://mail.example.org/
[email protected]23e482282013-06-14 16:08:024107 scoped_ptr<SpdyHeaderBlock> headers2(
bncce36dca22015-04-21 22:11:234108 spdy_util_.ConstructGetHeaderBlockForProxy("http://mail.example.org/"));
[email protected]745aa9c2014-06-27 02:21:294109 scoped_ptr<SpdyFrame> get2(
4110 spdy_util_.ConstructSpdySyn(3, *headers2, LOWEST, false, true));
[email protected]23e482282013-06-14 16:08:024111 scoped_ptr<SpdyFrame> get_resp2(
4112 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
4113 scoped_ptr<SpdyFrame> body2(
4114 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, true));
[email protected]f6c63db52013-02-02 00:35:224115
4116 MockWrite spdy_writes[] = {
4117 CreateMockWrite(*get1, 0),
4118 CreateMockWrite(*get2, 3),
4119 };
4120
4121 MockRead spdy_reads[] = {
4122 CreateMockRead(*get_resp1, 1, ASYNC),
4123 CreateMockRead(*body1, 2, ASYNC),
4124 CreateMockRead(*get_resp2, 4, ASYNC),
4125 CreateMockRead(*body2, 5, ASYNC),
4126 MockRead(ASYNC, 0, 6),
4127 };
4128
4129 DeterministicSocketData spdy_data(
4130 spdy_reads, arraysize(spdy_reads),
4131 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074132 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:224133
4134 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:024135 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:074136 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:224137
4138 TestCompletionCallback callback;
4139
[email protected]262eec82013-03-19 21:01:364140 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504141 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224142 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
4143 EXPECT_EQ(ERR_IO_PENDING, rv);
4144 spdy_data.RunFor(2);
4145
4146 rv = callback.WaitForResult();
4147 EXPECT_EQ(OK, rv);
4148
4149 LoadTimingInfo load_timing_info;
4150 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4151 TestLoadTimingNotReused(load_timing_info,
4152 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4153
4154 const HttpResponseInfo* response = trans->GetResponseInfo();
4155 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504156 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:224157 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4158
4159 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:294160 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]90499482013-06-01 00:39:504161 EXPECT_EQ(ERR_IO_PENDING, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:224162 spdy_data.RunFor(1);
4163 EXPECT_EQ(1, callback.WaitForResult());
4164 // Delete the first request, so the second one can reuse the socket.
4165 trans.reset();
4166
[email protected]262eec82013-03-19 21:01:364167 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:504168 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224169 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
4170 EXPECT_EQ(ERR_IO_PENDING, rv);
4171
4172 spdy_data.RunFor(2);
4173 rv = callback.WaitForResult();
4174 EXPECT_EQ(OK, rv);
4175
4176 LoadTimingInfo load_timing_info2;
4177 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4178 TestLoadTimingReused(load_timing_info2);
4179
4180 // The requests should have the same ID.
4181 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
4182
[email protected]90499482013-06-01 00:39:504183 EXPECT_EQ(ERR_IO_PENDING, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:224184 spdy_data.RunFor(1);
4185 EXPECT_EQ(2, callback.WaitForResult());
4186}
4187
[email protected]2df19bb2010-08-25 20:13:464188// Test the challenge-response-retry sequence through an HTTPS Proxy
[email protected]23e482282013-06-14 16:08:024189TEST_P(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:464190 HttpRequestInfo request;
4191 request.method = "GET";
bncce36dca22015-04-21 22:11:234192 request.url = GURL("http://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:464193 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:294194 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]2df19bb2010-08-25 20:13:464195
[email protected]79cb5c12011-09-12 13:12:044196 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:074197 session_deps_.proxy_service.reset(
[email protected]79cb5c12011-09-12 13:12:044198 ProxyService::CreateFixed("https://myproxy:70"));
vishal.b62985ca92015-04-17 08:45:514199 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074200 session_deps_.net_log = log.bound().net_log();
4201 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274202
[email protected]2df19bb2010-08-25 20:13:464203 // Since we have proxy, should use full url
4204 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:234205 MockWrite(
4206 "GET http://www.example.org/ HTTP/1.1\r\n"
4207 "Host: www.example.org\r\n"
4208 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:464209
bncce36dca22015-04-21 22:11:234210 // After calling trans->RestartWithAuth(), this is the request we should
4211 // be issuing -- the final header line contains the credentials.
4212 MockWrite(
4213 "GET http://www.example.org/ HTTP/1.1\r\n"
4214 "Host: www.example.org\r\n"
4215 "Proxy-Connection: keep-alive\r\n"
4216 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:464217 };
4218
4219 // The proxy responds to the GET with a 407, using a persistent
4220 // connection.
4221 MockRead data_reads1[] = {
4222 // No credentials.
4223 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4224 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4225 MockRead("Proxy-Connection: keep-alive\r\n"),
4226 MockRead("Content-Length: 0\r\n\r\n"),
4227
4228 MockRead("HTTP/1.1 200 OK\r\n"),
4229 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4230 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064231 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:464232 };
4233
4234 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4235 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074236 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:064237 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074238 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:464239
[email protected]49639fa2011-12-20 23:22:414240 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:464241
[email protected]262eec82013-03-19 21:01:364242 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504243 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504244
[email protected]49639fa2011-12-20 23:22:414245 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:464246 EXPECT_EQ(ERR_IO_PENDING, rv);
4247
4248 rv = callback1.WaitForResult();
4249 EXPECT_EQ(OK, rv);
4250
[email protected]58e32bb2013-01-21 18:23:254251 LoadTimingInfo load_timing_info;
4252 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4253 TestLoadTimingNotReused(load_timing_info,
4254 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4255
[email protected]2df19bb2010-08-25 20:13:464256 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504257 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504258 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]2df19bb2010-08-25 20:13:464259 EXPECT_EQ(407, response->headers->response_code());
4260 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:044261 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:464262
[email protected]49639fa2011-12-20 23:22:414263 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:464264
[email protected]49639fa2011-12-20 23:22:414265 rv = trans->RestartWithAuth(
4266 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]2df19bb2010-08-25 20:13:464267 EXPECT_EQ(ERR_IO_PENDING, rv);
4268
4269 rv = callback2.WaitForResult();
4270 EXPECT_EQ(OK, rv);
4271
[email protected]58e32bb2013-01-21 18:23:254272 load_timing_info = LoadTimingInfo();
4273 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4274 // Retrying with HTTP AUTH is considered to be reusing a socket.
4275 TestLoadTimingReused(load_timing_info);
4276
[email protected]2df19bb2010-08-25 20:13:464277 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504278 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:464279
4280 EXPECT_TRUE(response->headers->IsKeepAlive());
4281 EXPECT_EQ(200, response->headers->response_code());
4282 EXPECT_EQ(100, response->headers->GetContentLength());
4283 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4284
4285 // The password prompt info should not be set.
4286 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4287}
4288
[email protected]23e482282013-06-14 16:08:024289void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:084290 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:424291 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:084292 request.method = "GET";
bncce36dca22015-04-21 22:11:234293 request.url = GURL("https://www.example.org/");
[email protected]c744cf22009-02-27 07:28:084294 request.load_flags = 0;
4295
[email protected]cb9bf6ca2011-01-28 13:15:274296 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:074297 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]bb88e1d32013-05-03 23:11:074298 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274299
[email protected]c744cf22009-02-27 07:28:084300 // Since we have proxy, should try to establish tunnel.
4301 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:234302 MockWrite(
4303 "CONNECT www.example.org:443 HTTP/1.1\r\n"
4304 "Host: www.example.org\r\n"
4305 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:084306 };
4307
4308 MockRead data_reads[] = {
4309 status,
4310 MockRead("Content-Length: 10\r\n\r\n"),
4311 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:064312 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]c744cf22009-02-27 07:28:084313 };
4314
[email protected]31a2bfe2010-02-09 08:03:394315 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
4316 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:074317 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:084318
[email protected]49639fa2011-12-20 23:22:414319 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:084320
[email protected]262eec82013-03-19 21:01:364321 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504322 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504323
[email protected]49639fa2011-12-20 23:22:414324 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424325 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]c744cf22009-02-27 07:28:084326
4327 rv = callback.WaitForResult();
4328 EXPECT_EQ(expected_status, rv);
4329}
4330
[email protected]23e482282013-06-14 16:08:024331void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:234332 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:084333 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:424334 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:084335}
4336
[email protected]23e482282013-06-14 16:08:024337TEST_P(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:084338 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
4339}
4340
[email protected]23e482282013-06-14 16:08:024341TEST_P(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:084342 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
4343}
4344
[email protected]23e482282013-06-14 16:08:024345TEST_P(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:084346 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
4347}
4348
[email protected]23e482282013-06-14 16:08:024349TEST_P(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:084350 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
4351}
4352
[email protected]23e482282013-06-14 16:08:024353TEST_P(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:084354 ConnectStatusHelper(
4355 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
4356}
4357
[email protected]23e482282013-06-14 16:08:024358TEST_P(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:084359 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
4360}
4361
[email protected]23e482282013-06-14 16:08:024362TEST_P(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:084363 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
4364}
4365
[email protected]23e482282013-06-14 16:08:024366TEST_P(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:084367 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
4368}
4369
[email protected]23e482282013-06-14 16:08:024370TEST_P(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:084371 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
4372}
4373
[email protected]23e482282013-06-14 16:08:024374TEST_P(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:084375 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
4376}
4377
[email protected]23e482282013-06-14 16:08:024378TEST_P(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:084379 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
4380}
4381
[email protected]23e482282013-06-14 16:08:024382TEST_P(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:084383 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
4384}
4385
[email protected]23e482282013-06-14 16:08:024386TEST_P(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:084387 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
4388}
4389
[email protected]23e482282013-06-14 16:08:024390TEST_P(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:084391 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
4392}
4393
[email protected]23e482282013-06-14 16:08:024394TEST_P(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:084395 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
4396}
4397
[email protected]23e482282013-06-14 16:08:024398TEST_P(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:084399 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
4400}
4401
[email protected]0a17aab32014-04-24 03:32:374402TEST_P(HttpNetworkTransactionTest, ConnectStatus308) {
4403 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
4404}
4405
[email protected]23e482282013-06-14 16:08:024406TEST_P(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:084407 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
4408}
4409
[email protected]23e482282013-06-14 16:08:024410TEST_P(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:084411 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
4412}
4413
[email protected]23e482282013-06-14 16:08:024414TEST_P(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:084415 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
4416}
4417
[email protected]23e482282013-06-14 16:08:024418TEST_P(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:084419 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
4420}
4421
[email protected]23e482282013-06-14 16:08:024422TEST_P(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:084423 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
4424}
4425
[email protected]23e482282013-06-14 16:08:024426TEST_P(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:084427 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
4428}
4429
[email protected]23e482282013-06-14 16:08:024430TEST_P(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:084431 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
4432}
4433
[email protected]23e482282013-06-14 16:08:024434TEST_P(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:084435 ConnectStatusHelperWithExpectedStatus(
4436 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:544437 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:084438}
4439
[email protected]23e482282013-06-14 16:08:024440TEST_P(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:084441 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
4442}
4443
[email protected]23e482282013-06-14 16:08:024444TEST_P(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:084445 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
4446}
4447
[email protected]23e482282013-06-14 16:08:024448TEST_P(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:084449 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
4450}
4451
[email protected]23e482282013-06-14 16:08:024452TEST_P(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:084453 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
4454}
4455
[email protected]23e482282013-06-14 16:08:024456TEST_P(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:084457 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
4458}
4459
[email protected]23e482282013-06-14 16:08:024460TEST_P(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:084461 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
4462}
4463
[email protected]23e482282013-06-14 16:08:024464TEST_P(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:084465 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
4466}
4467
[email protected]23e482282013-06-14 16:08:024468TEST_P(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:084469 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
4470}
4471
[email protected]23e482282013-06-14 16:08:024472TEST_P(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:084473 ConnectStatusHelper(
4474 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
4475}
4476
[email protected]23e482282013-06-14 16:08:024477TEST_P(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:084478 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
4479}
4480
[email protected]23e482282013-06-14 16:08:024481TEST_P(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:084482 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
4483}
4484
[email protected]23e482282013-06-14 16:08:024485TEST_P(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:084486 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
4487}
4488
[email protected]23e482282013-06-14 16:08:024489TEST_P(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:084490 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
4491}
4492
[email protected]23e482282013-06-14 16:08:024493TEST_P(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:084494 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
4495}
4496
[email protected]23e482282013-06-14 16:08:024497TEST_P(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:084498 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
4499}
4500
[email protected]23e482282013-06-14 16:08:024501TEST_P(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:084502 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
4503}
4504
[email protected]038e9a32008-10-08 22:40:164505// Test the flow when both the proxy server AND origin server require
4506// authentication. Again, this uses basic auth for both since that is
4507// the simplest to mock.
[email protected]23e482282013-06-14 16:08:024508TEST_P(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:274509 HttpRequestInfo request;
4510 request.method = "GET";
bncce36dca22015-04-21 22:11:234511 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274512 request.load_flags = 0;
4513
[email protected]038e9a32008-10-08 22:40:164514 // Configure against proxy server "myproxy:70".
[email protected]3fe8d2f82013-10-17 08:56:074515 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
4516 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4517
4518 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:414519 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]038e9a32008-10-08 22:40:164520
[email protected]f9ee6b52008-11-08 06:46:234521 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:234522 MockWrite(
4523 "GET http://www.example.org/ HTTP/1.1\r\n"
4524 "Host: www.example.org\r\n"
4525 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:234526 };
4527
[email protected]038e9a32008-10-08 22:40:164528 MockRead data_reads1[] = {
4529 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
4530 // Give a couple authenticate options (only the middle one is actually
4531 // supported).
[email protected]22927ad2009-09-21 19:56:194532 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:164533 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4534 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
4535 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4536 // Large content-length -- won't matter, as connection will be reset.
4537 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064538 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:164539 };
4540
4541 // After calling trans->RestartWithAuth() the first time, this is the
4542 // request we should be issuing -- the final header line contains the
4543 // proxy's credentials.
4544 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:234545 MockWrite(
4546 "GET http://www.example.org/ HTTP/1.1\r\n"
4547 "Host: www.example.org\r\n"
4548 "Proxy-Connection: keep-alive\r\n"
4549 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:164550 };
4551
4552 // Now the proxy server lets the request pass through to origin server.
4553 // The origin server responds with a 401.
4554 MockRead data_reads2[] = {
4555 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4556 // Note: We are using the same realm-name as the proxy server. This is
4557 // completely valid, as realms are unique across hosts.
4558 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4559 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4560 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064561 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:164562 };
4563
4564 // After calling trans->RestartWithAuth() the second time, we should send
4565 // the credentials for both the proxy and origin server.
4566 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:234567 MockWrite(
4568 "GET http://www.example.org/ HTTP/1.1\r\n"
4569 "Host: www.example.org\r\n"
4570 "Proxy-Connection: keep-alive\r\n"
4571 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
4572 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:164573 };
4574
4575 // Lastly we get the desired content.
4576 MockRead data_reads3[] = {
4577 MockRead("HTTP/1.0 200 OK\r\n"),
4578 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4579 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064580 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:164581 };
4582
[email protected]31a2bfe2010-02-09 08:03:394583 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4584 data_writes1, arraysize(data_writes1));
4585 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4586 data_writes2, arraysize(data_writes2));
4587 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4588 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:074589 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4590 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4591 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:164592
[email protected]49639fa2011-12-20 23:22:414593 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:164594
[email protected]49639fa2011-12-20 23:22:414595 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424596 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:164597
4598 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424599 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:164600
[email protected]1c773ea12009-04-28 19:58:424601 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504602 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044603 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:164604
[email protected]49639fa2011-12-20 23:22:414605 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:164606
[email protected]49639fa2011-12-20 23:22:414607 rv = trans->RestartWithAuth(
4608 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:424609 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:164610
4611 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424612 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:164613
4614 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504615 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044616 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:164617
[email protected]49639fa2011-12-20 23:22:414618 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:164619
[email protected]49639fa2011-12-20 23:22:414620 rv = trans->RestartWithAuth(
4621 AuthCredentials(kFoo2, kBar2), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424622 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:164623
4624 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424625 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:164626
4627 response = trans->GetResponseInfo();
4628 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4629 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:164630}
[email protected]4ddaf2502008-10-23 18:26:194631
[email protected]ea9dc9a2009-09-05 00:43:324632// For the NTLM implementation using SSPI, we skip the NTLM tests since we
4633// can't hook into its internals to cause it to generate predictable NTLM
4634// authorization headers.
4635#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:294636// The NTLM authentication unit tests were generated by capturing the HTTP
4637// requests and responses using Fiddler 2 and inspecting the generated random
4638// bytes in the debugger.
4639
4640// Enter the correct password and authenticate successfully.
[email protected]23e482282013-06-14 16:08:024641TEST_P(HttpNetworkTransactionTest, NTLMAuth1) {
[email protected]1c773ea12009-04-28 19:58:424642 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:244643 request.method = "GET";
4644 request.url = GURL("http://172.22.68.17/kids/login.aspx");
[email protected]2217aa22013-10-11 03:03:544645
4646 // Ensure load is not disrupted by flags which suppress behaviour specific
4647 // to other auth schemes.
4648 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:244649
[email protected]cb9bf6ca2011-01-28 13:15:274650 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
4651 MockGetHostName);
[email protected]bb88e1d32013-05-03 23:11:074652 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274653
[email protected]3f918782009-02-28 01:29:244654 MockWrite data_writes1[] = {
4655 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4656 "Host: 172.22.68.17\r\n"
4657 "Connection: keep-alive\r\n\r\n"),
4658 };
4659
4660 MockRead data_reads1[] = {
4661 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:044662 // Negotiate and NTLM are often requested together. However, we only want
4663 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
4664 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:244665 MockRead("WWW-Authenticate: NTLM\r\n"),
4666 MockRead("Connection: close\r\n"),
4667 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364668 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:244669 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064670 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]3f918782009-02-28 01:29:244671 };
4672
4673 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:224674 // After restarting with a null identity, this is the
[email protected]3f918782009-02-28 01:29:244675 // request we should be issuing -- the final header line contains a Type
4676 // 1 message.
4677 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4678 "Host: 172.22.68.17\r\n"
4679 "Connection: keep-alive\r\n"
4680 "Authorization: NTLM "
4681 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4682
4683 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4684 // (the credentials for the origin server). The second request continues
4685 // on the same connection.
4686 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4687 "Host: 172.22.68.17\r\n"
4688 "Connection: keep-alive\r\n"
[email protected]385a4672009-03-11 22:21:294689 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4690 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4691 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
4692 "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
4693 "ahlhx5I=\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:244694 };
4695
4696 MockRead data_reads2[] = {
4697 // The origin server responds with a Type 2 message.
4698 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4699 MockRead("WWW-Authenticate: NTLM "
[email protected]385a4672009-03-11 22:21:294700 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
[email protected]3f918782009-02-28 01:29:244701 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4702 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4703 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4704 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4705 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4706 "BtAAAAAAA=\r\n"),
4707 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364708 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:244709 MockRead("You are not authorized to view this page\r\n"),
4710
4711 // Lastly we get the desired content.
4712 MockRead("HTTP/1.1 200 OK\r\n"),
4713 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
4714 MockRead("Content-Length: 13\r\n\r\n"),
4715 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:064716 MockRead(SYNCHRONOUS, OK),
[email protected]3f918782009-02-28 01:29:244717 };
4718
[email protected]31a2bfe2010-02-09 08:03:394719 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4720 data_writes1, arraysize(data_writes1));
4721 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4722 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:074723 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4724 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:244725
[email protected]49639fa2011-12-20 23:22:414726 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:244727
[email protected]262eec82013-03-19 21:01:364728 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504729 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504730
[email protected]49639fa2011-12-20 23:22:414731 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424732 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:244733
4734 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424735 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:244736
[email protected]0757e7702009-03-27 04:00:224737 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4738
[email protected]1c773ea12009-04-28 19:58:424739 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:044740 ASSERT_FALSE(response == NULL);
4741 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:244742
[email protected]49639fa2011-12-20 23:22:414743 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:254744
[email protected]f3cf9802011-10-28 18:44:584745 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:414746 callback2.callback());
[email protected]10af5fe72011-01-31 16:17:254747 EXPECT_EQ(ERR_IO_PENDING, rv);
4748
4749 rv = callback2.WaitForResult();
4750 EXPECT_EQ(OK, rv);
4751
4752 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4753
4754 response = trans->GetResponseInfo();
4755 ASSERT_TRUE(response != NULL);
[email protected]10af5fe72011-01-31 16:17:254756 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4757
[email protected]49639fa2011-12-20 23:22:414758 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:244759
[email protected]49639fa2011-12-20 23:22:414760 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424761 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:244762
[email protected]0757e7702009-03-27 04:00:224763 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424764 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:244765
4766 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504767 ASSERT_TRUE(response != NULL);
[email protected]3f918782009-02-28 01:29:244768 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4769 EXPECT_EQ(13, response->headers->GetContentLength());
4770}
4771
[email protected]385a4672009-03-11 22:21:294772// Enter a wrong password, and then the correct one.
[email protected]23e482282013-06-14 16:08:024773TEST_P(HttpNetworkTransactionTest, NTLMAuth2) {
[email protected]1c773ea12009-04-28 19:58:424774 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:294775 request.method = "GET";
4776 request.url = GURL("http://172.22.68.17/kids/login.aspx");
4777 request.load_flags = 0;
4778
[email protected]cb9bf6ca2011-01-28 13:15:274779 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
4780 MockGetHostName);
[email protected]bb88e1d32013-05-03 23:11:074781 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274782
[email protected]385a4672009-03-11 22:21:294783 MockWrite data_writes1[] = {
4784 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4785 "Host: 172.22.68.17\r\n"
4786 "Connection: keep-alive\r\n\r\n"),
4787 };
4788
4789 MockRead data_reads1[] = {
4790 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:044791 // Negotiate and NTLM are often requested together. However, we only want
4792 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
4793 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:294794 MockRead("WWW-Authenticate: NTLM\r\n"),
4795 MockRead("Connection: close\r\n"),
4796 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364797 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294798 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064799 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:294800 };
4801
4802 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:224803 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:294804 // request we should be issuing -- the final header line contains a Type
4805 // 1 message.
4806 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4807 "Host: 172.22.68.17\r\n"
4808 "Connection: keep-alive\r\n"
4809 "Authorization: NTLM "
4810 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4811
4812 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4813 // (the credentials for the origin server). The second request continues
4814 // on the same connection.
4815 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4816 "Host: 172.22.68.17\r\n"
4817 "Connection: keep-alive\r\n"
4818 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4819 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4820 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
4821 "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
4822 "4Ww7b7E=\r\n\r\n"),
4823 };
4824
4825 MockRead data_reads2[] = {
4826 // The origin server responds with a Type 2 message.
4827 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4828 MockRead("WWW-Authenticate: NTLM "
4829 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
4830 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4831 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4832 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4833 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4834 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4835 "BtAAAAAAA=\r\n"),
4836 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364837 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294838 MockRead("You are not authorized to view this page\r\n"),
4839
4840 // Wrong password.
4841 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]385a4672009-03-11 22:21:294842 MockRead("WWW-Authenticate: NTLM\r\n"),
4843 MockRead("Connection: close\r\n"),
4844 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364845 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294846 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064847 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:294848 };
4849
4850 MockWrite data_writes3[] = {
[email protected]0757e7702009-03-27 04:00:224851 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:294852 // request we should be issuing -- the final header line contains a Type
4853 // 1 message.
4854 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4855 "Host: 172.22.68.17\r\n"
4856 "Connection: keep-alive\r\n"
4857 "Authorization: NTLM "
4858 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4859
4860 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4861 // (the credentials for the origin server). The second request continues
4862 // on the same connection.
4863 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4864 "Host: 172.22.68.17\r\n"
4865 "Connection: keep-alive\r\n"
4866 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4867 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4868 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
4869 "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
4870 "+4MUm7c=\r\n\r\n"),
4871 };
4872
4873 MockRead data_reads3[] = {
4874 // The origin server responds with a Type 2 message.
4875 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4876 MockRead("WWW-Authenticate: NTLM "
4877 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
4878 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4879 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4880 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4881 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4882 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4883 "BtAAAAAAA=\r\n"),
4884 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364885 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294886 MockRead("You are not authorized to view this page\r\n"),
4887
4888 // Lastly we get the desired content.
4889 MockRead("HTTP/1.1 200 OK\r\n"),
4890 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
4891 MockRead("Content-Length: 13\r\n\r\n"),
4892 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:064893 MockRead(SYNCHRONOUS, OK),
[email protected]385a4672009-03-11 22:21:294894 };
4895
[email protected]31a2bfe2010-02-09 08:03:394896 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4897 data_writes1, arraysize(data_writes1));
4898 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4899 data_writes2, arraysize(data_writes2));
4900 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4901 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:074902 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4903 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4904 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:294905
[email protected]49639fa2011-12-20 23:22:414906 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:294907
[email protected]262eec82013-03-19 21:01:364908 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504909 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504910
[email protected]49639fa2011-12-20 23:22:414911 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424912 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:294913
4914 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424915 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:294916
[email protected]0757e7702009-03-27 04:00:224917 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:294918
[email protected]1c773ea12009-04-28 19:58:424919 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504920 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044921 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:294922
[email protected]49639fa2011-12-20 23:22:414923 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:294924
[email protected]0757e7702009-03-27 04:00:224925 // Enter the wrong password.
[email protected]f3cf9802011-10-28 18:44:584926 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword),
[email protected]49639fa2011-12-20 23:22:414927 callback2.callback());
[email protected]1c773ea12009-04-28 19:58:424928 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:294929
[email protected]10af5fe72011-01-31 16:17:254930 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424931 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:294932
[email protected]0757e7702009-03-27 04:00:224933 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:414934 TestCompletionCallback callback3;
4935 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424936 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]10af5fe72011-01-31 16:17:254937 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424938 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:224939 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4940
4941 response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:044942 ASSERT_FALSE(response == NULL);
4943 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:224944
[email protected]49639fa2011-12-20 23:22:414945 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:224946
4947 // Now enter the right password.
[email protected]f3cf9802011-10-28 18:44:584948 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:414949 callback4.callback());
[email protected]10af5fe72011-01-31 16:17:254950 EXPECT_EQ(ERR_IO_PENDING, rv);
4951
4952 rv = callback4.WaitForResult();
4953 EXPECT_EQ(OK, rv);
4954
4955 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4956
[email protected]49639fa2011-12-20 23:22:414957 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:254958
4959 // One more roundtrip
[email protected]49639fa2011-12-20 23:22:414960 rv = trans->RestartWithAuth(AuthCredentials(), callback5.callback());
[email protected]1c773ea12009-04-28 19:58:424961 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:224962
4963 rv = callback5.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424964 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:224965
[email protected]385a4672009-03-11 22:21:294966 response = trans->GetResponseInfo();
4967 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4968 EXPECT_EQ(13, response->headers->GetContentLength());
4969}
[email protected]ea9dc9a2009-09-05 00:43:324970#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:294971
[email protected]4ddaf2502008-10-23 18:26:194972// Test reading a server response which has only headers, and no body.
4973// After some maximum number of bytes is consumed, the transaction should
4974// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
[email protected]23e482282013-06-14 16:08:024975TEST_P(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:424976 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:194977 request.method = "GET";
bncce36dca22015-04-21 22:11:234978 request.url = GURL("http://www.example.org/");
[email protected]4ddaf2502008-10-23 18:26:194979 request.load_flags = 0;
4980
[email protected]3fe8d2f82013-10-17 08:56:074981 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274982 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:414983 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:274984
[email protected]b75b7b2f2009-10-06 00:54:534985 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:434986 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:534987 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:194988
4989 MockRead data_reads[] = {
4990 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:064991 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:194992 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:064993 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:194994 };
[email protected]31a2bfe2010-02-09 08:03:394995 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:074996 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:194997
[email protected]49639fa2011-12-20 23:22:414998 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:194999
[email protected]49639fa2011-12-20 23:22:415000 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425001 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]4ddaf2502008-10-23 18:26:195002
5003 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425004 EXPECT_EQ(ERR_RESPONSE_HEADERS_TOO_BIG, rv);
[email protected]4ddaf2502008-10-23 18:26:195005}
[email protected]f4e426b2008-11-05 00:24:495006
5007// Make sure that we don't try to reuse a TCPClientSocket when failing to
5008// establish tunnel.
5009// http://code.google.com/p/chromium/issues/detail?id=3772
[email protected]23e482282013-06-14 16:08:025010TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:235011 DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:275012 HttpRequestInfo request;
5013 request.method = "GET";
bncce36dca22015-04-21 22:11:235014 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275015 request.load_flags = 0;
5016
[email protected]f4e426b2008-11-05 00:24:495017 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:075018 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]db8f44c2008-12-13 04:52:015019
[email protected]bb88e1d32013-05-03 23:11:075020 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:495021
[email protected]262eec82013-03-19 21:01:365022 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505023 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f4e426b2008-11-05 00:24:495024
[email protected]f4e426b2008-11-05 00:24:495025 // Since we have proxy, should try to establish tunnel.
5026 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235027 MockWrite(
5028 "CONNECT www.example.org:443 HTTP/1.1\r\n"
5029 "Host: www.example.org\r\n"
5030 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:495031 };
5032
[email protected]77848d12008-11-14 00:00:225033 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:495034 // connection. Usually a proxy would return 501 (not implemented),
5035 // or 200 (tunnel established).
5036 MockRead data_reads1[] = {
5037 MockRead("HTTP/1.1 404 Not Found\r\n"),
5038 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065039 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]f4e426b2008-11-05 00:24:495040 };
5041
[email protected]31a2bfe2010-02-09 08:03:395042 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5043 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075044 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:495045
[email protected]49639fa2011-12-20 23:22:415046 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:495047
[email protected]49639fa2011-12-20 23:22:415048 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425049 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f4e426b2008-11-05 00:24:495050
5051 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425052 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]f4e426b2008-11-05 00:24:495053
[email protected]b4404c02009-04-10 16:38:525054 // Empty the current queue. This is necessary because idle sockets are
5055 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345056 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:525057
[email protected]f4e426b2008-11-05 00:24:495058 // We now check to make sure the TCPClientSocket was not added back to
5059 // the pool.
[email protected]90499482013-06-01 00:39:505060 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:495061 trans.reset();
[email protected]2da659e2013-05-23 20:51:345062 base::MessageLoop::current()->RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:495063 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:505064 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:495065}
[email protected]372d34a2008-11-05 21:30:515066
[email protected]1b157c02009-04-21 01:55:405067// Make sure that we recycle a socket after reading all of the response body.
[email protected]23e482282013-06-14 16:08:025068TEST_P(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:425069 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:405070 request.method = "GET";
bncce36dca22015-04-21 22:11:235071 request.url = GURL("http://www.example.org/");
[email protected]1b157c02009-04-21 01:55:405072 request.load_flags = 0;
5073
[email protected]bb88e1d32013-05-03 23:11:075074 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275075
[email protected]262eec82013-03-19 21:01:365076 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505077 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275078
[email protected]1b157c02009-04-21 01:55:405079 MockRead data_reads[] = {
5080 // A part of the response body is received with the response headers.
5081 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
5082 // The rest of the response body is received in two parts.
5083 MockRead("lo"),
5084 MockRead(" world"),
5085 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:065086 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:405087 };
5088
[email protected]31a2bfe2010-02-09 08:03:395089 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:075090 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:405091
[email protected]49639fa2011-12-20 23:22:415092 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:405093
[email protected]49639fa2011-12-20 23:22:415094 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425095 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]1b157c02009-04-21 01:55:405096
5097 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425098 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:405099
[email protected]1c773ea12009-04-28 19:58:425100 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505101 ASSERT_TRUE(response != NULL);
[email protected]1b157c02009-04-21 01:55:405102
[email protected]90499482013-06-01 00:39:505103 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]1b157c02009-04-21 01:55:405104 std::string status_line = response->headers->GetStatusLine();
5105 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
5106
[email protected]90499482013-06-01 00:39:505107 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:405108
5109 std::string response_data;
5110 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:425111 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:405112 EXPECT_EQ("hello world", response_data);
5113
5114 // Empty the current queue. This is necessary because idle sockets are
5115 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345116 base::MessageLoop::current()->RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:405117
5118 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505119 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:405120}
5121
[email protected]76a505b2010-08-25 06:23:005122// Make sure that we recycle a SSL socket after reading all of the response
5123// body.
[email protected]23e482282013-06-14 16:08:025124TEST_P(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:005125 HttpRequestInfo request;
5126 request.method = "GET";
bncce36dca22015-04-21 22:11:235127 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:005128 request.load_flags = 0;
5129
5130 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:235131 MockWrite(
5132 "GET / HTTP/1.1\r\n"
5133 "Host: www.example.org\r\n"
5134 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:005135 };
5136
5137 MockRead data_reads[] = {
5138 MockRead("HTTP/1.1 200 OK\r\n"),
5139 MockRead("Content-Length: 11\r\n\r\n"),
5140 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:065141 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:005142 };
5143
[email protected]8ddf8322012-02-23 18:08:065144 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075145 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:005146
5147 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5148 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:075149 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:005150
[email protected]49639fa2011-12-20 23:22:415151 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:005152
[email protected]bb88e1d32013-05-03 23:11:075153 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:365154 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505155 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:005156
[email protected]49639fa2011-12-20 23:22:415157 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:005158
5159 EXPECT_EQ(ERR_IO_PENDING, rv);
5160 EXPECT_EQ(OK, callback.WaitForResult());
5161
5162 const HttpResponseInfo* response = trans->GetResponseInfo();
5163 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:505164 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:005165 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5166
[email protected]90499482013-06-01 00:39:505167 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005168
5169 std::string response_data;
5170 rv = ReadTransaction(trans.get(), &response_data);
5171 EXPECT_EQ(OK, rv);
5172 EXPECT_EQ("hello world", response_data);
5173
5174 // Empty the current queue. This is necessary because idle sockets are
5175 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345176 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:005177
5178 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505179 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005180}
5181
5182// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
5183// from the pool and make sure that we recover okay.
[email protected]23e482282013-06-14 16:08:025184TEST_P(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:005185 HttpRequestInfo request;
5186 request.method = "GET";
bncce36dca22015-04-21 22:11:235187 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:005188 request.load_flags = 0;
5189
5190 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:235191 MockWrite(
5192 "GET / HTTP/1.1\r\n"
5193 "Host: www.example.org\r\n"
5194 "Connection: keep-alive\r\n\r\n"),
5195 MockWrite(
5196 "GET / HTTP/1.1\r\n"
5197 "Host: www.example.org\r\n"
5198 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:005199 };
5200
5201 MockRead data_reads[] = {
5202 MockRead("HTTP/1.1 200 OK\r\n"),
5203 MockRead("Content-Length: 11\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065204 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:005205 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:065206 MockRead(ASYNC, 0, 0) // EOF
[email protected]76a505b2010-08-25 06:23:005207 };
5208
[email protected]8ddf8322012-02-23 18:08:065209 SSLSocketDataProvider ssl(ASYNC, OK);
5210 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075211 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5212 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:005213
5214 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5215 data_writes, arraysize(data_writes));
5216 StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
5217 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:075218 session_deps_.socket_factory->AddSocketDataProvider(&data);
5219 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:005220
[email protected]49639fa2011-12-20 23:22:415221 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:005222
[email protected]bb88e1d32013-05-03 23:11:075223 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:365224 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505225 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:005226
[email protected]49639fa2011-12-20 23:22:415227 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:005228
5229 EXPECT_EQ(ERR_IO_PENDING, rv);
5230 EXPECT_EQ(OK, callback.WaitForResult());
5231
5232 const HttpResponseInfo* response = trans->GetResponseInfo();
5233 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:505234 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:005235 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5236
[email protected]90499482013-06-01 00:39:505237 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005238
5239 std::string response_data;
5240 rv = ReadTransaction(trans.get(), &response_data);
5241 EXPECT_EQ(OK, rv);
5242 EXPECT_EQ("hello world", response_data);
5243
5244 // Empty the current queue. This is necessary because idle sockets are
5245 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345246 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:005247
5248 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505249 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005250
5251 // Now start the second transaction, which should reuse the previous socket.
5252
[email protected]90499482013-06-01 00:39:505253 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:005254
[email protected]49639fa2011-12-20 23:22:415255 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:005256
5257 EXPECT_EQ(ERR_IO_PENDING, rv);
5258 EXPECT_EQ(OK, callback.WaitForResult());
5259
5260 response = trans->GetResponseInfo();
5261 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:505262 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:005263 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5264
[email protected]90499482013-06-01 00:39:505265 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005266
5267 rv = ReadTransaction(trans.get(), &response_data);
5268 EXPECT_EQ(OK, rv);
5269 EXPECT_EQ("hello world", response_data);
5270
5271 // Empty the current queue. This is necessary because idle sockets are
5272 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345273 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:005274
5275 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505276 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005277}
5278
[email protected]b4404c02009-04-10 16:38:525279// Make sure that we recycle a socket after a zero-length response.
5280// http://crbug.com/9880
[email protected]23e482282013-06-14 16:08:025281TEST_P(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:425282 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:525283 request.method = "GET";
bncce36dca22015-04-21 22:11:235284 request.url = GURL(
5285 "http://www.example.org/csi?v=3&s=web&action=&"
5286 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
5287 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
5288 "rt=prt.2642,ol.2649,xjs.2951");
[email protected]b4404c02009-04-10 16:38:525289 request.load_flags = 0;
5290
[email protected]bb88e1d32013-05-03 23:11:075291 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275292
[email protected]262eec82013-03-19 21:01:365293 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505294 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275295
[email protected]b4404c02009-04-10 16:38:525296 MockRead data_reads[] = {
5297 MockRead("HTTP/1.1 204 No Content\r\n"
5298 "Content-Length: 0\r\n"
5299 "Content-Type: text/html\r\n\r\n"),
5300 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:065301 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:525302 };
5303
[email protected]31a2bfe2010-02-09 08:03:395304 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:075305 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:525306
[email protected]49639fa2011-12-20 23:22:415307 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:525308
[email protected]49639fa2011-12-20 23:22:415309 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425310 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]b4404c02009-04-10 16:38:525311
5312 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425313 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:525314
[email protected]1c773ea12009-04-28 19:58:425315 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505316 ASSERT_TRUE(response != NULL);
[email protected]b4404c02009-04-10 16:38:525317
[email protected]90499482013-06-01 00:39:505318 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]b4404c02009-04-10 16:38:525319 std::string status_line = response->headers->GetStatusLine();
5320 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
5321
[email protected]90499482013-06-01 00:39:505322 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:525323
5324 std::string response_data;
5325 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:425326 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:525327 EXPECT_EQ("", response_data);
5328
5329 // Empty the current queue. This is necessary because idle sockets are
5330 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345331 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:525332
5333 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505334 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:525335}
5336
[email protected]23e482282013-06-14 16:08:025337TEST_P(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
[email protected]b2d26cfd2012-12-11 10:36:065338 ScopedVector<UploadElementReader> element_readers;
5339 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:075340 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:275341
[email protected]1c773ea12009-04-28 19:58:425342 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:515343 // Transaction 1: a GET request that succeeds. The socket is recycled
5344 // after use.
5345 request[0].method = "GET";
5346 request[0].url = GURL("http://www.google.com/");
5347 request[0].load_flags = 0;
5348 // Transaction 2: a POST request. Reuses the socket kept alive from
5349 // transaction 1. The first attempts fails when writing the POST data.
5350 // This causes the transaction to retry with a new socket. The second
5351 // attempt succeeds.
5352 request[1].method = "POST";
5353 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:275354 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:515355 request[1].load_flags = 0;
5356
[email protected]bb88e1d32013-05-03 23:11:075357 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:515358
5359 // The first socket is used for transaction 1 and the first attempt of
5360 // transaction 2.
5361
5362 // The response of transaction 1.
5363 MockRead data_reads1[] = {
5364 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
5365 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:065366 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:515367 };
5368 // The mock write results of transaction 1 and the first attempt of
5369 // transaction 2.
5370 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:065371 MockWrite(SYNCHRONOUS, 64), // GET
5372 MockWrite(SYNCHRONOUS, 93), // POST
5373 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:515374 };
[email protected]31a2bfe2010-02-09 08:03:395375 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5376 data_writes1, arraysize(data_writes1));
[email protected]372d34a2008-11-05 21:30:515377
5378 // The second socket is used for the second attempt of transaction 2.
5379
5380 // The response of transaction 2.
5381 MockRead data_reads2[] = {
5382 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
5383 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:065384 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:515385 };
5386 // The mock write results of the second attempt of transaction 2.
5387 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:065388 MockWrite(SYNCHRONOUS, 93), // POST
5389 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:515390 };
[email protected]31a2bfe2010-02-09 08:03:395391 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5392 data_writes2, arraysize(data_writes2));
[email protected]372d34a2008-11-05 21:30:515393
[email protected]bb88e1d32013-05-03 23:11:075394 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5395 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:515396
thestig9d3bb0c2015-01-24 00:49:515397 const char* const kExpectedResponseData[] = {
[email protected]372d34a2008-11-05 21:30:515398 "hello world", "welcome"
5399 };
5400
5401 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:425402 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505403 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]372d34a2008-11-05 21:30:515404
[email protected]49639fa2011-12-20 23:22:415405 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:515406
[email protected]49639fa2011-12-20 23:22:415407 int rv = trans->Start(&request[i], callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425408 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]372d34a2008-11-05 21:30:515409
5410 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425411 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:515412
[email protected]1c773ea12009-04-28 19:58:425413 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505414 ASSERT_TRUE(response != NULL);
[email protected]372d34a2008-11-05 21:30:515415
[email protected]90499482013-06-01 00:39:505416 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]372d34a2008-11-05 21:30:515417 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5418
5419 std::string response_data;
5420 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:425421 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:515422 EXPECT_EQ(kExpectedResponseData[i], response_data);
5423 }
5424}
[email protected]f9ee6b52008-11-08 06:46:235425
5426// Test the request-challenge-retry sequence for basic auth when there is
5427// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:165428// it fails the identity from the URL is used to answer the challenge.
[email protected]23e482282013-06-14 16:08:025429TEST_P(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:425430 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235431 request.method = "GET";
bncce36dca22015-04-21 22:11:235432 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:415433 request.load_flags = LOAD_NORMAL;
[email protected]a97cca42009-08-14 01:00:295434
[email protected]3fe8d2f82013-10-17 08:56:075435 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275436 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415437 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275438
[email protected]a97cca42009-08-14 01:00:295439 // The password contains an escaped character -- for this test to pass it
5440 // will need to be unescaped by HttpNetworkTransaction.
5441 EXPECT_EQ("b%40r", request.url.password());
5442
[email protected]f9ee6b52008-11-08 06:46:235443 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235444 MockWrite(
5445 "GET / HTTP/1.1\r\n"
5446 "Host: www.example.org\r\n"
5447 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235448 };
5449
5450 MockRead data_reads1[] = {
5451 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5452 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5453 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065454 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235455 };
5456
[email protected]2262e3a2012-05-22 16:08:165457 // After the challenge above, the transaction will be restarted using the
5458 // identity from the url (foo, b@r) to answer the challenge.
5459 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235460 MockWrite(
5461 "GET / HTTP/1.1\r\n"
5462 "Host: www.example.org\r\n"
5463 "Connection: keep-alive\r\n"
5464 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:165465 };
5466
5467 MockRead data_reads2[] = {
5468 MockRead("HTTP/1.0 200 OK\r\n"),
5469 MockRead("Content-Length: 100\r\n\r\n"),
5470 MockRead(SYNCHRONOUS, OK),
5471 };
5472
[email protected]31a2bfe2010-02-09 08:03:395473 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5474 data_writes1, arraysize(data_writes1));
[email protected]2262e3a2012-05-22 16:08:165475 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5476 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075477 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5478 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235479
[email protected]49639fa2011-12-20 23:22:415480 TestCompletionCallback callback1;
[email protected]49639fa2011-12-20 23:22:415481 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425482 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235483 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425484 EXPECT_EQ(OK, rv);
[email protected]2262e3a2012-05-22 16:08:165485 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5486
5487 TestCompletionCallback callback2;
5488 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
5489 EXPECT_EQ(ERR_IO_PENDING, rv);
5490 rv = callback2.WaitForResult();
5491 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225492 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5493
[email protected]2262e3a2012-05-22 16:08:165494 const HttpResponseInfo* response = trans->GetResponseInfo();
5495 ASSERT_TRUE(response != NULL);
5496
5497 // There is no challenge info, since the identity in URL worked.
5498 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5499
5500 EXPECT_EQ(100, response->headers->GetContentLength());
5501
5502 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:345503 base::MessageLoop::current()->RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:165504}
5505
5506// Test the request-challenge-retry sequence for basic auth when there is an
5507// incorrect identity in the URL. The identity from the URL should be used only
5508// once.
[email protected]23e482282013-06-14 16:08:025509TEST_P(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:165510 HttpRequestInfo request;
5511 request.method = "GET";
5512 // Note: the URL has a username:password in it. The password "baz" is
5513 // wrong (should be "bar").
bncce36dca22015-04-21 22:11:235514 request.url = GURL("http://foo:[email protected]/");
[email protected]2262e3a2012-05-22 16:08:165515
5516 request.load_flags = LOAD_NORMAL;
5517
[email protected]3fe8d2f82013-10-17 08:56:075518 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2262e3a2012-05-22 16:08:165519 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415520 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2262e3a2012-05-22 16:08:165521
5522 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235523 MockWrite(
5524 "GET / HTTP/1.1\r\n"
5525 "Host: www.example.org\r\n"
5526 "Connection: keep-alive\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:165527 };
5528
5529 MockRead data_reads1[] = {
5530 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5531 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5532 MockRead("Content-Length: 10\r\n\r\n"),
5533 MockRead(SYNCHRONOUS, ERR_FAILED),
5534 };
5535
5536 // After the challenge above, the transaction will be restarted using the
5537 // identity from the url (foo, baz) to answer the challenge.
5538 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235539 MockWrite(
5540 "GET / HTTP/1.1\r\n"
5541 "Host: www.example.org\r\n"
5542 "Connection: keep-alive\r\n"
5543 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:165544 };
5545
5546 MockRead data_reads2[] = {
5547 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5548 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5549 MockRead("Content-Length: 10\r\n\r\n"),
5550 MockRead(SYNCHRONOUS, ERR_FAILED),
5551 };
5552
5553 // After the challenge above, the transaction will be restarted using the
5554 // identity supplied by the user (foo, bar) to answer the challenge.
5555 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:235556 MockWrite(
5557 "GET / HTTP/1.1\r\n"
5558 "Host: www.example.org\r\n"
5559 "Connection: keep-alive\r\n"
5560 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:165561 };
5562
5563 MockRead data_reads3[] = {
5564 MockRead("HTTP/1.0 200 OK\r\n"),
5565 MockRead("Content-Length: 100\r\n\r\n"),
5566 MockRead(SYNCHRONOUS, OK),
5567 };
5568
5569 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5570 data_writes1, arraysize(data_writes1));
5571 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5572 data_writes2, arraysize(data_writes2));
5573 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5574 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075575 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5576 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5577 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:165578
5579 TestCompletionCallback callback1;
5580
5581 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5582 EXPECT_EQ(ERR_IO_PENDING, rv);
5583
5584 rv = callback1.WaitForResult();
5585 EXPECT_EQ(OK, rv);
5586
5587 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5588 TestCompletionCallback callback2;
5589 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
5590 EXPECT_EQ(ERR_IO_PENDING, rv);
5591 rv = callback2.WaitForResult();
5592 EXPECT_EQ(OK, rv);
5593 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5594
5595 const HttpResponseInfo* response = trans->GetResponseInfo();
5596 ASSERT_TRUE(response != NULL);
5597 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
5598
5599 TestCompletionCallback callback3;
5600 rv = trans->RestartWithAuth(
5601 AuthCredentials(kFoo, kBar), callback3.callback());
5602 EXPECT_EQ(ERR_IO_PENDING, rv);
5603 rv = callback3.WaitForResult();
5604 EXPECT_EQ(OK, rv);
5605 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5606
5607 response = trans->GetResponseInfo();
5608 ASSERT_TRUE(response != NULL);
5609
5610 // There is no challenge info, since the identity worked.
5611 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5612
5613 EXPECT_EQ(100, response->headers->GetContentLength());
5614
[email protected]ea9dc9a2009-09-05 00:43:325615 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:345616 base::MessageLoop::current()->RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:325617}
5618
[email protected]2217aa22013-10-11 03:03:545619
5620// Test the request-challenge-retry sequence for basic auth when there is a
5621// correct identity in the URL, but its use is being suppressed. The identity
5622// from the URL should never be used.
5623TEST_P(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
5624 HttpRequestInfo request;
5625 request.method = "GET";
bncce36dca22015-04-21 22:11:235626 request.url = GURL("http://foo:[email protected]/");
[email protected]2217aa22013-10-11 03:03:545627 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
5628
[email protected]3fe8d2f82013-10-17 08:56:075629 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2217aa22013-10-11 03:03:545630 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415631 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2217aa22013-10-11 03:03:545632
5633 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235634 MockWrite(
5635 "GET / HTTP/1.1\r\n"
5636 "Host: www.example.org\r\n"
5637 "Connection: keep-alive\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:545638 };
5639
5640 MockRead data_reads1[] = {
5641 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5642 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5643 MockRead("Content-Length: 10\r\n\r\n"),
5644 MockRead(SYNCHRONOUS, ERR_FAILED),
5645 };
5646
5647 // After the challenge above, the transaction will be restarted using the
5648 // identity supplied by the user, not the one in the URL, to answer the
5649 // challenge.
5650 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:235651 MockWrite(
5652 "GET / HTTP/1.1\r\n"
5653 "Host: www.example.org\r\n"
5654 "Connection: keep-alive\r\n"
5655 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:545656 };
5657
5658 MockRead data_reads3[] = {
5659 MockRead("HTTP/1.0 200 OK\r\n"),
5660 MockRead("Content-Length: 100\r\n\r\n"),
5661 MockRead(SYNCHRONOUS, OK),
5662 };
5663
5664 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5665 data_writes1, arraysize(data_writes1));
5666 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5667 data_writes3, arraysize(data_writes3));
5668 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5669 session_deps_.socket_factory->AddSocketDataProvider(&data3);
5670
5671 TestCompletionCallback callback1;
5672 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5673 EXPECT_EQ(ERR_IO_PENDING, rv);
5674 rv = callback1.WaitForResult();
5675 EXPECT_EQ(OK, rv);
5676 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5677
5678 const HttpResponseInfo* response = trans->GetResponseInfo();
5679 ASSERT_TRUE(response != NULL);
5680 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
5681
5682 TestCompletionCallback callback3;
5683 rv = trans->RestartWithAuth(
5684 AuthCredentials(kFoo, kBar), callback3.callback());
5685 EXPECT_EQ(ERR_IO_PENDING, rv);
5686 rv = callback3.WaitForResult();
5687 EXPECT_EQ(OK, rv);
5688 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5689
5690 response = trans->GetResponseInfo();
5691 ASSERT_TRUE(response != NULL);
5692
5693 // There is no challenge info, since the identity worked.
5694 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5695 EXPECT_EQ(100, response->headers->GetContentLength());
5696
5697 // Empty the current queue.
5698 base::MessageLoop::current()->RunUntilIdle();
5699}
5700
[email protected]f9ee6b52008-11-08 06:46:235701// Test that previously tried username/passwords for a realm get re-used.
[email protected]23e482282013-06-14 16:08:025702TEST_P(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
[email protected]bb88e1d32013-05-03 23:11:075703 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:235704
5705 // Transaction 1: authenticate (foo, bar) on MyRealm1
5706 {
[email protected]1c773ea12009-04-28 19:58:425707 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235708 request.method = "GET";
bncce36dca22015-04-21 22:11:235709 request.url = GURL("http://www.example.org/x/y/z");
[email protected]f9ee6b52008-11-08 06:46:235710 request.load_flags = 0;
5711
[email protected]262eec82013-03-19 21:01:365712 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505713 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275714
[email protected]f9ee6b52008-11-08 06:46:235715 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235716 MockWrite(
5717 "GET /x/y/z HTTP/1.1\r\n"
5718 "Host: www.example.org\r\n"
5719 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235720 };
5721
5722 MockRead data_reads1[] = {
5723 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5724 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5725 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065726 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235727 };
5728
5729 // Resend with authorization (username=foo, password=bar)
5730 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235731 MockWrite(
5732 "GET /x/y/z HTTP/1.1\r\n"
5733 "Host: www.example.org\r\n"
5734 "Connection: keep-alive\r\n"
5735 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235736 };
5737
5738 // Sever accepts the authorization.
5739 MockRead data_reads2[] = {
5740 MockRead("HTTP/1.0 200 OK\r\n"),
5741 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065742 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235743 };
5744
[email protected]31a2bfe2010-02-09 08:03:395745 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5746 data_writes1, arraysize(data_writes1));
5747 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5748 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075749 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5750 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235751
[email protected]49639fa2011-12-20 23:22:415752 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235753
[email protected]49639fa2011-12-20 23:22:415754 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425755 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235756
5757 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425758 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235759
[email protected]1c773ea12009-04-28 19:58:425760 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505761 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045762 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:235763
[email protected]49639fa2011-12-20 23:22:415764 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:235765
[email protected]49639fa2011-12-20 23:22:415766 rv = trans->RestartWithAuth(
5767 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425768 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235769
5770 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425771 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235772
5773 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505774 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235775 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5776 EXPECT_EQ(100, response->headers->GetContentLength());
5777 }
5778
5779 // ------------------------------------------------------------------------
5780
5781 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
5782 {
[email protected]1c773ea12009-04-28 19:58:425783 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235784 request.method = "GET";
5785 // Note that Transaction 1 was at /x/y/z, so this is in the same
5786 // protection space as MyRealm1.
bncce36dca22015-04-21 22:11:235787 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]f9ee6b52008-11-08 06:46:235788 request.load_flags = 0;
5789
[email protected]262eec82013-03-19 21:01:365790 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505791 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275792
[email protected]f9ee6b52008-11-08 06:46:235793 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235794 MockWrite(
5795 "GET /x/y/a/b HTTP/1.1\r\n"
5796 "Host: www.example.org\r\n"
5797 "Connection: keep-alive\r\n"
5798 // Send preemptive authorization for MyRealm1
5799 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235800 };
5801
5802 // The server didn't like the preemptive authorization, and
5803 // challenges us for a different realm (MyRealm2).
5804 MockRead data_reads1[] = {
5805 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5806 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
5807 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065808 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235809 };
5810
5811 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
5812 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235813 MockWrite(
5814 "GET /x/y/a/b HTTP/1.1\r\n"
5815 "Host: www.example.org\r\n"
5816 "Connection: keep-alive\r\n"
5817 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235818 };
5819
5820 // Sever accepts the authorization.
5821 MockRead data_reads2[] = {
5822 MockRead("HTTP/1.0 200 OK\r\n"),
5823 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065824 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235825 };
5826
[email protected]31a2bfe2010-02-09 08:03:395827 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5828 data_writes1, arraysize(data_writes1));
5829 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5830 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075831 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5832 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235833
[email protected]49639fa2011-12-20 23:22:415834 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235835
[email protected]49639fa2011-12-20 23:22:415836 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425837 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235838
5839 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425840 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235841
[email protected]1c773ea12009-04-28 19:58:425842 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505843 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045844 ASSERT_TRUE(response->auth_challenge.get());
5845 EXPECT_FALSE(response->auth_challenge->is_proxy);
bncce36dca22015-04-21 22:11:235846 EXPECT_EQ("www.example.org:80",
[email protected]79cb5c12011-09-12 13:12:045847 response->auth_challenge->challenger.ToString());
5848 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
5849 EXPECT_EQ("basic", response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:235850
[email protected]49639fa2011-12-20 23:22:415851 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:235852
[email protected]49639fa2011-12-20 23:22:415853 rv = trans->RestartWithAuth(
5854 AuthCredentials(kFoo2, kBar2), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425855 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235856
5857 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425858 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235859
5860 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505861 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235862 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5863 EXPECT_EQ(100, response->headers->GetContentLength());
5864 }
5865
5866 // ------------------------------------------------------------------------
5867
5868 // Transaction 3: Resend a request in MyRealm's protection space --
5869 // succeed with preemptive authorization.
5870 {
[email protected]1c773ea12009-04-28 19:58:425871 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235872 request.method = "GET";
bncce36dca22015-04-21 22:11:235873 request.url = GURL("http://www.example.org/x/y/z2");
[email protected]f9ee6b52008-11-08 06:46:235874 request.load_flags = 0;
5875
[email protected]262eec82013-03-19 21:01:365876 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505877 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275878
[email protected]f9ee6b52008-11-08 06:46:235879 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235880 MockWrite(
5881 "GET /x/y/z2 HTTP/1.1\r\n"
5882 "Host: www.example.org\r\n"
5883 "Connection: keep-alive\r\n"
5884 // The authorization for MyRealm1 gets sent preemptively
5885 // (since the url is in the same protection space)
5886 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235887 };
5888
5889 // Sever accepts the preemptive authorization
5890 MockRead data_reads1[] = {
5891 MockRead("HTTP/1.0 200 OK\r\n"),
5892 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065893 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235894 };
5895
[email protected]31a2bfe2010-02-09 08:03:395896 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5897 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075898 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:235899
[email protected]49639fa2011-12-20 23:22:415900 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235901
[email protected]49639fa2011-12-20 23:22:415902 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425903 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235904
5905 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425906 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235907
[email protected]1c773ea12009-04-28 19:58:425908 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505909 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235910
5911 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5912 EXPECT_EQ(100, response->headers->GetContentLength());
5913 }
5914
5915 // ------------------------------------------------------------------------
5916
5917 // Transaction 4: request another URL in MyRealm (however the
5918 // url is not known to belong to the protection space, so no pre-auth).
5919 {
[email protected]1c773ea12009-04-28 19:58:425920 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235921 request.method = "GET";
bncce36dca22015-04-21 22:11:235922 request.url = GURL("http://www.example.org/x/1");
[email protected]f9ee6b52008-11-08 06:46:235923 request.load_flags = 0;
5924
[email protected]262eec82013-03-19 21:01:365925 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505926 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275927
[email protected]f9ee6b52008-11-08 06:46:235928 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235929 MockWrite(
5930 "GET /x/1 HTTP/1.1\r\n"
5931 "Host: www.example.org\r\n"
5932 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235933 };
5934
5935 MockRead data_reads1[] = {
5936 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5937 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5938 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065939 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235940 };
5941
5942 // Resend with authorization from MyRealm's cache.
5943 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235944 MockWrite(
5945 "GET /x/1 HTTP/1.1\r\n"
5946 "Host: www.example.org\r\n"
5947 "Connection: keep-alive\r\n"
5948 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235949 };
5950
5951 // Sever accepts the authorization.
5952 MockRead data_reads2[] = {
5953 MockRead("HTTP/1.0 200 OK\r\n"),
5954 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065955 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235956 };
5957
[email protected]31a2bfe2010-02-09 08:03:395958 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5959 data_writes1, arraysize(data_writes1));
5960 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5961 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075962 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5963 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235964
[email protected]49639fa2011-12-20 23:22:415965 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235966
[email protected]49639fa2011-12-20 23:22:415967 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425968 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235969
5970 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425971 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235972
[email protected]0757e7702009-03-27 04:00:225973 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:415974 TestCompletionCallback callback2;
5975 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425976 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:225977 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425978 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225979 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5980
[email protected]1c773ea12009-04-28 19:58:425981 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505982 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235983 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5984 EXPECT_EQ(100, response->headers->GetContentLength());
5985 }
5986
5987 // ------------------------------------------------------------------------
5988
5989 // Transaction 5: request a URL in MyRealm, but the server rejects the
5990 // cached identity. Should invalidate and re-prompt.
5991 {
[email protected]1c773ea12009-04-28 19:58:425992 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235993 request.method = "GET";
bncce36dca22015-04-21 22:11:235994 request.url = GURL("http://www.example.org/p/q/t");
[email protected]f9ee6b52008-11-08 06:46:235995 request.load_flags = 0;
5996
[email protected]262eec82013-03-19 21:01:365997 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505998 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275999
[email protected]f9ee6b52008-11-08 06:46:236000 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236001 MockWrite(
6002 "GET /p/q/t HTTP/1.1\r\n"
6003 "Host: www.example.org\r\n"
6004 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236005 };
6006
6007 MockRead data_reads1[] = {
6008 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6009 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6010 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066011 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236012 };
6013
6014 // Resend with authorization from cache for MyRealm.
6015 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236016 MockWrite(
6017 "GET /p/q/t HTTP/1.1\r\n"
6018 "Host: www.example.org\r\n"
6019 "Connection: keep-alive\r\n"
6020 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236021 };
6022
6023 // Sever rejects the authorization.
6024 MockRead data_reads2[] = {
6025 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6026 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6027 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066028 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236029 };
6030
6031 // At this point we should prompt for new credentials for MyRealm.
6032 // Restart with username=foo3, password=foo4.
6033 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236034 MockWrite(
6035 "GET /p/q/t HTTP/1.1\r\n"
6036 "Host: www.example.org\r\n"
6037 "Connection: keep-alive\r\n"
6038 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236039 };
6040
6041 // Sever accepts the authorization.
6042 MockRead data_reads3[] = {
6043 MockRead("HTTP/1.0 200 OK\r\n"),
6044 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066045 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:236046 };
6047
[email protected]31a2bfe2010-02-09 08:03:396048 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6049 data_writes1, arraysize(data_writes1));
6050 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6051 data_writes2, arraysize(data_writes2));
6052 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6053 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076054 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6055 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6056 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:236057
[email protected]49639fa2011-12-20 23:22:416058 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:236059
[email protected]49639fa2011-12-20 23:22:416060 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426061 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236062
6063 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426064 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236065
[email protected]0757e7702009-03-27 04:00:226066 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:416067 TestCompletionCallback callback2;
6068 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:426069 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:226070 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426071 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:226072 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6073
[email protected]1c773ea12009-04-28 19:58:426074 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506075 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:046076 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:236077
[email protected]49639fa2011-12-20 23:22:416078 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:236079
[email protected]49639fa2011-12-20 23:22:416080 rv = trans->RestartWithAuth(
6081 AuthCredentials(kFoo3, kBar3), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:426082 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236083
[email protected]0757e7702009-03-27 04:00:226084 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426085 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236086
6087 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506088 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:236089 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6090 EXPECT_EQ(100, response->headers->GetContentLength());
6091 }
6092}
[email protected]89ceba9a2009-03-21 03:46:066093
[email protected]3c32c5f2010-05-18 15:18:126094// Tests that nonce count increments when multiple auth attempts
6095// are started with the same nonce.
[email protected]23e482282013-06-14 16:08:026096TEST_P(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:446097 HttpAuthHandlerDigest::Factory* digest_factory =
6098 new HttpAuthHandlerDigest::Factory();
6099 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
6100 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
6101 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:076102 session_deps_.http_auth_handler_factory.reset(digest_factory);
6103 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:126104
6105 // Transaction 1: authenticate (foo, bar) on MyRealm1
6106 {
[email protected]3c32c5f2010-05-18 15:18:126107 HttpRequestInfo request;
6108 request.method = "GET";
bncce36dca22015-04-21 22:11:236109 request.url = GURL("http://www.example.org/x/y/z");
[email protected]3c32c5f2010-05-18 15:18:126110 request.load_flags = 0;
6111
[email protected]262eec82013-03-19 21:01:366112 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506113 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276114
[email protected]3c32c5f2010-05-18 15:18:126115 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236116 MockWrite(
6117 "GET /x/y/z HTTP/1.1\r\n"
6118 "Host: www.example.org\r\n"
6119 "Connection: keep-alive\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:126120 };
6121
6122 MockRead data_reads1[] = {
6123 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6124 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
6125 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066126 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:126127 };
6128
6129 // Resend with authorization (username=foo, password=bar)
6130 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236131 MockWrite(
6132 "GET /x/y/z HTTP/1.1\r\n"
6133 "Host: www.example.org\r\n"
6134 "Connection: keep-alive\r\n"
6135 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
6136 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
6137 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
6138 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:126139 };
6140
6141 // Sever accepts the authorization.
6142 MockRead data_reads2[] = {
6143 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:066144 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:126145 };
6146
6147 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6148 data_writes1, arraysize(data_writes1));
6149 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6150 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076151 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6152 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:126153
[email protected]49639fa2011-12-20 23:22:416154 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:126155
[email protected]49639fa2011-12-20 23:22:416156 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:126157 EXPECT_EQ(ERR_IO_PENDING, rv);
6158
6159 rv = callback1.WaitForResult();
6160 EXPECT_EQ(OK, rv);
6161
6162 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506163 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:046164 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:126165
[email protected]49639fa2011-12-20 23:22:416166 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:126167
[email protected]49639fa2011-12-20 23:22:416168 rv = trans->RestartWithAuth(
6169 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]3c32c5f2010-05-18 15:18:126170 EXPECT_EQ(ERR_IO_PENDING, rv);
6171
6172 rv = callback2.WaitForResult();
6173 EXPECT_EQ(OK, rv);
6174
6175 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506176 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:126177 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6178 }
6179
6180 // ------------------------------------------------------------------------
6181
6182 // Transaction 2: Request another resource in digestive's protection space.
6183 // This will preemptively add an Authorization header which should have an
6184 // "nc" value of 2 (as compared to 1 in the first use.
6185 {
[email protected]3c32c5f2010-05-18 15:18:126186 HttpRequestInfo request;
6187 request.method = "GET";
6188 // Note that Transaction 1 was at /x/y/z, so this is in the same
6189 // protection space as digest.
bncce36dca22015-04-21 22:11:236190 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]3c32c5f2010-05-18 15:18:126191 request.load_flags = 0;
6192
[email protected]262eec82013-03-19 21:01:366193 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506194 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276195
[email protected]3c32c5f2010-05-18 15:18:126196 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236197 MockWrite(
6198 "GET /x/y/a/b HTTP/1.1\r\n"
6199 "Host: www.example.org\r\n"
6200 "Connection: keep-alive\r\n"
6201 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
6202 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
6203 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
6204 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:126205 };
6206
6207 // Sever accepts the authorization.
6208 MockRead data_reads1[] = {
6209 MockRead("HTTP/1.0 200 OK\r\n"),
6210 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066211 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:126212 };
6213
6214 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6215 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:076216 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:126217
[email protected]49639fa2011-12-20 23:22:416218 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:126219
[email protected]49639fa2011-12-20 23:22:416220 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:126221 EXPECT_EQ(ERR_IO_PENDING, rv);
6222
6223 rv = callback1.WaitForResult();
6224 EXPECT_EQ(OK, rv);
6225
6226 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506227 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:126228 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6229 }
6230}
6231
[email protected]89ceba9a2009-03-21 03:46:066232// Test the ResetStateForRestart() private method.
[email protected]23e482282013-06-14 16:08:026233TEST_P(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:066234 // Create a transaction (the dependencies aren't important).
[email protected]3fe8d2f82013-10-17 08:56:076235 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:406236 scoped_ptr<HttpNetworkTransaction> trans(
dcheng48459ac22014-08-26 00:46:416237 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]89ceba9a2009-03-21 03:46:066238
6239 // Setup some state (which we expect ResetStateForRestart() will clear).
[email protected]89ceba9a2009-03-21 03:46:066240 trans->read_buf_ = new IOBuffer(15);
6241 trans->read_buf_len_ = 15;
[email protected]b94f92d2010-10-27 16:45:206242 trans->request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:066243
6244 // Setup state in response_
[email protected]a7e41312009-12-16 23:18:146245 HttpResponseInfo* response = &trans->response_;
[email protected]0877e3d2009-10-17 22:29:576246 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:086247 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:576248 response->response_time = base::Time::Now();
6249 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:066250
6251 { // Setup state for response_.vary_data
6252 HttpRequestInfo request;
6253 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
6254 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:276255 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:436256 request.extra_headers.SetHeader("Foo", "1");
6257 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:506258 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:066259 }
6260
6261 // Cause the above state to be reset.
6262 trans->ResetStateForRestart();
6263
6264 // Verify that the state that needed to be reset, has been reset.
[email protected]9b6fee12009-09-29 18:13:076265 EXPECT_TRUE(trans->read_buf_.get() == NULL);
[email protected]89ceba9a2009-03-21 03:46:066266 EXPECT_EQ(0, trans->read_buf_len_);
[email protected]b94f92d2010-10-27 16:45:206267 EXPECT_TRUE(trans->request_headers_.IsEmpty());
[email protected]0877e3d2009-10-17 22:29:576268 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6269 EXPECT_TRUE(response->headers.get() == NULL);
[email protected]34f40942010-10-04 00:34:046270 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:086271 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:576272 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:066273}
6274
[email protected]bacff652009-03-31 17:50:336275// Test HTTPS connections to a site with a bad certificate
[email protected]23e482282013-06-14 16:08:026276TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:336277 HttpRequestInfo request;
6278 request.method = "GET";
bncce36dca22015-04-21 22:11:236279 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:336280 request.load_flags = 0;
6281
[email protected]3fe8d2f82013-10-17 08:56:076282 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276283 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416284 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276285
[email protected]bacff652009-03-31 17:50:336286 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236287 MockWrite(
6288 "GET / HTTP/1.1\r\n"
6289 "Host: www.example.org\r\n"
6290 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:336291 };
6292
6293 MockRead data_reads[] = {
6294 MockRead("HTTP/1.0 200 OK\r\n"),
6295 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6296 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066297 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:336298 };
6299
[email protected]5ecc992a42009-11-11 01:41:596300 StaticSocketDataProvider ssl_bad_certificate;
[email protected]31a2bfe2010-02-09 08:03:396301 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6302 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066303 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
6304 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:336305
[email protected]bb88e1d32013-05-03 23:11:076306 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
6307 session_deps_.socket_factory->AddSocketDataProvider(&data);
6308 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
6309 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:336310
[email protected]49639fa2011-12-20 23:22:416311 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:336312
[email protected]49639fa2011-12-20 23:22:416313 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:336314 EXPECT_EQ(ERR_IO_PENDING, rv);
6315
6316 rv = callback.WaitForResult();
6317 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
6318
[email protected]49639fa2011-12-20 23:22:416319 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:336320 EXPECT_EQ(ERR_IO_PENDING, rv);
6321
6322 rv = callback.WaitForResult();
6323 EXPECT_EQ(OK, rv);
6324
6325 const HttpResponseInfo* response = trans->GetResponseInfo();
6326
[email protected]fe2255a2011-09-20 19:37:506327 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:336328 EXPECT_EQ(100, response->headers->GetContentLength());
6329}
6330
6331// Test HTTPS connections to a site with a bad certificate, going through a
6332// proxy
[email protected]23e482282013-06-14 16:08:026333TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
[email protected]bb88e1d32013-05-03 23:11:076334 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]bacff652009-03-31 17:50:336335
6336 HttpRequestInfo request;
6337 request.method = "GET";
bncce36dca22015-04-21 22:11:236338 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:336339 request.load_flags = 0;
6340
6341 MockWrite proxy_writes[] = {
bncce36dca22015-04-21 22:11:236342 MockWrite(
6343 "CONNECT www.example.org:443 HTTP/1.1\r\n"
6344 "Host: www.example.org\r\n"
6345 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:336346 };
6347
6348 MockRead proxy_reads[] = {
6349 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066350 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:336351 };
6352
6353 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236354 MockWrite(
6355 "CONNECT www.example.org:443 HTTP/1.1\r\n"
6356 "Host: www.example.org\r\n"
6357 "Proxy-Connection: keep-alive\r\n\r\n"),
6358 MockWrite(
6359 "GET / HTTP/1.1\r\n"
6360 "Host: www.example.org\r\n"
6361 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:336362 };
6363
6364 MockRead data_reads[] = {
6365 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
6366 MockRead("HTTP/1.0 200 OK\r\n"),
6367 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6368 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066369 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:336370 };
6371
[email protected]31a2bfe2010-02-09 08:03:396372 StaticSocketDataProvider ssl_bad_certificate(
6373 proxy_reads, arraysize(proxy_reads),
6374 proxy_writes, arraysize(proxy_writes));
6375 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6376 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066377 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
6378 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:336379
[email protected]bb88e1d32013-05-03 23:11:076380 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
6381 session_deps_.socket_factory->AddSocketDataProvider(&data);
6382 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
6383 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:336384
[email protected]49639fa2011-12-20 23:22:416385 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:336386
6387 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:076388 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:336389
[email protected]3fe8d2f82013-10-17 08:56:076390 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:406391 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416392 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bacff652009-03-31 17:50:336393
[email protected]49639fa2011-12-20 23:22:416394 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:336395 EXPECT_EQ(ERR_IO_PENDING, rv);
6396
6397 rv = callback.WaitForResult();
6398 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
6399
[email protected]49639fa2011-12-20 23:22:416400 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:336401 EXPECT_EQ(ERR_IO_PENDING, rv);
6402
6403 rv = callback.WaitForResult();
6404 EXPECT_EQ(OK, rv);
6405
6406 const HttpResponseInfo* response = trans->GetResponseInfo();
6407
[email protected]fe2255a2011-09-20 19:37:506408 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:336409 EXPECT_EQ(100, response->headers->GetContentLength());
6410 }
6411}
6412
[email protected]2df19bb2010-08-25 20:13:466413
6414// Test HTTPS connections to a site, going through an HTTPS proxy
[email protected]23e482282013-06-14 16:08:026415TEST_P(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076416 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206417 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
vishal.b62985ca92015-04-17 08:45:516418 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076419 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:466420
6421 HttpRequestInfo request;
6422 request.method = "GET";
bncce36dca22015-04-21 22:11:236423 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:466424 request.load_flags = 0;
6425
6426 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236427 MockWrite(
6428 "CONNECT www.example.org:443 HTTP/1.1\r\n"
6429 "Host: www.example.org\r\n"
6430 "Proxy-Connection: keep-alive\r\n\r\n"),
6431 MockWrite(
6432 "GET / HTTP/1.1\r\n"
6433 "Host: www.example.org\r\n"
6434 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:466435 };
6436
6437 MockRead data_reads[] = {
6438 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
6439 MockRead("HTTP/1.1 200 OK\r\n"),
6440 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6441 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066442 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:466443 };
6444
6445 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6446 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066447 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
6448 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:466449
[email protected]bb88e1d32013-05-03 23:11:076450 session_deps_.socket_factory->AddSocketDataProvider(&data);
6451 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
6452 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:466453
[email protected]49639fa2011-12-20 23:22:416454 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:466455
[email protected]3fe8d2f82013-10-17 08:56:076456 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:466457 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416458 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2df19bb2010-08-25 20:13:466459
[email protected]49639fa2011-12-20 23:22:416460 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:466461 EXPECT_EQ(ERR_IO_PENDING, rv);
6462
6463 rv = callback.WaitForResult();
6464 EXPECT_EQ(OK, rv);
6465 const HttpResponseInfo* response = trans->GetResponseInfo();
6466
[email protected]fe2255a2011-09-20 19:37:506467 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:466468
6469 EXPECT_TRUE(response->headers->IsKeepAlive());
6470 EXPECT_EQ(200, response->headers->response_code());
6471 EXPECT_EQ(100, response->headers->GetContentLength());
6472 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:206473
6474 LoadTimingInfo load_timing_info;
6475 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6476 TestLoadTimingNotReusedWithPac(load_timing_info,
6477 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:466478}
6479
[email protected]511f6f52010-12-17 03:58:296480// Test an HTTPS Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:026481TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076482 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206483 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
vishal.b62985ca92015-04-17 08:45:516484 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076485 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:296486
6487 HttpRequestInfo request;
6488 request.method = "GET";
bncce36dca22015-04-21 22:11:236489 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:296490 request.load_flags = 0;
6491
6492 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236493 MockWrite(
6494 "CONNECT www.example.org:443 HTTP/1.1\r\n"
6495 "Host: www.example.org\r\n"
6496 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:296497 };
6498
6499 MockRead data_reads[] = {
6500 MockRead("HTTP/1.1 302 Redirect\r\n"),
6501 MockRead("Location: http://login.example.com/\r\n"),
6502 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066503 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:296504 };
6505
6506 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6507 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066508 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:296509
[email protected]bb88e1d32013-05-03 23:11:076510 session_deps_.socket_factory->AddSocketDataProvider(&data);
6511 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296512
[email protected]49639fa2011-12-20 23:22:416513 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296514
[email protected]3fe8d2f82013-10-17 08:56:076515 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296516 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416517 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:296518
[email protected]49639fa2011-12-20 23:22:416519 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296520 EXPECT_EQ(ERR_IO_PENDING, rv);
6521
6522 rv = callback.WaitForResult();
6523 EXPECT_EQ(OK, rv);
6524 const HttpResponseInfo* response = trans->GetResponseInfo();
6525
[email protected]fe2255a2011-09-20 19:37:506526 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:296527
6528 EXPECT_EQ(302, response->headers->response_code());
6529 std::string url;
6530 EXPECT_TRUE(response->headers->IsRedirect(&url));
6531 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:206532
6533 // In the case of redirects from proxies, HttpNetworkTransaction returns
6534 // timing for the proxy connection instead of the connection to the host,
6535 // and no send / receive times.
6536 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
6537 LoadTimingInfo load_timing_info;
6538 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6539
6540 EXPECT_FALSE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:296541 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:206542
6543 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
6544 EXPECT_LE(load_timing_info.proxy_resolve_start,
6545 load_timing_info.proxy_resolve_end);
6546 EXPECT_LE(load_timing_info.proxy_resolve_end,
6547 load_timing_info.connect_timing.connect_start);
6548 ExpectConnectTimingHasTimes(
6549 load_timing_info.connect_timing,
6550 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
6551
6552 EXPECT_TRUE(load_timing_info.send_start.is_null());
6553 EXPECT_TRUE(load_timing_info.send_end.is_null());
6554 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:296555}
6556
6557// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:026558TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
[email protected]bb88e1d32013-05-03 23:11:076559 session_deps_.proxy_service.reset(
[email protected]511f6f52010-12-17 03:58:296560 ProxyService::CreateFixed("https://proxy:70"));
6561
6562 HttpRequestInfo request;
6563 request.method = "GET";
bncce36dca22015-04-21 22:11:236564 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:296565 request.load_flags = 0;
6566
lgarrona91df87f2014-12-05 00:51:346567 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:236568 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]c10b20852013-05-15 21:29:206569 scoped_ptr<SpdyFrame> goaway(
6570 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:296571 MockWrite data_writes[] = {
rch8e6c6c42015-05-01 14:05:136572 CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
6573 CreateMockWrite(*goaway.get(), 2, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:296574 };
6575
6576 static const char* const kExtraHeaders[] = {
6577 "location",
6578 "http://login.example.com/",
6579 };
[email protected]ff98d7f02012-03-22 21:44:196580 scoped_ptr<SpdyFrame> resp(
[email protected]23e482282013-06-14 16:08:026581 spdy_util_.ConstructSpdySynReplyError("302 Redirect", kExtraHeaders,
[email protected]511f6f52010-12-17 03:58:296582 arraysize(kExtraHeaders)/2, 1));
6583 MockRead data_reads[] = {
rch8e6c6c42015-05-01 14:05:136584 CreateMockRead(*resp.get(), 1), MockRead(ASYNC, 0, 3), // EOF
[email protected]511f6f52010-12-17 03:58:296585 };
6586
rch8e6c6c42015-05-01 14:05:136587 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
6588 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066589 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]23e482282013-06-14 16:08:026590 proxy_ssl.SetNextProto(GetParam());
[email protected]511f6f52010-12-17 03:58:296591
[email protected]bb88e1d32013-05-03 23:11:076592 session_deps_.socket_factory->AddSocketDataProvider(&data);
6593 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296594
[email protected]49639fa2011-12-20 23:22:416595 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296596
[email protected]3fe8d2f82013-10-17 08:56:076597 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296598 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416599 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:296600
[email protected]49639fa2011-12-20 23:22:416601 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296602 EXPECT_EQ(ERR_IO_PENDING, rv);
6603
6604 rv = callback.WaitForResult();
6605 EXPECT_EQ(OK, rv);
6606 const HttpResponseInfo* response = trans->GetResponseInfo();
6607
[email protected]fe2255a2011-09-20 19:37:506608 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:296609
6610 EXPECT_EQ(302, response->headers->response_code());
6611 std::string url;
6612 EXPECT_TRUE(response->headers->IsRedirect(&url));
6613 EXPECT_EQ("http://login.example.com/", url);
6614}
6615
[email protected]4eddbc732012-08-09 05:40:176616// Test that an HTTPS proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:026617TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:176618 ErrorResponseToHttpsConnectViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076619 session_deps_.proxy_service.reset(
[email protected]511f6f52010-12-17 03:58:296620 ProxyService::CreateFixed("https://proxy:70"));
6621
6622 HttpRequestInfo request;
6623 request.method = "GET";
bncce36dca22015-04-21 22:11:236624 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:296625 request.load_flags = 0;
6626
6627 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236628 MockWrite(
6629 "CONNECT www.example.org:443 HTTP/1.1\r\n"
6630 "Host: www.example.org\r\n"
6631 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:296632 };
6633
6634 MockRead data_reads[] = {
6635 MockRead("HTTP/1.1 404 Not Found\r\n"),
6636 MockRead("Content-Length: 23\r\n\r\n"),
6637 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:066638 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:296639 };
6640
6641 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6642 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066643 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:296644
[email protected]bb88e1d32013-05-03 23:11:076645 session_deps_.socket_factory->AddSocketDataProvider(&data);
6646 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296647
[email protected]49639fa2011-12-20 23:22:416648 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296649
[email protected]3fe8d2f82013-10-17 08:56:076650 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296651 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416652 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:296653
[email protected]49639fa2011-12-20 23:22:416654 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296655 EXPECT_EQ(ERR_IO_PENDING, rv);
6656
6657 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:176658 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:296659
[email protected]4eddbc732012-08-09 05:40:176660 // TODO(ttuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:296661}
6662
[email protected]4eddbc732012-08-09 05:40:176663// Test that a SPDY proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:026664TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:176665 ErrorResponseToHttpsConnectViaSpdyProxy) {
[email protected]bb88e1d32013-05-03 23:11:076666 session_deps_.proxy_service.reset(
6667 ProxyService::CreateFixed("https://proxy:70"));
[email protected]511f6f52010-12-17 03:58:296668
6669 HttpRequestInfo request;
6670 request.method = "GET";
bncce36dca22015-04-21 22:11:236671 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:296672 request.load_flags = 0;
6673
lgarrona91df87f2014-12-05 00:51:346674 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:236675 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]c10b20852013-05-15 21:29:206676 scoped_ptr<SpdyFrame> rst(
6677 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:296678 MockWrite data_writes[] = {
rch8e6c6c42015-05-01 14:05:136679 CreateMockWrite(*conn.get(), 0), CreateMockWrite(*rst.get(), 3),
[email protected]511f6f52010-12-17 03:58:296680 };
6681
6682 static const char* const kExtraHeaders[] = {
6683 "location",
6684 "http://login.example.com/",
6685 };
[email protected]ff98d7f02012-03-22 21:44:196686 scoped_ptr<SpdyFrame> resp(
[email protected]23e482282013-06-14 16:08:026687 spdy_util_.ConstructSpdySynReplyError("404 Not Found", kExtraHeaders,
[email protected]511f6f52010-12-17 03:58:296688 arraysize(kExtraHeaders)/2, 1));
[email protected]ff98d7f02012-03-22 21:44:196689 scoped_ptr<SpdyFrame> body(
[email protected]23e482282013-06-14 16:08:026690 spdy_util_.ConstructSpdyBodyFrame(
6691 1, "The host does not exist", 23, true));
[email protected]511f6f52010-12-17 03:58:296692 MockRead data_reads[] = {
rch8e6c6c42015-05-01 14:05:136693 CreateMockRead(*resp.get(), 1),
6694 CreateMockRead(*body.get(), 2),
6695 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:296696 };
6697
rch8e6c6c42015-05-01 14:05:136698 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
6699 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066700 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]23e482282013-06-14 16:08:026701 proxy_ssl.SetNextProto(GetParam());
[email protected]511f6f52010-12-17 03:58:296702
[email protected]bb88e1d32013-05-03 23:11:076703 session_deps_.socket_factory->AddSocketDataProvider(&data);
6704 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296705
[email protected]49639fa2011-12-20 23:22:416706 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296707
[email protected]3fe8d2f82013-10-17 08:56:076708 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296709 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416710 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:296711
[email protected]49639fa2011-12-20 23:22:416712 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296713 EXPECT_EQ(ERR_IO_PENDING, rv);
6714
6715 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:176716 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:296717
[email protected]4eddbc732012-08-09 05:40:176718 // TODO(ttuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:296719}
6720
[email protected]0c5fb722012-02-28 11:50:356721// Test the request-challenge-retry sequence for basic auth, through
6722// a SPDY proxy over a single SPDY session.
[email protected]23e482282013-06-14 16:08:026723TEST_P(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:356724 HttpRequestInfo request;
6725 request.method = "GET";
bncce36dca22015-04-21 22:11:236726 request.url = GURL("https://www.example.org/");
[email protected]0c5fb722012-02-28 11:50:356727 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:296728 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]0c5fb722012-02-28 11:50:356729
6730 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076731 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206732 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
vishal.b62985ca92015-04-17 08:45:516733 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076734 session_deps_.net_log = log.bound().net_log();
6735 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:356736
6737 // Since we have proxy, should try to establish tunnel.
lgarrona91df87f2014-12-05 00:51:346738 scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:236739 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]c10b20852013-05-15 21:29:206740 scoped_ptr<SpdyFrame> rst(
6741 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]0c5fb722012-02-28 11:50:356742
6743 // After calling trans->RestartWithAuth(), this is the request we should
6744 // be issuing -- the final header line contains the credentials.
6745 const char* const kAuthCredentials[] = {
6746 "proxy-authorization", "Basic Zm9vOmJhcg==",
6747 };
[email protected]fba2dbde2013-05-24 16:09:016748 scoped_ptr<SpdyFrame> connect2(spdy_util_.ConstructSpdyConnect(
lgarrona91df87f2014-12-05 00:51:346749 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST,
bncce36dca22015-04-21 22:11:236750 HostPortPair("www.example.org", 443)));
6751 // fetch https://www.example.org/ via HTTP
6752 const char get[] =
6753 "GET / HTTP/1.1\r\n"
6754 "Host: www.example.org\r\n"
6755 "Connection: keep-alive\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:196756 scoped_ptr<SpdyFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:026757 spdy_util_.ConstructSpdyBodyFrame(3, get, strlen(get), false));
[email protected]0c5fb722012-02-28 11:50:356758
6759 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:136760 CreateMockWrite(*req, 0, ASYNC),
6761 CreateMockWrite(*rst, 2, ASYNC),
6762 CreateMockWrite(*connect2, 3),
6763 CreateMockWrite(*wrapped_get, 5),
[email protected]0c5fb722012-02-28 11:50:356764 };
6765
6766 // The proxy responds to the connect with a 407, using a persistent
6767 // connection.
thestig9d3bb0c2015-01-24 00:49:516768 const char kAuthStatus[] = "407";
[email protected]0c5fb722012-02-28 11:50:356769 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:356770 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
6771 };
[email protected]745aa9c2014-06-27 02:21:296772 scoped_ptr<SpdyFrame> conn_auth_resp(spdy_util_.ConstructSpdySynReplyError(
6773 kAuthStatus, kAuthChallenge, arraysize(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:356774
[email protected]23e482282013-06-14 16:08:026775 scoped_ptr<SpdyFrame> conn_resp(
6776 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:356777 const char resp[] = "HTTP/1.1 200 OK\r\n"
6778 "Content-Length: 5\r\n\r\n";
6779
[email protected]ff98d7f02012-03-22 21:44:196780 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:026781 spdy_util_.ConstructSpdyBodyFrame(3, resp, strlen(resp), false));
[email protected]ff98d7f02012-03-22 21:44:196782 scoped_ptr<SpdyFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:026783 spdy_util_.ConstructSpdyBodyFrame(3, "hello", 5, false));
[email protected]0c5fb722012-02-28 11:50:356784 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:136785 CreateMockRead(*conn_auth_resp, 1, ASYNC),
6786 CreateMockRead(*conn_resp, 4, ASYNC),
6787 CreateMockRead(*wrapped_get_resp, 6, ASYNC),
6788 CreateMockRead(*wrapped_body, 7, ASYNC),
6789 MockRead(ASYNC, OK, 8), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:356790 };
6791
rch8e6c6c42015-05-01 14:05:136792 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
6793 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:076794 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:356795 // Negotiate SPDY to the proxy
6796 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:026797 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:076798 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:356799 // Vanilla SSL to the server
6800 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076801 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:356802
6803 TestCompletionCallback callback1;
6804
[email protected]262eec82013-03-19 21:01:366805 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506806 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0c5fb722012-02-28 11:50:356807
6808 int rv = trans->Start(&request, callback1.callback(), log.bound());
6809 EXPECT_EQ(ERR_IO_PENDING, rv);
6810
6811 rv = callback1.WaitForResult();
6812 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:466813 TestNetLogEntry::List entries;
[email protected]0c5fb722012-02-28 11:50:356814 log.GetEntries(&entries);
6815 size_t pos = ExpectLogContainsSomewhere(
6816 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
6817 NetLog::PHASE_NONE);
6818 ExpectLogContainsSomewhere(
6819 entries, pos,
6820 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
6821 NetLog::PHASE_NONE);
6822
6823 const HttpResponseInfo* response = trans->GetResponseInfo();
6824 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:506825 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]0c5fb722012-02-28 11:50:356826 EXPECT_EQ(407, response->headers->response_code());
6827 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6828 EXPECT_TRUE(response->auth_challenge.get() != NULL);
6829 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
6830
6831 TestCompletionCallback callback2;
6832
6833 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
6834 callback2.callback());
6835 EXPECT_EQ(ERR_IO_PENDING, rv);
6836
6837 rv = callback2.WaitForResult();
6838 EXPECT_EQ(OK, rv);
6839
6840 response = trans->GetResponseInfo();
6841 ASSERT_TRUE(response != NULL);
6842
6843 EXPECT_TRUE(response->headers->IsKeepAlive());
6844 EXPECT_EQ(200, response->headers->response_code());
6845 EXPECT_EQ(5, response->headers->GetContentLength());
6846 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6847
6848 // The password prompt info should not be set.
6849 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6850
[email protected]029c83b62013-01-24 05:28:206851 LoadTimingInfo load_timing_info;
6852 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6853 TestLoadTimingNotReusedWithPac(load_timing_info,
6854 CONNECT_TIMING_HAS_SSL_TIMES);
6855
[email protected]0c5fb722012-02-28 11:50:356856 trans.reset();
6857 session->CloseAllConnections();
6858}
6859
[email protected]7c6f7ba2012-04-03 04:09:296860// Test that an explicitly trusted SPDY proxy can push a resource from an
6861// origin that is different from that of its associated resource.
[email protected]23e482282013-06-14 16:08:026862TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPush) {
[email protected]7c6f7ba2012-04-03 04:09:296863 HttpRequestInfo request;
6864 HttpRequestInfo push_request;
6865
[email protected]7c6f7ba2012-04-03 04:09:296866 request.method = "GET";
bncce36dca22015-04-21 22:11:236867 request.url = GURL("http://www.example.org/");
[email protected]7c6f7ba2012-04-03 04:09:296868 push_request.method = "GET";
6869 push_request.url = GURL("http://www.another-origin.com/foo.dat");
6870
[email protected]7c6f7ba2012-04-03 04:09:296871 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076872 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206873 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
vishal.b62985ca92015-04-17 08:45:516874 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076875 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:506876
6877 // Enable cross-origin push.
[email protected]bb88e1d32013-05-03 23:11:076878 session_deps_.trusted_spdy_proxy = "myproxy:70";
[email protected]61b4efc2012-04-27 18:12:506879
[email protected]bb88e1d32013-05-03 23:11:076880 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:296881
[email protected]cdf8f7e72013-05-23 10:56:466882 scoped_ptr<SpdyFrame> stream1_syn(
6883 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]7c6f7ba2012-04-03 04:09:296884
6885 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:136886 CreateMockWrite(*stream1_syn, 0, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:296887 };
6888
6889 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026890 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:296891
6892 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026893 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:296894
6895 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026896 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
[email protected]7c6f7ba2012-04-03 04:09:296897 0,
6898 2,
6899 1,
6900 "http://www.another-origin.com/foo.dat"));
[email protected]8a0fc822013-06-27 20:52:436901 const char kPushedData[] = "pushed";
6902 scoped_ptr<SpdyFrame> stream2_body(
6903 spdy_util_.ConstructSpdyBodyFrame(
6904 2, kPushedData, strlen(kPushedData), true));
[email protected]7c6f7ba2012-04-03 04:09:296905
6906 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:136907 CreateMockRead(*stream1_reply, 1, ASYNC),
6908 CreateMockRead(*stream2_syn, 2, ASYNC),
6909 CreateMockRead(*stream1_body, 3, ASYNC),
6910 CreateMockRead(*stream2_body, 4, ASYNC),
6911 MockRead(ASYNC, ERR_IO_PENDING, 5), // Force a pause
[email protected]7c6f7ba2012-04-03 04:09:296912 };
6913
rch8e6c6c42015-05-01 14:05:136914 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
6915 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:076916 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:296917 // Negotiate SPDY to the proxy
6918 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:026919 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:076920 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:296921
[email protected]262eec82013-03-19 21:01:366922 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506923 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7c6f7ba2012-04-03 04:09:296924 TestCompletionCallback callback;
6925 int rv = trans->Start(&request, callback.callback(), log.bound());
6926 EXPECT_EQ(ERR_IO_PENDING, rv);
6927
6928 rv = callback.WaitForResult();
6929 EXPECT_EQ(OK, rv);
6930 const HttpResponseInfo* response = trans->GetResponseInfo();
6931
[email protected]262eec82013-03-19 21:01:366932 scoped_ptr<HttpTransaction> push_trans(
[email protected]90499482013-06-01 00:39:506933 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
6934 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
[email protected]7c6f7ba2012-04-03 04:09:296935 EXPECT_EQ(ERR_IO_PENDING, rv);
6936
6937 rv = callback.WaitForResult();
6938 EXPECT_EQ(OK, rv);
6939 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
6940
6941 ASSERT_TRUE(response != NULL);
6942 EXPECT_TRUE(response->headers->IsKeepAlive());
6943
6944 EXPECT_EQ(200, response->headers->response_code());
6945 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6946
6947 std::string response_data;
6948 rv = ReadTransaction(trans.get(), &response_data);
6949 EXPECT_EQ(OK, rv);
6950 EXPECT_EQ("hello!", response_data);
6951
[email protected]029c83b62013-01-24 05:28:206952 LoadTimingInfo load_timing_info;
6953 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6954 TestLoadTimingNotReusedWithPac(load_timing_info,
6955 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6956
[email protected]7c6f7ba2012-04-03 04:09:296957 // Verify the pushed stream.
[email protected]90499482013-06-01 00:39:506958 EXPECT_TRUE(push_response->headers.get() != NULL);
[email protected]7c6f7ba2012-04-03 04:09:296959 EXPECT_EQ(200, push_response->headers->response_code());
6960
6961 rv = ReadTransaction(push_trans.get(), &response_data);
6962 EXPECT_EQ(OK, rv);
6963 EXPECT_EQ("pushed", response_data);
6964
[email protected]029c83b62013-01-24 05:28:206965 LoadTimingInfo push_load_timing_info;
6966 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
6967 TestLoadTimingReusedWithPac(push_load_timing_info);
6968 // The transactions should share a socket ID, despite being for different
6969 // origins.
6970 EXPECT_EQ(load_timing_info.socket_log_id,
6971 push_load_timing_info.socket_log_id);
6972
[email protected]7c6f7ba2012-04-03 04:09:296973 trans.reset();
6974 push_trans.reset();
6975 session->CloseAllConnections();
6976}
6977
[email protected]8c843192012-04-05 07:15:006978// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
[email protected]23e482282013-06-14 16:08:026979TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
[email protected]8c843192012-04-05 07:15:006980 HttpRequestInfo request;
6981
6982 request.method = "GET";
bncce36dca22015-04-21 22:11:236983 request.url = GURL("http://www.example.org/");
[email protected]8c843192012-04-05 07:15:006984
[email protected]8c843192012-04-05 07:15:006985 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076986 session_deps_.proxy_service.reset(
[email protected]8c843192012-04-05 07:15:006987 ProxyService::CreateFixed("https://myproxy:70"));
vishal.b62985ca92015-04-17 08:45:516988 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076989 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:506990
6991 // Enable cross-origin push.
[email protected]bb88e1d32013-05-03 23:11:076992 session_deps_.trusted_spdy_proxy = "myproxy:70";
[email protected]61b4efc2012-04-27 18:12:506993
[email protected]bb88e1d32013-05-03 23:11:076994 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:006995
[email protected]cdf8f7e72013-05-23 10:56:466996 scoped_ptr<SpdyFrame> stream1_syn(
6997 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]8c843192012-04-05 07:15:006998
6999 scoped_ptr<SpdyFrame> push_rst(
[email protected]c10b20852013-05-15 21:29:207000 spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:007001
7002 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:137003 CreateMockWrite(*stream1_syn, 0, ASYNC), CreateMockWrite(*push_rst, 3),
[email protected]8c843192012-04-05 07:15:007004 };
7005
7006 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:027007 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:007008
7009 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:027010 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8c843192012-04-05 07:15:007011
7012 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:027013 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
[email protected]8c843192012-04-05 07:15:007014 0,
7015 2,
7016 1,
7017 "https://www.another-origin.com/foo.dat"));
7018
7019 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:137020 CreateMockRead(*stream1_reply, 1, ASYNC),
7021 CreateMockRead(*stream2_syn, 2, ASYNC),
7022 CreateMockRead(*stream1_body, 4, ASYNC),
7023 MockRead(ASYNC, ERR_IO_PENDING, 5), // Force a pause
[email protected]8c843192012-04-05 07:15:007024 };
7025
rch8e6c6c42015-05-01 14:05:137026 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
7027 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:077028 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:007029 // Negotiate SPDY to the proxy
7030 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:027031 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:077032 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:007033
[email protected]262eec82013-03-19 21:01:367034 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507035 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c843192012-04-05 07:15:007036 TestCompletionCallback callback;
7037 int rv = trans->Start(&request, callback.callback(), log.bound());
7038 EXPECT_EQ(ERR_IO_PENDING, rv);
7039
7040 rv = callback.WaitForResult();
7041 EXPECT_EQ(OK, rv);
7042 const HttpResponseInfo* response = trans->GetResponseInfo();
7043
7044 ASSERT_TRUE(response != NULL);
7045 EXPECT_TRUE(response->headers->IsKeepAlive());
7046
7047 EXPECT_EQ(200, response->headers->response_code());
7048 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
7049
7050 std::string response_data;
7051 rv = ReadTransaction(trans.get(), &response_data);
7052 EXPECT_EQ(OK, rv);
7053 EXPECT_EQ("hello!", response_data);
7054
7055 trans.reset();
7056 session->CloseAllConnections();
7057}
7058
[email protected]2df19bb2010-08-25 20:13:467059// Test HTTPS connections to a site with a bad certificate, going through an
7060// HTTPS proxy
[email protected]23e482282013-06-14 16:08:027061TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:077062 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:117063 "https://proxy:70"));
[email protected]2df19bb2010-08-25 20:13:467064
7065 HttpRequestInfo request;
7066 request.method = "GET";
bncce36dca22015-04-21 22:11:237067 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:467068 request.load_flags = 0;
7069
7070 // Attempt to fetch the URL from a server with a bad cert
7071 MockWrite bad_cert_writes[] = {
bncce36dca22015-04-21 22:11:237072 MockWrite(
7073 "CONNECT www.example.org:443 HTTP/1.1\r\n"
7074 "Host: www.example.org\r\n"
7075 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:467076 };
7077
7078 MockRead bad_cert_reads[] = {
7079 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067080 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:467081 };
7082
7083 // Attempt to fetch the URL with a good cert
7084 MockWrite good_data_writes[] = {
bncce36dca22015-04-21 22:11:237085 MockWrite(
7086 "CONNECT www.example.org:443 HTTP/1.1\r\n"
7087 "Host: www.example.org\r\n"
7088 "Proxy-Connection: keep-alive\r\n\r\n"),
7089 MockWrite(
7090 "GET / HTTP/1.1\r\n"
7091 "Host: www.example.org\r\n"
7092 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:467093 };
7094
7095 MockRead good_cert_reads[] = {
7096 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
7097 MockRead("HTTP/1.0 200 OK\r\n"),
7098 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7099 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067100 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:467101 };
7102
7103 StaticSocketDataProvider ssl_bad_certificate(
7104 bad_cert_reads, arraysize(bad_cert_reads),
7105 bad_cert_writes, arraysize(bad_cert_writes));
7106 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
7107 good_data_writes, arraysize(good_data_writes));
[email protected]8ddf8322012-02-23 18:08:067108 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
7109 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:467110
7111 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:077112 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7113 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
7114 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:467115
7116 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:077117 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7118 session_deps_.socket_factory->AddSocketDataProvider(&data);
7119 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:467120
[email protected]49639fa2011-12-20 23:22:417121 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:467122
[email protected]3fe8d2f82013-10-17 08:56:077123 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:467124 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417125 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2df19bb2010-08-25 20:13:467126
[email protected]49639fa2011-12-20 23:22:417127 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:467128 EXPECT_EQ(ERR_IO_PENDING, rv);
7129
7130 rv = callback.WaitForResult();
7131 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
7132
[email protected]49639fa2011-12-20 23:22:417133 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]2df19bb2010-08-25 20:13:467134 EXPECT_EQ(ERR_IO_PENDING, rv);
7135
7136 rv = callback.WaitForResult();
7137 EXPECT_EQ(OK, rv);
7138
7139 const HttpResponseInfo* response = trans->GetResponseInfo();
7140
[email protected]fe2255a2011-09-20 19:37:507141 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:467142 EXPECT_EQ(100, response->headers->GetContentLength());
7143}
7144
[email protected]23e482282013-06-14 16:08:027145TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:427146 HttpRequestInfo request;
7147 request.method = "GET";
bncce36dca22015-04-21 22:11:237148 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:437149 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
7150 "Chromium Ultra Awesome X Edition");
[email protected]1c773ea12009-04-28 19:58:427151
[email protected]3fe8d2f82013-10-17 08:56:077152 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277153 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417154 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277155
[email protected]1c773ea12009-04-28 19:58:427156 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237157 MockWrite(
7158 "GET / HTTP/1.1\r\n"
7159 "Host: www.example.org\r\n"
7160 "Connection: keep-alive\r\n"
7161 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427162 };
7163
7164 // Lastly, the server responds with the actual content.
7165 MockRead data_reads[] = {
7166 MockRead("HTTP/1.0 200 OK\r\n"),
7167 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7168 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067169 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427170 };
7171
[email protected]31a2bfe2010-02-09 08:03:397172 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7173 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077174 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427175
[email protected]49639fa2011-12-20 23:22:417176 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427177
[email protected]49639fa2011-12-20 23:22:417178 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427179 EXPECT_EQ(ERR_IO_PENDING, rv);
7180
7181 rv = callback.WaitForResult();
7182 EXPECT_EQ(OK, rv);
7183}
7184
[email protected]23e482282013-06-14 16:08:027185TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:297186 HttpRequestInfo request;
7187 request.method = "GET";
bncce36dca22015-04-21 22:11:237188 request.url = GURL("https://www.example.org/");
[email protected]da81f132010-08-18 23:39:297189 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
7190 "Chromium Ultra Awesome X Edition");
7191
[email protected]bb88e1d32013-05-03 23:11:077192 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]3fe8d2f82013-10-17 08:56:077193 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277194 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417195 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277196
[email protected]da81f132010-08-18 23:39:297197 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237198 MockWrite(
7199 "CONNECT www.example.org:443 HTTP/1.1\r\n"
7200 "Host: www.example.org\r\n"
7201 "Proxy-Connection: keep-alive\r\n"
7202 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]da81f132010-08-18 23:39:297203 };
7204 MockRead data_reads[] = {
7205 // Return an error, so the transaction stops here (this test isn't
7206 // interested in the rest).
7207 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
7208 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7209 MockRead("Proxy-Connection: close\r\n\r\n"),
7210 };
7211
7212 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7213 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077214 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:297215
[email protected]49639fa2011-12-20 23:22:417216 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:297217
[email protected]49639fa2011-12-20 23:22:417218 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]da81f132010-08-18 23:39:297219 EXPECT_EQ(ERR_IO_PENDING, rv);
7220
7221 rv = callback.WaitForResult();
7222 EXPECT_EQ(OK, rv);
7223}
7224
[email protected]23e482282013-06-14 16:08:027225TEST_P(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:427226 HttpRequestInfo request;
7227 request.method = "GET";
bncce36dca22015-04-21 22:11:237228 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427229 request.load_flags = 0;
[email protected]c10450102011-06-27 09:06:167230 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
7231 "http://the.previous.site.com/");
[email protected]1c773ea12009-04-28 19:58:427232
[email protected]3fe8d2f82013-10-17 08:56:077233 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277234 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417235 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277236
[email protected]1c773ea12009-04-28 19:58:427237 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237238 MockWrite(
7239 "GET / HTTP/1.1\r\n"
7240 "Host: www.example.org\r\n"
7241 "Connection: keep-alive\r\n"
7242 "Referer: http://the.previous.site.com/\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427243 };
7244
7245 // Lastly, the server responds with the actual content.
7246 MockRead data_reads[] = {
7247 MockRead("HTTP/1.0 200 OK\r\n"),
7248 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7249 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067250 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427251 };
7252
[email protected]31a2bfe2010-02-09 08:03:397253 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7254 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077255 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427256
[email protected]49639fa2011-12-20 23:22:417257 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427258
[email protected]49639fa2011-12-20 23:22:417259 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427260 EXPECT_EQ(ERR_IO_PENDING, rv);
7261
7262 rv = callback.WaitForResult();
7263 EXPECT_EQ(OK, rv);
7264}
7265
[email protected]23e482282013-06-14 16:08:027266TEST_P(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:427267 HttpRequestInfo request;
7268 request.method = "POST";
bncce36dca22015-04-21 22:11:237269 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427270
[email protected]3fe8d2f82013-10-17 08:56:077271 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277272 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417273 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277274
[email protected]1c773ea12009-04-28 19:58:427275 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237276 MockWrite(
7277 "POST / HTTP/1.1\r\n"
7278 "Host: www.example.org\r\n"
7279 "Connection: keep-alive\r\n"
7280 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427281 };
7282
7283 // Lastly, the server responds with the actual content.
7284 MockRead data_reads[] = {
7285 MockRead("HTTP/1.0 200 OK\r\n"),
7286 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7287 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067288 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427289 };
7290
[email protected]31a2bfe2010-02-09 08:03:397291 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7292 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077293 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427294
[email protected]49639fa2011-12-20 23:22:417295 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427296
[email protected]49639fa2011-12-20 23:22:417297 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427298 EXPECT_EQ(ERR_IO_PENDING, rv);
7299
7300 rv = callback.WaitForResult();
7301 EXPECT_EQ(OK, rv);
7302}
7303
[email protected]23e482282013-06-14 16:08:027304TEST_P(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:427305 HttpRequestInfo request;
7306 request.method = "PUT";
bncce36dca22015-04-21 22:11:237307 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427308
[email protected]3fe8d2f82013-10-17 08:56:077309 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277310 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417311 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277312
[email protected]1c773ea12009-04-28 19:58:427313 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237314 MockWrite(
7315 "PUT / HTTP/1.1\r\n"
7316 "Host: www.example.org\r\n"
7317 "Connection: keep-alive\r\n"
7318 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427319 };
7320
7321 // Lastly, the server responds with the actual content.
7322 MockRead data_reads[] = {
7323 MockRead("HTTP/1.0 200 OK\r\n"),
7324 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7325 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067326 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427327 };
7328
[email protected]31a2bfe2010-02-09 08:03:397329 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7330 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077331 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427332
[email protected]49639fa2011-12-20 23:22:417333 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427334
[email protected]49639fa2011-12-20 23:22:417335 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427336 EXPECT_EQ(ERR_IO_PENDING, rv);
7337
7338 rv = callback.WaitForResult();
7339 EXPECT_EQ(OK, rv);
7340}
7341
[email protected]23e482282013-06-14 16:08:027342TEST_P(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:427343 HttpRequestInfo request;
7344 request.method = "HEAD";
bncce36dca22015-04-21 22:11:237345 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427346
[email protected]3fe8d2f82013-10-17 08:56:077347 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277348 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417349 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277350
[email protected]1c773ea12009-04-28 19:58:427351 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237352 MockWrite(
7353 "HEAD / HTTP/1.1\r\n"
7354 "Host: www.example.org\r\n"
7355 "Connection: keep-alive\r\n"
7356 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427357 };
7358
7359 // Lastly, the server responds with the actual content.
7360 MockRead data_reads[] = {
7361 MockRead("HTTP/1.0 200 OK\r\n"),
7362 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7363 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067364 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427365 };
7366
[email protected]31a2bfe2010-02-09 08:03:397367 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7368 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077369 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427370
[email protected]49639fa2011-12-20 23:22:417371 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427372
[email protected]49639fa2011-12-20 23:22:417373 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427374 EXPECT_EQ(ERR_IO_PENDING, rv);
7375
7376 rv = callback.WaitForResult();
7377 EXPECT_EQ(OK, rv);
7378}
7379
[email protected]23e482282013-06-14 16:08:027380TEST_P(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:427381 HttpRequestInfo request;
7382 request.method = "GET";
bncce36dca22015-04-21 22:11:237383 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427384 request.load_flags = LOAD_BYPASS_CACHE;
7385
[email protected]3fe8d2f82013-10-17 08:56:077386 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277387 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417388 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277389
[email protected]1c773ea12009-04-28 19:58:427390 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237391 MockWrite(
7392 "GET / HTTP/1.1\r\n"
7393 "Host: www.example.org\r\n"
7394 "Connection: keep-alive\r\n"
7395 "Pragma: no-cache\r\n"
7396 "Cache-Control: no-cache\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427397 };
7398
7399 // Lastly, the server responds with the actual content.
7400 MockRead data_reads[] = {
7401 MockRead("HTTP/1.0 200 OK\r\n"),
7402 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7403 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067404 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427405 };
7406
[email protected]31a2bfe2010-02-09 08:03:397407 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7408 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077409 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427410
[email protected]49639fa2011-12-20 23:22:417411 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427412
[email protected]49639fa2011-12-20 23:22:417413 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427414 EXPECT_EQ(ERR_IO_PENDING, rv);
7415
7416 rv = callback.WaitForResult();
7417 EXPECT_EQ(OK, rv);
7418}
7419
[email protected]23e482282013-06-14 16:08:027420TEST_P(HttpNetworkTransactionTest,
[email protected]1c773ea12009-04-28 19:58:427421 BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:427422 HttpRequestInfo request;
7423 request.method = "GET";
bncce36dca22015-04-21 22:11:237424 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427425 request.load_flags = LOAD_VALIDATE_CACHE;
7426
[email protected]3fe8d2f82013-10-17 08:56:077427 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277428 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417429 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277430
[email protected]1c773ea12009-04-28 19:58:427431 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237432 MockWrite(
7433 "GET / HTTP/1.1\r\n"
7434 "Host: www.example.org\r\n"
7435 "Connection: keep-alive\r\n"
7436 "Cache-Control: max-age=0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427437 };
7438
7439 // Lastly, the server responds with the actual content.
7440 MockRead data_reads[] = {
7441 MockRead("HTTP/1.0 200 OK\r\n"),
7442 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7443 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067444 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427445 };
7446
[email protected]31a2bfe2010-02-09 08:03:397447 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7448 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077449 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427450
[email protected]49639fa2011-12-20 23:22:417451 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427452
[email protected]49639fa2011-12-20 23:22:417453 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427454 EXPECT_EQ(ERR_IO_PENDING, rv);
7455
7456 rv = callback.WaitForResult();
7457 EXPECT_EQ(OK, rv);
7458}
7459
[email protected]23e482282013-06-14 16:08:027460TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:427461 HttpRequestInfo request;
7462 request.method = "GET";
bncce36dca22015-04-21 22:11:237463 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:437464 request.extra_headers.SetHeader("FooHeader", "Bar");
[email protected]1c773ea12009-04-28 19:58:427465
[email protected]3fe8d2f82013-10-17 08:56:077466 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277467 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417468 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277469
[email protected]1c773ea12009-04-28 19:58:427470 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237471 MockWrite(
7472 "GET / HTTP/1.1\r\n"
7473 "Host: www.example.org\r\n"
7474 "Connection: keep-alive\r\n"
7475 "FooHeader: Bar\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427476 };
7477
7478 // Lastly, the server responds with the actual content.
7479 MockRead data_reads[] = {
7480 MockRead("HTTP/1.0 200 OK\r\n"),
7481 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7482 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067483 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427484 };
7485
[email protected]31a2bfe2010-02-09 08:03:397486 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7487 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077488 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427489
[email protected]49639fa2011-12-20 23:22:417490 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427491
[email protected]49639fa2011-12-20 23:22:417492 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427493 EXPECT_EQ(ERR_IO_PENDING, rv);
7494
7495 rv = callback.WaitForResult();
7496 EXPECT_EQ(OK, rv);
7497}
7498
[email protected]23e482282013-06-14 16:08:027499TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:477500 HttpRequestInfo request;
7501 request.method = "GET";
bncce36dca22015-04-21 22:11:237502 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:437503 request.extra_headers.SetHeader("referer", "www.foo.com");
7504 request.extra_headers.SetHeader("hEllo", "Kitty");
7505 request.extra_headers.SetHeader("FoO", "bar");
[email protected]270c6412010-03-29 22:02:477506
[email protected]3fe8d2f82013-10-17 08:56:077507 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277508 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417509 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277510
[email protected]270c6412010-03-29 22:02:477511 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237512 MockWrite(
7513 "GET / HTTP/1.1\r\n"
7514 "Host: www.example.org\r\n"
7515 "Connection: keep-alive\r\n"
7516 "referer: www.foo.com\r\n"
7517 "hEllo: Kitty\r\n"
7518 "FoO: bar\r\n\r\n"),
[email protected]270c6412010-03-29 22:02:477519 };
7520
7521 // Lastly, the server responds with the actual content.
7522 MockRead data_reads[] = {
7523 MockRead("HTTP/1.0 200 OK\r\n"),
7524 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7525 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067526 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:477527 };
7528
7529 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7530 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077531 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:477532
[email protected]49639fa2011-12-20 23:22:417533 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:477534
[email protected]49639fa2011-12-20 23:22:417535 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]270c6412010-03-29 22:02:477536 EXPECT_EQ(ERR_IO_PENDING, rv);
7537
7538 rv = callback.WaitForResult();
7539 EXPECT_EQ(OK, rv);
7540}
7541
[email protected]23e482282013-06-14 16:08:027542TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277543 HttpRequestInfo request;
7544 request.method = "GET";
bncce36dca22015-04-21 22:11:237545 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:277546 request.load_flags = 0;
7547
[email protected]bb88e1d32013-05-03 23:11:077548 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207549 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
vishal.b62985ca92015-04-17 08:45:517550 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077551 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:027552
[email protected]3fe8d2f82013-10-17 08:56:077553 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3cd17242009-06-23 02:59:027554 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417555 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3cd17242009-06-23 02:59:027556
[email protected]3cd17242009-06-23 02:59:027557 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
7558 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7559
7560 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237561 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
7562 MockWrite(
7563 "GET / HTTP/1.1\r\n"
7564 "Host: www.example.org\r\n"
7565 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:027566
7567 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:067568 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:027569 MockRead("HTTP/1.0 200 OK\r\n"),
7570 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7571 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067572 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:027573 };
7574
[email protected]31a2bfe2010-02-09 08:03:397575 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7576 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077577 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:027578
[email protected]49639fa2011-12-20 23:22:417579 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:027580
[email protected]49639fa2011-12-20 23:22:417581 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:027582 EXPECT_EQ(ERR_IO_PENDING, rv);
7583
7584 rv = callback.WaitForResult();
7585 EXPECT_EQ(OK, rv);
7586
7587 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507588 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:027589
[email protected]029c83b62013-01-24 05:28:207590 LoadTimingInfo load_timing_info;
7591 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7592 TestLoadTimingNotReusedWithPac(load_timing_info,
7593 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7594
[email protected]3cd17242009-06-23 02:59:027595 std::string response_text;
7596 rv = ReadTransaction(trans.get(), &response_text);
7597 EXPECT_EQ(OK, rv);
7598 EXPECT_EQ("Payload", response_text);
7599}
7600
[email protected]23e482282013-06-14 16:08:027601TEST_P(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277602 HttpRequestInfo request;
7603 request.method = "GET";
bncce36dca22015-04-21 22:11:237604 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:277605 request.load_flags = 0;
7606
[email protected]bb88e1d32013-05-03 23:11:077607 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207608 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
vishal.b62985ca92015-04-17 08:45:517609 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077610 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:027611
[email protected]3fe8d2f82013-10-17 08:56:077612 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3cd17242009-06-23 02:59:027613 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417614 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3cd17242009-06-23 02:59:027615
[email protected]3cd17242009-06-23 02:59:027616 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
7617 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7618
7619 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237620 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
7621 arraysize(write_buffer)),
7622 MockWrite(
7623 "GET / HTTP/1.1\r\n"
7624 "Host: www.example.org\r\n"
7625 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:027626
7627 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:017628 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
7629 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:357630 MockRead("HTTP/1.0 200 OK\r\n"),
7631 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7632 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067633 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:357634 };
7635
[email protected]31a2bfe2010-02-09 08:03:397636 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7637 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077638 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:357639
[email protected]8ddf8322012-02-23 18:08:067640 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077641 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:357642
[email protected]49639fa2011-12-20 23:22:417643 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:357644
[email protected]49639fa2011-12-20 23:22:417645 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:357646 EXPECT_EQ(ERR_IO_PENDING, rv);
7647
7648 rv = callback.WaitForResult();
7649 EXPECT_EQ(OK, rv);
7650
[email protected]029c83b62013-01-24 05:28:207651 LoadTimingInfo load_timing_info;
7652 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7653 TestLoadTimingNotReusedWithPac(load_timing_info,
7654 CONNECT_TIMING_HAS_SSL_TIMES);
7655
[email protected]e0c27be2009-07-15 13:09:357656 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507657 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:357658
7659 std::string response_text;
7660 rv = ReadTransaction(trans.get(), &response_text);
7661 EXPECT_EQ(OK, rv);
7662 EXPECT_EQ("Payload", response_text);
7663}
7664
[email protected]23e482282013-06-14 16:08:027665TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:207666 HttpRequestInfo request;
7667 request.method = "GET";
bncce36dca22015-04-21 22:11:237668 request.url = GURL("http://www.example.org/");
[email protected]029c83b62013-01-24 05:28:207669 request.load_flags = 0;
7670
[email protected]bb88e1d32013-05-03 23:11:077671 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207672 ProxyService::CreateFixed("socks4://myproxy:1080"));
vishal.b62985ca92015-04-17 08:45:517673 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077674 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:207675
[email protected]3fe8d2f82013-10-17 08:56:077676 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:207677 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417678 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:207679
7680 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
7681 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7682
7683 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237684 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
7685 MockWrite(
7686 "GET / HTTP/1.1\r\n"
7687 "Host: www.example.org\r\n"
7688 "Connection: keep-alive\r\n\r\n")};
[email protected]029c83b62013-01-24 05:28:207689
7690 MockRead data_reads[] = {
7691 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
7692 MockRead("HTTP/1.0 200 OK\r\n"),
7693 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7694 MockRead("Payload"),
7695 MockRead(SYNCHRONOUS, OK)
7696 };
7697
7698 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7699 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077700 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:207701
7702 TestCompletionCallback callback;
7703
7704 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7705 EXPECT_EQ(ERR_IO_PENDING, rv);
7706
7707 rv = callback.WaitForResult();
7708 EXPECT_EQ(OK, rv);
7709
7710 const HttpResponseInfo* response = trans->GetResponseInfo();
7711 ASSERT_TRUE(response != NULL);
7712
7713 LoadTimingInfo load_timing_info;
7714 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7715 TestLoadTimingNotReused(load_timing_info,
7716 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7717
7718 std::string response_text;
7719 rv = ReadTransaction(trans.get(), &response_text);
7720 EXPECT_EQ(OK, rv);
7721 EXPECT_EQ("Payload", response_text);
7722}
7723
[email protected]23e482282013-06-14 16:08:027724TEST_P(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277725 HttpRequestInfo request;
7726 request.method = "GET";
bncce36dca22015-04-21 22:11:237727 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:277728 request.load_flags = 0;
7729
[email protected]bb88e1d32013-05-03 23:11:077730 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207731 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
vishal.b62985ca92015-04-17 08:45:517732 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077733 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:357734
[email protected]3fe8d2f82013-10-17 08:56:077735 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e0c27be2009-07-15 13:09:357736 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417737 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]e0c27be2009-07-15 13:09:357738
[email protected]e0c27be2009-07-15 13:09:357739 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
7740 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:377741 const char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:237742 0x05, // Version
7743 0x01, // Command (CONNECT)
7744 0x00, // Reserved.
7745 0x03, // Address type (DOMAINNAME).
7746 0x0F, // Length of domain (15)
7747 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
7748 '.', 'o', 'r', 'g', 0x00, 0x50, // 16-bit port (80)
[email protected]f209dba2009-12-18 00:24:377749 };
[email protected]e0c27be2009-07-15 13:09:357750 const char kSOCKS5OkResponse[] =
7751 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
7752
7753 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237754 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
7755 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
7756 MockWrite(
7757 "GET / HTTP/1.1\r\n"
7758 "Host: www.example.org\r\n"
7759 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:357760
7761 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:017762 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
7763 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:357764 MockRead("HTTP/1.0 200 OK\r\n"),
7765 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7766 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067767 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:357768 };
7769
[email protected]31a2bfe2010-02-09 08:03:397770 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7771 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077772 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:357773
[email protected]49639fa2011-12-20 23:22:417774 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:357775
[email protected]49639fa2011-12-20 23:22:417776 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:357777 EXPECT_EQ(ERR_IO_PENDING, rv);
7778
7779 rv = callback.WaitForResult();
7780 EXPECT_EQ(OK, rv);
7781
7782 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507783 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:357784
[email protected]029c83b62013-01-24 05:28:207785 LoadTimingInfo load_timing_info;
7786 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7787 TestLoadTimingNotReusedWithPac(load_timing_info,
7788 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7789
[email protected]e0c27be2009-07-15 13:09:357790 std::string response_text;
7791 rv = ReadTransaction(trans.get(), &response_text);
7792 EXPECT_EQ(OK, rv);
7793 EXPECT_EQ("Payload", response_text);
7794}
7795
[email protected]23e482282013-06-14 16:08:027796TEST_P(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277797 HttpRequestInfo request;
7798 request.method = "GET";
bncce36dca22015-04-21 22:11:237799 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:277800 request.load_flags = 0;
7801
[email protected]bb88e1d32013-05-03 23:11:077802 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207803 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
vishal.b62985ca92015-04-17 08:45:517804 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077805 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:357806
[email protected]3fe8d2f82013-10-17 08:56:077807 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e0c27be2009-07-15 13:09:357808 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417809 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]e0c27be2009-07-15 13:09:357810
[email protected]e0c27be2009-07-15 13:09:357811 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
7812 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:377813 const unsigned char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:237814 0x05, // Version
7815 0x01, // Command (CONNECT)
7816 0x00, // Reserved.
7817 0x03, // Address type (DOMAINNAME).
7818 0x0F, // Length of domain (15)
7819 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
7820 '.', 'o', 'r', 'g', 0x01, 0xBB, // 16-bit port (443)
[email protected]f209dba2009-12-18 00:24:377821 };
7822
[email protected]e0c27be2009-07-15 13:09:357823 const char kSOCKS5OkResponse[] =
7824 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
7825
7826 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237827 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
7828 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
7829 arraysize(kSOCKS5OkRequest)),
7830 MockWrite(
7831 "GET / HTTP/1.1\r\n"
7832 "Host: www.example.org\r\n"
7833 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:357834
7835 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:017836 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
7837 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:027838 MockRead("HTTP/1.0 200 OK\r\n"),
7839 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7840 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067841 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:027842 };
7843
[email protected]31a2bfe2010-02-09 08:03:397844 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7845 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077846 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:027847
[email protected]8ddf8322012-02-23 18:08:067848 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077849 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:027850
[email protected]49639fa2011-12-20 23:22:417851 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:027852
[email protected]49639fa2011-12-20 23:22:417853 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:027854 EXPECT_EQ(ERR_IO_PENDING, rv);
7855
7856 rv = callback.WaitForResult();
7857 EXPECT_EQ(OK, rv);
7858
7859 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507860 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:027861
[email protected]029c83b62013-01-24 05:28:207862 LoadTimingInfo load_timing_info;
7863 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7864 TestLoadTimingNotReusedWithPac(load_timing_info,
7865 CONNECT_TIMING_HAS_SSL_TIMES);
7866
[email protected]3cd17242009-06-23 02:59:027867 std::string response_text;
7868 rv = ReadTransaction(trans.get(), &response_text);
7869 EXPECT_EQ(OK, rv);
7870 EXPECT_EQ("Payload", response_text);
7871}
7872
[email protected]448d4ca52012-03-04 04:12:237873namespace {
7874
[email protected]04e5be32009-06-26 20:00:317875// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:067876
7877struct GroupNameTest {
7878 std::string proxy_server;
7879 std::string url;
7880 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:187881 bool ssl;
[email protected]2d731a32010-04-29 01:04:067882};
7883
7884scoped_refptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]8a0fc822013-06-27 20:52:437885 NextProto next_proto,
[email protected]bb88e1d32013-05-03 23:11:077886 SpdySessionDependencies* session_deps_) {
7887 scoped_refptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:067888
[email protected]30d4c022013-07-18 22:58:167889 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:537890 session->http_server_properties();
bnccacc0992015-03-20 20:22:227891 AlternativeService alternative_service(
bnc4988e432015-03-31 03:06:257892 AlternateProtocolFromNextProto(next_proto), "", 443);
bnccacc0992015-03-20 20:22:227893 http_server_properties->SetAlternativeService(
7894 HostPortPair("host.with.alternate", 80), alternative_service, 1.0);
[email protected]2d731a32010-04-29 01:04:067895
7896 return session;
7897}
7898
7899int GroupNameTransactionHelper(
7900 const std::string& url,
7901 const scoped_refptr<HttpNetworkSession>& session) {
[email protected]2d731a32010-04-29 01:04:067902 HttpRequestInfo request;
7903 request.method = "GET";
7904 request.url = GURL(url);
7905 request.load_flags = 0;
7906
[email protected]262eec82013-03-19 21:01:367907 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507908 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277909
[email protected]49639fa2011-12-20 23:22:417910 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:067911
7912 // We do not complete this request, the dtor will clean the transaction up.
[email protected]49639fa2011-12-20 23:22:417913 return trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d731a32010-04-29 01:04:067914}
7915
[email protected]448d4ca52012-03-04 04:12:237916} // namespace
7917
[email protected]23e482282013-06-14 16:08:027918TEST_P(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:067919 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:237920 {
7921 "", // unused
7922 "http://www.example.org/direct",
7923 "www.example.org:80",
7924 false,
7925 },
7926 {
7927 "", // unused
7928 "http://[2001:1418:13:1::25]/direct",
7929 "[2001:1418:13:1::25]:80",
7930 false,
7931 },
[email protected]04e5be32009-06-26 20:00:317932
bncce36dca22015-04-21 22:11:237933 // SSL Tests
7934 {
7935 "", // unused
7936 "https://www.example.org/direct_ssl",
7937 "ssl/www.example.org:443",
7938 true,
7939 },
7940 {
7941 "", // unused
7942 "https://[2001:1418:13:1::25]/direct",
7943 "ssl/[2001:1418:13:1::25]:443",
7944 true,
7945 },
7946 {
7947 "", // unused
7948 "http://host.with.alternate/direct",
7949 "ssl/host.with.alternate:443",
7950 true,
7951 },
[email protected]2d731a32010-04-29 01:04:067952 };
[email protected]2ff8b312010-04-26 22:20:547953
[email protected]d7599122014-05-24 03:37:237954 session_deps_.use_alternate_protocols = true;
[email protected]2d731a32010-04-29 01:04:067955
viettrungluue4a8b882014-10-16 06:17:387956 for (size_t i = 0; i < arraysize(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:077957 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:027958 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:067959 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:437960 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:067961
7962 HttpNetworkSessionPeer peer(session);
[email protected]ab739042011-04-07 15:22:287963 CaptureGroupNameTransportSocketPool* transport_conn_pool =
7964 new CaptureGroupNameTransportSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:137965 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347966 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]831e4a32013-11-14 02:14:447967 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
7968 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:027969 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
7970 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
dchenge3d1ddc2014-10-15 19:30:517971 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]2d731a32010-04-29 01:04:067972
7973 EXPECT_EQ(ERR_IO_PENDING,
7974 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:187975 if (tests[i].ssl)
7976 EXPECT_EQ(tests[i].expected_group_name,
7977 ssl_conn_pool->last_group_name_received());
7978 else
7979 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:287980 transport_conn_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:067981 }
7982
[email protected]2d731a32010-04-29 01:04:067983}
7984
[email protected]23e482282013-06-14 16:08:027985TEST_P(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:067986 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:237987 {
7988 "http_proxy",
7989 "http://www.example.org/http_proxy_normal",
7990 "www.example.org:80",
7991 false,
7992 },
[email protected]2d731a32010-04-29 01:04:067993
bncce36dca22015-04-21 22:11:237994 // SSL Tests
7995 {
7996 "http_proxy",
7997 "https://www.example.org/http_connect_ssl",
7998 "ssl/www.example.org:443",
7999 true,
8000 },
[email protected]af3490e2010-10-16 21:02:298001
bncce36dca22015-04-21 22:11:238002 {
8003 "http_proxy",
8004 "http://host.with.alternate/direct",
8005 "ssl/host.with.alternate:443",
8006 true,
8007 },
[email protected]45499252013-01-23 17:12:568008
bncce36dca22015-04-21 22:11:238009 {
8010 "http_proxy",
8011 "ftp://ftp.google.com/http_proxy_normal",
8012 "ftp/ftp.google.com:21",
8013 false,
8014 },
[email protected]2d731a32010-04-29 01:04:068015 };
8016
[email protected]d7599122014-05-24 03:37:238017 session_deps_.use_alternate_protocols = true;
[email protected]2d731a32010-04-29 01:04:068018
viettrungluue4a8b882014-10-16 06:17:388019 for (size_t i = 0; i < arraysize(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:078020 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:028021 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:068022 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:438023 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:068024
8025 HttpNetworkSessionPeer peer(session);
8026
[email protected]e60e47a2010-07-14 03:37:188027 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:138028 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:348029 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:138030 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:348031 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:028032
[email protected]831e4a32013-11-14 02:14:448033 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
8034 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:028035 mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool);
8036 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
dchenge3d1ddc2014-10-15 19:30:518037 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]2d731a32010-04-29 01:04:068038
8039 EXPECT_EQ(ERR_IO_PENDING,
8040 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:188041 if (tests[i].ssl)
8042 EXPECT_EQ(tests[i].expected_group_name,
8043 ssl_conn_pool->last_group_name_received());
8044 else
8045 EXPECT_EQ(tests[i].expected_group_name,
8046 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:068047 }
[email protected]2d731a32010-04-29 01:04:068048}
8049
[email protected]23e482282013-06-14 16:08:028050TEST_P(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:068051 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:238052 {
8053 "socks4://socks_proxy:1080",
8054 "http://www.example.org/socks4_direct",
8055 "socks4/www.example.org:80",
8056 false,
8057 },
8058 {
8059 "socks5://socks_proxy:1080",
8060 "http://www.example.org/socks5_direct",
8061 "socks5/www.example.org:80",
8062 false,
8063 },
[email protected]2d731a32010-04-29 01:04:068064
bncce36dca22015-04-21 22:11:238065 // SSL Tests
8066 {
8067 "socks4://socks_proxy:1080",
8068 "https://www.example.org/socks4_ssl",
8069 "socks4/ssl/www.example.org:443",
8070 true,
8071 },
8072 {
8073 "socks5://socks_proxy:1080",
8074 "https://www.example.org/socks5_ssl",
8075 "socks5/ssl/www.example.org:443",
8076 true,
8077 },
[email protected]af3490e2010-10-16 21:02:298078
bncce36dca22015-04-21 22:11:238079 {
8080 "socks4://socks_proxy:1080",
8081 "http://host.with.alternate/direct",
8082 "socks4/ssl/host.with.alternate:443",
8083 true,
8084 },
[email protected]04e5be32009-06-26 20:00:318085 };
8086
[email protected]d7599122014-05-24 03:37:238087 session_deps_.use_alternate_protocols = true;
[email protected]2ff8b312010-04-26 22:20:548088
viettrungluue4a8b882014-10-16 06:17:388089 for (size_t i = 0; i < arraysize(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:078090 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:028091 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:068092 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:438093 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]8b114dd72011-03-25 05:33:028094
[email protected]2d731a32010-04-29 01:04:068095 HttpNetworkSessionPeer peer(session);
[email protected]04e5be32009-06-26 20:00:318096
[email protected]e60e47a2010-07-14 03:37:188097 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:138098 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:348099 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:138100 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:348101 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:028102
[email protected]831e4a32013-11-14 02:14:448103 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
8104 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:028105 mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_conn_pool);
8106 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
dchenge3d1ddc2014-10-15 19:30:518107 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]04e5be32009-06-26 20:00:318108
[email protected]262eec82013-03-19 21:01:368109 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508110 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]04e5be32009-06-26 20:00:318111
[email protected]2d731a32010-04-29 01:04:068112 EXPECT_EQ(ERR_IO_PENDING,
8113 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:188114 if (tests[i].ssl)
8115 EXPECT_EQ(tests[i].expected_group_name,
8116 ssl_conn_pool->last_group_name_received());
8117 else
8118 EXPECT_EQ(tests[i].expected_group_name,
8119 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:318120 }
8121}
8122
[email protected]23e482282013-06-14 16:08:028123TEST_P(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:278124 HttpRequestInfo request;
8125 request.method = "GET";
bncce36dca22015-04-21 22:11:238126 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278127
[email protected]bb88e1d32013-05-03 23:11:078128 session_deps_.proxy_service.reset(
[email protected]81cdfcd2010-10-16 00:49:008129 ProxyService::CreateFixed("myproxy:70;foobar:80"));
[email protected]b59ff372009-07-15 22:04:328130
[email protected]69719062010-01-05 20:09:218131 // This simulates failure resolving all hostnames; that means we will fail
8132 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:078133 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:328134
[email protected]3fe8d2f82013-10-17 08:56:078135 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]9172a982009-06-06 00:30:258136 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418137 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]9172a982009-06-06 00:30:258138
[email protected]49639fa2011-12-20 23:22:418139 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:258140
[email protected]49639fa2011-12-20 23:22:418141 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9172a982009-06-06 00:30:258142 EXPECT_EQ(ERR_IO_PENDING, rv);
8143
[email protected]9172a982009-06-06 00:30:258144 rv = callback.WaitForResult();
[email protected]f7fccee2010-09-16 20:53:018145 EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
[email protected]9172a982009-06-06 00:30:258146}
8147
[email protected]685af592010-05-11 19:31:248148// Base test to make sure that when the load flags for a request specify to
8149// bypass the cache, the DNS cache is not used.
[email protected]23e482282013-06-14 16:08:028150void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
[email protected]bb88e1d32013-05-03 23:11:078151 int load_flags) {
[email protected]cb9bf6ca2011-01-28 13:15:278152 // Issue a request, asking to bypass the cache(s).
8153 HttpRequestInfo request;
8154 request.method = "GET";
8155 request.load_flags = load_flags;
bncce36dca22015-04-21 22:11:238156 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278157
[email protected]a2c2fb92009-07-18 07:31:048158 // Select a host resolver that does caching.
[email protected]bb88e1d32013-05-03 23:11:078159 session_deps_.host_resolver.reset(new MockCachingHostResolver);
[email protected]b59ff372009-07-15 22:04:328160
[email protected]3fe8d2f82013-10-17 08:56:078161 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8162 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418163 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3b9cca42009-06-16 01:08:288164
bncce36dca22015-04-21 22:11:238165 // Warm up the host cache so it has an entry for "www.example.org".
[email protected]3b9cca42009-06-16 01:08:288166 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:298167 TestCompletionCallback callback;
[email protected]bb88e1d32013-05-03 23:11:078168 int rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:238169 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
8170 DEFAULT_PRIORITY, &addrlist, callback.callback(), NULL, BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:478171 EXPECT_EQ(ERR_IO_PENDING, rv);
8172 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:288173 EXPECT_EQ(OK, rv);
8174
8175 // Verify that it was added to host cache, by doing a subsequent async lookup
8176 // and confirming it completes synchronously.
[email protected]bb88e1d32013-05-03 23:11:078177 rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:238178 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
8179 DEFAULT_PRIORITY, &addrlist, callback.callback(), NULL, BoundNetLog());
[email protected]b59ff372009-07-15 22:04:328180 ASSERT_EQ(OK, rv);
[email protected]3b9cca42009-06-16 01:08:288181
bncce36dca22015-04-21 22:11:238182 // Inject a failure the next time that "www.example.org" is resolved. This way
[email protected]3b9cca42009-06-16 01:08:288183 // we can tell if the next lookup hit the cache, or the "network".
8184 // (cache --> success, "network" --> failure).
bncce36dca22015-04-21 22:11:238185 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.example.org");
[email protected]3b9cca42009-06-16 01:08:288186
8187 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
8188 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:068189 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
[email protected]31a2bfe2010-02-09 08:03:398190 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078191 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:288192
[email protected]3b9cca42009-06-16 01:08:288193 // Run the request.
[email protected]49639fa2011-12-20 23:22:418194 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3b9cca42009-06-16 01:08:288195 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:418196 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:288197
8198 // If we bypassed the cache, we would have gotten a failure while resolving
bncce36dca22015-04-21 22:11:238199 // "www.example.org".
[email protected]3b9cca42009-06-16 01:08:288200 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
8201}
8202
[email protected]685af592010-05-11 19:31:248203// There are multiple load flags that should trigger the host cache bypass.
8204// Test each in isolation:
[email protected]23e482282013-06-14 16:08:028205TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
[email protected]685af592010-05-11 19:31:248206 BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
8207}
8208
[email protected]23e482282013-06-14 16:08:028209TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
[email protected]685af592010-05-11 19:31:248210 BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
8211}
8212
[email protected]23e482282013-06-14 16:08:028213TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
[email protected]685af592010-05-11 19:31:248214 BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
8215}
8216
[email protected]0877e3d2009-10-17 22:29:578217// Make sure we can handle an error when writing the request.
[email protected]23e482282013-06-14 16:08:028218TEST_P(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:578219 HttpRequestInfo request;
8220 request.method = "GET";
8221 request.url = GURL("http://www.foo.com/");
8222 request.load_flags = 0;
8223
8224 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:068225 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:578226 };
[email protected]31a2bfe2010-02-09 08:03:398227 StaticSocketDataProvider data(NULL, 0,
8228 write_failure, arraysize(write_failure));
[email protected]bb88e1d32013-05-03 23:11:078229 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3fe8d2f82013-10-17 08:56:078230 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578231
[email protected]49639fa2011-12-20 23:22:418232 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:578233
8234 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418235 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:578236
[email protected]49639fa2011-12-20 23:22:418237 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578238 EXPECT_EQ(ERR_IO_PENDING, rv);
8239
8240 rv = callback.WaitForResult();
8241 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
8242}
8243
8244// Check that a connection closed after the start of the headers finishes ok.
[email protected]23e482282013-06-14 16:08:028245TEST_P(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:578246 HttpRequestInfo request;
8247 request.method = "GET";
8248 request.url = GURL("http://www.foo.com/");
8249 request.load_flags = 0;
8250
8251 MockRead data_reads[] = {
8252 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:068253 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:578254 };
8255
[email protected]31a2bfe2010-02-09 08:03:398256 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078257 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3fe8d2f82013-10-17 08:56:078258 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578259
[email protected]49639fa2011-12-20 23:22:418260 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:578261
8262 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418263 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:578264
[email protected]49639fa2011-12-20 23:22:418265 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578266 EXPECT_EQ(ERR_IO_PENDING, rv);
8267
8268 rv = callback.WaitForResult();
8269 EXPECT_EQ(OK, rv);
8270
8271 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508272 ASSERT_TRUE(response != NULL);
[email protected]0877e3d2009-10-17 22:29:578273
[email protected]90499482013-06-01 00:39:508274 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]0877e3d2009-10-17 22:29:578275 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
8276
8277 std::string response_data;
8278 rv = ReadTransaction(trans.get(), &response_data);
8279 EXPECT_EQ(OK, rv);
8280 EXPECT_EQ("", response_data);
8281}
8282
8283// Make sure that a dropped connection while draining the body for auth
8284// restart does the right thing.
[email protected]23e482282013-06-14 16:08:028285TEST_P(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:578286 HttpRequestInfo request;
8287 request.method = "GET";
bncce36dca22015-04-21 22:11:238288 request.url = GURL("http://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:578289 request.load_flags = 0;
8290
8291 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238292 MockWrite(
8293 "GET / HTTP/1.1\r\n"
8294 "Host: www.example.org\r\n"
8295 "Connection: keep-alive\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:578296 };
8297
8298 MockRead data_reads1[] = {
8299 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
8300 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8301 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8302 MockRead("Content-Length: 14\r\n\r\n"),
8303 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:068304 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:578305 };
8306
[email protected]31a2bfe2010-02-09 08:03:398307 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8308 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:078309 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:578310
8311 // After calling trans->RestartWithAuth(), this is the request we should
8312 // be issuing -- the final header line contains the credentials.
8313 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238314 MockWrite(
8315 "GET / HTTP/1.1\r\n"
8316 "Host: www.example.org\r\n"
8317 "Connection: keep-alive\r\n"
8318 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:578319 };
8320
8321 // Lastly, the server responds with the actual content.
8322 MockRead data_reads2[] = {
8323 MockRead("HTTP/1.1 200 OK\r\n"),
8324 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8325 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068326 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:578327 };
8328
[email protected]31a2bfe2010-02-09 08:03:398329 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8330 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:078331 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3fe8d2f82013-10-17 08:56:078332 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578333
[email protected]49639fa2011-12-20 23:22:418334 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:578335
[email protected]262eec82013-03-19 21:01:368336 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508337 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:508338
[email protected]49639fa2011-12-20 23:22:418339 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578340 EXPECT_EQ(ERR_IO_PENDING, rv);
8341
8342 rv = callback1.WaitForResult();
8343 EXPECT_EQ(OK, rv);
8344
8345 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508346 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048347 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:578348
[email protected]49639fa2011-12-20 23:22:418349 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:578350
[email protected]49639fa2011-12-20 23:22:418351 rv = trans->RestartWithAuth(
8352 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]0877e3d2009-10-17 22:29:578353 EXPECT_EQ(ERR_IO_PENDING, rv);
8354
8355 rv = callback2.WaitForResult();
8356 EXPECT_EQ(OK, rv);
8357
8358 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508359 ASSERT_TRUE(response != NULL);
[email protected]0877e3d2009-10-17 22:29:578360 EXPECT_TRUE(response->auth_challenge.get() == NULL);
8361 EXPECT_EQ(100, response->headers->GetContentLength());
8362}
8363
8364// Test HTTPS connections going through a proxy that sends extra data.
[email protected]23e482282013-06-14 16:08:028365TEST_P(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
[email protected]bb88e1d32013-05-03 23:11:078366 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]0877e3d2009-10-17 22:29:578367
8368 HttpRequestInfo request;
8369 request.method = "GET";
bncce36dca22015-04-21 22:11:238370 request.url = GURL("https://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:578371 request.load_flags = 0;
8372
8373 MockRead proxy_reads[] = {
8374 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:068375 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:578376 };
8377
[email protected]31a2bfe2010-02-09 08:03:398378 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
[email protected]8ddf8322012-02-23 18:08:068379 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:578380
[email protected]bb88e1d32013-05-03 23:11:078381 session_deps_.socket_factory->AddSocketDataProvider(&data);
8382 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:578383
[email protected]49639fa2011-12-20 23:22:418384 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:578385
[email protected]bb88e1d32013-05-03 23:11:078386 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:578387
[email protected]3fe8d2f82013-10-17 08:56:078388 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578389 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418390 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:578391
[email protected]49639fa2011-12-20 23:22:418392 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578393 EXPECT_EQ(ERR_IO_PENDING, rv);
8394
8395 rv = callback.WaitForResult();
8396 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
8397}
8398
[email protected]23e482282013-06-14 16:08:028399TEST_P(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:468400 HttpRequestInfo request;
8401 request.method = "GET";
bncce36dca22015-04-21 22:11:238402 request.url = GURL("http://www.example.org/");
[email protected]9492e4a2010-02-24 00:58:468403 request.load_flags = 0;
8404
[email protected]3fe8d2f82013-10-17 08:56:078405 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:278406 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418407 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278408
[email protected]e22e1362009-11-23 21:31:128409 MockRead data_reads[] = {
8410 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068411 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:128412 };
[email protected]9492e4a2010-02-24 00:58:468413
8414 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078415 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:468416
[email protected]49639fa2011-12-20 23:22:418417 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:468418
[email protected]49639fa2011-12-20 23:22:418419 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9492e4a2010-02-24 00:58:468420 EXPECT_EQ(ERR_IO_PENDING, rv);
8421
8422 EXPECT_EQ(OK, callback.WaitForResult());
8423
8424 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508425 ASSERT_TRUE(response != NULL);
[email protected]9492e4a2010-02-24 00:58:468426
[email protected]90499482013-06-01 00:39:508427 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]9492e4a2010-02-24 00:58:468428 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
8429
8430 std::string response_data;
8431 rv = ReadTransaction(trans.get(), &response_data);
[email protected]5543cbb2012-04-20 16:35:238432 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
[email protected]e22e1362009-11-23 21:31:128433}
8434
[email protected]23e482282013-06-14 16:08:028435TEST_P(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:158436 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:528437 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
[email protected]95d88ffe2010-02-04 21:25:338438 const uint64 kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:218439 UploadFileElementReader::ScopedOverridingContentLengthForTests
8440 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:338441
[email protected]b2d26cfd2012-12-11 10:36:068442 ScopedVector<UploadElementReader> element_readers;
8443 element_readers.push_back(
[email protected]cadac622013-06-11 16:46:368444 new UploadFileElementReader(base::MessageLoopProxy::current().get(),
8445 temp_file_path,
8446 0,
8447 kuint64max,
8448 base::Time()));
mmenkecbc2b712014-10-09 20:29:078449 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:278450
8451 HttpRequestInfo request;
8452 request.method = "POST";
bncce36dca22015-04-21 22:11:238453 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:278454 request.upload_data_stream = &upload_data_stream;
8455 request.load_flags = 0;
8456
[email protected]3fe8d2f82013-10-17 08:56:078457 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]329b68b2012-11-14 17:54:278458 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418459 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]95d88ffe2010-02-04 21:25:338460
8461 MockRead data_reads[] = {
8462 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
8463 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068464 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:338465 };
[email protected]31a2bfe2010-02-09 08:03:398466 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078467 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:338468
[email protected]49639fa2011-12-20 23:22:418469 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:338470
[email protected]49639fa2011-12-20 23:22:418471 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]95d88ffe2010-02-04 21:25:338472 EXPECT_EQ(ERR_IO_PENDING, rv);
8473
8474 rv = callback.WaitForResult();
8475 EXPECT_EQ(OK, rv);
8476
8477 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508478 ASSERT_TRUE(response != NULL);
[email protected]95d88ffe2010-02-04 21:25:338479
[email protected]90499482013-06-01 00:39:508480 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]95d88ffe2010-02-04 21:25:338481 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
8482
8483 std::string response_data;
8484 rv = ReadTransaction(trans.get(), &response_data);
8485 EXPECT_EQ(OK, rv);
8486 EXPECT_EQ("hello world", response_data);
8487
[email protected]dd3aa792013-07-16 19:10:238488 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:338489}
8490
[email protected]23e482282013-06-14 16:08:028491TEST_P(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:158492 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:528493 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:368494 std::string temp_file_content("Unreadable file.");
[email protected]e5c2a22e2014-03-06 20:42:308495 ASSERT_TRUE(base::WriteFile(temp_file, temp_file_content.c_str(),
[email protected]6624b4622010-03-29 19:58:368496 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:118497 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:368498
[email protected]b2d26cfd2012-12-11 10:36:068499 ScopedVector<UploadElementReader> element_readers;
8500 element_readers.push_back(
[email protected]cadac622013-06-11 16:46:368501 new UploadFileElementReader(base::MessageLoopProxy::current().get(),
8502 temp_file,
8503 0,
8504 kuint64max,
8505 base::Time()));
mmenkecbc2b712014-10-09 20:29:078506 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:278507
8508 HttpRequestInfo request;
8509 request.method = "POST";
bncce36dca22015-04-21 22:11:238510 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:278511 request.upload_data_stream = &upload_data_stream;
8512 request.load_flags = 0;
8513
[email protected]999dd8c2013-11-12 06:45:548514 // If we try to upload an unreadable file, the transaction should fail.
[email protected]3fe8d2f82013-10-17 08:56:078515 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]329b68b2012-11-14 17:54:278516 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418517 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]6624b4622010-03-29 19:58:368518
[email protected]999dd8c2013-11-12 06:45:548519 StaticSocketDataProvider data(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078520 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:368521
[email protected]49639fa2011-12-20 23:22:418522 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:368523
[email protected]49639fa2011-12-20 23:22:418524 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]6624b4622010-03-29 19:58:368525 EXPECT_EQ(ERR_IO_PENDING, rv);
8526
8527 rv = callback.WaitForResult();
[email protected]999dd8c2013-11-12 06:45:548528 EXPECT_EQ(ERR_ACCESS_DENIED, rv);
[email protected]6624b4622010-03-29 19:58:368529
[email protected]dd3aa792013-07-16 19:10:238530 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:368531}
8532
[email protected]02cad5d2013-10-02 08:14:038533TEST_P(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
8534 class FakeUploadElementReader : public UploadElementReader {
8535 public:
8536 FakeUploadElementReader() {}
dchengb03027d2014-10-21 12:00:208537 ~FakeUploadElementReader() override {}
[email protected]02cad5d2013-10-02 08:14:038538
8539 const CompletionCallback& callback() const { return callback_; }
8540
8541 // UploadElementReader overrides:
dchengb03027d2014-10-21 12:00:208542 int Init(const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:038543 callback_ = callback;
8544 return ERR_IO_PENDING;
8545 }
dchengb03027d2014-10-21 12:00:208546 uint64 GetContentLength() const override { return 0; }
8547 uint64 BytesRemaining() const override { return 0; }
8548 int Read(IOBuffer* buf,
8549 int buf_length,
8550 const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:038551 return ERR_FAILED;
8552 }
8553
8554 private:
8555 CompletionCallback callback_;
8556 };
8557
8558 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
8559 ScopedVector<UploadElementReader> element_readers;
8560 element_readers.push_back(fake_reader);
mmenkecbc2b712014-10-09 20:29:078561 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02cad5d2013-10-02 08:14:038562
8563 HttpRequestInfo request;
8564 request.method = "POST";
bncce36dca22015-04-21 22:11:238565 request.url = GURL("http://www.example.org/upload");
[email protected]02cad5d2013-10-02 08:14:038566 request.upload_data_stream = &upload_data_stream;
8567 request.load_flags = 0;
8568
[email protected]3fe8d2f82013-10-17 08:56:078569 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02cad5d2013-10-02 08:14:038570 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418571 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02cad5d2013-10-02 08:14:038572
8573 StaticSocketDataProvider data;
8574 session_deps_.socket_factory->AddSocketDataProvider(&data);
8575
8576 TestCompletionCallback callback;
8577 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8578 EXPECT_EQ(ERR_IO_PENDING, rv);
8579 base::MessageLoop::current()->RunUntilIdle();
8580
8581 // Transaction is pending on request body initialization.
8582 ASSERT_FALSE(fake_reader->callback().is_null());
8583
8584 // Return Init()'s result after the transaction gets destroyed.
8585 trans.reset();
8586 fake_reader->callback().Run(OK); // Should not crash.
8587}
8588
[email protected]aeefc9e82010-02-19 16:18:278589// Tests that changes to Auth realms are treated like auth rejections.
[email protected]23e482282013-06-14 16:08:028590TEST_P(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:278591
8592 HttpRequestInfo request;
8593 request.method = "GET";
bncce36dca22015-04-21 22:11:238594 request.url = GURL("http://www.example.org/");
[email protected]aeefc9e82010-02-19 16:18:278595 request.load_flags = 0;
8596
8597 // First transaction will request a resource and receive a Basic challenge
8598 // with realm="first_realm".
8599 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238600 MockWrite(
8601 "GET / HTTP/1.1\r\n"
8602 "Host: www.example.org\r\n"
8603 "Connection: keep-alive\r\n"
8604 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:278605 };
8606 MockRead data_reads1[] = {
8607 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8608 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
8609 "\r\n"),
8610 };
8611
8612 // After calling trans->RestartWithAuth(), provide an Authentication header
8613 // for first_realm. The server will reject and provide a challenge with
8614 // second_realm.
8615 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238616 MockWrite(
8617 "GET / HTTP/1.1\r\n"
8618 "Host: www.example.org\r\n"
8619 "Connection: keep-alive\r\n"
8620 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
8621 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:278622 };
8623 MockRead data_reads2[] = {
8624 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8625 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
8626 "\r\n"),
8627 };
8628
8629 // This again fails, and goes back to first_realm. Make sure that the
8630 // entry is removed from cache.
8631 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:238632 MockWrite(
8633 "GET / HTTP/1.1\r\n"
8634 "Host: www.example.org\r\n"
8635 "Connection: keep-alive\r\n"
8636 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
8637 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:278638 };
8639 MockRead data_reads3[] = {
8640 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8641 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
8642 "\r\n"),
8643 };
8644
8645 // Try one last time (with the correct password) and get the resource.
8646 MockWrite data_writes4[] = {
bncce36dca22015-04-21 22:11:238647 MockWrite(
8648 "GET / HTTP/1.1\r\n"
8649 "Host: www.example.org\r\n"
8650 "Connection: keep-alive\r\n"
8651 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
8652 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:278653 };
8654 MockRead data_reads4[] = {
8655 MockRead("HTTP/1.1 200 OK\r\n"
8656 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:508657 "Content-Length: 5\r\n"
8658 "\r\n"
8659 "hello"),
[email protected]aeefc9e82010-02-19 16:18:278660 };
8661
8662 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8663 data_writes1, arraysize(data_writes1));
8664 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8665 data_writes2, arraysize(data_writes2));
8666 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
8667 data_writes3, arraysize(data_writes3));
8668 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
8669 data_writes4, arraysize(data_writes4));
[email protected]bb88e1d32013-05-03 23:11:078670 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8671 session_deps_.socket_factory->AddSocketDataProvider(&data2);
8672 session_deps_.socket_factory->AddSocketDataProvider(&data3);
8673 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:278674
[email protected]49639fa2011-12-20 23:22:418675 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:278676
[email protected]3fe8d2f82013-10-17 08:56:078677 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0b0bf032010-09-21 18:08:508678 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418679 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:508680
[email protected]aeefc9e82010-02-19 16:18:278681 // Issue the first request with Authorize headers. There should be a
8682 // password prompt for first_realm waiting to be filled in after the
8683 // transaction completes.
[email protected]49639fa2011-12-20 23:22:418684 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]aeefc9e82010-02-19 16:18:278685 EXPECT_EQ(ERR_IO_PENDING, rv);
8686 rv = callback1.WaitForResult();
8687 EXPECT_EQ(OK, rv);
8688 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508689 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048690 const AuthChallengeInfo* challenge = response->auth_challenge.get();
8691 ASSERT_FALSE(challenge == NULL);
8692 EXPECT_FALSE(challenge->is_proxy);
bncce36dca22015-04-21 22:11:238693 EXPECT_EQ("www.example.org:80", challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:048694 EXPECT_EQ("first_realm", challenge->realm);
8695 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278696
8697 // Issue the second request with an incorrect password. There should be a
8698 // password prompt for second_realm waiting to be filled in after the
8699 // transaction completes.
[email protected]49639fa2011-12-20 23:22:418700 TestCompletionCallback callback2;
8701 rv = trans->RestartWithAuth(
8702 AuthCredentials(kFirst, kBaz), callback2.callback());
[email protected]aeefc9e82010-02-19 16:18:278703 EXPECT_EQ(ERR_IO_PENDING, rv);
8704 rv = callback2.WaitForResult();
8705 EXPECT_EQ(OK, rv);
8706 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508707 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048708 challenge = response->auth_challenge.get();
8709 ASSERT_FALSE(challenge == NULL);
8710 EXPECT_FALSE(challenge->is_proxy);
bncce36dca22015-04-21 22:11:238711 EXPECT_EQ("www.example.org:80", challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:048712 EXPECT_EQ("second_realm", challenge->realm);
8713 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278714
8715 // Issue the third request with another incorrect password. There should be
8716 // a password prompt for first_realm waiting to be filled in. If the password
8717 // prompt is not present, it indicates that the HttpAuthCacheEntry for
8718 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:418719 TestCompletionCallback callback3;
8720 rv = trans->RestartWithAuth(
8721 AuthCredentials(kSecond, kFou), callback3.callback());
[email protected]aeefc9e82010-02-19 16:18:278722 EXPECT_EQ(ERR_IO_PENDING, rv);
8723 rv = callback3.WaitForResult();
8724 EXPECT_EQ(OK, rv);
8725 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508726 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048727 challenge = response->auth_challenge.get();
8728 ASSERT_FALSE(challenge == NULL);
8729 EXPECT_FALSE(challenge->is_proxy);
bncce36dca22015-04-21 22:11:238730 EXPECT_EQ("www.example.org:80", challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:048731 EXPECT_EQ("first_realm", challenge->realm);
8732 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278733
8734 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:418735 TestCompletionCallback callback4;
8736 rv = trans->RestartWithAuth(
8737 AuthCredentials(kFirst, kBar), callback4.callback());
[email protected]aeefc9e82010-02-19 16:18:278738 EXPECT_EQ(ERR_IO_PENDING, rv);
8739 rv = callback4.WaitForResult();
8740 EXPECT_EQ(OK, rv);
8741 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508742 ASSERT_TRUE(response != NULL);
[email protected]aeefc9e82010-02-19 16:18:278743 EXPECT_TRUE(response->auth_challenge.get() == NULL);
8744}
8745
[email protected]23e482282013-06-14 16:08:028746TEST_P(HttpNetworkTransactionTest, HonorAlternateProtocolHeader) {
[email protected]d7599122014-05-24 03:37:238747 session_deps_.next_protos = SpdyNextProtos();
8748 session_deps_.use_alternate_protocols = true;
[email protected]a2cb8122010-03-10 17:22:428749
[email protected]8a0fc822013-06-27 20:52:438750 std::string alternate_protocol_http_header =
8751 GetAlternateProtocolHttpHeader();
8752
[email protected]564b4912010-03-09 16:30:428753 MockRead data_reads[] = {
8754 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438755 MockRead(alternate_protocol_http_header.c_str()),
[email protected]564b4912010-03-09 16:30:428756 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068757 MockRead(SYNCHRONOUS, OK),
[email protected]564b4912010-03-09 16:30:428758 };
8759
8760 HttpRequestInfo request;
8761 request.method = "GET";
bncce36dca22015-04-21 22:11:238762 request.url = GURL("http://www.example.org/");
[email protected]564b4912010-03-09 16:30:428763 request.load_flags = 0;
8764
8765 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
8766
[email protected]bb88e1d32013-05-03 23:11:078767 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]564b4912010-03-09 16:30:428768
[email protected]49639fa2011-12-20 23:22:418769 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:428770
[email protected]bb88e1d32013-05-03 23:11:078771 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:368772 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508773 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]564b4912010-03-09 16:30:428774
[email protected]49639fa2011-12-20 23:22:418775 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:428776 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]9e743cd2010-03-16 07:03:538777
bncce36dca22015-04-21 22:11:238778 HostPortPair http_host_port_pair("www.example.org", 80);
[email protected]9801e3702014-03-07 09:33:558779 HttpServerProperties& http_server_properties =
[email protected]17291a022011-10-10 07:32:538780 *session->http_server_properties();
bnc181b39a2015-03-17 21:36:478781 AlternativeService alternative_service =
8782 http_server_properties.GetAlternativeService(http_host_port_pair);
8783 EXPECT_EQ(alternative_service.protocol, UNINITIALIZED_ALTERNATE_PROTOCOL);
[email protected]564b4912010-03-09 16:30:428784
8785 EXPECT_EQ(OK, callback.WaitForResult());
8786
8787 const HttpResponseInfo* response = trans->GetResponseInfo();
8788 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508789 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:428790 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:538791 EXPECT_FALSE(response->was_fetched_via_spdy);
8792 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]564b4912010-03-09 16:30:428793
8794 std::string response_data;
8795 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8796 EXPECT_EQ("hello world", response_data);
8797
bnc181b39a2015-03-17 21:36:478798 alternative_service =
8799 http_server_properties.GetAlternativeService(http_host_port_pair);
8800 EXPECT_EQ(443, alternative_service.port);
8801 EXPECT_EQ(AlternateProtocolFromNextProto(GetParam()),
8802 alternative_service.protocol);
[email protected]564b4912010-03-09 16:30:428803}
8804
rch89c6e102015-03-18 18:56:528805TEST_P(HttpNetworkTransactionTest, EmptyAlternateProtocolHeader) {
8806 session_deps_.next_protos = SpdyNextProtos();
8807 session_deps_.use_alternate_protocols = true;
8808
8809 MockRead data_reads[] = {
8810 MockRead("HTTP/1.1 200 OK\r\n"),
8811 MockRead("Alternate-Protocol: \r\n\r\n"),
8812 MockRead("hello world"),
8813 MockRead(SYNCHRONOUS, OK),
8814 };
8815
8816 HttpRequestInfo request;
8817 request.method = "GET";
bncce36dca22015-04-21 22:11:238818 request.url = GURL("http://www.example.org/");
rch89c6e102015-03-18 18:56:528819 request.load_flags = 0;
8820
8821 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
8822
8823 session_deps_.socket_factory->AddSocketDataProvider(&data);
8824
8825 TestCompletionCallback callback;
8826
8827 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8828
bncce36dca22015-04-21 22:11:238829 HostPortPair http_host_port_pair("www.example.org", 80);
rch89c6e102015-03-18 18:56:528830 HttpServerProperties& http_server_properties =
8831 *session->http_server_properties();
bnccacc0992015-03-20 20:22:228832 AlternativeService alternative_service(QUIC, "", 80);
8833 http_server_properties.SetAlternativeService(http_host_port_pair,
8834 alternative_service, 1.0);
8835
8836 alternative_service =
rch89c6e102015-03-18 18:56:528837 http_server_properties.GetAlternativeService(http_host_port_pair);
8838 EXPECT_EQ(alternative_service.protocol, QUIC);
8839
8840 scoped_ptr<HttpTransaction> trans(
8841 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8842
8843 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8844 EXPECT_EQ(ERR_IO_PENDING, rv);
8845
8846 EXPECT_EQ(OK, callback.WaitForResult());
8847
8848 const HttpResponseInfo* response = trans->GetResponseInfo();
8849 ASSERT_TRUE(response != NULL);
8850 ASSERT_TRUE(response->headers.get() != NULL);
8851 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8852 EXPECT_FALSE(response->was_fetched_via_spdy);
8853 EXPECT_FALSE(response->was_npn_negotiated);
8854
8855 std::string response_data;
8856 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8857 EXPECT_EQ("hello world", response_data);
8858
8859 alternative_service =
8860 http_server_properties.GetAlternativeService(http_host_port_pair);
8861 EXPECT_EQ(alternative_service.protocol, UNINITIALIZED_ALTERNATE_PROTOCOL);
8862}
8863
[email protected]23e482282013-06-14 16:08:028864TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238865 MarkBrokenAlternateProtocolAndFallback) {
[email protected]d7599122014-05-24 03:37:238866 session_deps_.use_alternate_protocols = true;
[email protected]564b4912010-03-09 16:30:428867
8868 HttpRequestInfo request;
8869 request.method = "GET";
bncce36dca22015-04-21 22:11:238870 request.url = GURL("http://www.example.org/");
[email protected]564b4912010-03-09 16:30:428871 request.load_flags = 0;
8872
[email protected]d973e99a2012-02-17 21:02:368873 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:428874 StaticSocketDataProvider first_data;
8875 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078876 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]564b4912010-03-09 16:30:428877
8878 MockRead data_reads[] = {
8879 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8880 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068881 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:428882 };
8883 StaticSocketDataProvider second_data(
8884 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078885 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:428886
[email protected]bb88e1d32013-05-03 23:11:078887 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:428888
[email protected]30d4c022013-07-18 22:58:168889 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538890 session->http_server_properties();
bnc8445b3002015-03-13 01:57:098891 const HostPortPair host_port_pair = HostPortPair::FromURL(request.url);
[email protected]3912662a32011-10-04 00:51:118892 // Port must be < 1024, or the header will be ignored (since initial port was
8893 // port 80 (another restricted port).
bnccacc0992015-03-20 20:22:228894 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:238895 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:228896 666); /* port is ignored by MockConnect anyway */
8897 http_server_properties->SetAlternativeService(host_port_pair,
8898 alternative_service, 1.0);
[email protected]564b4912010-03-09 16:30:428899
[email protected]262eec82013-03-19 21:01:368900 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508901 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418902 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:428903
[email protected]49639fa2011-12-20 23:22:418904 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:428905 EXPECT_EQ(ERR_IO_PENDING, rv);
8906 EXPECT_EQ(OK, callback.WaitForResult());
8907
8908 const HttpResponseInfo* response = trans->GetResponseInfo();
8909 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508910 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:428911 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8912
8913 std::string response_data;
8914 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8915 EXPECT_EQ("hello world", response_data);
8916
bnccacc0992015-03-20 20:22:228917 alternative_service =
bnc181b39a2015-03-17 21:36:478918 http_server_properties->GetAlternativeService(host_port_pair);
8919 EXPECT_NE(UNINITIALIZED_ALTERNATE_PROTOCOL, alternative_service.protocol);
bnc8445b3002015-03-13 01:57:098920 EXPECT_TRUE(
8921 http_server_properties->IsAlternativeServiceBroken(alternative_service));
[email protected]564b4912010-03-09 16:30:428922}
8923
[email protected]23e482282013-06-14 16:08:028924TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238925 AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:118926 // Ensure that we're not allowed to redirect traffic via an alternate
8927 // protocol to an unrestricted (port >= 1024) when the original traffic was
8928 // on a restricted port (port < 1024). Ensure that we can redirect in all
8929 // other cases.
[email protected]d7599122014-05-24 03:37:238930 session_deps_.use_alternate_protocols = true;
[email protected]3912662a32011-10-04 00:51:118931
8932 HttpRequestInfo restricted_port_request;
8933 restricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:238934 restricted_port_request.url = GURL("http://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:118935 restricted_port_request.load_flags = 0;
8936
[email protected]d973e99a2012-02-17 21:02:368937 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118938 StaticSocketDataProvider first_data;
8939 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078940 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118941
8942 MockRead data_reads[] = {
8943 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8944 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068945 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118946 };
8947 StaticSocketDataProvider second_data(
8948 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078949 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118950
[email protected]bb88e1d32013-05-03 23:11:078951 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118952
[email protected]30d4c022013-07-18 22:58:168953 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538954 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118955 const int kUnrestrictedAlternatePort = 1024;
bnccacc0992015-03-20 20:22:228956 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:238957 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:228958 kUnrestrictedAlternatePort);
8959 http_server_properties->SetAlternativeService(
8960 HostPortPair::FromURL(restricted_port_request.url), alternative_service,
bnc1102b552015-01-30 20:11:018961 1.0);
[email protected]3912662a32011-10-04 00:51:118962
[email protected]262eec82013-03-19 21:01:368963 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508964 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418965 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118966
[email protected]49639fa2011-12-20 23:22:418967 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:368968 &restricted_port_request,
8969 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118970 EXPECT_EQ(ERR_IO_PENDING, rv);
8971 // Invalid change to unrestricted port should fail.
8972 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.WaitForResult());
[email protected]c54c6962013-02-01 04:53:198973}
[email protected]3912662a32011-10-04 00:51:118974
[email protected]23e482282013-06-14 16:08:028975TEST_P(HttpNetworkTransactionTest,
[email protected]c54c6962013-02-01 04:53:198976 AlternateProtocolPortRestrictedPermitted) {
8977 // Ensure that we're allowed to redirect traffic via an alternate
8978 // protocol to an unrestricted (port >= 1024) when the original traffic was
8979 // on a restricted port (port < 1024) if we set
8980 // enable_user_alternate_protocol_ports.
8981
[email protected]d7599122014-05-24 03:37:238982 session_deps_.use_alternate_protocols = true;
[email protected]bb88e1d32013-05-03 23:11:078983 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:198984
8985 HttpRequestInfo restricted_port_request;
8986 restricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:238987 restricted_port_request.url = GURL("http://www.example.org:1023/");
[email protected]c54c6962013-02-01 04:53:198988 restricted_port_request.load_flags = 0;
8989
8990 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
8991 StaticSocketDataProvider first_data;
8992 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078993 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:198994
8995 MockRead data_reads[] = {
8996 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8997 MockRead("hello world"),
8998 MockRead(ASYNC, OK),
8999 };
9000 StaticSocketDataProvider second_data(
9001 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079002 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]c54c6962013-02-01 04:53:199003
[email protected]bb88e1d32013-05-03 23:11:079004 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:199005
[email protected]30d4c022013-07-18 22:58:169006 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]c54c6962013-02-01 04:53:199007 session->http_server_properties();
9008 const int kUnrestrictedAlternatePort = 1024;
bnccacc0992015-03-20 20:22:229009 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239010 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229011 kUnrestrictedAlternatePort);
9012 http_server_properties->SetAlternativeService(
9013 HostPortPair::FromURL(restricted_port_request.url), alternative_service,
bnc1102b552015-01-30 20:11:019014 1.0);
[email protected]c54c6962013-02-01 04:53:199015
[email protected]262eec82013-03-19 21:01:369016 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509017 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]c54c6962013-02-01 04:53:199018 TestCompletionCallback callback;
9019
9020 EXPECT_EQ(ERR_IO_PENDING, trans->Start(
[email protected]262eec82013-03-19 21:01:369021 &restricted_port_request,
9022 callback.callback(), BoundNetLog()));
[email protected]c54c6962013-02-01 04:53:199023 // Change to unrestricted port should succeed.
9024 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:119025}
9026
[email protected]23e482282013-06-14 16:08:029027TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239028 AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:119029 // Ensure that we're not allowed to redirect traffic via an alternate
9030 // protocol to an unrestricted (port >= 1024) when the original traffic was
9031 // on a restricted port (port < 1024). Ensure that we can redirect in all
9032 // other cases.
[email protected]d7599122014-05-24 03:37:239033 session_deps_.use_alternate_protocols = true;
[email protected]3912662a32011-10-04 00:51:119034
9035 HttpRequestInfo restricted_port_request;
9036 restricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:239037 restricted_port_request.url = GURL("http://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:119038 restricted_port_request.load_flags = 0;
9039
[email protected]d973e99a2012-02-17 21:02:369040 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:119041 StaticSocketDataProvider first_data;
9042 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079043 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:119044
9045 MockRead data_reads[] = {
9046 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9047 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069048 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:119049 };
9050 StaticSocketDataProvider second_data(
9051 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079052 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:119053
[email protected]bb88e1d32013-05-03 23:11:079054 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:119055
[email protected]30d4c022013-07-18 22:58:169056 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:539057 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:119058 const int kRestrictedAlternatePort = 80;
bnccacc0992015-03-20 20:22:229059 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239060 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229061 kRestrictedAlternatePort);
9062 http_server_properties->SetAlternativeService(
9063 HostPortPair::FromURL(restricted_port_request.url), alternative_service,
bnc1102b552015-01-30 20:11:019064 1.0);
[email protected]3912662a32011-10-04 00:51:119065
[email protected]262eec82013-03-19 21:01:369066 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509067 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419068 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:119069
[email protected]49639fa2011-12-20 23:22:419070 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:369071 &restricted_port_request,
9072 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:119073 EXPECT_EQ(ERR_IO_PENDING, rv);
9074 // Valid change to restricted port should pass.
9075 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:119076}
9077
[email protected]23e482282013-06-14 16:08:029078TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239079 AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:119080 // Ensure that we're not allowed to redirect traffic via an alternate
9081 // protocol to an unrestricted (port >= 1024) when the original traffic was
9082 // on a restricted port (port < 1024). Ensure that we can redirect in all
9083 // other cases.
[email protected]d7599122014-05-24 03:37:239084 session_deps_.use_alternate_protocols = true;
[email protected]3912662a32011-10-04 00:51:119085
9086 HttpRequestInfo unrestricted_port_request;
9087 unrestricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:239088 unrestricted_port_request.url = GURL("http://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:119089 unrestricted_port_request.load_flags = 0;
9090
[email protected]d973e99a2012-02-17 21:02:369091 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:119092 StaticSocketDataProvider first_data;
9093 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079094 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:119095
9096 MockRead data_reads[] = {
9097 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9098 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069099 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:119100 };
9101 StaticSocketDataProvider second_data(
9102 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079103 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:119104
[email protected]bb88e1d32013-05-03 23:11:079105 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:119106
[email protected]30d4c022013-07-18 22:58:169107 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:539108 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:119109 const int kRestrictedAlternatePort = 80;
bnccacc0992015-03-20 20:22:229110 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239111 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229112 kRestrictedAlternatePort);
9113 http_server_properties->SetAlternativeService(
9114 HostPortPair::FromURL(unrestricted_port_request.url), alternative_service,
bnc1102b552015-01-30 20:11:019115 1.0);
[email protected]3912662a32011-10-04 00:51:119116
[email protected]262eec82013-03-19 21:01:369117 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509118 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419119 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:119120
[email protected]49639fa2011-12-20 23:22:419121 int rv = trans->Start(
9122 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:119123 EXPECT_EQ(ERR_IO_PENDING, rv);
9124 // Valid change to restricted port should pass.
9125 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:119126}
9127
[email protected]23e482282013-06-14 16:08:029128TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239129 AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:119130 // Ensure that we're not allowed to redirect traffic via an alternate
9131 // protocol to an unrestricted (port >= 1024) when the original traffic was
9132 // on a restricted port (port < 1024). Ensure that we can redirect in all
9133 // other cases.
[email protected]d7599122014-05-24 03:37:239134 session_deps_.use_alternate_protocols = true;
[email protected]3912662a32011-10-04 00:51:119135
9136 HttpRequestInfo unrestricted_port_request;
9137 unrestricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:239138 unrestricted_port_request.url = GURL("http://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:119139 unrestricted_port_request.load_flags = 0;
9140
[email protected]d973e99a2012-02-17 21:02:369141 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:119142 StaticSocketDataProvider first_data;
9143 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079144 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:119145
9146 MockRead data_reads[] = {
9147 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9148 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069149 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:119150 };
9151 StaticSocketDataProvider second_data(
9152 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079153 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:119154
[email protected]bb88e1d32013-05-03 23:11:079155 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:119156
[email protected]30d4c022013-07-18 22:58:169157 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:539158 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:119159 const int kUnrestrictedAlternatePort = 1024;
bnccacc0992015-03-20 20:22:229160 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239161 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229162 kUnrestrictedAlternatePort);
9163 http_server_properties->SetAlternativeService(
9164 HostPortPair::FromURL(unrestricted_port_request.url), alternative_service,
bnc1102b552015-01-30 20:11:019165 1.0);
[email protected]3912662a32011-10-04 00:51:119166
[email protected]262eec82013-03-19 21:01:369167 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509168 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419169 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:119170
[email protected]49639fa2011-12-20 23:22:419171 int rv = trans->Start(
9172 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:119173 EXPECT_EQ(ERR_IO_PENDING, rv);
9174 // Valid change to an unrestricted port should pass.
9175 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:119176}
9177
[email protected]d7599122014-05-24 03:37:239178TEST_P(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:029179 // Ensure that we're not allowed to redirect traffic via an alternate
9180 // protocol to an unsafe port, and that we resume the second
9181 // HttpStreamFactoryImpl::Job once the alternate protocol request fails.
[email protected]d7599122014-05-24 03:37:239182 session_deps_.use_alternate_protocols = true;
[email protected]eb6234e2012-01-19 01:50:029183
9184 HttpRequestInfo request;
9185 request.method = "GET";
bncce36dca22015-04-21 22:11:239186 request.url = GURL("http://www.example.org/");
[email protected]eb6234e2012-01-19 01:50:029187 request.load_flags = 0;
9188
9189 // The alternate protocol request will error out before we attempt to connect,
9190 // so only the standard HTTP request will try to connect.
9191 MockRead data_reads[] = {
9192 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9193 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069194 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:029195 };
9196 StaticSocketDataProvider data(
9197 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079198 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:029199
[email protected]bb88e1d32013-05-03 23:11:079200 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:029201
[email protected]30d4c022013-07-18 22:58:169202 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]eb6234e2012-01-19 01:50:029203 session->http_server_properties();
9204 const int kUnsafePort = 7;
bnccacc0992015-03-20 20:22:229205 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239206 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229207 kUnsafePort);
9208 http_server_properties->SetAlternativeService(
9209 HostPortPair::FromURL(request.url), alternative_service, 1.0);
[email protected]eb6234e2012-01-19 01:50:029210
[email protected]262eec82013-03-19 21:01:369211 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509212 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]eb6234e2012-01-19 01:50:029213 TestCompletionCallback callback;
9214
9215 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9216 EXPECT_EQ(ERR_IO_PENDING, rv);
9217 // The HTTP request should succeed.
9218 EXPECT_EQ(OK, callback.WaitForResult());
9219
9220 // Disable alternate protocol before the asserts.
[email protected]d7599122014-05-24 03:37:239221 // HttpStreamFactory::set_use_alternate_protocols(false);
[email protected]eb6234e2012-01-19 01:50:029222
9223 const HttpResponseInfo* response = trans->GetResponseInfo();
9224 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509225 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]eb6234e2012-01-19 01:50:029226 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9227
9228 std::string response_data;
9229 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9230 EXPECT_EQ("hello world", response_data);
9231}
9232
[email protected]23e482282013-06-14 16:08:029233TEST_P(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]d7599122014-05-24 03:37:239234 session_deps_.use_alternate_protocols = true;
9235 session_deps_.next_protos = SpdyNextProtos();
[email protected]2ff8b312010-04-26 22:20:549236
9237 HttpRequestInfo request;
9238 request.method = "GET";
bncce36dca22015-04-21 22:11:239239 request.url = GURL("http://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:549240 request.load_flags = 0;
9241
[email protected]8a0fc822013-06-27 20:52:439242 std::string alternate_protocol_http_header =
9243 GetAlternateProtocolHttpHeader();
9244
[email protected]2ff8b312010-04-26 22:20:549245 MockRead data_reads[] = {
9246 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439247 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2ff8b312010-04-26 22:20:549248 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:179249 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
9250 MockRead(ASYNC, OK)
[email protected]2ff8b312010-04-26 22:20:549251 };
9252
9253 StaticSocketDataProvider first_transaction(
9254 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079255 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:549256
[email protected]8ddf8322012-02-23 18:08:069257 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029258 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:239259 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
9260 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:079261 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:549262
[email protected]cdf8f7e72013-05-23 10:56:469263 scoped_ptr<SpdyFrame> req(
9264 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
rch8e6c6c42015-05-01 14:05:139265 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]2ff8b312010-04-26 22:20:549266
[email protected]23e482282013-06-14 16:08:029267 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9268 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:549269 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:139270 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:549271 };
9272
rch8e6c6c42015-05-01 14:05:139273 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9274 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079275 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:549276
[email protected]d973e99a2012-02-17 21:02:369277 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559278 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
9279 NULL, 0, NULL, 0);
9280 hanging_non_alternate_protocol_socket.set_connect_data(
9281 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:079282 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:559283 &hanging_non_alternate_protocol_socket);
9284
[email protected]49639fa2011-12-20 23:22:419285 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:549286
[email protected]bb88e1d32013-05-03 23:11:079287 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369288 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509289 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:549290
[email protected]49639fa2011-12-20 23:22:419291 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:549292 EXPECT_EQ(ERR_IO_PENDING, rv);
9293 EXPECT_EQ(OK, callback.WaitForResult());
9294
9295 const HttpResponseInfo* response = trans->GetResponseInfo();
9296 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509297 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:549298 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9299
9300 std::string response_data;
9301 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9302 EXPECT_EQ("hello world", response_data);
9303
[email protected]90499482013-06-01 00:39:509304 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:549305
[email protected]49639fa2011-12-20 23:22:419306 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:549307 EXPECT_EQ(ERR_IO_PENDING, rv);
9308 EXPECT_EQ(OK, callback.WaitForResult());
9309
9310 response = trans->GetResponseInfo();
9311 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509312 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:549313 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539314 EXPECT_TRUE(response->was_fetched_via_spdy);
9315 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:549316
9317 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9318 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:549319}
9320
[email protected]23e482282013-06-14 16:08:029321TEST_P(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]d7599122014-05-24 03:37:239322 session_deps_.use_alternate_protocols = true;
9323 session_deps_.next_protos = SpdyNextProtos();
[email protected]2d6728692011-03-12 01:39:559324
9325 HttpRequestInfo request;
9326 request.method = "GET";
bncce36dca22015-04-21 22:11:239327 request.url = GURL("http://www.example.org/");
[email protected]2d6728692011-03-12 01:39:559328 request.load_flags = 0;
9329
[email protected]8a0fc822013-06-27 20:52:439330 std::string alternate_protocol_http_header =
9331 GetAlternateProtocolHttpHeader();
9332
[email protected]2d6728692011-03-12 01:39:559333 MockRead data_reads[] = {
9334 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439335 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2d6728692011-03-12 01:39:559336 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:179337 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:069338 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:559339 };
9340
9341 StaticSocketDataProvider first_transaction(
9342 data_reads, arraysize(data_reads), NULL, 0);
9343 // Socket 1 is the HTTP transaction with the Alternate-Protocol header.
[email protected]bb88e1d32013-05-03 23:11:079344 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:559345
[email protected]d973e99a2012-02-17 21:02:369346 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559347 StaticSocketDataProvider hanging_socket(
9348 NULL, 0, NULL, 0);
9349 hanging_socket.set_connect_data(never_finishing_connect);
9350 // Socket 2 and 3 are the hanging Alternate-Protocol and
9351 // non-Alternate-Protocol jobs from the 2nd transaction.
[email protected]bb88e1d32013-05-03 23:11:079352 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
9353 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
[email protected]2d6728692011-03-12 01:39:559354
[email protected]8ddf8322012-02-23 18:08:069355 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029356 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:239357 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
9358 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:079359 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:559360
[email protected]cdf8f7e72013-05-23 10:56:469361 scoped_ptr<SpdyFrame> req1(
9362 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
9363 scoped_ptr<SpdyFrame> req2(
9364 spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
[email protected]2d6728692011-03-12 01:39:559365 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:139366 CreateMockWrite(*req1, 0), CreateMockWrite(*req2, 1),
[email protected]2d6728692011-03-12 01:39:559367 };
[email protected]23e482282013-06-14 16:08:029368 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9369 scoped_ptr<SpdyFrame> data1(spdy_util_.ConstructSpdyBodyFrame(1, true));
9370 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
9371 scoped_ptr<SpdyFrame> data2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]2d6728692011-03-12 01:39:559372 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:139373 CreateMockRead(*resp1, 2),
9374 CreateMockRead(*data1, 3),
9375 CreateMockRead(*resp2, 4),
9376 CreateMockRead(*data2, 5),
9377 MockRead(ASYNC, 0, 6),
[email protected]2d6728692011-03-12 01:39:559378 };
9379
rch8e6c6c42015-05-01 14:05:139380 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9381 arraysize(spdy_writes));
[email protected]2d6728692011-03-12 01:39:559382 // Socket 4 is the successful Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:079383 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:559384
9385 // Socket 5 is the unsuccessful non-Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:079386 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
[email protected]2d6728692011-03-12 01:39:559387
[email protected]bb88e1d32013-05-03 23:11:079388 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:419389 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:509390 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:559391
[email protected]49639fa2011-12-20 23:22:419392 int rv = trans1.Start(&request, callback1.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559393 EXPECT_EQ(ERR_IO_PENDING, rv);
9394 EXPECT_EQ(OK, callback1.WaitForResult());
9395
9396 const HttpResponseInfo* response = trans1.GetResponseInfo();
9397 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509398 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559399 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9400
9401 std::string response_data;
9402 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
9403 EXPECT_EQ("hello world", response_data);
9404
[email protected]49639fa2011-12-20 23:22:419405 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:509406 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:419407 rv = trans2.Start(&request, callback2.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559408 EXPECT_EQ(ERR_IO_PENDING, rv);
9409
[email protected]49639fa2011-12-20 23:22:419410 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:509411 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:419412 rv = trans3.Start(&request, callback3.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559413 EXPECT_EQ(ERR_IO_PENDING, rv);
9414
9415 EXPECT_EQ(OK, callback2.WaitForResult());
9416 EXPECT_EQ(OK, callback3.WaitForResult());
9417
9418 response = trans2.GetResponseInfo();
9419 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509420 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559421 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9422 EXPECT_TRUE(response->was_fetched_via_spdy);
9423 EXPECT_TRUE(response->was_npn_negotiated);
9424 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
9425 EXPECT_EQ("hello!", response_data);
9426
9427 response = trans3.GetResponseInfo();
9428 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509429 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559430 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9431 EXPECT_TRUE(response->was_fetched_via_spdy);
9432 EXPECT_TRUE(response->was_npn_negotiated);
9433 ASSERT_EQ(OK, ReadTransaction(&trans3, &response_data));
9434 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:559435}
9436
[email protected]23e482282013-06-14 16:08:029437TEST_P(HttpNetworkTransactionTest, StallAlternateProtocolForNpnSpdy) {
[email protected]d7599122014-05-24 03:37:239438 session_deps_.use_alternate_protocols = true;
9439 session_deps_.next_protos = SpdyNextProtos();
[email protected]2d6728692011-03-12 01:39:559440
9441 HttpRequestInfo request;
9442 request.method = "GET";
bncce36dca22015-04-21 22:11:239443 request.url = GURL("http://www.example.org/");
[email protected]2d6728692011-03-12 01:39:559444 request.load_flags = 0;
9445
[email protected]8a0fc822013-06-27 20:52:439446 std::string alternate_protocol_http_header =
9447 GetAlternateProtocolHttpHeader();
9448
[email protected]2d6728692011-03-12 01:39:559449 MockRead data_reads[] = {
9450 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439451 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2d6728692011-03-12 01:39:559452 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:179453 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:069454 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:559455 };
9456
9457 StaticSocketDataProvider first_transaction(
9458 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079459 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:559460
[email protected]8ddf8322012-02-23 18:08:069461 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029462 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:079463 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:559464
[email protected]d973e99a2012-02-17 21:02:369465 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559466 StaticSocketDataProvider hanging_alternate_protocol_socket(
9467 NULL, 0, NULL, 0);
9468 hanging_alternate_protocol_socket.set_connect_data(
9469 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:079470 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:559471 &hanging_alternate_protocol_socket);
9472
9473 // 2nd request is just a copy of the first one, over HTTP again.
[email protected]bb88e1d32013-05-03 23:11:079474 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:559475
[email protected]49639fa2011-12-20 23:22:419476 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:559477
[email protected]bb88e1d32013-05-03 23:11:079478 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369479 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509480 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:559481
[email protected]49639fa2011-12-20 23:22:419482 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559483 EXPECT_EQ(ERR_IO_PENDING, rv);
9484 EXPECT_EQ(OK, callback.WaitForResult());
9485
9486 const HttpResponseInfo* response = trans->GetResponseInfo();
9487 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509488 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559489 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9490
9491 std::string response_data;
9492 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9493 EXPECT_EQ("hello world", response_data);
9494
[email protected]90499482013-06-01 00:39:509495 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:559496
[email protected]49639fa2011-12-20 23:22:419497 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559498 EXPECT_EQ(ERR_IO_PENDING, rv);
9499 EXPECT_EQ(OK, callback.WaitForResult());
9500
9501 response = trans->GetResponseInfo();
9502 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509503 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559504 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9505 EXPECT_FALSE(response->was_fetched_via_spdy);
9506 EXPECT_FALSE(response->was_npn_negotiated);
9507
9508 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9509 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:559510}
9511
[email protected]631f1322010-04-30 17:59:119512class CapturingProxyResolver : public ProxyResolver {
9513 public:
sammce90c9212015-05-27 23:43:359514 CapturingProxyResolver() {}
dchengb03027d2014-10-21 12:00:209515 ~CapturingProxyResolver() override {}
[email protected]631f1322010-04-30 17:59:119516
dchengb03027d2014-10-21 12:00:209517 int GetProxyForURL(const GURL& url,
9518 ProxyInfo* results,
9519 const CompletionCallback& callback,
9520 RequestHandle* request,
9521 const BoundNetLog& net_log) override {
[email protected]fae7669f2010-08-02 21:49:409522 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
9523 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:429524 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:119525 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:429526 return OK;
[email protected]631f1322010-04-30 17:59:119527 }
9528
dchengb03027d2014-10-21 12:00:209529 void CancelRequest(RequestHandle request) override { NOTREACHED(); }
[email protected]631f1322010-04-30 17:59:119530
dchengb03027d2014-10-21 12:00:209531 LoadState GetLoadState(RequestHandle request) const override {
[email protected]f2c971f2011-11-08 00:33:179532 NOTREACHED();
9533 return LOAD_STATE_IDLE;
9534 }
9535
[email protected]24476402010-07-20 20:55:179536 const std::vector<GURL>& resolved() const { return resolved_; }
9537
9538 private:
[email protected]631f1322010-04-30 17:59:119539 std::vector<GURL> resolved_;
9540
9541 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
9542};
9543
sammce64b2362015-04-29 03:50:239544class CapturingProxyResolverFactory : public ProxyResolverFactory {
9545 public:
9546 explicit CapturingProxyResolverFactory(CapturingProxyResolver* resolver)
9547 : ProxyResolverFactory(false), resolver_(resolver) {}
9548
9549 int CreateProxyResolver(
9550 const scoped_refptr<ProxyResolverScriptData>& pac_script,
9551 scoped_ptr<ProxyResolver>* resolver,
9552 const net::CompletionCallback& callback,
9553 scoped_ptr<Request>* request) override {
9554 resolver->reset(new ForwardingProxyResolver(resolver_));
9555 return OK;
9556 }
9557
9558 private:
9559 ProxyResolver* resolver_;
9560};
9561
[email protected]23e482282013-06-14 16:08:029562TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239563 UseAlternateProtocolForTunneledNpnSpdy) {
[email protected]d7599122014-05-24 03:37:239564 session_deps_.use_alternate_protocols = true;
9565 session_deps_.next_protos = SpdyNextProtos();
[email protected]631f1322010-04-30 17:59:119566
9567 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:429568 proxy_config.set_auto_detect(true);
9569 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:119570
sammc5dd160c2015-04-02 02:43:139571 CapturingProxyResolver capturing_proxy_resolver;
[email protected]bb88e1d32013-05-03 23:11:079572 session_deps_.proxy_service.reset(new ProxyService(
sammc5dd160c2015-04-02 02:43:139573 new ProxyConfigServiceFixed(proxy_config),
9574 make_scoped_ptr(
sammce64b2362015-04-29 03:50:239575 new CapturingProxyResolverFactory(&capturing_proxy_resolver)),
[email protected]66761b952010-06-25 21:30:389576 NULL));
vishal.b62985ca92015-04-17 08:45:519577 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079578 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:119579
9580 HttpRequestInfo request;
9581 request.method = "GET";
bncce36dca22015-04-21 22:11:239582 request.url = GURL("http://www.example.org/");
[email protected]631f1322010-04-30 17:59:119583 request.load_flags = 0;
9584
[email protected]8a0fc822013-06-27 20:52:439585 std::string alternate_protocol_http_header =
9586 GetAlternateProtocolHttpHeader();
9587
[email protected]631f1322010-04-30 17:59:119588 MockRead data_reads[] = {
9589 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439590 MockRead(alternate_protocol_http_header.c_str()),
[email protected]631f1322010-04-30 17:59:119591 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:179592 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:069593 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:119594 };
9595
9596 StaticSocketDataProvider first_transaction(
9597 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079598 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]631f1322010-04-30 17:59:119599
[email protected]8ddf8322012-02-23 18:08:069600 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029601 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:239602 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
9603 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:079604 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]631f1322010-04-30 17:59:119605
[email protected]cdf8f7e72013-05-23 10:56:469606 scoped_ptr<SpdyFrame> req(
9607 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]631f1322010-04-30 17:59:119608 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:139609 MockWrite(ASYNC, 0,
9610 "CONNECT www.example.org:443 HTTP/1.1\r\n"
9611 "Host: www.example.org\r\n"
9612 "Proxy-Connection: keep-alive\r\n\r\n"),
9613 CreateMockWrite(*req, 2),
[email protected]631f1322010-04-30 17:59:119614 };
9615
[email protected]d911f1b2010-05-05 22:39:429616 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
9617
[email protected]23e482282013-06-14 16:08:029618 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9619 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]631f1322010-04-30 17:59:119620 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:139621 MockRead(ASYNC, 1, kCONNECTResponse),
9622 CreateMockRead(*resp.get(), 3),
9623 CreateMockRead(*data.get(), 4),
9624 MockRead(ASYNC, ERR_IO_PENDING, 5),
[email protected]631f1322010-04-30 17:59:119625 };
9626
rch8e6c6c42015-05-01 14:05:139627 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9628 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079629 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:119630
[email protected]d973e99a2012-02-17 21:02:369631 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559632 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
9633 NULL, 0, NULL, 0);
9634 hanging_non_alternate_protocol_socket.set_connect_data(
9635 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:079636 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:559637 &hanging_non_alternate_protocol_socket);
9638
[email protected]49639fa2011-12-20 23:22:419639 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:119640
[email protected]bb88e1d32013-05-03 23:11:079641 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369642 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509643 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:119644
[email protected]49639fa2011-12-20 23:22:419645 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:119646 EXPECT_EQ(ERR_IO_PENDING, rv);
9647 EXPECT_EQ(OK, callback.WaitForResult());
9648
9649 const HttpResponseInfo* response = trans->GetResponseInfo();
9650 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509651 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]631f1322010-04-30 17:59:119652 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539653 EXPECT_FALSE(response->was_fetched_via_spdy);
9654 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:119655
9656 std::string response_data;
9657 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9658 EXPECT_EQ("hello world", response_data);
9659
[email protected]90499482013-06-01 00:39:509660 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:119661
[email protected]49639fa2011-12-20 23:22:419662 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 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_TRUE(response->was_fetched_via_spdy);
9671 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:119672
9673 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9674 EXPECT_EQ("hello!", response_data);
sammc5dd160c2015-04-02 02:43:139675 ASSERT_EQ(3u, capturing_proxy_resolver.resolved().size());
bncce36dca22015-04-21 22:11:239676 EXPECT_EQ("http://www.example.org/",
sammc5dd160c2015-04-02 02:43:139677 capturing_proxy_resolver.resolved()[0].spec());
bncce36dca22015-04-21 22:11:239678 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:139679 capturing_proxy_resolver.resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:119680
[email protected]029c83b62013-01-24 05:28:209681 LoadTimingInfo load_timing_info;
9682 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
9683 TestLoadTimingNotReusedWithPac(load_timing_info,
9684 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:119685}
[email protected]631f1322010-04-30 17:59:119686
[email protected]23e482282013-06-14 16:08:029687TEST_P(HttpNetworkTransactionTest,
[email protected]2ff8b312010-04-26 22:20:549688 UseAlternateProtocolForNpnSpdyWithExistingSpdySession) {
[email protected]d7599122014-05-24 03:37:239689 session_deps_.use_alternate_protocols = true;
9690 session_deps_.next_protos = SpdyNextProtos();
[email protected]2ff8b312010-04-26 22:20:549691
9692 HttpRequestInfo request;
9693 request.method = "GET";
bncce36dca22015-04-21 22:11:239694 request.url = GURL("http://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:549695 request.load_flags = 0;
9696
[email protected]8a0fc822013-06-27 20:52:439697 std::string alternate_protocol_http_header =
9698 GetAlternateProtocolHttpHeader();
9699
[email protected]2ff8b312010-04-26 22:20:549700 MockRead data_reads[] = {
9701 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439702 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2ff8b312010-04-26 22:20:549703 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069704 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:549705 };
9706
9707 StaticSocketDataProvider first_transaction(
9708 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079709 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:549710
[email protected]8ddf8322012-02-23 18:08:069711 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029712 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:239713 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
9714 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:079715 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:549716
[email protected]cdf8f7e72013-05-23 10:56:469717 scoped_ptr<SpdyFrame> req(
9718 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
rch8e6c6c42015-05-01 14:05:139719 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]2ff8b312010-04-26 22:20:549720
[email protected]23e482282013-06-14 16:08:029721 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9722 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:549723 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:139724 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:549725 };
9726
rch8e6c6c42015-05-01 14:05:139727 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9728 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079729 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:549730
[email protected]83039bb2011-12-09 18:43:559731 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:549732
[email protected]bb88e1d32013-05-03 23:11:079733 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:549734
[email protected]262eec82013-03-19 21:01:369735 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509736 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:549737
[email protected]49639fa2011-12-20 23:22:419738 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:549739 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:419740 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:549741
9742 const HttpResponseInfo* response = trans->GetResponseInfo();
9743 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509744 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:549745 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9746
9747 std::string response_data;
9748 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9749 EXPECT_EQ("hello world", response_data);
9750
9751 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:239752 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:409753 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:539754 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:279755 base::WeakPtr<SpdySession> spdy_session =
[email protected]41d64e82013-07-03 22:44:269756 CreateSecureSpdySession(session, key, BoundNetLog());
[email protected]02b0c342010-09-25 21:09:389757
[email protected]90499482013-06-01 00:39:509758 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:549759
[email protected]49639fa2011-12-20 23:22:419760 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:549761 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:419762 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:549763
9764 response = trans->GetResponseInfo();
9765 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509766 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:549767 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539768 EXPECT_TRUE(response->was_fetched_via_spdy);
9769 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:549770
9771 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9772 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:429773}
9774
[email protected]044de0642010-06-17 10:42:159775// GenerateAuthToken is a mighty big test.
9776// It tests all permutation of GenerateAuthToken behavior:
9777// - Synchronous and Asynchronous completion.
9778// - OK or error on completion.
9779// - Direct connection, non-authenticating proxy, and authenticating proxy.
9780// - HTTP or HTTPS backend (to include proxy tunneling).
9781// - Non-authenticating and authenticating backend.
9782//
[email protected]fe3b7dc2012-02-03 19:52:099783// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:159784// problems generating an auth token for an authenticating proxy, we don't
9785// need to test all permutations of the backend server).
9786//
9787// The test proceeds by going over each of the configuration cases, and
9788// potentially running up to three rounds in each of the tests. The TestConfig
9789// specifies both the configuration for the test as well as the expectations
9790// for the results.
[email protected]23e482282013-06-14 16:08:029791TEST_P(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:509792 static const char kServer[] = "http://www.example.com";
9793 static const char kSecureServer[] = "https://www.example.com";
9794 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:159795 const int kAuthErr = ERR_INVALID_AUTH_CREDENTIALS;
9796
9797 enum AuthTiming {
9798 AUTH_NONE,
9799 AUTH_SYNC,
9800 AUTH_ASYNC,
9801 };
9802
9803 const MockWrite kGet(
9804 "GET / HTTP/1.1\r\n"
9805 "Host: www.example.com\r\n"
9806 "Connection: keep-alive\r\n\r\n");
9807 const MockWrite kGetProxy(
9808 "GET http://www.example.com/ HTTP/1.1\r\n"
9809 "Host: www.example.com\r\n"
9810 "Proxy-Connection: keep-alive\r\n\r\n");
9811 const MockWrite kGetAuth(
9812 "GET / HTTP/1.1\r\n"
9813 "Host: www.example.com\r\n"
9814 "Connection: keep-alive\r\n"
9815 "Authorization: auth_token\r\n\r\n");
9816 const MockWrite kGetProxyAuth(
9817 "GET http://www.example.com/ HTTP/1.1\r\n"
9818 "Host: www.example.com\r\n"
9819 "Proxy-Connection: keep-alive\r\n"
9820 "Proxy-Authorization: auth_token\r\n\r\n");
9821 const MockWrite kGetAuthThroughProxy(
9822 "GET http://www.example.com/ HTTP/1.1\r\n"
9823 "Host: www.example.com\r\n"
9824 "Proxy-Connection: keep-alive\r\n"
9825 "Authorization: auth_token\r\n\r\n");
9826 const MockWrite kGetAuthWithProxyAuth(
9827 "GET http://www.example.com/ HTTP/1.1\r\n"
9828 "Host: www.example.com\r\n"
9829 "Proxy-Connection: keep-alive\r\n"
9830 "Proxy-Authorization: auth_token\r\n"
9831 "Authorization: auth_token\r\n\r\n");
9832 const MockWrite kConnect(
9833 "CONNECT www.example.com:443 HTTP/1.1\r\n"
9834 "Host: www.example.com\r\n"
9835 "Proxy-Connection: keep-alive\r\n\r\n");
9836 const MockWrite kConnectProxyAuth(
9837 "CONNECT www.example.com:443 HTTP/1.1\r\n"
9838 "Host: www.example.com\r\n"
9839 "Proxy-Connection: keep-alive\r\n"
9840 "Proxy-Authorization: auth_token\r\n\r\n");
9841
9842 const MockRead kSuccess(
9843 "HTTP/1.1 200 OK\r\n"
9844 "Content-Type: text/html; charset=iso-8859-1\r\n"
9845 "Content-Length: 3\r\n\r\n"
9846 "Yes");
9847 const MockRead kFailure(
9848 "Should not be called.");
9849 const MockRead kServerChallenge(
9850 "HTTP/1.1 401 Unauthorized\r\n"
9851 "WWW-Authenticate: Mock realm=server\r\n"
9852 "Content-Type: text/html; charset=iso-8859-1\r\n"
9853 "Content-Length: 14\r\n\r\n"
9854 "Unauthorized\r\n");
9855 const MockRead kProxyChallenge(
9856 "HTTP/1.1 407 Unauthorized\r\n"
9857 "Proxy-Authenticate: Mock realm=proxy\r\n"
9858 "Proxy-Connection: close\r\n"
9859 "Content-Type: text/html; charset=iso-8859-1\r\n"
9860 "Content-Length: 14\r\n\r\n"
9861 "Unauthorized\r\n");
9862 const MockRead kProxyConnected(
9863 "HTTP/1.1 200 Connection Established\r\n\r\n");
9864
9865 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
9866 // no constructors, but the C++ compiler on Windows warns about
9867 // unspecified data in compound literals. So, moved to using constructors,
9868 // and TestRound's created with the default constructor should not be used.
9869 struct TestRound {
9870 TestRound()
9871 : expected_rv(ERR_UNEXPECTED),
9872 extra_write(NULL),
9873 extra_read(NULL) {
9874 }
9875 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
9876 int expected_rv_arg)
9877 : write(write_arg),
9878 read(read_arg),
9879 expected_rv(expected_rv_arg),
9880 extra_write(NULL),
9881 extra_read(NULL) {
9882 }
9883 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
9884 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:019885 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:159886 : write(write_arg),
9887 read(read_arg),
9888 expected_rv(expected_rv_arg),
9889 extra_write(extra_write_arg),
9890 extra_read(extra_read_arg) {
9891 }
9892 MockWrite write;
9893 MockRead read;
9894 int expected_rv;
9895 const MockWrite* extra_write;
9896 const MockRead* extra_read;
9897 };
9898
9899 static const int kNoSSL = 500;
9900
9901 struct TestConfig {
thestig9d3bb0c2015-01-24 00:49:519902 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:159903 AuthTiming proxy_auth_timing;
9904 int proxy_auth_rv;
thestig9d3bb0c2015-01-24 00:49:519905 const char* const server_url;
[email protected]044de0642010-06-17 10:42:159906 AuthTiming server_auth_timing;
9907 int server_auth_rv;
9908 int num_auth_rounds;
9909 int first_ssl_round;
9910 TestRound rounds[3];
9911 } test_configs[] = {
9912 // Non-authenticating HTTP server with a direct connection.
9913 { NULL, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
9914 { TestRound(kGet, kSuccess, OK)}},
9915 // Authenticating HTTP server with a direct connection.
9916 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
9917 { TestRound(kGet, kServerChallenge, OK),
9918 TestRound(kGetAuth, kSuccess, OK)}},
9919 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
9920 { TestRound(kGet, kServerChallenge, OK),
9921 TestRound(kGetAuth, kFailure, kAuthErr)}},
9922 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
9923 { TestRound(kGet, kServerChallenge, OK),
9924 TestRound(kGetAuth, kSuccess, OK)}},
9925 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
9926 { TestRound(kGet, kServerChallenge, OK),
9927 TestRound(kGetAuth, kFailure, kAuthErr)}},
9928 // Non-authenticating HTTP server through a non-authenticating proxy.
9929 { kProxy, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
9930 { TestRound(kGetProxy, kSuccess, OK)}},
9931 // Authenticating HTTP server through a non-authenticating proxy.
9932 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
9933 { TestRound(kGetProxy, kServerChallenge, OK),
9934 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
9935 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
9936 { TestRound(kGetProxy, kServerChallenge, OK),
9937 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
9938 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
9939 { TestRound(kGetProxy, kServerChallenge, OK),
9940 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
9941 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
9942 { TestRound(kGetProxy, kServerChallenge, OK),
9943 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
9944 // Non-authenticating HTTP server through an authenticating proxy.
9945 { kProxy, AUTH_SYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
9946 { TestRound(kGetProxy, kProxyChallenge, OK),
9947 TestRound(kGetProxyAuth, kSuccess, OK)}},
9948 { kProxy, AUTH_SYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
9949 { TestRound(kGetProxy, kProxyChallenge, OK),
9950 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
9951 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
9952 { TestRound(kGetProxy, kProxyChallenge, OK),
9953 TestRound(kGetProxyAuth, kSuccess, OK)}},
9954 { kProxy, AUTH_ASYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
9955 { TestRound(kGetProxy, kProxyChallenge, OK),
9956 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
9957 // Authenticating HTTP server through an authenticating proxy.
9958 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
9959 { TestRound(kGetProxy, kProxyChallenge, OK),
9960 TestRound(kGetProxyAuth, kServerChallenge, OK),
9961 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9962 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
9963 { TestRound(kGetProxy, kProxyChallenge, OK),
9964 TestRound(kGetProxyAuth, kServerChallenge, OK),
9965 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9966 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
9967 { TestRound(kGetProxy, kProxyChallenge, OK),
9968 TestRound(kGetProxyAuth, kServerChallenge, OK),
9969 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9970 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
9971 { TestRound(kGetProxy, kProxyChallenge, OK),
9972 TestRound(kGetProxyAuth, kServerChallenge, OK),
9973 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9974 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
9975 { TestRound(kGetProxy, kProxyChallenge, OK),
9976 TestRound(kGetProxyAuth, kServerChallenge, OK),
9977 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9978 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
9979 { TestRound(kGetProxy, kProxyChallenge, OK),
9980 TestRound(kGetProxyAuth, kServerChallenge, OK),
9981 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9982 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
9983 { TestRound(kGetProxy, kProxyChallenge, OK),
9984 TestRound(kGetProxyAuth, kServerChallenge, OK),
9985 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9986 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
9987 { TestRound(kGetProxy, kProxyChallenge, OK),
9988 TestRound(kGetProxyAuth, kServerChallenge, OK),
9989 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9990 // Non-authenticating HTTPS server with a direct connection.
9991 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
9992 { TestRound(kGet, kSuccess, OK)}},
9993 // Authenticating HTTPS server with a direct connection.
9994 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
9995 { TestRound(kGet, kServerChallenge, OK),
9996 TestRound(kGetAuth, kSuccess, OK)}},
9997 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
9998 { TestRound(kGet, kServerChallenge, OK),
9999 TestRound(kGetAuth, kFailure, kAuthErr)}},
10000 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
10001 { TestRound(kGet, kServerChallenge, OK),
10002 TestRound(kGetAuth, kSuccess, OK)}},
10003 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
10004 { TestRound(kGet, kServerChallenge, OK),
10005 TestRound(kGetAuth, kFailure, kAuthErr)}},
10006 // Non-authenticating HTTPS server with a non-authenticating proxy.
10007 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
10008 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
10009 // Authenticating HTTPS server through a non-authenticating proxy.
10010 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
10011 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
10012 TestRound(kGetAuth, kSuccess, OK)}},
10013 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
10014 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
10015 TestRound(kGetAuth, kFailure, kAuthErr)}},
10016 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
10017 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
10018 TestRound(kGetAuth, kSuccess, OK)}},
10019 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
10020 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
10021 TestRound(kGetAuth, kFailure, kAuthErr)}},
10022 // Non-Authenticating HTTPS server through an authenticating proxy.
10023 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
10024 { TestRound(kConnect, kProxyChallenge, OK),
10025 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
10026 { kProxy, AUTH_SYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
10027 { TestRound(kConnect, kProxyChallenge, OK),
10028 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
10029 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
10030 { TestRound(kConnect, kProxyChallenge, OK),
10031 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
10032 { kProxy, AUTH_ASYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
10033 { TestRound(kConnect, kProxyChallenge, OK),
10034 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
10035 // Authenticating HTTPS server through an authenticating proxy.
10036 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
10037 { TestRound(kConnect, kProxyChallenge, OK),
10038 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10039 &kGet, &kServerChallenge),
10040 TestRound(kGetAuth, kSuccess, OK)}},
10041 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
10042 { TestRound(kConnect, kProxyChallenge, OK),
10043 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10044 &kGet, &kServerChallenge),
10045 TestRound(kGetAuth, kFailure, kAuthErr)}},
10046 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
10047 { TestRound(kConnect, kProxyChallenge, OK),
10048 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10049 &kGet, &kServerChallenge),
10050 TestRound(kGetAuth, kSuccess, OK)}},
10051 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
10052 { TestRound(kConnect, kProxyChallenge, OK),
10053 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10054 &kGet, &kServerChallenge),
10055 TestRound(kGetAuth, kFailure, kAuthErr)}},
10056 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
10057 { TestRound(kConnect, kProxyChallenge, OK),
10058 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10059 &kGet, &kServerChallenge),
10060 TestRound(kGetAuth, kSuccess, OK)}},
10061 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
10062 { TestRound(kConnect, kProxyChallenge, OK),
10063 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10064 &kGet, &kServerChallenge),
10065 TestRound(kGetAuth, kFailure, kAuthErr)}},
10066 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
10067 { TestRound(kConnect, kProxyChallenge, OK),
10068 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10069 &kGet, &kServerChallenge),
10070 TestRound(kGetAuth, kSuccess, OK)}},
10071 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
10072 { TestRound(kConnect, kProxyChallenge, OK),
10073 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10074 &kGet, &kServerChallenge),
10075 TestRound(kGetAuth, kFailure, kAuthErr)}},
10076 };
10077
viettrungluue4a8b882014-10-16 06:17:3810078 for (size_t i = 0; i < arraysize(test_configs); ++i) {
[email protected]2d01c262011-08-11 23:07:0810079 HttpAuthHandlerMock::Factory* auth_factory(
10080 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0710081 session_deps_.http_auth_handler_factory.reset(auth_factory);
[email protected]044de0642010-06-17 10:42:1510082 const TestConfig& test_config = test_configs[i];
[email protected]65d34382010-07-01 18:12:2610083
10084 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:1510085 if (test_config.proxy_auth_timing != AUTH_NONE) {
[email protected]2d01c262011-08-11 23:07:0810086 for (int n = 0; n < 2; n++) {
10087 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
10088 std::string auth_challenge = "Mock realm=proxy";
10089 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:2410090 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
10091 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:0810092 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
10093 origin, BoundNetLog());
10094 auth_handler->SetGenerateExpectation(
10095 test_config.proxy_auth_timing == AUTH_ASYNC,
10096 test_config.proxy_auth_rv);
10097 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
10098 }
[email protected]044de0642010-06-17 10:42:1510099 }
10100 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:0010101 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:1510102 std::string auth_challenge = "Mock realm=server";
10103 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:2410104 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
10105 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:1510106 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
10107 origin, BoundNetLog());
10108 auth_handler->SetGenerateExpectation(
10109 test_config.server_auth_timing == AUTH_ASYNC,
10110 test_config.server_auth_rv);
[email protected]2d01c262011-08-11 23:07:0810111 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:1510112 }
10113 if (test_config.proxy_url) {
[email protected]bb88e1d32013-05-03 23:11:0710114 session_deps_.proxy_service.reset(
[email protected]6104ea5d2011-04-27 21:37:1210115 ProxyService::CreateFixed(test_config.proxy_url));
[email protected]044de0642010-06-17 10:42:1510116 } else {
[email protected]bb88e1d32013-05-03 23:11:0710117 session_deps_.proxy_service.reset(ProxyService::CreateDirect());
[email protected]044de0642010-06-17 10:42:1510118 }
10119
10120 HttpRequestInfo request;
10121 request.method = "GET";
10122 request.url = GURL(test_config.server_url);
10123 request.load_flags = 0;
10124
[email protected]bb88e1d32013-05-03 23:11:0710125 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
dcheng48459ac22014-08-26 00:46:4110126 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]044de0642010-06-17 10:42:1510127
rchcb68dc62015-05-21 04:45:3610128 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
10129
10130 std::vector<std::vector<MockRead>> mock_reads(1);
10131 std::vector<std::vector<MockWrite>> mock_writes(1);
[email protected]044de0642010-06-17 10:42:1510132 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
10133 const TestRound& read_write_round = test_config.rounds[round];
10134
10135 // Set up expected reads and writes.
rchcb68dc62015-05-21 04:45:3610136 mock_reads.back().push_back(read_write_round.read);
10137 mock_writes.back().push_back(read_write_round.write);
10138
10139 // kProxyChallenge uses Proxy-Connection: close which means that the
10140 // socket is closed and a new one will be created for the next request.
10141 if (read_write_round.read.data == kProxyChallenge.data &&
10142 read_write_round.write.data != kConnect.data) {
10143 mock_reads.push_back(std::vector<MockRead>());
10144 mock_writes.push_back(std::vector<MockWrite>());
[email protected]044de0642010-06-17 10:42:1510145 }
10146
rchcb68dc62015-05-21 04:45:3610147 if (read_write_round.extra_read) {
10148 mock_reads.back().push_back(*read_write_round.extra_read);
[email protected]044de0642010-06-17 10:42:1510149 }
rchcb68dc62015-05-21 04:45:3610150 if (read_write_round.extra_write) {
10151 mock_writes.back().push_back(*read_write_round.extra_write);
10152 }
[email protected]044de0642010-06-17 10:42:1510153
10154 // Add an SSL sequence if necessary.
[email protected]044de0642010-06-17 10:42:1510155 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0710156 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1510157 &ssl_socket_data_provider);
rchcb68dc62015-05-21 04:45:3610158 }
[email protected]044de0642010-06-17 10:42:1510159
rchcb68dc62015-05-21 04:45:3610160 ScopedVector<StaticSocketDataProvider> data_providers;
10161 for (size_t i = 0; i < mock_reads.size(); ++i) {
10162 data_providers.push_back(new StaticSocketDataProvider(
10163 vector_as_array(&mock_reads[i]), mock_reads[i].size(),
10164 vector_as_array(&mock_writes[i]), mock_writes[i].size()));
10165 session_deps_.socket_factory->AddSocketDataProvider(
10166 data_providers.back());
10167 }
10168
10169 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
10170 const TestRound& read_write_round = test_config.rounds[round];
[email protected]044de0642010-06-17 10:42:1510171 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4110172 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1510173 int rv;
10174 if (round == 0) {
[email protected]49639fa2011-12-20 23:22:4110175 rv = trans.Start(&request, callback.callback(), BoundNetLog());
[email protected]044de0642010-06-17 10:42:1510176 } else {
[email protected]49639fa2011-12-20 23:22:4110177 rv = trans.RestartWithAuth(
10178 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1510179 }
10180 if (rv == ERR_IO_PENDING)
10181 rv = callback.WaitForResult();
10182
10183 // Compare results with expected data.
10184 EXPECT_EQ(read_write_round.expected_rv, rv);
[email protected]0b0bf032010-09-21 18:08:5010185 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttlec0c828492015-05-15 01:25:5510186 if (read_write_round.expected_rv != OK) {
[email protected]044de0642010-06-17 10:42:1510187 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
10188 continue;
10189 }
10190 if (round + 1 < test_config.num_auth_rounds) {
10191 EXPECT_FALSE(response->auth_challenge.get() == NULL);
10192 } else {
10193 EXPECT_TRUE(response->auth_challenge.get() == NULL);
10194 }
10195 }
[email protected]e5ae96a2010-04-14 20:12:4510196 }
10197}
10198
[email protected]23e482282013-06-14 16:08:0210199TEST_P(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1410200 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1410201 HttpAuthHandlerMock::Factory* auth_factory(
10202 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0710203 session_deps_.http_auth_handler_factory.reset(auth_factory);
10204 session_deps_.proxy_service.reset(ProxyService::CreateDirect());
10205 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
10206 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:1410207
10208 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
10209 auth_handler->set_connection_based(true);
10210 std::string auth_challenge = "Mock realm=server";
10211 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2410212 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
10213 auth_challenge.end());
[email protected]c871bce92010-07-15 21:51:1410214 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
10215 origin, BoundNetLog());
[email protected]2d01c262011-08-11 23:07:0810216 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1410217
[email protected]c871bce92010-07-15 21:51:1410218 int rv = OK;
10219 const HttpResponseInfo* response = NULL;
10220 HttpRequestInfo request;
10221 request.method = "GET";
10222 request.url = origin;
10223 request.load_flags = 0;
[email protected]cb9bf6ca2011-01-28 13:15:2710224
[email protected]bb88e1d32013-05-03 23:11:0710225 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1010226
10227 // Use a TCP Socket Pool with only one connection per group. This is used
10228 // to validate that the TCP socket is not released to the pool between
10229 // each round of multi-round authentication.
10230 HttpNetworkSessionPeer session_peer(session);
[email protected]ab739042011-04-07 15:22:2810231 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:1010232 50, // Max sockets for pool
10233 1, // Max sockets per group
[email protected]bb88e1d32013-05-03 23:11:0710234 session_deps_.host_resolver.get(),
10235 session_deps_.socket_factory.get(),
10236 session_deps_.net_log);
[email protected]831e4a32013-11-14 02:14:4410237 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
10238 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:0210239 mock_pool_manager->SetTransportSocketPool(transport_pool);
dchenge3d1ddc2014-10-15 19:30:5110240 session_peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]7ef4cbbb2011-02-06 11:19:1010241
[email protected]262eec82013-03-19 21:01:3610242 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010243 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110244 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1410245
10246 const MockWrite kGet(
10247 "GET / HTTP/1.1\r\n"
10248 "Host: www.example.com\r\n"
10249 "Connection: keep-alive\r\n\r\n");
10250 const MockWrite kGetAuth(
10251 "GET / HTTP/1.1\r\n"
10252 "Host: www.example.com\r\n"
10253 "Connection: keep-alive\r\n"
10254 "Authorization: auth_token\r\n\r\n");
10255
10256 const MockRead kServerChallenge(
10257 "HTTP/1.1 401 Unauthorized\r\n"
10258 "WWW-Authenticate: Mock realm=server\r\n"
10259 "Content-Type: text/html; charset=iso-8859-1\r\n"
10260 "Content-Length: 14\r\n\r\n"
10261 "Unauthorized\r\n");
10262 const MockRead kSuccess(
10263 "HTTP/1.1 200 OK\r\n"
10264 "Content-Type: text/html; charset=iso-8859-1\r\n"
10265 "Content-Length: 3\r\n\r\n"
10266 "Yes");
10267
10268 MockWrite writes[] = {
10269 // First round
10270 kGet,
10271 // Second round
10272 kGetAuth,
10273 // Third round
10274 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3010275 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1010276 kGetAuth,
10277 // Competing request
10278 kGet,
[email protected]c871bce92010-07-15 21:51:1410279 };
10280 MockRead reads[] = {
10281 // First round
10282 kServerChallenge,
10283 // Second round
10284 kServerChallenge,
10285 // Third round
[email protected]eca50e122010-09-11 14:03:3010286 kServerChallenge,
10287 // Fourth round
[email protected]c871bce92010-07-15 21:51:1410288 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1010289 // Competing response
10290 kSuccess,
[email protected]c871bce92010-07-15 21:51:1410291 };
10292 StaticSocketDataProvider data_provider(reads, arraysize(reads),
10293 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:0710294 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1410295
thestig9d3bb0c2015-01-24 00:49:5110296 const char kSocketGroup[] = "www.example.com:80";
[email protected]7ef4cbbb2011-02-06 11:19:1010297
10298 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1410299 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4110300 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]c871bce92010-07-15 21:51:1410301 if (rv == ERR_IO_PENDING)
10302 rv = callback.WaitForResult();
10303 EXPECT_EQ(OK, rv);
10304 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010305 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:1410306 EXPECT_FALSE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2810307 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1410308
[email protected]7ef4cbbb2011-02-06 11:19:1010309 // In between rounds, another request comes in for the same domain.
10310 // It should not be able to grab the TCP socket that trans has already
10311 // claimed.
10312 scoped_ptr<HttpTransaction> trans_compete(
[email protected]90499482013-06-01 00:39:5010313 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110314 TestCompletionCallback callback_compete;
10315 rv = trans_compete->Start(
10316 &request, callback_compete.callback(), BoundNetLog());
[email protected]7ef4cbbb2011-02-06 11:19:1010317 EXPECT_EQ(ERR_IO_PENDING, rv);
10318 // callback_compete.WaitForResult at this point would stall forever,
10319 // since the HttpNetworkTransaction does not release the request back to
10320 // the pool until after authentication completes.
10321
10322 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1410323 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4110324 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1410325 if (rv == ERR_IO_PENDING)
10326 rv = callback.WaitForResult();
10327 EXPECT_EQ(OK, rv);
10328 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010329 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:1410330 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2810331 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1410332
[email protected]7ef4cbbb2011-02-06 11:19:1010333 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1410334 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4110335 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1410336 if (rv == ERR_IO_PENDING)
10337 rv = callback.WaitForResult();
10338 EXPECT_EQ(OK, rv);
10339 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010340 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:1410341 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2810342 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]eca50e122010-09-11 14:03:3010343
[email protected]7ef4cbbb2011-02-06 11:19:1010344 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3010345 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4110346 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3010347 if (rv == ERR_IO_PENDING)
10348 rv = callback.WaitForResult();
10349 EXPECT_EQ(OK, rv);
10350 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010351 ASSERT_TRUE(response != NULL);
[email protected]eca50e122010-09-11 14:03:3010352 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2810353 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1010354
10355 // Read the body since the fourth round was successful. This will also
10356 // release the socket back to the pool.
10357 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
[email protected]90499482013-06-01 00:39:5010358 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1010359 if (rv == ERR_IO_PENDING)
10360 rv = callback.WaitForResult();
10361 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:5010362 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1010363 EXPECT_EQ(0, rv);
10364 // There are still 0 idle sockets, since the trans_compete transaction
10365 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:2810366 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1010367
10368 // The competing request can now finish. Wait for the headers and then
10369 // read the body.
10370 rv = callback_compete.WaitForResult();
10371 EXPECT_EQ(OK, rv);
[email protected]90499482013-06-01 00:39:5010372 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1010373 if (rv == ERR_IO_PENDING)
10374 rv = callback.WaitForResult();
10375 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:5010376 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1010377 EXPECT_EQ(0, rv);
10378
10379 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:2810380 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1410381}
10382
[email protected]65041fa2010-05-21 06:56:5310383// This tests the case that a request is issued via http instead of spdy after
10384// npn is negotiated.
[email protected]23e482282013-06-14 16:08:0210385TEST_P(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]d7599122014-05-24 03:37:2310386 session_deps_.use_alternate_protocols = true;
10387 NextProtoVector next_protos;
[email protected]0ce3af82013-07-22 16:17:1610388 next_protos.push_back(kProtoHTTP11);
[email protected]d7599122014-05-24 03:37:2310389 session_deps_.next_protos = next_protos;
10390
[email protected]65041fa2010-05-21 06:56:5310391 HttpRequestInfo request;
10392 request.method = "GET";
bncce36dca22015-04-21 22:11:2310393 request.url = GURL("https://www.example.org/");
[email protected]65041fa2010-05-21 06:56:5310394 request.load_flags = 0;
10395
10396 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310397 MockWrite(
10398 "GET / HTTP/1.1\r\n"
10399 "Host: www.example.org\r\n"
10400 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5310401 };
10402
[email protected]8a0fc822013-06-27 20:52:4310403 std::string alternate_protocol_http_header =
10404 GetAlternateProtocolHttpHeader();
10405
[email protected]65041fa2010-05-21 06:56:5310406 MockRead data_reads[] = {
10407 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:4310408 MockRead(alternate_protocol_http_header.c_str()),
[email protected]65041fa2010-05-21 06:56:5310409 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610410 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5310411 };
10412
[email protected]8ddf8322012-02-23 18:08:0610413 SSLSocketDataProvider ssl(ASYNC, OK);
davidben6974bf72015-04-27 17:52:4810414 ssl.SetNextProto(kProtoHTTP11);
[email protected]65041fa2010-05-21 06:56:5310415
[email protected]bb88e1d32013-05-03 23:11:0710416 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5310417
10418 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
10419 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0710420 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5310421
[email protected]49639fa2011-12-20 23:22:4110422 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5310423
[email protected]bb88e1d32013-05-03 23:11:0710424 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610425 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010426 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]65041fa2010-05-21 06:56:5310427
[email protected]49639fa2011-12-20 23:22:4110428 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]65041fa2010-05-21 06:56:5310429
10430 EXPECT_EQ(ERR_IO_PENDING, rv);
10431 EXPECT_EQ(OK, callback.WaitForResult());
10432
10433 const HttpResponseInfo* response = trans->GetResponseInfo();
10434 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010435 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]65041fa2010-05-21 06:56:5310436 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10437
10438 std::string response_data;
10439 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10440 EXPECT_EQ("hello world", response_data);
10441
10442 EXPECT_FALSE(response->was_fetched_via_spdy);
10443 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]65041fa2010-05-21 06:56:5310444}
[email protected]26ef6582010-06-24 02:30:4710445
[email protected]23e482282013-06-14 16:08:0210446TEST_P(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:4710447 // Simulate the SSL handshake completing with an NPN negotiation
10448 // followed by an immediate server closing of the socket.
10449 // Fix crash: http://crbug.com/46369
[email protected]d7599122014-05-24 03:37:2310450 session_deps_.use_alternate_protocols = true;
10451 session_deps_.next_protos = SpdyNextProtos();
[email protected]26ef6582010-06-24 02:30:4710452
10453 HttpRequestInfo request;
10454 request.method = "GET";
bncce36dca22015-04-21 22:11:2310455 request.url = GURL("https://www.example.org/");
[email protected]26ef6582010-06-24 02:30:4710456 request.load_flags = 0;
10457
[email protected]8ddf8322012-02-23 18:08:0610458 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210459 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710460 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4710461
[email protected]cdf8f7e72013-05-23 10:56:4610462 scoped_ptr<SpdyFrame> req(
10463 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
rch8e6c6c42015-05-01 14:05:1310464 MockWrite spdy_writes[] = {CreateMockWrite(*req, 1)};
[email protected]26ef6582010-06-24 02:30:4710465
10466 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0610467 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4710468 };
10469
rch8e6c6c42015-05-01 14:05:1310470 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10471 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710472 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4710473
[email protected]49639fa2011-12-20 23:22:4110474 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4710475
[email protected]bb88e1d32013-05-03 23:11:0710476 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610477 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010478 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]26ef6582010-06-24 02:30:4710479
[email protected]49639fa2011-12-20 23:22:4110480 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]26ef6582010-06-24 02:30:4710481 EXPECT_EQ(ERR_IO_PENDING, rv);
10482 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult());
[email protected]26ef6582010-06-24 02:30:4710483}
[email protected]65d34382010-07-01 18:12:2610484
[email protected]795cbf82013-07-22 09:37:2710485// A subclass of HttpAuthHandlerMock that records the request URL when
10486// it gets it. This is needed since the auth handler may get destroyed
10487// before we get a chance to query it.
10488class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
10489 public:
10490 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
10491
dchengb03027d2014-10-21 12:00:2010492 ~UrlRecordingHttpAuthHandlerMock() override {}
[email protected]795cbf82013-07-22 09:37:2710493
10494 protected:
dchengb03027d2014-10-21 12:00:2010495 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
10496 const HttpRequestInfo* request,
10497 const CompletionCallback& callback,
10498 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2710499 *url_ = request->url;
10500 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
10501 credentials, request, callback, auth_token);
10502 }
10503
10504 private:
10505 GURL* url_;
10506};
10507
[email protected]23e482282013-06-14 16:08:0210508TEST_P(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) {
[email protected]f45c1ee2010-08-03 00:54:3010509 // This test ensures that the URL passed into the proxy is upgraded
10510 // to https when doing an Alternate Protocol upgrade.
[email protected]d7599122014-05-24 03:37:2310511 session_deps_.use_alternate_protocols = true;
10512 session_deps_.next_protos = SpdyNextProtos();
[email protected]f45c1ee2010-08-03 00:54:3010513
[email protected]bb88e1d32013-05-03 23:11:0710514 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:2010515 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
vishal.b62985ca92015-04-17 08:45:5110516 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710517 session_deps_.net_log = &net_log;
[email protected]795cbf82013-07-22 09:37:2710518 GURL request_url;
10519 {
10520 HttpAuthHandlerMock::Factory* auth_factory =
10521 new HttpAuthHandlerMock::Factory();
10522 UrlRecordingHttpAuthHandlerMock* auth_handler =
10523 new UrlRecordingHttpAuthHandlerMock(&request_url);
10524 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
10525 auth_factory->set_do_init_from_challenge(true);
10526 session_deps_.http_auth_handler_factory.reset(auth_factory);
10527 }
[email protected]f45c1ee2010-08-03 00:54:3010528
10529 HttpRequestInfo request;
10530 request.method = "GET";
bncce36dca22015-04-21 22:11:2310531 request.url = GURL("http://www.example.org");
[email protected]f45c1ee2010-08-03 00:54:3010532 request.load_flags = 0;
10533
10534 // First round goes unauthenticated through the proxy.
10535 MockWrite data_writes_1[] = {
bncce36dca22015-04-21 22:11:2310536 MockWrite(
10537 "GET http://www.example.org/ HTTP/1.1\r\n"
10538 "Host: www.example.org\r\n"
10539 "Proxy-Connection: keep-alive\r\n"
10540 "\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3010541 };
10542 MockRead data_reads_1[] = {
[email protected]8ddf8322012-02-23 18:08:0610543 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
bnc33b8cef42014-11-19 17:30:3810544 MockRead("HTTP/1.1 200 OK\r\n"),
10545 MockRead("Alternate-Protocol: 443:"),
10546 MockRead(GetAlternateProtocolFromParam()),
10547 MockRead("\r\n"),
10548 MockRead("Proxy-Connection: close\r\n"),
10549 MockRead("\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3010550 };
10551 StaticSocketDataProvider data_1(data_reads_1, arraysize(data_reads_1),
10552 data_writes_1, arraysize(data_writes_1));
10553
bncce36dca22015-04-21 22:11:2310554 // Second round tries to tunnel to www.example.org due to the
[email protected]f45c1ee2010-08-03 00:54:3010555 // Alternate-Protocol announcement in the first round. It fails due
10556 // to a proxy authentication challenge.
bncce36dca22015-04-21 22:11:2310557 // After the failure, a tunnel is established to www.example.org using
[email protected]394816e92010-08-03 07:38:5910558 // Proxy-Authorization headers. There is then a SPDY request round.
10559 //
[email protected]fe3b7dc2012-02-03 19:52:0910560 // NOTE: Despite the "Proxy-Connection: Close", these are done on the
10561 // same MockTCPClientSocket since the underlying HttpNetworkClientSocket
10562 // does a Disconnect and Connect on the same socket, rather than trying
10563 // to obtain a new one.
10564 //
[email protected]394816e92010-08-03 07:38:5910565 // NOTE: Originally, the proxy response to the second CONNECT request
10566 // simply returned another 407 so the unit test could skip the SSL connection
10567 // establishment and SPDY framing issues. Alas, the
10568 // retry-http-when-alternate-protocol fails logic kicks in, which was more
[email protected]f45c1ee2010-08-03 00:54:3010569 // complicated to set up expectations for than the SPDY session.
[email protected]394816e92010-08-03 07:38:5910570
[email protected]cdf8f7e72013-05-23 10:56:4610571 scoped_ptr<SpdyFrame> req(
10572 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]23e482282013-06-14 16:08:0210573 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10574 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]f45c1ee2010-08-03 00:54:3010575
[email protected]394816e92010-08-03 07:38:5910576 MockWrite data_writes_2[] = {
bncce36dca22015-04-21 22:11:2310577 // First connection attempt without Proxy-Authorization.
rch8e6c6c42015-05-01 14:05:1310578 MockWrite(ASYNC, 0,
10579 "CONNECT www.example.org:443 HTTP/1.1\r\n"
10580 "Host: www.example.org\r\n"
10581 "Proxy-Connection: keep-alive\r\n"
10582 "\r\n"),
[email protected]394816e92010-08-03 07:38:5910583
bncce36dca22015-04-21 22:11:2310584 // Second connection attempt with Proxy-Authorization.
rch8e6c6c42015-05-01 14:05:1310585 MockWrite(ASYNC, 2,
10586 "CONNECT www.example.org:443 HTTP/1.1\r\n"
10587 "Host: www.example.org\r\n"
10588 "Proxy-Connection: keep-alive\r\n"
10589 "Proxy-Authorization: auth_token\r\n"
10590 "\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3010591
bncce36dca22015-04-21 22:11:2310592 // SPDY request
rch8e6c6c42015-05-01 14:05:1310593 CreateMockWrite(*req, 4),
[email protected]f45c1ee2010-08-03 00:54:3010594 };
[email protected]394816e92010-08-03 07:38:5910595 const char kRejectConnectResponse[] = ("HTTP/1.1 407 Unauthorized\r\n"
10596 "Proxy-Authenticate: Mock\r\n"
10597 "Proxy-Connection: close\r\n"
10598 "\r\n");
10599 const char kAcceptConnectResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
10600 MockRead data_reads_2[] = {
rch8e6c6c42015-05-01 14:05:1310601 // First connection attempt fails
10602 MockRead(ASYNC, kRejectConnectResponse,
10603 arraysize(kRejectConnectResponse) - 1, 1),
[email protected]394816e92010-08-03 07:38:5910604
rch8e6c6c42015-05-01 14:05:1310605 // Second connection attempt passes
10606 MockRead(ASYNC, kAcceptConnectResponse,
10607 arraysize(kAcceptConnectResponse) - 1, 3),
[email protected]394816e92010-08-03 07:38:5910608
rch8e6c6c42015-05-01 14:05:1310609 // SPDY response
10610 CreateMockRead(*resp.get(), 5),
10611 CreateMockRead(*data.get(), 6),
10612 MockRead(ASYNC, 0, 0, 7),
[email protected]394816e92010-08-03 07:38:5910613 };
rch8e6c6c42015-05-01 14:05:1310614 SequencedSocketData data_2(data_reads_2, arraysize(data_reads_2),
10615 data_writes_2, arraysize(data_writes_2));
[email protected]f45c1ee2010-08-03 00:54:3010616
[email protected]8ddf8322012-02-23 18:08:0610617 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210618 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:2310619 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
10620 ASSERT_TRUE(ssl.cert.get());
[email protected]f45c1ee2010-08-03 00:54:3010621
[email protected]d973e99a2012-02-17 21:02:3610622 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5510623 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
10624 NULL, 0, NULL, 0);
10625 hanging_non_alternate_protocol_socket.set_connect_data(
10626 never_finishing_connect);
10627
[email protected]bb88e1d32013-05-03 23:11:0710628 session_deps_.socket_factory->AddSocketDataProvider(&data_1);
10629 session_deps_.socket_factory->AddSocketDataProvider(&data_2);
10630 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10631 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5510632 &hanging_non_alternate_protocol_socket);
[email protected]bb88e1d32013-05-03 23:11:0710633 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f45c1ee2010-08-03 00:54:3010634
10635 // First round should work and provide the Alternate-Protocol state.
[email protected]49639fa2011-12-20 23:22:4110636 TestCompletionCallback callback_1;
[email protected]262eec82013-03-19 21:01:3610637 scoped_ptr<HttpTransaction> trans_1(
[email protected]90499482013-06-01 00:39:5010638 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110639 int rv = trans_1->Start(&request, callback_1.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:3010640 EXPECT_EQ(ERR_IO_PENDING, rv);
10641 EXPECT_EQ(OK, callback_1.WaitForResult());
10642
10643 // Second round should attempt a tunnel connect and get an auth challenge.
[email protected]49639fa2011-12-20 23:22:4110644 TestCompletionCallback callback_2;
[email protected]262eec82013-03-19 21:01:3610645 scoped_ptr<HttpTransaction> trans_2(
[email protected]90499482013-06-01 00:39:5010646 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110647 rv = trans_2->Start(&request, callback_2.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:3010648 EXPECT_EQ(ERR_IO_PENDING, rv);
10649 EXPECT_EQ(OK, callback_2.WaitForResult());
10650 const HttpResponseInfo* response = trans_2->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010651 ASSERT_TRUE(response != NULL);
[email protected]f45c1ee2010-08-03 00:54:3010652 ASSERT_FALSE(response->auth_challenge.get() == NULL);
10653
10654 // Restart with auth. Tunnel should work and response received.
[email protected]49639fa2011-12-20 23:22:4110655 TestCompletionCallback callback_3;
10656 rv = trans_2->RestartWithAuth(
10657 AuthCredentials(kFoo, kBar), callback_3.callback());
[email protected]f45c1ee2010-08-03 00:54:3010658 EXPECT_EQ(ERR_IO_PENDING, rv);
10659 EXPECT_EQ(OK, callback_3.WaitForResult());
10660
10661 // After all that work, these two lines (or actually, just the scheme) are
10662 // what this test is all about. Make sure it happens correctly.
[email protected]f45c1ee2010-08-03 00:54:3010663 EXPECT_EQ("https", request_url.scheme());
bncce36dca22015-04-21 22:11:2310664 EXPECT_EQ("www.example.org", request_url.host());
[email protected]f45c1ee2010-08-03 00:54:3010665
[email protected]029c83b62013-01-24 05:28:2010666 LoadTimingInfo load_timing_info;
10667 EXPECT_TRUE(trans_2->GetLoadTimingInfo(&load_timing_info));
10668 TestLoadTimingNotReusedWithPac(load_timing_info,
10669 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]8e6441ca2010-08-19 05:56:3810670}
10671
10672// Test that if we cancel the transaction as the connection is completing, that
10673// everything tears down correctly.
[email protected]23e482282013-06-14 16:08:0210674TEST_P(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3810675 // Setup everything about the connection to complete synchronously, so that
10676 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
10677 // for is the callback from the HttpStreamRequest.
10678 // Then cancel the transaction.
10679 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3610680 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3810681 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0610682 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
10683 MockRead(SYNCHRONOUS, "hello world"),
10684 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3810685 };
10686
[email protected]8e6441ca2010-08-19 05:56:3810687 HttpRequestInfo request;
10688 request.method = "GET";
bncce36dca22015-04-21 22:11:2310689 request.url = GURL("http://www.example.org/");
[email protected]8e6441ca2010-08-19 05:56:3810690 request.load_flags = 0;
10691
[email protected]bb88e1d32013-05-03 23:11:0710692 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]3fe8d2f82013-10-17 08:56:0710693 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:2710694 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4110695 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:2710696
[email protected]8e6441ca2010-08-19 05:56:3810697 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10698 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710699 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3810700
[email protected]49639fa2011-12-20 23:22:4110701 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3810702
vishal.b62985ca92015-04-17 08:45:5110703 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4110704 int rv = trans->Start(&request, callback.callback(), log.bound());
[email protected]8e6441ca2010-08-19 05:56:3810705 EXPECT_EQ(ERR_IO_PENDING, rv);
10706 trans.reset(); // Cancel the transaction here.
10707
[email protected]2da659e2013-05-23 20:51:3410708 base::MessageLoop::current()->RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3010709}
10710
[email protected]ecab6e052014-05-16 14:58:1210711// Test that if a transaction is cancelled after receiving the headers, the
10712// stream is drained properly and added back to the socket pool. The main
10713// purpose of this test is to make sure that an HttpStreamParser can be read
10714// from after the HttpNetworkTransaction and the objects it owns have been
10715// deleted.
10716// See http://crbug.com/368418
10717TEST_P(HttpNetworkTransactionTest, CancelAfterHeaders) {
10718 MockRead data_reads[] = {
10719 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
10720 MockRead(ASYNC, "Content-Length: 2\r\n"),
10721 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
10722 MockRead(ASYNC, "1"),
10723 // 2 async reads are necessary to trigger a ReadResponseBody call after the
10724 // HttpNetworkTransaction has been deleted.
10725 MockRead(ASYNC, "2"),
10726 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
10727 };
10728 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10729 session_deps_.socket_factory->AddSocketDataProvider(&data);
10730
10731 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10732
10733 {
10734 HttpRequestInfo request;
10735 request.method = "GET";
bncce36dca22015-04-21 22:11:2310736 request.url = GURL("http://www.example.org/");
[email protected]ecab6e052014-05-16 14:58:1210737 request.load_flags = 0;
10738
dcheng48459ac22014-08-26 00:46:4110739 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1210740 TestCompletionCallback callback;
10741
10742 int rv = trans.Start(&request, callback.callback(), BoundNetLog());
10743 EXPECT_EQ(ERR_IO_PENDING, rv);
10744 callback.WaitForResult();
10745
10746 const HttpResponseInfo* response = trans.GetResponseInfo();
10747 ASSERT_TRUE(response != NULL);
10748 EXPECT_TRUE(response->headers.get() != NULL);
10749 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10750
10751 // The transaction and HttpRequestInfo are deleted.
10752 }
10753
10754 // Let the HttpResponseBodyDrainer drain the socket.
10755 base::MessageLoop::current()->RunUntilIdle();
10756
10757 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4110758 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1210759}
10760
[email protected]76a505b2010-08-25 06:23:0010761// Test a basic GET request through a proxy.
[email protected]23e482282013-06-14 16:08:0210762TEST_P(HttpNetworkTransactionTest, ProxyGet) {
[email protected]bb88e1d32013-05-03 23:11:0710763 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:2010764 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
vishal.b62985ca92015-04-17 08:45:5110765 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710766 session_deps_.net_log = log.bound().net_log();
10767 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0010768
[email protected]76a505b2010-08-25 06:23:0010769 HttpRequestInfo request;
10770 request.method = "GET";
bncce36dca22015-04-21 22:11:2310771 request.url = GURL("http://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0010772
10773 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2310774 MockWrite(
10775 "GET http://www.example.org/ HTTP/1.1\r\n"
10776 "Host: www.example.org\r\n"
10777 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0010778 };
10779
10780 MockRead data_reads1[] = {
10781 MockRead("HTTP/1.1 200 OK\r\n"),
10782 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10783 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610784 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0010785 };
10786
10787 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10788 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710789 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0010790
[email protected]49639fa2011-12-20 23:22:4110791 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0010792
[email protected]262eec82013-03-19 21:01:3610793 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010794 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]597a1ab2014-06-26 08:12:2710795 BeforeProxyHeadersSentHandler proxy_headers_handler;
10796 trans->SetBeforeProxyHeadersSentCallback(
10797 base::Bind(&BeforeProxyHeadersSentHandler::OnBeforeProxyHeadersSent,
10798 base::Unretained(&proxy_headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5010799
[email protected]49639fa2011-12-20 23:22:4110800 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0010801 EXPECT_EQ(ERR_IO_PENDING, rv);
10802
10803 rv = callback1.WaitForResult();
10804 EXPECT_EQ(OK, rv);
10805
10806 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010807 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:0010808
10809 EXPECT_TRUE(response->headers->IsKeepAlive());
10810 EXPECT_EQ(200, response->headers->response_code());
10811 EXPECT_EQ(100, response->headers->GetContentLength());
10812 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]d8fc4722014-06-13 13:17:1510813 EXPECT_TRUE(
10814 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
[email protected]597a1ab2014-06-26 08:12:2710815 EXPECT_TRUE(proxy_headers_handler.observed_before_proxy_headers_sent());
10816 EXPECT_EQ("myproxy:70", proxy_headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0010817 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2010818
10819 LoadTimingInfo load_timing_info;
10820 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10821 TestLoadTimingNotReusedWithPac(load_timing_info,
10822 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0010823}
10824
10825// Test a basic HTTPS GET request through a proxy.
[email protected]23e482282013-06-14 16:08:0210826TEST_P(HttpNetworkTransactionTest, ProxyTunnelGet) {
[email protected]bb88e1d32013-05-03 23:11:0710827 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:2010828 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
vishal.b62985ca92015-04-17 08:45:5110829 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710830 session_deps_.net_log = log.bound().net_log();
10831 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0010832
[email protected]76a505b2010-08-25 06:23:0010833 HttpRequestInfo request;
10834 request.method = "GET";
bncce36dca22015-04-21 22:11:2310835 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0010836
10837 // Since we have proxy, should try to establish tunnel.
10838 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2310839 MockWrite(
10840 "CONNECT www.example.org:443 HTTP/1.1\r\n"
10841 "Host: www.example.org\r\n"
10842 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0010843
bncce36dca22015-04-21 22:11:2310844 MockWrite(
10845 "GET / HTTP/1.1\r\n"
10846 "Host: www.example.org\r\n"
10847 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0010848 };
10849
10850 MockRead data_reads1[] = {
10851 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
10852
10853 MockRead("HTTP/1.1 200 OK\r\n"),
10854 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10855 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610856 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0010857 };
10858
10859 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10860 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710861 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0610862 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710863 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0010864
[email protected]49639fa2011-12-20 23:22:4110865 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0010866
[email protected]262eec82013-03-19 21:01:3610867 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010868 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5010869
[email protected]49639fa2011-12-20 23:22:4110870 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0010871 EXPECT_EQ(ERR_IO_PENDING, rv);
10872
10873 rv = callback1.WaitForResult();
10874 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:4610875 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4010876 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0010877 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010878 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0010879 NetLog::PHASE_NONE);
10880 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010881 entries, pos,
[email protected]76a505b2010-08-25 06:23:0010882 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
10883 NetLog::PHASE_NONE);
10884
10885 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010886 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:0010887
10888 EXPECT_TRUE(response->headers->IsKeepAlive());
10889 EXPECT_EQ(200, response->headers->response_code());
10890 EXPECT_EQ(100, response->headers->GetContentLength());
10891 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10892 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]d8fc4722014-06-13 13:17:1510893 EXPECT_TRUE(
10894 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
[email protected]029c83b62013-01-24 05:28:2010895
10896 LoadTimingInfo load_timing_info;
10897 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10898 TestLoadTimingNotReusedWithPac(load_timing_info,
10899 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0010900}
10901
10902// Test a basic HTTPS GET request through a proxy, but the server hangs up
10903// while establishing the tunnel.
[email protected]23e482282013-06-14 16:08:0210904TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
[email protected]bb88e1d32013-05-03 23:11:0710905 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
vishal.b62985ca92015-04-17 08:45:5110906 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710907 session_deps_.net_log = log.bound().net_log();
10908 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0010909
[email protected]76a505b2010-08-25 06:23:0010910 HttpRequestInfo request;
10911 request.method = "GET";
bncce36dca22015-04-21 22:11:2310912 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0010913
10914 // Since we have proxy, should try to establish tunnel.
10915 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2310916 MockWrite(
10917 "CONNECT www.example.org:443 HTTP/1.1\r\n"
10918 "Host: www.example.org\r\n"
10919 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0010920
bncce36dca22015-04-21 22:11:2310921 MockWrite(
10922 "GET / HTTP/1.1\r\n"
10923 "Host: www.example.org\r\n"
10924 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0010925 };
10926
10927 MockRead data_reads1[] = {
[email protected]8ddf8322012-02-23 18:08:0610928 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:0010929 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610930 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0010931 };
10932
10933 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10934 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710935 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0610936 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710937 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0010938
[email protected]49639fa2011-12-20 23:22:4110939 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0010940
[email protected]262eec82013-03-19 21:01:3610941 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010942 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5010943
[email protected]49639fa2011-12-20 23:22:4110944 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0010945 EXPECT_EQ(ERR_IO_PENDING, rv);
10946
10947 rv = callback1.WaitForResult();
10948 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
mmenke43758e62015-05-04 21:09:4610949 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4010950 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0010951 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010952 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0010953 NetLog::PHASE_NONE);
10954 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010955 entries, pos,
[email protected]76a505b2010-08-25 06:23:0010956 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
10957 NetLog::PHASE_NONE);
10958}
10959
[email protected]749eefa82010-09-13 22:14:0310960// Test for crbug.com/55424.
[email protected]23e482282013-06-14 16:08:0210961TEST_P(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
[email protected]cdf8f7e72013-05-23 10:56:4610962 scoped_ptr<SpdyFrame> req(
bncce36dca22015-04-21 22:11:2310963 spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
rch8e6c6c42015-05-01 14:05:1310964 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]749eefa82010-09-13 22:14:0310965
[email protected]23e482282013-06-14 16:08:0210966 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10967 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0310968 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1310969 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0310970 };
10971
rch8e6c6c42015-05-01 14:05:1310972 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10973 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710974 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0310975
[email protected]8ddf8322012-02-23 18:08:0610976 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210977 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710978 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0310979
[email protected]bb88e1d32013-05-03 23:11:0710980 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0310981
10982 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2310983 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4010984 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5310985 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2710986 base::WeakPtr<SpdySession> spdy_session =
[email protected]41d64e82013-07-03 22:44:2610987 CreateInsecureSpdySession(session, key, BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0310988
10989 HttpRequestInfo request;
10990 request.method = "GET";
bncce36dca22015-04-21 22:11:2310991 request.url = GURL("https://www.example.org/");
[email protected]749eefa82010-09-13 22:14:0310992 request.load_flags = 0;
10993
10994 // This is the important line that marks this as a preconnect.
10995 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
10996
[email protected]262eec82013-03-19 21:01:3610997 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010998 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]749eefa82010-09-13 22:14:0310999
[email protected]41d64e82013-07-03 22:44:2611000 TestCompletionCallback callback;
[email protected]49639fa2011-12-20 23:22:4111001 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0311002 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111003 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]749eefa82010-09-13 22:14:0311004}
11005
[email protected]73b8dd222010-11-11 19:55:2411006// Given a net error, cause that error to be returned from the first Write()
11007// call and verify that the HttpTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0211008void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0711009 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2911010 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2711011 request_info.url = GURL("https://www.example.com/");
11012 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2911013 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2711014
[email protected]8ddf8322012-02-23 18:08:0611015 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2911016 MockWrite data_writes[] = {
11017 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2411018 };
ttuttle859dc7a2015-04-23 19:42:2911019 StaticSocketDataProvider data(NULL, 0, data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0711020 session_deps_.socket_factory->AddSocketDataProvider(&data);
11021 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2411022
[email protected]bb88e1d32013-05-03 23:11:0711023 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3611024 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011025 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]73b8dd222010-11-11 19:55:2411026
[email protected]49639fa2011-12-20 23:22:4111027 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2911028 int rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
11029 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2411030 rv = callback.WaitForResult();
11031 ASSERT_EQ(error, rv);
11032}
11033
[email protected]23e482282013-06-14 16:08:0211034TEST_P(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2411035 // Just check a grab bag of cert errors.
11036 static const int kErrors[] = {
11037 ERR_CERT_COMMON_NAME_INVALID,
11038 ERR_CERT_AUTHORITY_INVALID,
11039 ERR_CERT_DATE_INVALID,
11040 };
11041 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0611042 CheckErrorIsPassedBack(kErrors[i], ASYNC);
11043 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2411044 }
11045}
11046
[email protected]bd0b6772011-01-11 19:59:3011047// Ensure that a client certificate is removed from the SSL client auth
11048// cache when:
11049// 1) No proxy is involved.
11050// 2) TLS False Start is disabled.
11051// 3) The initial TLS handshake requests a client certificate.
11052// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0211053TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2311054 ClientAuthCertCache_Direct_NoFalseStart) {
ttuttle859dc7a2015-04-23 19:42:2911055 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2711056 request_info.url = GURL("https://www.example.com/");
11057 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2911058 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2711059
[email protected]bd0b6772011-01-11 19:59:3011060 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4111061 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3011062
11063 // [ssl_]data1 contains the data for the first SSL handshake. When a
11064 // CertificateRequest is received for the first time, the handshake will
11065 // be aborted to allow the caller to provide a certificate.
ttuttle859dc7a2015-04-23 19:42:2911066 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3011067 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711068 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2911069 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711070 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3011071
11072 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
11073 // False Start is not being used, the result of the SSL handshake will be
11074 // returned as part of the SSLClientSocket::Connect() call. This test
11075 // matches the result of a server sending a handshake_failure alert,
11076 // rather than a Finished message, because it requires a client
11077 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2911078 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3011079 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711080 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2911081 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711082 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3011083
11084 // [ssl_]data3 contains the data for the third SSL handshake. When a
11085 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4211086 // HttpNetworkTransaction will attempt to fallback to TLSv1.1 if the previous
11087 // connection was attempted with TLSv1.2. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3011088 // of the HttpNetworkTransaction. Because this test failure is due to
11089 // requiring a client certificate, this fallback handshake should also
11090 // fail.
ttuttle859dc7a2015-04-23 19:42:2911091 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3011092 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711093 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2911094 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711095 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3011096
[email protected]80c75f682012-05-26 16:22:1711097 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
11098 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4211099 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
11100 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]80c75f682012-05-26 16:22:1711101 // of the HttpNetworkTransaction. Because this test failure is due to
11102 // requiring a client certificate, this fallback handshake should also
11103 // fail.
ttuttle859dc7a2015-04-23 19:42:2911104 SSLSocketDataProvider ssl_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1711105 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711106 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2911107 StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711108 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1711109
[email protected]bb88e1d32013-05-03 23:11:0711110 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3611111 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011112 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3011113
[email protected]bd0b6772011-01-11 19:59:3011114 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4111115 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2911116 int rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
11117 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3011118
11119 // Complete the SSL handshake, which should abort due to requiring a
11120 // client certificate.
11121 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911122 ASSERT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
[email protected]bd0b6772011-01-11 19:59:3011123
11124 // Indicate that no certificate should be supplied. From the perspective
11125 // of SSLClientCertCache, NULL is just as meaningful as a real
11126 // certificate, so this is the same as supply a
11127 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4111128 rv = trans->RestartWithCertificate(NULL, callback.callback());
ttuttle859dc7a2015-04-23 19:42:2911129 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3011130
11131 // Ensure the certificate was added to the client auth cache before
11132 // allowing the connection to continue restarting.
11133 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4111134 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
11135 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3011136 ASSERT_EQ(NULL, client_cert.get());
11137
11138 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1711139 // then consume ssl_data3 and ssl_data4, both of which should also fail.
11140 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3011141 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911142 ASSERT_EQ(ERR_SSL_PROTOCOL_ERROR, rv);
[email protected]bd0b6772011-01-11 19:59:3011143
11144 // Ensure that the client certificate is removed from the cache on a
11145 // handshake failure.
[email protected]791879c2013-12-17 07:22:4111146 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11147 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3011148}
11149
11150// Ensure that a client certificate is removed from the SSL client auth
11151// cache when:
11152// 1) No proxy is involved.
11153// 2) TLS False Start is enabled.
11154// 3) The initial TLS handshake requests a client certificate.
11155// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0211156TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2311157 ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2911158 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2711159 request_info.url = GURL("https://www.example.com/");
11160 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2911161 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2711162
[email protected]bd0b6772011-01-11 19:59:3011163 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4111164 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3011165
11166 // When TLS False Start is used, SSLClientSocket::Connect() calls will
11167 // return successfully after reading up to the peer's Certificate message.
11168 // This is to allow the caller to call SSLClientSocket::Write(), which can
11169 // enqueue application data to be sent in the same packet as the
11170 // ChangeCipherSpec and Finished messages.
11171 // The actual handshake will be finished when SSLClientSocket::Read() is
11172 // called, which expects to process the peer's ChangeCipherSpec and
11173 // Finished messages. If there was an error negotiating with the peer,
11174 // such as due to the peer requiring a client certificate when none was
11175 // supplied, the alert sent by the peer won't be processed until Read() is
11176 // called.
11177
11178 // Like the non-False Start case, when a client certificate is requested by
11179 // the peer, the handshake is aborted during the Connect() call.
11180 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2911181 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3011182 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711183 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2911184 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711185 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3011186
11187 // When a client certificate is supplied, Connect() will not be aborted
11188 // when the peer requests the certificate. Instead, the handshake will
11189 // artificially succeed, allowing the caller to write the HTTP request to
11190 // the socket. The handshake messages are not processed until Read() is
11191 // called, which then detects that the handshake was aborted, due to the
11192 // peer sending a handshake_failure because it requires a client
11193 // certificate.
ttuttle859dc7a2015-04-23 19:42:2911194 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3011195 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711196 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2911197 MockRead data2_reads[] = {
11198 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3011199 };
ttuttle859dc7a2015-04-23 19:42:2911200 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711201 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3011202
11203 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1711204 // the data for the SSL handshake once the TLSv1.1 connection falls back to
11205 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2911206 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3011207 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711208 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2911209 StaticSocketDataProvider data3(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711210 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3011211
[email protected]80c75f682012-05-26 16:22:1711212 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
11213 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2911214 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1711215 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711216 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2911217 StaticSocketDataProvider data4(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711218 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1711219
[email protected]7799de12013-05-30 05:52:5111220 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2911221 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5111222 ssl_data5.cert_request_info = cert_request.get();
11223 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
ttuttle859dc7a2015-04-23 19:42:2911224 StaticSocketDataProvider data5(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]7799de12013-05-30 05:52:5111225 session_deps_.socket_factory->AddSocketDataProvider(&data5);
11226
[email protected]bb88e1d32013-05-03 23:11:0711227 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3611228 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011229 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3011230
[email protected]bd0b6772011-01-11 19:59:3011231 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4111232 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2911233 int rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
11234 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3011235
11236 // Complete the SSL handshake, which should abort due to requiring a
11237 // client certificate.
11238 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911239 ASSERT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
[email protected]bd0b6772011-01-11 19:59:3011240
11241 // Indicate that no certificate should be supplied. From the perspective
11242 // of SSLClientCertCache, NULL is just as meaningful as a real
11243 // certificate, so this is the same as supply a
11244 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4111245 rv = trans->RestartWithCertificate(NULL, callback.callback());
ttuttle859dc7a2015-04-23 19:42:2911246 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3011247
11248 // Ensure the certificate was added to the client auth cache before
11249 // allowing the connection to continue restarting.
11250 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4111251 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
11252 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3011253 ASSERT_EQ(NULL, client_cert.get());
11254
[email protected]bd0b6772011-01-11 19:59:3011255 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1711256 // then consume ssl_data3 and ssl_data4, both of which should also fail.
11257 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3011258 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911259 ASSERT_EQ(ERR_SSL_PROTOCOL_ERROR, rv);
[email protected]bd0b6772011-01-11 19:59:3011260
11261 // Ensure that the client certificate is removed from the cache on a
11262 // handshake failure.
[email protected]791879c2013-12-17 07:22:4111263 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11264 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3011265}
11266
[email protected]8c405132011-01-11 22:03:1811267// Ensure that a client certificate is removed from the SSL client auth
11268// cache when:
11269// 1) An HTTPS proxy is involved.
11270// 3) The HTTPS proxy requests a client certificate.
11271// 4) The client supplies an invalid/unacceptable certificate for the
11272// proxy.
11273// The test is repeated twice, first for connecting to an HTTPS endpoint,
11274// then for connecting to an HTTP endpoint.
[email protected]23e482282013-06-14 16:08:0211275TEST_P(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
[email protected]bb88e1d32013-05-03 23:11:0711276 session_deps_.proxy_service.reset(
[email protected]8c405132011-01-11 22:03:1811277 ProxyService::CreateFixed("https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:5111278 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0711279 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1811280
11281 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4111282 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1811283
11284 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
11285 // [ssl_]data[1-3]. Rather than represending the endpoint
11286 // (www.example.com:443), they represent failures with the HTTPS proxy
11287 // (proxy:70).
ttuttle859dc7a2015-04-23 19:42:2911288 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1811289 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711290 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2911291 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711292 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1811293
ttuttle859dc7a2015-04-23 19:42:2911294 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1811295 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711296 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2911297 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711298 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1811299
[email protected]80c75f682012-05-26 16:22:1711300 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
11301#if 0
ttuttle859dc7a2015-04-23 19:42:2911302 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1811303 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711304 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2911305 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711306 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1711307#endif
[email protected]8c405132011-01-11 22:03:1811308
ttuttle859dc7a2015-04-23 19:42:2911309 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1811310 requests[0].url = GURL("https://www.example.com/");
11311 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2911312 requests[0].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1811313
11314 requests[1].url = GURL("http://www.example.com/");
11315 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2911316 requests[1].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1811317
11318 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0711319 session_deps_.socket_factory->ResetNextMockIndexes();
11320 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c405132011-01-11 22:03:1811321 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5011322 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c405132011-01-11 22:03:1811323
11324 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4111325 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2911326 int rv = trans->Start(&requests[i], callback.callback(), BoundNetLog());
11327 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]8c405132011-01-11 22:03:1811328
11329 // Complete the SSL handshake, which should abort due to requiring a
11330 // client certificate.
11331 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911332 ASSERT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
[email protected]8c405132011-01-11 22:03:1811333
11334 // Indicate that no certificate should be supplied. From the perspective
11335 // of SSLClientCertCache, NULL is just as meaningful as a real
11336 // certificate, so this is the same as supply a
11337 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4111338 rv = trans->RestartWithCertificate(NULL, callback.callback());
ttuttle859dc7a2015-04-23 19:42:2911339 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]8c405132011-01-11 22:03:1811340
11341 // Ensure the certificate was added to the client auth cache before
11342 // allowing the connection to continue restarting.
11343 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4111344 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
11345 HostPortPair("proxy", 70), &client_cert));
[email protected]8c405132011-01-11 22:03:1811346 ASSERT_EQ(NULL, client_cert.get());
11347 // Ensure the certificate was NOT cached for the endpoint. This only
11348 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4111349 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11350 HostPortPair("www.example.com", 443), &client_cert));
[email protected]8c405132011-01-11 22:03:1811351
11352 // Restart the handshake. This will consume ssl_data2, which fails, and
11353 // then consume ssl_data3, which should also fail. The result code is
11354 // checked against what ssl_data3 should return.
11355 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911356 ASSERT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
[email protected]8c405132011-01-11 22:03:1811357
11358 // Now that the new handshake has failed, ensure that the client
11359 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4111360 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11361 HostPortPair("proxy", 70), &client_cert));
11362 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}
11366
mmenke5c642132015-06-02 16:05:1311367TEST_P(HttpNetworkTransactionTest, UseIPConnectionPooling) {
[email protected]d7599122014-05-24 03:37:2311368 session_deps_.use_alternate_protocols = true;
11369 session_deps_.next_protos = SpdyNextProtos();
[email protected]e3ceb682011-06-28 23:55:4611370
11371 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0711372 session_deps_.host_resolver.reset(new MockCachingHostResolver());
11373 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2611374 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
11375 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4611376
[email protected]8ddf8322012-02-23 18:08:0611377 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211378 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711379 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4611380
[email protected]cdf8f7e72013-05-23 10:56:4611381 scoped_ptr<SpdyFrame> host1_req(
bncce36dca22015-04-21 22:11:2311382 spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
[email protected]cdf8f7e72013-05-23 10:56:4611383 scoped_ptr<SpdyFrame> host2_req(
11384 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4611385 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1311386 CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4611387 };
[email protected]23e482282013-06-14 16:08:0211388 scoped_ptr<SpdyFrame> host1_resp(
11389 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11390 scoped_ptr<SpdyFrame> host1_resp_body(
11391 spdy_util_.ConstructSpdyBodyFrame(1, true));
11392 scoped_ptr<SpdyFrame> host2_resp(
11393 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11394 scoped_ptr<SpdyFrame> host2_resp_body(
11395 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4611396 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1311397 CreateMockRead(*host1_resp, 1),
11398 CreateMockRead(*host1_resp_body, 2),
11399 CreateMockRead(*host2_resp, 4),
11400 CreateMockRead(*host2_resp_body, 5),
11401 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4611402 };
11403
[email protected]d2b5f092012-06-08 23:55:0211404 IPAddressNumber ip;
11405 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
11406 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11407 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1311408 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
11409 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711410 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4611411
[email protected]aa22b242011-11-16 18:58:2911412 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4611413 HttpRequestInfo request1;
11414 request1.method = "GET";
bncce36dca22015-04-21 22:11:2311415 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4611416 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011417 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611418
[email protected]49639fa2011-12-20 23:22:4111419 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611420 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111421 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611422
11423 const HttpResponseInfo* response = trans1.GetResponseInfo();
11424 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011425 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611426 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11427
11428 std::string response_data;
11429 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
11430 EXPECT_EQ("hello!", response_data);
11431
11432 // Preload www.gmail.com into HostCache.
11433 HostPortPair host_port("www.gmail.com", 443);
[email protected]5109c1952013-08-20 18:44:1011434 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4611435 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1011436 rv = session_deps_.host_resolver->Resolve(resolve_info,
11437 DEFAULT_PRIORITY,
11438 &ignored,
11439 callback.callback(),
11440 NULL,
11441 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4711442 EXPECT_EQ(ERR_IO_PENDING, rv);
11443 rv = callback.WaitForResult();
11444 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4611445
11446 HttpRequestInfo request2;
11447 request2.method = "GET";
11448 request2.url = GURL("https://www.gmail.com/");
11449 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011450 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611451
[email protected]49639fa2011-12-20 23:22:4111452 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611453 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111454 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611455
11456 response = trans2.GetResponseInfo();
11457 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011458 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611459 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11460 EXPECT_TRUE(response->was_fetched_via_spdy);
11461 EXPECT_TRUE(response->was_npn_negotiated);
11462 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
11463 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4611464}
[email protected]e3ceb682011-06-28 23:55:4611465
[email protected]23e482282013-06-14 16:08:0211466TEST_P(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d7599122014-05-24 03:37:2311467 session_deps_.use_alternate_protocols = true;
11468 session_deps_.next_protos = SpdyNextProtos();
[email protected]d2b5f092012-06-08 23:55:0211469
11470 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0711471 session_deps_.host_resolver.reset(new MockCachingHostResolver());
11472 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0211473 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
11474 pool_peer.DisableDomainAuthenticationVerification();
11475
11476 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211477 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711478 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]d2b5f092012-06-08 23:55:0211479
[email protected]cdf8f7e72013-05-23 10:56:4611480 scoped_ptr<SpdyFrame> host1_req(
bncce36dca22015-04-21 22:11:2311481 spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
[email protected]cdf8f7e72013-05-23 10:56:4611482 scoped_ptr<SpdyFrame> host2_req(
11483 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0211484 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1311485 CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0211486 };
[email protected]23e482282013-06-14 16:08:0211487 scoped_ptr<SpdyFrame> host1_resp(
11488 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11489 scoped_ptr<SpdyFrame> host1_resp_body(
11490 spdy_util_.ConstructSpdyBodyFrame(1, true));
11491 scoped_ptr<SpdyFrame> host2_resp(
11492 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11493 scoped_ptr<SpdyFrame> host2_resp_body(
11494 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0211495 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1311496 CreateMockRead(*host1_resp, 1),
11497 CreateMockRead(*host1_resp_body, 2),
11498 CreateMockRead(*host2_resp, 4),
11499 CreateMockRead(*host2_resp_body, 5),
11500 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0211501 };
11502
11503 IPAddressNumber ip;
11504 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
11505 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11506 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1311507 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
11508 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711509 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0211510
11511 TestCompletionCallback callback;
11512 HttpRequestInfo request1;
11513 request1.method = "GET";
bncce36dca22015-04-21 22:11:2311514 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0211515 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011516 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0211517
11518 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
11519 EXPECT_EQ(ERR_IO_PENDING, rv);
11520 EXPECT_EQ(OK, callback.WaitForResult());
11521
11522 const HttpResponseInfo* response = trans1.GetResponseInfo();
11523 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011524 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d2b5f092012-06-08 23:55:0211525 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11526
11527 std::string response_data;
11528 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
11529 EXPECT_EQ("hello!", response_data);
11530
11531 HttpRequestInfo request2;
11532 request2.method = "GET";
11533 request2.url = GURL("https://www.gmail.com/");
11534 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011535 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0211536
11537 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
11538 EXPECT_EQ(ERR_IO_PENDING, rv);
11539 EXPECT_EQ(OK, callback.WaitForResult());
11540
11541 response = trans2.GetResponseInfo();
11542 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011543 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d2b5f092012-06-08 23:55:0211544 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11545 EXPECT_TRUE(response->was_fetched_via_spdy);
11546 EXPECT_TRUE(response->was_npn_negotiated);
11547 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
11548 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0211549}
11550
ttuttle859dc7a2015-04-23 19:42:2911551class OneTimeCachingHostResolver : public HostResolver {
[email protected]e3ceb682011-06-28 23:55:4611552 public:
11553 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
11554 : host_port_(host_port) {}
dchengb03027d2014-10-21 12:00:2011555 ~OneTimeCachingHostResolver() override {}
[email protected]e3ceb682011-06-28 23:55:4611556
11557 RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); }
11558
11559 // HostResolver methods:
dchengb03027d2014-10-21 12:00:2011560 int Resolve(const RequestInfo& info,
11561 RequestPriority priority,
11562 AddressList* addresses,
11563 const CompletionCallback& callback,
11564 RequestHandle* out_req,
11565 const BoundNetLog& net_log) override {
[email protected]95a214c2011-08-04 21:50:4011566 return host_resolver_.Resolve(
[email protected]5109c1952013-08-20 18:44:1011567 info, priority, addresses, callback, out_req, net_log);
[email protected]95a214c2011-08-04 21:50:4011568 }
11569
dchengb03027d2014-10-21 12:00:2011570 int ResolveFromCache(const RequestInfo& info,
11571 AddressList* addresses,
11572 const BoundNetLog& net_log) override {
[email protected]95a214c2011-08-04 21:50:4011573 int rv = host_resolver_.ResolveFromCache(info, addresses, net_log);
11574 if (rv == OK && info.host_port_pair().Equals(host_port_))
[email protected]98e1cd012011-11-08 15:33:0911575 host_resolver_.GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4611576 return rv;
11577 }
11578
dchengb03027d2014-10-21 12:00:2011579 void CancelRequest(RequestHandle req) override {
[email protected]e3ceb682011-06-28 23:55:4611580 host_resolver_.CancelRequest(req);
11581 }
11582
[email protected]46da33be2011-07-19 21:58:0411583 MockCachingHostResolver* GetMockHostResolver() {
11584 return &host_resolver_;
11585 }
11586
[email protected]e3ceb682011-06-28 23:55:4611587 private:
11588 MockCachingHostResolver host_resolver_;
11589 const HostPortPair host_port_;
11590};
11591
mmenke5c642132015-06-02 16:05:1311592TEST_P(HttpNetworkTransactionTest,
11593 UseIPConnectionPoolingWithHostCacheExpiration) {
[email protected]d7599122014-05-24 03:37:2311594 session_deps_.use_alternate_protocols = true;
11595 session_deps_.next_protos = SpdyNextProtos();
[email protected]e3ceb682011-06-28 23:55:4611596
11597 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
[email protected]e3ceb682011-06-28 23:55:4611598 OneTimeCachingHostResolver host_resolver(HostPortPair("www.gmail.com", 443));
[email protected]c6bf8152012-12-02 07:43:3411599 HttpNetworkSession::Params params =
[email protected]bb88e1d32013-05-03 23:11:0711600 SpdySessionDependencies::CreateSessionParams(&session_deps_);
[email protected]e3ceb682011-06-28 23:55:4611601 params.host_resolver = &host_resolver;
[email protected]bb88e1d32013-05-03 23:11:0711602 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2611603 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
11604 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4611605
[email protected]8ddf8322012-02-23 18:08:0611606 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211607 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711608 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4611609
[email protected]cdf8f7e72013-05-23 10:56:4611610 scoped_ptr<SpdyFrame> host1_req(
bncce36dca22015-04-21 22:11:2311611 spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
[email protected]cdf8f7e72013-05-23 10:56:4611612 scoped_ptr<SpdyFrame> host2_req(
11613 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4611614 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1311615 CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4611616 };
[email protected]23e482282013-06-14 16:08:0211617 scoped_ptr<SpdyFrame> host1_resp(
11618 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11619 scoped_ptr<SpdyFrame> host1_resp_body(
11620 spdy_util_.ConstructSpdyBodyFrame(1, true));
11621 scoped_ptr<SpdyFrame> host2_resp(
11622 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11623 scoped_ptr<SpdyFrame> host2_resp_body(
11624 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4611625 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1311626 CreateMockRead(*host1_resp, 1),
11627 CreateMockRead(*host1_resp_body, 2),
11628 CreateMockRead(*host2_resp, 4),
11629 CreateMockRead(*host2_resp_body, 5),
11630 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4611631 };
11632
[email protected]d2b5f092012-06-08 23:55:0211633 IPAddressNumber ip;
11634 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
11635 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11636 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1311637 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
11638 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711639 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4611640
[email protected]aa22b242011-11-16 18:58:2911641 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4611642 HttpRequestInfo request1;
11643 request1.method = "GET";
bncce36dca22015-04-21 22:11:2311644 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4611645 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011646 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611647
[email protected]49639fa2011-12-20 23:22:4111648 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611649 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111650 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611651
11652 const HttpResponseInfo* response = trans1.GetResponseInfo();
11653 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011654 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611655 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11656
11657 std::string response_data;
11658 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
11659 EXPECT_EQ("hello!", response_data);
11660
11661 // Preload cache entries into HostCache.
[email protected]5109c1952013-08-20 18:44:1011662 HostResolver::RequestInfo resolve_info(HostPortPair("www.gmail.com", 443));
[email protected]e3ceb682011-06-28 23:55:4611663 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1011664 rv = host_resolver.Resolve(resolve_info,
11665 DEFAULT_PRIORITY,
11666 &ignored,
11667 callback.callback(),
11668 NULL,
11669 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4711670 EXPECT_EQ(ERR_IO_PENDING, rv);
11671 rv = callback.WaitForResult();
11672 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4611673
11674 HttpRequestInfo request2;
11675 request2.method = "GET";
11676 request2.url = GURL("https://www.gmail.com/");
11677 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011678 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611679
[email protected]49639fa2011-12-20 23:22:4111680 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611681 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111682 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611683
11684 response = trans2.GetResponseInfo();
11685 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011686 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611687 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11688 EXPECT_TRUE(response->was_fetched_via_spdy);
11689 EXPECT_TRUE(response->was_npn_negotiated);
11690 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
11691 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4611692}
[email protected]e3ceb682011-06-28 23:55:4611693
[email protected]23e482282013-06-14 16:08:0211694TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2311695 const std::string https_url = "https://www.example.org:8080/";
11696 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0411697
11698 // SPDY GET for HTTPS URL
[email protected]cdf8f7e72013-05-23 10:56:4611699 scoped_ptr<SpdyFrame> req1(
11700 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0411701
11702 MockWrite writes1[] = {
11703 CreateMockWrite(*req1, 0),
11704 };
11705
[email protected]23e482282013-06-14 16:08:0211706 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11707 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8450d722012-07-02 19:14:0411708 MockRead reads1[] = {
11709 CreateMockRead(*resp1, 1),
11710 CreateMockRead(*body1, 2),
11711 MockRead(ASYNC, ERR_IO_PENDING, 3)
11712 };
11713
rch8e6c6c42015-05-01 14:05:1311714 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
11715 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0411716 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5711717 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0411718
11719 // HTTP GET for the HTTP URL
11720 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1311721 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3411722 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2311723 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3411724 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0411725 };
11726
11727 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1311728 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
11729 MockRead(ASYNC, 2, "hello"),
11730 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0411731 };
11732
rch8e6c6c42015-05-01 14:05:1311733 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
11734 arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0411735
[email protected]8450d722012-07-02 19:14:0411736 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211737 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711738 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11739 session_deps_.socket_factory->AddSocketDataProvider(&data1);
11740 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0411741
[email protected]bb88e1d32013-05-03 23:11:0711742 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0411743
11744 // Start the first transaction to set up the SpdySession
11745 HttpRequestInfo request1;
11746 request1.method = "GET";
11747 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0411748 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011749 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0411750 TestCompletionCallback callback1;
11751 EXPECT_EQ(ERR_IO_PENDING,
11752 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411753 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411754
11755 EXPECT_EQ(OK, callback1.WaitForResult());
11756 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11757
11758 // Now, start the HTTP request
11759 HttpRequestInfo request2;
11760 request2.method = "GET";
11761 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0411762 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011763 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0411764 TestCompletionCallback callback2;
11765 EXPECT_EQ(ERR_IO_PENDING,
11766 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411767 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411768
11769 EXPECT_EQ(OK, callback2.WaitForResult());
11770 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11771}
11772
bnc1b0e36852015-04-28 15:32:5911773class AltSvcCertificateVerificationTest : public HttpNetworkTransactionTest {
11774 public:
11775 void Run(bool pooling, bool valid) {
11776 HostPortPair origin(valid ? "mail.example.org" : "invalid.example.org",
11777 443);
11778 HostPortPair alternative("www.example.org", 443);
11779
11780 base::FilePath certs_dir = GetTestCertsDirectory();
11781 scoped_refptr<X509Certificate> cert(
11782 ImportCertFromFile(certs_dir, "spdy_pooling.pem"));
11783 ASSERT_TRUE(cert.get());
11784 bool common_name_fallback_used;
11785 EXPECT_EQ(valid,
11786 cert->VerifyNameMatch(origin.host(), &common_name_fallback_used));
11787 EXPECT_TRUE(
11788 cert->VerifyNameMatch(alternative.host(), &common_name_fallback_used));
11789 SSLSocketDataProvider ssl(ASYNC, OK);
11790 ssl.SetNextProto(GetParam());
11791 ssl.cert = cert;
11792 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11793
11794 // If pooling, then start a request to alternative first to create a
11795 // SpdySession.
11796 std::string url0 = "https://www.example.org:443";
11797 // Second request to origin, which has an alternative service, and could
11798 // open a connection to the alternative host or pool to the existing one.
11799 std::string url1("https://");
11800 url1.append(origin.host());
11801 url1.append(":443");
11802
11803 scoped_ptr<SpdyFrame> req0;
11804 scoped_ptr<SpdyFrame> req1;
11805 scoped_ptr<SpdyFrame> resp0;
11806 scoped_ptr<SpdyFrame> body0;
11807 scoped_ptr<SpdyFrame> resp1;
11808 scoped_ptr<SpdyFrame> body1;
11809 std::vector<MockWrite> writes;
11810 std::vector<MockRead> reads;
11811
11812 if (pooling) {
11813 req0.reset(spdy_util_.ConstructSpdyGet(url0.c_str(), false, 1, LOWEST));
11814 req1.reset(spdy_util_.ConstructSpdyGet(url1.c_str(), false, 3, LOWEST));
11815
11816 writes.push_back(CreateMockWrite(*req0, 0));
11817 writes.push_back(CreateMockWrite(*req1, 3));
11818
11819 resp0.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11820 body0.reset(spdy_util_.ConstructSpdyBodyFrame(1, true));
11821 resp1.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11822 body1.reset(spdy_util_.ConstructSpdyBodyFrame(3, true));
11823
11824 reads.push_back(CreateMockRead(*resp0, 1));
11825 reads.push_back(CreateMockRead(*body0, 2));
11826 reads.push_back(MockRead(ASYNC, ERR_IO_PENDING, 4));
11827 reads.push_back(CreateMockRead(*resp1, 5));
11828 reads.push_back(CreateMockRead(*body1, 6));
11829 reads.push_back(MockRead(ASYNC, OK, 7));
11830 } else {
11831 req1.reset(spdy_util_.ConstructSpdyGet(url1.c_str(), false, 1, LOWEST));
11832
11833 writes.push_back(CreateMockWrite(*req1, 0));
11834
11835 resp1.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11836 body1.reset(spdy_util_.ConstructSpdyBodyFrame(1, true));
11837
11838 reads.push_back(CreateMockRead(*resp1, 1));
11839 reads.push_back(CreateMockRead(*body1, 2));
11840 reads.push_back(MockRead(ASYNC, OK, 3));
11841 }
11842
rch32320842015-05-16 15:57:0911843 SequencedSocketData data(vector_as_array(&reads), reads.size(),
11844 vector_as_array(&writes), writes.size());
bnc1b0e36852015-04-28 15:32:5911845 session_deps_.socket_factory->AddSocketDataProvider(&data);
11846
11847 // Connection to the origin fails.
11848 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11849 StaticSocketDataProvider data_refused;
11850 data_refused.set_connect_data(mock_connect);
11851 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
11852
11853 session_deps_.use_alternate_protocols = true;
11854 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11855 base::WeakPtr<HttpServerProperties> http_server_properties =
11856 session->http_server_properties();
11857 AlternativeService alternative_service(
11858 AlternateProtocolFromNextProto(GetParam()), alternative);
11859 http_server_properties->SetAlternativeService(origin, alternative_service,
11860 1.0);
11861
11862 // First request to alternative.
11863 if (pooling) {
11864 scoped_ptr<HttpTransaction> trans0(
11865 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
11866 HttpRequestInfo request0;
11867 request0.method = "GET";
11868 request0.url = GURL(url0);
11869 request0.load_flags = 0;
11870 TestCompletionCallback callback0;
11871
11872 int rv = trans0->Start(&request0, callback0.callback(), BoundNetLog());
11873 EXPECT_EQ(ERR_IO_PENDING, rv);
11874 rv = callback0.WaitForResult();
11875 EXPECT_EQ(OK, rv);
11876 }
11877
11878 // Second request to origin.
11879 scoped_ptr<HttpTransaction> trans1(
11880 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
11881 HttpRequestInfo request1;
11882 request1.method = "GET";
11883 request1.url = GURL(url1);
11884 request1.load_flags = 0;
11885 TestCompletionCallback callback1;
11886
11887 int rv = trans1->Start(&request1, callback1.callback(), BoundNetLog());
11888 EXPECT_EQ(ERR_IO_PENDING, rv);
rch32320842015-05-16 15:57:0911889 base::MessageLoop::current()->RunUntilIdle();
11890 if (data.IsReadPaused()) {
11891 data.CompleteRead();
11892 }
bnc1b0e36852015-04-28 15:32:5911893 rv = callback1.WaitForResult();
11894 if (valid) {
11895 EXPECT_EQ(OK, rv);
11896 } else {
11897 if (pooling) {
11898 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
11899 } else {
11900 EXPECT_EQ(ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN, rv);
11901 }
11902 }
11903 }
11904};
11905
11906INSTANTIATE_TEST_CASE_P(NextProto,
11907 AltSvcCertificateVerificationTest,
11908 testing::Values(kProtoSPDY31,
11909 kProtoSPDY4_14,
11910 kProtoSPDY4));
11911
11912// The alternative service host must exhibit a certificate that is valid for the
11913// origin host. Test that this is enforced when pooling to an existing
11914// connection.
11915TEST_P(AltSvcCertificateVerificationTest, PoolingValid) {
11916 Run(true, true);
11917}
11918
11919TEST_P(AltSvcCertificateVerificationTest, PoolingInvalid) {
11920 Run(true, false);
11921}
11922
11923// The alternative service host must exhibit a certificate that is valid for the
11924// origin host. Test that this is enforced when opening a new connection.
11925TEST_P(AltSvcCertificateVerificationTest, NewConnectionValid) {
11926 Run(false, true);
11927}
11928
11929TEST_P(AltSvcCertificateVerificationTest, NewConnectionInvalid) {
11930 Run(false, false);
11931}
11932
bnc5452e2a2015-05-08 16:27:4211933// Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
11934// with the alternative server. That connection should not be used.
11935TEST_P(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
11936 HostPortPair origin("origin.example.org", 443);
11937 HostPortPair alternative("alternative.example.org", 443);
11938
11939 // Negotiate HTTP/1.1 with alternative.example.org.
11940 SSLSocketDataProvider ssl(ASYNC, OK);
11941 ssl.SetNextProto(kProtoHTTP11);
11942 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11943
11944 // No data should be read from the alternative, because HTTP/1.1 is
11945 // negotiated.
11946 StaticSocketDataProvider data;
11947 session_deps_.socket_factory->AddSocketDataProvider(&data);
11948
11949 // This test documents that an alternate Job should not be used if HTTP/1.1 is
11950 // negotiated. In order to test this, a failed connection to the origin is
11951 // mocked. This way the request relies on the alternate Job.
11952 StaticSocketDataProvider data_refused;
11953 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
11954 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
11955
11956 // Set up alternative service for origin.
11957 session_deps_.use_alternate_protocols = true;
11958 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11959 base::WeakPtr<HttpServerProperties> http_server_properties =
11960 session->http_server_properties();
11961 AlternativeService alternative_service(
11962 AlternateProtocolFromNextProto(GetParam()), alternative);
11963 http_server_properties->SetAlternativeService(origin, alternative_service,
11964 1.0);
11965
11966 scoped_ptr<HttpTransaction> trans(
11967 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
11968 HttpRequestInfo request;
11969 request.method = "GET";
11970 request.url = GURL("https://origin.example.org:443");
11971 request.load_flags = 0;
11972 TestCompletionCallback callback;
11973
11974 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
11975 // negotiated, the alternate Job should fail with ERR_NPN_NEGOTIATION_FAILED.
11976 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11977 EXPECT_EQ(ERR_NPN_NEGOTIATION_FAILED, callback.GetResult(rv));
11978}
11979
bnc40448a532015-05-11 19:13:1411980// A request to a server with an alternative service fires two Jobs: one to the
11981// origin, and an alternate one to the alternative server. If the former
11982// succeeds, the request should succeed, even if the latter fails because
11983// HTTP/1.1 is negotiated which is insufficient for alternative service.
11984TEST_P(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
11985 HostPortPair origin("origin.example.org", 443);
11986 HostPortPair alternative("alternative.example.org", 443);
11987
11988 // Negotiate HTTP/1.1 with alternative.
11989 SSLSocketDataProvider alternative_ssl(ASYNC, OK);
11990 alternative_ssl.SetNextProto(kProtoHTTP11);
11991 session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
11992
11993 // No data should be read from the alternative, because HTTP/1.1 is
11994 // negotiated.
11995 StaticSocketDataProvider data;
11996 session_deps_.socket_factory->AddSocketDataProvider(&data);
11997
11998 // Negotiate HTTP/1.1 with origin.
11999 SSLSocketDataProvider origin_ssl(ASYNC, OK);
12000 origin_ssl.SetNextProto(kProtoHTTP11);
12001 session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
12002
12003 MockWrite http_writes[] = {
12004 MockWrite(
12005 "GET / HTTP/1.1\r\n"
12006 "Host: origin.example.org\r\n"
12007 "Connection: keep-alive\r\n\r\n"),
12008 MockWrite(
12009 "GET /second HTTP/1.1\r\n"
12010 "Host: origin.example.org\r\n"
12011 "Connection: keep-alive\r\n\r\n"),
12012 };
12013
12014 MockRead http_reads[] = {
12015 MockRead("HTTP/1.1 200 OK\r\n"),
12016 MockRead("Content-Type: text/html\r\n"),
12017 MockRead("Content-Length: 6\r\n\r\n"),
12018 MockRead("foobar"),
12019 MockRead("HTTP/1.1 200 OK\r\n"),
12020 MockRead("Content-Type: text/html\r\n"),
12021 MockRead("Content-Length: 7\r\n\r\n"),
12022 MockRead("another"),
12023 };
12024 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
12025 http_writes, arraysize(http_writes));
12026 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12027
12028 // Set up alternative service for origin.
12029 session_deps_.use_alternate_protocols = true;
12030 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12031 base::WeakPtr<HttpServerProperties> http_server_properties =
12032 session->http_server_properties();
12033 AlternativeService alternative_service(
12034 AlternateProtocolFromNextProto(GetParam()), alternative);
12035 http_server_properties->SetAlternativeService(origin, alternative_service,
12036 1.0);
12037
12038 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
12039 HttpRequestInfo request1;
12040 request1.method = "GET";
12041 request1.url = GURL("https://origin.example.org:443");
12042 request1.load_flags = 0;
12043 TestCompletionCallback callback1;
12044
12045 int rv = trans1.Start(&request1, callback1.callback(), BoundNetLog());
12046 rv = callback1.GetResult(rv);
12047 EXPECT_EQ(OK, rv);
12048
12049 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
12050 ASSERT_TRUE(response1 != nullptr);
12051 ASSERT_TRUE(response1->headers.get() != nullptr);
12052 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
12053
12054 std::string response_data1;
12055 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data1));
12056 EXPECT_EQ("foobar", response_data1);
12057
12058 // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
12059 // for alternative service.
12060 EXPECT_TRUE(
12061 http_server_properties->IsAlternativeServiceBroken(alternative_service));
12062
12063 // Since |alternative_service| is broken, a second transaction to origin
12064 // should not start an alternate Job. It should pool to existing connection
12065 // to origin.
12066 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
12067 HttpRequestInfo request2;
12068 request2.method = "GET";
12069 request2.url = GURL("https://origin.example.org:443/second");
12070 request2.load_flags = 0;
12071 TestCompletionCallback callback2;
12072
12073 rv = trans2.Start(&request2, callback2.callback(), BoundNetLog());
12074 rv = callback2.GetResult(rv);
12075 EXPECT_EQ(OK, rv);
12076
12077 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
12078 ASSERT_TRUE(response2 != nullptr);
12079 ASSERT_TRUE(response2->headers.get() != nullptr);
12080 EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
12081
12082 std::string response_data2;
12083 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data2));
12084 EXPECT_EQ("another", response_data2);
12085}
12086
bnc5452e2a2015-05-08 16:27:4212087// Alternative service requires HTTP/2 (or SPDY), but there is already a
12088// HTTP/1.1 socket open to the alternative server. That socket should not be
12089// used.
12090TEST_P(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
12091 HostPortPair origin("origin.example.org", 443);
12092 HostPortPair alternative("alternative.example.org", 443);
12093 std::string origin_url = "https://origin.example.org:443";
12094 std::string alternative_url = "https://alternative.example.org:443";
12095
12096 // Negotiate HTTP/1.1 with alternative.example.org.
12097 SSLSocketDataProvider ssl(ASYNC, OK);
12098 ssl.SetNextProto(kProtoHTTP11);
12099 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12100
12101 // HTTP/1.1 data for |request1| and |request2|.
12102 MockWrite http_writes[] = {
12103 MockWrite(
12104 "GET / HTTP/1.1\r\n"
12105 "Host: alternative.example.org\r\n"
12106 "Connection: keep-alive\r\n\r\n"),
12107 MockWrite(
12108 "GET / HTTP/1.1\r\n"
12109 "Host: alternative.example.org\r\n"
12110 "Connection: keep-alive\r\n\r\n"),
12111 };
12112
12113 MockRead http_reads[] = {
12114 MockRead(
12115 "HTTP/1.1 200 OK\r\n"
12116 "Content-Type: text/html; charset=iso-8859-1\r\n"
12117 "Content-Length: 40\r\n\r\n"
12118 "first HTTP/1.1 response from alternative"),
12119 MockRead(
12120 "HTTP/1.1 200 OK\r\n"
12121 "Content-Type: text/html; charset=iso-8859-1\r\n"
12122 "Content-Length: 41\r\n\r\n"
12123 "second HTTP/1.1 response from alternative"),
12124 };
12125 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
12126 http_writes, arraysize(http_writes));
12127 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12128
12129 // This test documents that an alternate Job should not pool to an already
12130 // existing HTTP/1.1 connection. In order to test this, a failed connection
12131 // to the origin is mocked. This way |request2| relies on the alternate Job.
12132 StaticSocketDataProvider data_refused;
12133 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
12134 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
12135
12136 // Set up alternative service for origin.
12137 session_deps_.use_alternate_protocols = true;
12138 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12139 base::WeakPtr<HttpServerProperties> http_server_properties =
12140 session->http_server_properties();
12141 AlternativeService alternative_service(
12142 AlternateProtocolFromNextProto(GetParam()), alternative);
12143 http_server_properties->SetAlternativeService(origin, alternative_service,
12144 1.0);
12145
12146 // First transaction to alternative to open an HTTP/1.1 socket.
12147 scoped_ptr<HttpTransaction> trans1(
12148 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12149 HttpRequestInfo request1;
12150 request1.method = "GET";
12151 request1.url = GURL(alternative_url);
12152 request1.load_flags = 0;
12153 TestCompletionCallback callback1;
12154
12155 int rv = trans1->Start(&request1, callback1.callback(), BoundNetLog());
12156 EXPECT_EQ(OK, callback1.GetResult(rv));
12157 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
12158 ASSERT_TRUE(response1);
12159 ASSERT_TRUE(response1->headers.get());
12160 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
12161 EXPECT_TRUE(response1->was_npn_negotiated);
12162 EXPECT_FALSE(response1->was_fetched_via_spdy);
12163 std::string response_data1;
12164 ASSERT_EQ(OK, ReadTransaction(trans1.get(), &response_data1));
12165 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
12166
12167 // Request for origin.example.org, which has an alternative service. This
12168 // will start two Jobs: the alternative looks for connections to pool to,
12169 // finds one which is HTTP/1.1, and should ignore it, and should not try to
12170 // open other connections to alternative server. The Job to origin fails, so
12171 // this request fails.
12172 scoped_ptr<HttpTransaction> trans2(
12173 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12174 HttpRequestInfo request2;
12175 request2.method = "GET";
12176 request2.url = GURL(origin_url);
12177 request2.load_flags = 0;
12178 TestCompletionCallback callback2;
12179
12180 rv = trans2->Start(&request2, callback2.callback(), BoundNetLog());
12181 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback2.GetResult(rv));
12182
12183 // Another transaction to alternative. This is to test that the HTTP/1.1
12184 // socket is still open and in the pool.
12185 scoped_ptr<HttpTransaction> trans3(
12186 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12187 HttpRequestInfo request3;
12188 request3.method = "GET";
12189 request3.url = GURL(alternative_url);
12190 request3.load_flags = 0;
12191 TestCompletionCallback callback3;
12192
12193 rv = trans3->Start(&request3, callback3.callback(), BoundNetLog());
12194 EXPECT_EQ(OK, callback3.GetResult(rv));
12195 const HttpResponseInfo* response3 = trans3->GetResponseInfo();
12196 ASSERT_TRUE(response3);
12197 ASSERT_TRUE(response3->headers.get());
12198 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
12199 EXPECT_TRUE(response3->was_npn_negotiated);
12200 EXPECT_FALSE(response3->was_fetched_via_spdy);
12201 std::string response_data3;
12202 ASSERT_EQ(OK, ReadTransaction(trans3.get(), &response_data3));
12203 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
12204}
12205
[email protected]23e482282013-06-14 16:08:0212206TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2312207 const std::string https_url = "https://www.example.org:8080/";
12208 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0412209
12210 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2312211 const HostPortPair host_port_pair("www.example.org", 8080);
lgarrona91df87f2014-12-05 00:51:3412212 scoped_ptr<SpdyFrame> connect(
12213 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
[email protected]cdf8f7e72013-05-23 10:56:4612214 scoped_ptr<SpdyFrame> req1(
12215 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]23e482282013-06-14 16:08:0212216 scoped_ptr<SpdyFrame> wrapped_req1(
12217 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3912218
12219 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
[email protected]745aa9c2014-06-27 02:21:2912220 SpdyHeaderBlock req2_block;
12221 req2_block[spdy_util_.GetMethodKey()] = "GET";
bnc33b8cef42014-11-19 17:30:3812222 req2_block[spdy_util_.GetPathKey()] = "/";
bncce36dca22015-04-21 22:11:2312223 req2_block[spdy_util_.GetHostKey()] = "www.example.org:8080";
[email protected]745aa9c2014-06-27 02:21:2912224 req2_block[spdy_util_.GetSchemeKey()] = "http";
12225 spdy_util_.MaybeAddVersionHeader(&req2_block);
[email protected]601e03f12014-04-06 16:26:3912226 scoped_ptr<SpdyFrame> req2(
[email protected]745aa9c2014-06-27 02:21:2912227 spdy_util_.ConstructSpdySyn(3, req2_block, MEDIUM, false, true));
[email protected]8450d722012-07-02 19:14:0412228
12229 MockWrite writes1[] = {
12230 CreateMockWrite(*connect, 0),
12231 CreateMockWrite(*wrapped_req1, 2),
12232 CreateMockWrite(*req2, 5),
12233 };
12234
[email protected]23e482282013-06-14 16:08:0212235 scoped_ptr<SpdyFrame> conn_resp(
12236 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12237 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12238 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
12239 scoped_ptr<SpdyFrame> wrapped_resp1(
12240 spdy_util_.ConstructWrappedSpdyFrame(resp1, 1));
12241 scoped_ptr<SpdyFrame> wrapped_body1(
12242 spdy_util_.ConstructWrappedSpdyFrame(body1, 1));
12243 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
12244 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]8450d722012-07-02 19:14:0412245 MockRead reads1[] = {
12246 CreateMockRead(*conn_resp, 1),
12247 CreateMockRead(*wrapped_resp1, 3),
12248 CreateMockRead(*wrapped_body1, 4),
12249 CreateMockRead(*resp2, 6),
12250 CreateMockRead(*body2, 7),
12251 MockRead(ASYNC, ERR_IO_PENDING, 8)
12252 };
12253
[email protected]dd54bd82012-07-19 23:44:5712254 DeterministicSocketData data1(reads1, arraysize(reads1),
12255 writes1, arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0412256 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5712257 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0412258
[email protected]bb88e1d32013-05-03 23:11:0712259 session_deps_.proxy_service.reset(
[email protected]f6c63db52013-02-02 00:35:2212260 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
vishal.b62985ca92015-04-17 08:45:5112261 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712262 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0412263 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
[email protected]23e482282013-06-14 16:08:0212264 ssl1.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0712265 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0412266 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
[email protected]23e482282013-06-14 16:08:0212267 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0712268 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
12269 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0412270
12271 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0712272 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]8450d722012-07-02 19:14:0412273
12274 // Start the first transaction to set up the SpdySession
12275 HttpRequestInfo request1;
12276 request1.method = "GET";
12277 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0412278 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012279 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0412280 TestCompletionCallback callback1;
12281 EXPECT_EQ(ERR_IO_PENDING,
12282 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412283 base::MessageLoop::current()->RunUntilIdle();
[email protected]dd54bd82012-07-19 23:44:5712284 data1.RunFor(4);
[email protected]8450d722012-07-02 19:14:0412285
12286 EXPECT_EQ(OK, callback1.WaitForResult());
12287 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
12288
[email protected]f6c63db52013-02-02 00:35:2212289 LoadTimingInfo load_timing_info1;
12290 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
12291 TestLoadTimingNotReusedWithPac(load_timing_info1,
12292 CONNECT_TIMING_HAS_SSL_TIMES);
12293
[email protected]8450d722012-07-02 19:14:0412294 // Now, start the HTTP request
12295 HttpRequestInfo request2;
12296 request2.method = "GET";
12297 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0412298 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012299 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0412300 TestCompletionCallback callback2;
12301 EXPECT_EQ(ERR_IO_PENDING,
12302 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412303 base::MessageLoop::current()->RunUntilIdle();
[email protected]dd54bd82012-07-19 23:44:5712304 data1.RunFor(3);
[email protected]8450d722012-07-02 19:14:0412305
12306 EXPECT_EQ(OK, callback2.WaitForResult());
12307 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2212308
12309 LoadTimingInfo load_timing_info2;
12310 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
12311 // The established SPDY sessions is considered reused by the HTTP request.
12312 TestLoadTimingReusedWithPac(load_timing_info2);
12313 // HTTP requests over a SPDY session should have a different connection
12314 // socket_log_id than requests over a tunnel.
12315 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0412316}
12317
[email protected]2d88e7d2012-07-19 17:55:1712318// Test that in the case where we have a SPDY session to a SPDY proxy
12319// that we do not pool other origins that resolve to the same IP when
12320// the certificate does not match the new origin.
12321// http://crbug.com/134690
[email protected]23e482282013-06-14 16:08:0212322TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2312323 const std::string url1 = "http://www.example.org/";
12324 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1712325 const std::string ip_addr = "1.2.3.4";
12326
12327 // SPDY GET for HTTP URL (through SPDY proxy)
[email protected]23e482282013-06-14 16:08:0212328 scoped_ptr<SpdyHeaderBlock> headers(
bncce36dca22015-04-21 22:11:2312329 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
[email protected]745aa9c2014-06-27 02:21:2912330 scoped_ptr<SpdyFrame> req1(
12331 spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, false, true));
[email protected]2d88e7d2012-07-19 17:55:1712332
12333 MockWrite writes1[] = {
12334 CreateMockWrite(*req1, 0),
12335 };
12336
[email protected]23e482282013-06-14 16:08:0212337 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12338 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1712339 MockRead reads1[] = {
12340 CreateMockRead(*resp1, 1),
12341 CreateMockRead(*body1, 2),
12342 MockRead(ASYNC, OK, 3) // EOF
12343 };
12344
12345 scoped_ptr<DeterministicSocketData> data1(
12346 new DeterministicSocketData(reads1, arraysize(reads1),
12347 writes1, arraysize(writes1)));
12348 IPAddressNumber ip;
12349 ASSERT_TRUE(ParseIPLiteralToNumber(ip_addr, &ip));
12350 IPEndPoint peer_addr = IPEndPoint(ip, 443);
12351 MockConnect connect_data1(ASYNC, OK, peer_addr);
12352 data1->set_connect_data(connect_data1);
12353
12354 // SPDY GET for HTTPS URL (direct)
[email protected]cdf8f7e72013-05-23 10:56:4612355 scoped_ptr<SpdyFrame> req2(
12356 spdy_util_.ConstructSpdyGet(url2.c_str(), false, 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1712357
12358 MockWrite writes2[] = {
12359 CreateMockWrite(*req2, 0),
12360 };
12361
[email protected]23e482282013-06-14 16:08:0212362 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12363 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1712364 MockRead reads2[] = {
12365 CreateMockRead(*resp2, 1),
12366 CreateMockRead(*body2, 2),
12367 MockRead(ASYNC, OK, 3) // EOF
12368 };
12369
12370 scoped_ptr<DeterministicSocketData> data2(
12371 new DeterministicSocketData(reads2, arraysize(reads2),
12372 writes2, arraysize(writes2)));
12373 MockConnect connect_data2(ASYNC, OK);
12374 data2->set_connect_data(connect_data2);
12375
12376 // Set up a proxy config that sends HTTP requests to a proxy, and
12377 // all others direct.
12378 ProxyConfig proxy_config;
12379 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
[email protected]bb88e1d32013-05-03 23:11:0712380 session_deps_.proxy_service.reset(new ProxyService(
sammc5dd160c2015-04-02 02:43:1312381 new ProxyConfigServiceFixed(proxy_config), nullptr, NULL));
[email protected]2d88e7d2012-07-19 17:55:1712382
bncce36dca22015-04-21 22:11:2312383 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
12384 ssl1.SetNextProto(GetParam());
[email protected]2d88e7d2012-07-19 17:55:1712385 // Load a valid cert. Note, that this does not need to
12386 // be valid for proxy because the MockSSLClientSocket does
12387 // not actually verify it. But SpdySession will use this
12388 // to see if it is valid for the new origin
bncce36dca22015-04-21 22:11:2312389 ssl1.cert = ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
12390 ASSERT_TRUE(ssl1.cert.get());
[email protected]bb88e1d32013-05-03 23:11:0712391 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
12392 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
12393 data1.get());
[email protected]2d88e7d2012-07-19 17:55:1712394
12395 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
[email protected]23e482282013-06-14 16:08:0212396 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0712397 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
12398 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
12399 data2.get());
[email protected]2d88e7d2012-07-19 17:55:1712400
[email protected]bb88e1d32013-05-03 23:11:0712401 session_deps_.host_resolver.reset(new MockCachingHostResolver());
bncce36dca22015-04-21 22:11:2312402 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0712403 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1712404
12405 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0712406 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]2d88e7d2012-07-19 17:55:1712407
12408 // Start the first transaction to set up the SpdySession
12409 HttpRequestInfo request1;
12410 request1.method = "GET";
12411 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1712412 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012413 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1712414 TestCompletionCallback callback1;
12415 ASSERT_EQ(ERR_IO_PENDING,
12416 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
12417 data1->RunFor(3);
12418
12419 ASSERT_TRUE(callback1.have_result());
12420 EXPECT_EQ(OK, callback1.WaitForResult());
12421 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
12422
12423 // Now, start the HTTP request
12424 HttpRequestInfo request2;
12425 request2.method = "GET";
12426 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1712427 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012428 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1712429 TestCompletionCallback callback2;
12430 EXPECT_EQ(ERR_IO_PENDING,
12431 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412432 base::MessageLoop::current()->RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1712433 data2->RunFor(3);
12434
12435 ASSERT_TRUE(callback2.have_result());
12436 EXPECT_EQ(OK, callback2.WaitForResult());
12437 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
12438}
12439
[email protected]85f97342013-04-17 06:12:2412440// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
12441// error) in SPDY session, removes the socket from pool and closes the SPDY
12442// session. Verify that new url's from the same HttpNetworkSession (and a new
12443// SpdySession) do work. http://crbug.com/224701
[email protected]23e482282013-06-14 16:08:0212444TEST_P(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2312445 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2412446
12447 MockRead reads1[] = {
12448 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
12449 };
12450
12451 scoped_ptr<DeterministicSocketData> data1(
12452 new DeterministicSocketData(reads1, arraysize(reads1), NULL, 0));
12453 data1->SetStop(1);
12454
[email protected]cdf8f7e72013-05-23 10:56:4612455 scoped_ptr<SpdyFrame> req2(
12456 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2412457 MockWrite writes2[] = {
12458 CreateMockWrite(*req2, 0),
12459 };
12460
[email protected]23e482282013-06-14 16:08:0212461 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12462 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]85f97342013-04-17 06:12:2412463 MockRead reads2[] = {
12464 CreateMockRead(*resp2, 1),
12465 CreateMockRead(*body2, 2),
12466 MockRead(ASYNC, OK, 3) // EOF
12467 };
12468
12469 scoped_ptr<DeterministicSocketData> data2(
12470 new DeterministicSocketData(reads2, arraysize(reads2),
12471 writes2, arraysize(writes2)));
12472
[email protected]85f97342013-04-17 06:12:2412473 SSLSocketDataProvider ssl1(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212474 ssl1.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0712475 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
12476 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
12477 data1.get());
[email protected]85f97342013-04-17 06:12:2412478
12479 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212480 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0712481 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
12482 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
12483 data2.get());
[email protected]85f97342013-04-17 06:12:2412484
12485 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0712486 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]85f97342013-04-17 06:12:2412487
12488 // Start the first transaction to set up the SpdySession and verify that
12489 // connection was closed.
12490 HttpRequestInfo request1;
12491 request1.method = "GET";
12492 request1.url = GURL(https_url);
12493 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012494 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2412495 TestCompletionCallback callback1;
12496 EXPECT_EQ(ERR_IO_PENDING,
12497 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412498 base::MessageLoop::current()->RunUntilIdle();
[email protected]85f97342013-04-17 06:12:2412499 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback1.WaitForResult());
12500
12501 // Now, start the second request and make sure it succeeds.
12502 HttpRequestInfo request2;
12503 request2.method = "GET";
12504 request2.url = GURL(https_url);
12505 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012506 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2412507 TestCompletionCallback callback2;
12508 EXPECT_EQ(ERR_IO_PENDING,
12509 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412510 base::MessageLoop::current()->RunUntilIdle();
[email protected]85f97342013-04-17 06:12:2412511 data2->RunFor(3);
12512
12513 ASSERT_TRUE(callback2.have_result());
12514 EXPECT_EQ(OK, callback2.WaitForResult());
12515 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
12516}
12517
[email protected]23e482282013-06-14 16:08:0212518TEST_P(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]d7599122014-05-24 03:37:2312519 session_deps_.next_protos = SpdyNextProtos();
[email protected]483fa202013-05-14 01:07:0312520 ClientSocketPoolManager::set_max_sockets_per_group(
12521 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12522 ClientSocketPoolManager::set_max_sockets_per_pool(
12523 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12524
12525 // Use two different hosts with different IPs so they don't get pooled.
12526 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
12527 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
12528 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12529
12530 SSLSocketDataProvider ssl1(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212531 ssl1.SetNextProto(GetParam());
[email protected]483fa202013-05-14 01:07:0312532 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212533 ssl2.SetNextProto(GetParam());
[email protected]483fa202013-05-14 01:07:0312534 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
12535 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
12536
[email protected]cdf8f7e72013-05-23 10:56:4612537 scoped_ptr<SpdyFrame> host1_req(spdy_util_.ConstructSpdyGet(
[email protected]483fa202013-05-14 01:07:0312538 "https://www.a.com", false, 1, DEFAULT_PRIORITY));
12539 MockWrite spdy1_writes[] = {
rch8e6c6c42015-05-01 14:05:1312540 CreateMockWrite(*host1_req, 0),
[email protected]483fa202013-05-14 01:07:0312541 };
[email protected]23e482282013-06-14 16:08:0212542 scoped_ptr<SpdyFrame> host1_resp(
12543 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12544 scoped_ptr<SpdyFrame> host1_resp_body(
12545 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0312546 MockRead spdy1_reads[] = {
rch8e6c6c42015-05-01 14:05:1312547 CreateMockRead(*host1_resp, 1),
12548 CreateMockRead(*host1_resp_body, 2),
12549 MockRead(ASYNC, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0312550 };
12551
rch8e6c6c42015-05-01 14:05:1312552 scoped_ptr<SequencedSocketData> spdy1_data(
12553 new SequencedSocketData(spdy1_reads, arraysize(spdy1_reads), spdy1_writes,
12554 arraysize(spdy1_writes)));
[email protected]483fa202013-05-14 01:07:0312555 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
12556
[email protected]cdf8f7e72013-05-23 10:56:4612557 scoped_ptr<SpdyFrame> host2_req(spdy_util_.ConstructSpdyGet(
[email protected]483fa202013-05-14 01:07:0312558 "https://www.b.com", false, 1, DEFAULT_PRIORITY));
12559 MockWrite spdy2_writes[] = {
rch8e6c6c42015-05-01 14:05:1312560 CreateMockWrite(*host2_req, 0),
[email protected]483fa202013-05-14 01:07:0312561 };
[email protected]23e482282013-06-14 16:08:0212562 scoped_ptr<SpdyFrame> host2_resp(
12563 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12564 scoped_ptr<SpdyFrame> host2_resp_body(
12565 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0312566 MockRead spdy2_reads[] = {
rch8e6c6c42015-05-01 14:05:1312567 CreateMockRead(*host2_resp, 1),
12568 CreateMockRead(*host2_resp_body, 2),
12569 MockRead(ASYNC, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0312570 };
12571
rch8e6c6c42015-05-01 14:05:1312572 scoped_ptr<SequencedSocketData> spdy2_data(
12573 new SequencedSocketData(spdy2_reads, arraysize(spdy2_reads), spdy2_writes,
12574 arraysize(spdy2_writes)));
[email protected]483fa202013-05-14 01:07:0312575 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
12576
12577 MockWrite http_write[] = {
12578 MockWrite("GET / HTTP/1.1\r\n"
12579 "Host: www.a.com\r\n"
12580 "Connection: keep-alive\r\n\r\n"),
12581 };
12582
12583 MockRead http_read[] = {
12584 MockRead("HTTP/1.1 200 OK\r\n"),
12585 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12586 MockRead("Content-Length: 6\r\n\r\n"),
12587 MockRead("hello!"),
12588 };
12589 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
12590 http_write, arraysize(http_write));
12591 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12592
12593 HostPortPair host_port_pair_a("www.a.com", 443);
[email protected]e6d017652013-05-17 18:01:4012594 SpdySessionKey spdy_session_key_a(
[email protected]314b03992014-04-01 01:28:5312595 host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0312596 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2612597 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0312598
12599 TestCompletionCallback callback;
12600 HttpRequestInfo request1;
12601 request1.method = "GET";
12602 request1.url = GURL("https://www.a.com/");
12603 request1.load_flags = 0;
12604 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5012605 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0312606
12607 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
12608 EXPECT_EQ(ERR_IO_PENDING, rv);
12609 EXPECT_EQ(OK, callback.WaitForResult());
12610
12611 const HttpResponseInfo* response = trans->GetResponseInfo();
12612 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5012613 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0312614 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12615 EXPECT_TRUE(response->was_fetched_via_spdy);
12616 EXPECT_TRUE(response->was_npn_negotiated);
12617
12618 std::string response_data;
12619 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
12620 EXPECT_EQ("hello!", response_data);
12621 trans.reset();
12622 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2612623 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0312624
12625 HostPortPair host_port_pair_b("www.b.com", 443);
[email protected]e6d017652013-05-17 18:01:4012626 SpdySessionKey spdy_session_key_b(
[email protected]314b03992014-04-01 01:28:5312627 host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0312628 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2612629 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0312630 HttpRequestInfo request2;
12631 request2.method = "GET";
12632 request2.url = GURL("https://www.b.com/");
12633 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012634 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0312635
12636 rv = trans->Start(&request2, callback.callback(), BoundNetLog());
12637 EXPECT_EQ(ERR_IO_PENDING, rv);
12638 EXPECT_EQ(OK, callback.WaitForResult());
12639
12640 response = trans->GetResponseInfo();
12641 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5012642 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0312643 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12644 EXPECT_TRUE(response->was_fetched_via_spdy);
12645 EXPECT_TRUE(response->was_npn_negotiated);
12646 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
12647 EXPECT_EQ("hello!", response_data);
12648 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2612649 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0312650 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2612651 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0312652
12653 HostPortPair host_port_pair_a1("www.a.com", 80);
[email protected]e6d017652013-05-17 18:01:4012654 SpdySessionKey spdy_session_key_a1(
[email protected]314b03992014-04-01 01:28:5312655 host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0312656 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2612657 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0312658 HttpRequestInfo request3;
12659 request3.method = "GET";
12660 request3.url = GURL("http://www.a.com/");
12661 request3.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012662 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0312663
12664 rv = trans->Start(&request3, callback.callback(), BoundNetLog());
12665 EXPECT_EQ(ERR_IO_PENDING, rv);
12666 EXPECT_EQ(OK, callback.WaitForResult());
12667
12668 response = trans->GetResponseInfo();
12669 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5012670 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0312671 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12672 EXPECT_FALSE(response->was_fetched_via_spdy);
12673 EXPECT_FALSE(response->was_npn_negotiated);
12674 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
12675 EXPECT_EQ("hello!", response_data);
12676 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2612677 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0312678 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2612679 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0312680}
12681
[email protected]79e1fd62013-06-20 06:50:0412682TEST_P(HttpNetworkTransactionTest, HttpSyncConnectError) {
12683 HttpRequestInfo request;
12684 request.method = "GET";
bncce36dca22015-04-21 22:11:2312685 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0412686 request.load_flags = 0;
12687
[email protected]3fe8d2f82013-10-17 08:56:0712688 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412689 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112690 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412691
12692 MockConnect mock_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
12693 StaticSocketDataProvider data;
12694 data.set_connect_data(mock_connect);
12695 session_deps_.socket_factory->AddSocketDataProvider(&data);
12696
12697 TestCompletionCallback callback;
12698
12699 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12700 EXPECT_EQ(ERR_IO_PENDING, rv);
12701
12702 rv = callback.WaitForResult();
12703 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
12704
[email protected]79e1fd62013-06-20 06:50:0412705 // We don't care whether this succeeds or fails, but it shouldn't crash.
12706 HttpRequestHeaders request_headers;
12707 trans->GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4712708
12709 ConnectionAttempts attempts;
12710 trans->GetConnectionAttempts(&attempts);
12711 ASSERT_EQ(1u, attempts.size());
12712 EXPECT_EQ(ERR_CONNECTION_REFUSED, attempts[0].result);
[email protected]79e1fd62013-06-20 06:50:0412713}
12714
12715TEST_P(HttpNetworkTransactionTest, HttpAsyncConnectError) {
12716 HttpRequestInfo request;
12717 request.method = "GET";
bncce36dca22015-04-21 22:11:2312718 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0412719 request.load_flags = 0;
12720
[email protected]3fe8d2f82013-10-17 08:56:0712721 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412722 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112723 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412724
12725 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
12726 StaticSocketDataProvider data;
12727 data.set_connect_data(mock_connect);
12728 session_deps_.socket_factory->AddSocketDataProvider(&data);
12729
12730 TestCompletionCallback callback;
12731
12732 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12733 EXPECT_EQ(ERR_IO_PENDING, rv);
12734
12735 rv = callback.WaitForResult();
12736 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
12737
[email protected]79e1fd62013-06-20 06:50:0412738 // We don't care whether this succeeds or fails, but it shouldn't crash.
12739 HttpRequestHeaders request_headers;
12740 trans->GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4712741
12742 ConnectionAttempts attempts;
12743 trans->GetConnectionAttempts(&attempts);
12744 ASSERT_EQ(1u, attempts.size());
12745 EXPECT_EQ(ERR_CONNECTION_REFUSED, attempts[0].result);
[email protected]79e1fd62013-06-20 06:50:0412746}
12747
12748TEST_P(HttpNetworkTransactionTest, HttpSyncWriteError) {
12749 HttpRequestInfo request;
12750 request.method = "GET";
bncce36dca22015-04-21 22:11:2312751 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0412752 request.load_flags = 0;
12753
[email protected]3fe8d2f82013-10-17 08:56:0712754 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412755 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112756 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412757
12758 MockWrite data_writes[] = {
12759 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
12760 };
12761 MockRead data_reads[] = {
12762 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
12763 };
12764
12765 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12766 data_writes, arraysize(data_writes));
12767 session_deps_.socket_factory->AddSocketDataProvider(&data);
12768
12769 TestCompletionCallback callback;
12770
12771 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12772 EXPECT_EQ(ERR_IO_PENDING, rv);
12773
12774 rv = callback.WaitForResult();
12775 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12776
[email protected]79e1fd62013-06-20 06:50:0412777 HttpRequestHeaders request_headers;
12778 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12779 EXPECT_TRUE(request_headers.HasHeader("Host"));
12780}
12781
12782TEST_P(HttpNetworkTransactionTest, HttpAsyncWriteError) {
12783 HttpRequestInfo request;
12784 request.method = "GET";
bncce36dca22015-04-21 22:11:2312785 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0412786 request.load_flags = 0;
12787
[email protected]3fe8d2f82013-10-17 08:56:0712788 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412789 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112790 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412791
12792 MockWrite data_writes[] = {
12793 MockWrite(ASYNC, ERR_CONNECTION_RESET),
12794 };
12795 MockRead data_reads[] = {
12796 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
12797 };
12798
12799 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12800 data_writes, arraysize(data_writes));
12801 session_deps_.socket_factory->AddSocketDataProvider(&data);
12802
12803 TestCompletionCallback callback;
12804
12805 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12806 EXPECT_EQ(ERR_IO_PENDING, rv);
12807
12808 rv = callback.WaitForResult();
12809 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12810
[email protected]79e1fd62013-06-20 06:50:0412811 HttpRequestHeaders request_headers;
12812 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12813 EXPECT_TRUE(request_headers.HasHeader("Host"));
12814}
12815
12816TEST_P(HttpNetworkTransactionTest, HttpSyncReadError) {
12817 HttpRequestInfo request;
12818 request.method = "GET";
bncce36dca22015-04-21 22:11:2312819 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0412820 request.load_flags = 0;
12821
[email protected]3fe8d2f82013-10-17 08:56:0712822 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412823 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112824 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412825
12826 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2312827 MockWrite(
12828 "GET / HTTP/1.1\r\n"
12829 "Host: www.example.org\r\n"
12830 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0412831 };
12832 MockRead data_reads[] = {
12833 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
12834 };
12835
12836 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12837 data_writes, arraysize(data_writes));
12838 session_deps_.socket_factory->AddSocketDataProvider(&data);
12839
12840 TestCompletionCallback callback;
12841
12842 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12843 EXPECT_EQ(ERR_IO_PENDING, rv);
12844
12845 rv = callback.WaitForResult();
12846 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12847
[email protected]79e1fd62013-06-20 06:50:0412848 HttpRequestHeaders request_headers;
12849 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12850 EXPECT_TRUE(request_headers.HasHeader("Host"));
12851}
12852
12853TEST_P(HttpNetworkTransactionTest, HttpAsyncReadError) {
12854 HttpRequestInfo request;
12855 request.method = "GET";
bncce36dca22015-04-21 22:11:2312856 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0412857 request.load_flags = 0;
12858
[email protected]3fe8d2f82013-10-17 08:56:0712859 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412860 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112861 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412862
12863 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2312864 MockWrite(
12865 "GET / HTTP/1.1\r\n"
12866 "Host: www.example.org\r\n"
12867 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0412868 };
12869 MockRead data_reads[] = {
12870 MockRead(ASYNC, ERR_CONNECTION_RESET),
12871 };
12872
12873 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12874 data_writes, arraysize(data_writes));
12875 session_deps_.socket_factory->AddSocketDataProvider(&data);
12876
12877 TestCompletionCallback callback;
12878
12879 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12880 EXPECT_EQ(ERR_IO_PENDING, rv);
12881
12882 rv = callback.WaitForResult();
12883 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12884
[email protected]79e1fd62013-06-20 06:50:0412885 HttpRequestHeaders request_headers;
12886 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12887 EXPECT_TRUE(request_headers.HasHeader("Host"));
12888}
12889
12890TEST_P(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
12891 HttpRequestInfo request;
12892 request.method = "GET";
bncce36dca22015-04-21 22:11:2312893 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0412894 request.load_flags = 0;
12895 request.extra_headers.SetHeader("X-Foo", "bar");
12896
[email protected]3fe8d2f82013-10-17 08:56:0712897 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412898 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112899 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412900
12901 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2312902 MockWrite(
12903 "GET / HTTP/1.1\r\n"
12904 "Host: www.example.org\r\n"
12905 "Connection: keep-alive\r\n"
12906 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0412907 };
12908 MockRead data_reads[] = {
12909 MockRead("HTTP/1.1 200 OK\r\n"
12910 "Content-Length: 5\r\n\r\n"
12911 "hello"),
12912 MockRead(ASYNC, ERR_UNEXPECTED),
12913 };
12914
12915 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12916 data_writes, arraysize(data_writes));
12917 session_deps_.socket_factory->AddSocketDataProvider(&data);
12918
12919 TestCompletionCallback callback;
12920
12921 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12922 EXPECT_EQ(ERR_IO_PENDING, rv);
12923
12924 rv = callback.WaitForResult();
12925 EXPECT_EQ(OK, rv);
12926
12927 HttpRequestHeaders request_headers;
12928 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12929 std::string foo;
12930 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
12931 EXPECT_EQ("bar", foo);
12932}
12933
[email protected]bf828982013-08-14 18:01:4712934namespace {
12935
yhiranoa7e05bb2014-11-06 05:40:3912936// Fake HttpStream that simply records calls to SetPriority().
12937class FakeStream : public HttpStream,
[email protected]e86839fd2013-08-14 18:29:0312938 public base::SupportsWeakPtr<FakeStream> {
12939 public:
12940 explicit FakeStream(RequestPriority priority) : priority_(priority) {}
dchengb03027d2014-10-21 12:00:2012941 ~FakeStream() override {}
[email protected]e86839fd2013-08-14 18:29:0312942
12943 RequestPriority priority() const { return priority_; }
12944
dchengb03027d2014-10-21 12:00:2012945 int InitializeStream(const HttpRequestInfo* request_info,
12946 RequestPriority priority,
12947 const BoundNetLog& net_log,
12948 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0312949 return ERR_IO_PENDING;
12950 }
12951
dchengb03027d2014-10-21 12:00:2012952 int SendRequest(const HttpRequestHeaders& request_headers,
12953 HttpResponseInfo* response,
12954 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0312955 ADD_FAILURE();
12956 return ERR_UNEXPECTED;
12957 }
12958
dchengb03027d2014-10-21 12:00:2012959 int ReadResponseHeaders(const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0312960 ADD_FAILURE();
12961 return ERR_UNEXPECTED;
12962 }
12963
dchengb03027d2014-10-21 12:00:2012964 int ReadResponseBody(IOBuffer* buf,
12965 int buf_len,
12966 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0312967 ADD_FAILURE();
12968 return ERR_UNEXPECTED;
12969 }
12970
dchengb03027d2014-10-21 12:00:2012971 void Close(bool not_reusable) override {}
[email protected]e86839fd2013-08-14 18:29:0312972
dchengb03027d2014-10-21 12:00:2012973 bool IsResponseBodyComplete() const override {
[email protected]e86839fd2013-08-14 18:29:0312974 ADD_FAILURE();
12975 return false;
12976 }
12977
dchengb03027d2014-10-21 12:00:2012978 bool CanFindEndOfResponse() const override { return false; }
[email protected]e86839fd2013-08-14 18:29:0312979
dchengb03027d2014-10-21 12:00:2012980 bool IsConnectionReused() const override {
[email protected]e86839fd2013-08-14 18:29:0312981 ADD_FAILURE();
12982 return false;
12983 }
12984
dchengb03027d2014-10-21 12:00:2012985 void SetConnectionReused() override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0312986
dchengb03027d2014-10-21 12:00:2012987 bool IsConnectionReusable() const override {
[email protected]e86839fd2013-08-14 18:29:0312988 ADD_FAILURE();
12989 return false;
12990 }
12991
dchengb03027d2014-10-21 12:00:2012992 int64 GetTotalReceivedBytes() const override {
[email protected]bc92bc972013-12-13 08:32:5912993 ADD_FAILURE();
12994 return 0;
12995 }
12996
dchengb03027d2014-10-21 12:00:2012997 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
[email protected]e86839fd2013-08-14 18:29:0312998 ADD_FAILURE();
12999 return false;
13000 }
13001
dchengb03027d2014-10-21 12:00:2013002 void GetSSLInfo(SSLInfo* ssl_info) override { ADD_FAILURE(); }
13003
13004 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
[email protected]e86839fd2013-08-14 18:29:0313005 ADD_FAILURE();
13006 }
13007
dchengb03027d2014-10-21 12:00:2013008 bool IsSpdyHttpStream() const override {
[email protected]e86839fd2013-08-14 18:29:0313009 ADD_FAILURE();
13010 return false;
13011 }
13012
dchengb03027d2014-10-21 12:00:2013013 void Drain(HttpNetworkSession* session) override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0313014
dchengb03027d2014-10-21 12:00:2013015 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]e86839fd2013-08-14 18:29:0313016
yhiranoa7e05bb2014-11-06 05:40:3913017 UploadProgress GetUploadProgress() const override { return UploadProgress(); }
13018
13019 HttpStream* RenewStreamForAuth() override { return NULL; }
13020
[email protected]e86839fd2013-08-14 18:29:0313021 private:
13022 RequestPriority priority_;
13023
13024 DISALLOW_COPY_AND_ASSIGN(FakeStream);
13025};
13026
13027// Fake HttpStreamRequest that simply records calls to SetPriority()
13028// and vends FakeStreams with its current priority.
[email protected]bf828982013-08-14 18:01:4713029class FakeStreamRequest : public HttpStreamRequest,
13030 public base::SupportsWeakPtr<FakeStreamRequest> {
13031 public:
[email protected]e86839fd2013-08-14 18:29:0313032 FakeStreamRequest(RequestPriority priority,
13033 HttpStreamRequest::Delegate* delegate)
13034 : priority_(priority),
[email protected]831e4a32013-11-14 02:14:4413035 delegate_(delegate),
13036 websocket_stream_create_helper_(NULL) {}
13037
13038 FakeStreamRequest(RequestPriority priority,
13039 HttpStreamRequest::Delegate* delegate,
13040 WebSocketHandshakeStreamBase::CreateHelper* create_helper)
13041 : priority_(priority),
13042 delegate_(delegate),
13043 websocket_stream_create_helper_(create_helper) {}
[email protected]e86839fd2013-08-14 18:29:0313044
dchengb03027d2014-10-21 12:00:2013045 ~FakeStreamRequest() override {}
[email protected]bf828982013-08-14 18:01:4713046
13047 RequestPriority priority() const { return priority_; }
13048
[email protected]831e4a32013-11-14 02:14:4413049 const WebSocketHandshakeStreamBase::CreateHelper*
13050 websocket_stream_create_helper() const {
13051 return websocket_stream_create_helper_;
13052 }
13053
[email protected]e86839fd2013-08-14 18:29:0313054 // Create a new FakeStream and pass it to the request's
13055 // delegate. Returns a weak pointer to the FakeStream.
13056 base::WeakPtr<FakeStream> FinishStreamRequest() {
13057 FakeStream* fake_stream = new FakeStream(priority_);
13058 // Do this before calling OnStreamReady() as OnStreamReady() may
13059 // immediately delete |fake_stream|.
13060 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
13061 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), fake_stream);
13062 return weak_stream;
13063 }
13064
dchengb03027d2014-10-21 12:00:2013065 int RestartTunnelWithProxyAuth(const AuthCredentials& credentials) override {
[email protected]bf828982013-08-14 18:01:4713066 ADD_FAILURE();
13067 return ERR_UNEXPECTED;
13068 }
13069
dchengb03027d2014-10-21 12:00:2013070 LoadState GetLoadState() const override {
[email protected]bf828982013-08-14 18:01:4713071 ADD_FAILURE();
13072 return LoadState();
13073 }
13074
dchengb03027d2014-10-21 12:00:2013075 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]bf828982013-08-14 18:01:4713076
dchengb03027d2014-10-21 12:00:2013077 bool was_npn_negotiated() const override { return false; }
[email protected]bf828982013-08-14 18:01:4713078
dchengb03027d2014-10-21 12:00:2013079 NextProto protocol_negotiated() const override { return kProtoUnknown; }
[email protected]bf828982013-08-14 18:01:4713080
dchengb03027d2014-10-21 12:00:2013081 bool using_spdy() const override { return false; }
[email protected]bf828982013-08-14 18:01:4713082
ttuttle1f2d7e92015-04-28 16:17:4713083 const ConnectionAttempts& connection_attempts() const override {
13084 static ConnectionAttempts no_attempts;
13085 return no_attempts;
13086 }
13087
[email protected]bf828982013-08-14 18:01:4713088 private:
13089 RequestPriority priority_;
[email protected]e86839fd2013-08-14 18:29:0313090 HttpStreamRequest::Delegate* const delegate_;
[email protected]831e4a32013-11-14 02:14:4413091 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
[email protected]bf828982013-08-14 18:01:4713092
13093 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
13094};
13095
13096// Fake HttpStreamFactory that vends FakeStreamRequests.
13097class FakeStreamFactory : public HttpStreamFactory {
13098 public:
13099 FakeStreamFactory() {}
dchengb03027d2014-10-21 12:00:2013100 ~FakeStreamFactory() override {}
[email protected]bf828982013-08-14 18:01:4713101
13102 // Returns a WeakPtr<> to the last HttpStreamRequest returned by
13103 // RequestStream() (which may be NULL if it was destroyed already).
13104 base::WeakPtr<FakeStreamRequest> last_stream_request() {
13105 return last_stream_request_;
13106 }
13107
dchengb03027d2014-10-21 12:00:2013108 HttpStreamRequest* RequestStream(const HttpRequestInfo& info,
13109 RequestPriority priority,
13110 const SSLConfig& server_ssl_config,
13111 const SSLConfig& proxy_ssl_config,
13112 HttpStreamRequest::Delegate* delegate,
13113 const BoundNetLog& net_log) override {
[email protected]e86839fd2013-08-14 18:29:0313114 FakeStreamRequest* fake_request = new FakeStreamRequest(priority, delegate);
[email protected]bf828982013-08-14 18:01:4713115 last_stream_request_ = fake_request->AsWeakPtr();
13116 return fake_request;
13117 }
13118
dchengb03027d2014-10-21 12:00:2013119 HttpStreamRequest* RequestWebSocketHandshakeStream(
[email protected]bf828982013-08-14 18:01:4713120 const HttpRequestInfo& info,
13121 RequestPriority priority,
13122 const SSLConfig& server_ssl_config,
13123 const SSLConfig& proxy_ssl_config,
13124 HttpStreamRequest::Delegate* delegate,
[email protected]467086b2013-11-12 08:19:4613125 WebSocketHandshakeStreamBase::CreateHelper* create_helper,
mostynbba063d6032014-10-09 11:01:1313126 const BoundNetLog& net_log) override {
[email protected]831e4a32013-11-14 02:14:4413127 FakeStreamRequest* fake_request =
13128 new FakeStreamRequest(priority, delegate, create_helper);
13129 last_stream_request_ = fake_request->AsWeakPtr();
13130 return fake_request;
[email protected]bf828982013-08-14 18:01:4713131 }
13132
dchengb03027d2014-10-21 12:00:2013133 void PreconnectStreams(int num_streams,
13134 const HttpRequestInfo& info,
13135 RequestPriority priority,
13136 const SSLConfig& server_ssl_config,
13137 const SSLConfig& proxy_ssl_config) override {
[email protected]bf828982013-08-14 18:01:4713138 ADD_FAILURE();
13139 }
13140
dchengb03027d2014-10-21 12:00:2013141 const HostMappingRules* GetHostMappingRules() const override {
[email protected]bf828982013-08-14 18:01:4713142 ADD_FAILURE();
13143 return NULL;
13144 }
13145
13146 private:
13147 base::WeakPtr<FakeStreamRequest> last_stream_request_;
13148
13149 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
13150};
13151
Adam Rice425cf122015-01-19 06:18:2413152// TODO(ricea): Maybe unify this with the one in
13153// url_request_http_job_unittest.cc ?
13154class FakeWebSocketBasicHandshakeStream : public WebSocketHandshakeStreamBase {
13155 public:
13156 FakeWebSocketBasicHandshakeStream(scoped_ptr<ClientSocketHandle> connection,
13157 bool using_proxy)
13158 : state_(connection.release(), using_proxy) {}
13159
13160 // Fake implementation of HttpStreamBase methods.
13161 // This ends up being quite "real" because this object has to really send data
13162 // on the mock socket. It might be easier to use the real implementation, but
13163 // the fact that the WebSocket code is not compiled on iOS makes that
13164 // difficult.
13165 int InitializeStream(const HttpRequestInfo* request_info,
13166 RequestPriority priority,
13167 const BoundNetLog& net_log,
13168 const CompletionCallback& callback) override {
13169 state_.Initialize(request_info, priority, net_log, callback);
13170 return OK;
13171 }
13172
13173 int SendRequest(const HttpRequestHeaders& request_headers,
13174 HttpResponseInfo* response,
13175 const CompletionCallback& callback) override {
13176 return parser()->SendRequest(state_.GenerateRequestLine(), request_headers,
13177 response, callback);
13178 }
13179
13180 int ReadResponseHeaders(const CompletionCallback& callback) override {
13181 return parser()->ReadResponseHeaders(callback);
13182 }
13183
13184 int ReadResponseBody(IOBuffer* buf,
13185 int buf_len,
13186 const CompletionCallback& callback) override {
13187 NOTREACHED();
13188 return ERR_IO_PENDING;
13189 }
13190
13191 void Close(bool not_reusable) override {
13192 if (parser())
13193 parser()->Close(true);
13194 }
13195
13196 bool IsResponseBodyComplete() const override {
13197 NOTREACHED();
13198 return false;
13199 }
13200
13201 bool CanFindEndOfResponse() const override {
13202 return parser()->CanFindEndOfResponse();
13203 }
13204
13205 bool IsConnectionReused() const override {
13206 NOTREACHED();
13207 return false;
13208 }
13209 void SetConnectionReused() override { NOTREACHED(); }
13210
13211 bool IsConnectionReusable() const override {
13212 NOTREACHED();
13213 return false;
13214 }
13215
13216 int64 GetTotalReceivedBytes() const override {
13217 NOTREACHED();
13218 return 0;
13219 }
13220
13221 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
13222 NOTREACHED();
13223 return false;
13224 }
13225
Adam Ricecb76ac62015-02-20 05:33:2513226 void GetSSLInfo(SSLInfo* ssl_info) override {}
Adam Rice425cf122015-01-19 06:18:2413227
13228 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
13229 NOTREACHED();
13230 }
13231
13232 bool IsSpdyHttpStream() const override {
13233 NOTREACHED();
13234 return false;
13235 }
13236
13237 void Drain(HttpNetworkSession* session) override { NOTREACHED(); }
13238
13239 void SetPriority(RequestPriority priority) override { NOTREACHED(); }
13240
13241 UploadProgress GetUploadProgress() const override {
13242 NOTREACHED();
13243 return UploadProgress();
13244 }
13245
13246 HttpStream* RenewStreamForAuth() override {
13247 NOTREACHED();
13248 return nullptr;
13249 }
13250
13251 // Fake implementation of WebSocketHandshakeStreamBase method(s)
13252 scoped_ptr<WebSocketStream> Upgrade() override {
13253 NOTREACHED();
13254 return scoped_ptr<WebSocketStream>();
13255 }
13256
13257 private:
13258 HttpStreamParser* parser() const { return state_.parser(); }
13259 HttpBasicState state_;
13260
13261 DISALLOW_COPY_AND_ASSIGN(FakeWebSocketBasicHandshakeStream);
13262};
13263
[email protected]831e4a32013-11-14 02:14:4413264// TODO(yhirano): Split this class out into a net/websockets file, if it is
13265// worth doing.
13266class FakeWebSocketStreamCreateHelper :
13267 public WebSocketHandshakeStreamBase::CreateHelper {
13268 public:
dchengb03027d2014-10-21 12:00:2013269 WebSocketHandshakeStreamBase* CreateBasicStream(
[email protected]7e841a52013-11-22 09:04:2113270 scoped_ptr<ClientSocketHandle> connection,
mostynbba063d6032014-10-09 11:01:1313271 bool using_proxy) override {
Adam Rice425cf122015-01-19 06:18:2413272 return new FakeWebSocketBasicHandshakeStream(connection.Pass(),
13273 using_proxy);
[email protected]831e4a32013-11-14 02:14:4413274 }
13275
dchengb03027d2014-10-21 12:00:2013276 WebSocketHandshakeStreamBase* CreateSpdyStream(
[email protected]831e4a32013-11-14 02:14:4413277 const base::WeakPtr<SpdySession>& session,
mostynbba063d6032014-10-09 11:01:1313278 bool use_relative_url) override {
[email protected]831e4a32013-11-14 02:14:4413279 NOTREACHED();
13280 return NULL;
13281 };
13282
dchengb03027d2014-10-21 12:00:2013283 ~FakeWebSocketStreamCreateHelper() override {}
[email protected]831e4a32013-11-14 02:14:4413284
13285 virtual scoped_ptr<WebSocketStream> Upgrade() {
13286 NOTREACHED();
13287 return scoped_ptr<WebSocketStream>();
13288 }
13289};
13290
[email protected]bf828982013-08-14 18:01:4713291} // namespace
13292
13293// Make sure that HttpNetworkTransaction passes on its priority to its
13294// stream request on start.
13295TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
13296 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13297 HttpNetworkSessionPeer peer(session);
13298 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4413299 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4713300
dcheng48459ac22014-08-26 00:46:4113301 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4713302
13303 ASSERT_TRUE(fake_factory->last_stream_request() == NULL);
13304
13305 HttpRequestInfo request;
13306 TestCompletionCallback callback;
13307 EXPECT_EQ(ERR_IO_PENDING,
13308 trans.Start(&request, callback.callback(), BoundNetLog()));
13309
13310 base::WeakPtr<FakeStreamRequest> fake_request =
13311 fake_factory->last_stream_request();
13312 ASSERT_TRUE(fake_request != NULL);
13313 EXPECT_EQ(LOW, fake_request->priority());
13314}
13315
13316// Make sure that HttpNetworkTransaction passes on its priority
13317// updates to its stream request.
13318TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriority) {
13319 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13320 HttpNetworkSessionPeer peer(session);
13321 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4413322 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4713323
dcheng48459ac22014-08-26 00:46:4113324 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4713325
13326 HttpRequestInfo request;
13327 TestCompletionCallback callback;
13328 EXPECT_EQ(ERR_IO_PENDING,
13329 trans.Start(&request, callback.callback(), BoundNetLog()));
13330
13331 base::WeakPtr<FakeStreamRequest> fake_request =
13332 fake_factory->last_stream_request();
13333 ASSERT_TRUE(fake_request != NULL);
13334 EXPECT_EQ(LOW, fake_request->priority());
13335
13336 trans.SetPriority(LOWEST);
13337 ASSERT_TRUE(fake_request != NULL);
13338 EXPECT_EQ(LOWEST, fake_request->priority());
13339}
13340
[email protected]e86839fd2013-08-14 18:29:0313341// Make sure that HttpNetworkTransaction passes on its priority
13342// updates to its stream.
13343TEST_P(HttpNetworkTransactionTest, SetStreamPriority) {
13344 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13345 HttpNetworkSessionPeer peer(session);
13346 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4413347 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]e86839fd2013-08-14 18:29:0313348
dcheng48459ac22014-08-26 00:46:4113349 HttpNetworkTransaction trans(LOW, session.get());
[email protected]e86839fd2013-08-14 18:29:0313350
13351 HttpRequestInfo request;
13352 TestCompletionCallback callback;
13353 EXPECT_EQ(ERR_IO_PENDING,
13354 trans.Start(&request, callback.callback(), BoundNetLog()));
13355
13356 base::WeakPtr<FakeStreamRequest> fake_request =
13357 fake_factory->last_stream_request();
13358 ASSERT_TRUE(fake_request != NULL);
13359 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
13360 ASSERT_TRUE(fake_stream != NULL);
13361 EXPECT_EQ(LOW, fake_stream->priority());
13362
13363 trans.SetPriority(LOWEST);
13364 EXPECT_EQ(LOWEST, fake_stream->priority());
13365}
13366
[email protected]831e4a32013-11-14 02:14:4413367TEST_P(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
13368 // The same logic needs to be tested for both ws: and wss: schemes, but this
13369 // test is already parameterised on NextProto, so it uses a loop to verify
13370 // that the different schemes work.
bncce36dca22015-04-21 22:11:2313371 std::string test_cases[] = {"ws://www.example.org/",
13372 "wss://www.example.org/"};
[email protected]831e4a32013-11-14 02:14:4413373 for (size_t i = 0; i < arraysize(test_cases); ++i) {
13374 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13375 HttpNetworkSessionPeer peer(session);
13376 FakeStreamFactory* fake_factory = new FakeStreamFactory();
13377 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
[email protected]0191b51c2013-11-18 10:55:2313378 peer.SetHttpStreamFactoryForWebSocket(
[email protected]831e4a32013-11-14 02:14:4413379 scoped_ptr<HttpStreamFactory>(fake_factory));
13380
dcheng48459ac22014-08-26 00:46:4113381 HttpNetworkTransaction trans(LOW, session.get());
[email protected]831e4a32013-11-14 02:14:4413382 trans.SetWebSocketHandshakeStreamCreateHelper(
13383 &websocket_stream_create_helper);
13384
13385 HttpRequestInfo request;
13386 TestCompletionCallback callback;
13387 request.method = "GET";
13388 request.url = GURL(test_cases[i]);
13389
13390 EXPECT_EQ(ERR_IO_PENDING,
13391 trans.Start(&request, callback.callback(), BoundNetLog()));
13392
13393 base::WeakPtr<FakeStreamRequest> fake_request =
13394 fake_factory->last_stream_request();
13395 ASSERT_TRUE(fake_request != NULL);
13396 EXPECT_EQ(&websocket_stream_create_helper,
13397 fake_request->websocket_stream_create_helper());
13398 }
13399}
13400
[email protected]043b68c82013-08-22 23:41:5213401// Tests that when a used socket is returned to the SSL socket pool, it's closed
13402// if the transport socket pool is stalled on the global socket limit.
13403TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
13404 ClientSocketPoolManager::set_max_sockets_per_group(
13405 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13406 ClientSocketPoolManager::set_max_sockets_per_pool(
13407 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13408
13409 // Set up SSL request.
13410
13411 HttpRequestInfo ssl_request;
13412 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2313413 ssl_request.url = GURL("https://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5213414
13415 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2313416 MockWrite(
13417 "GET / HTTP/1.1\r\n"
13418 "Host: www.example.org\r\n"
13419 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5213420 };
13421 MockRead ssl_reads[] = {
13422 MockRead("HTTP/1.1 200 OK\r\n"),
13423 MockRead("Content-Length: 11\r\n\r\n"),
13424 MockRead("hello world"),
13425 MockRead(SYNCHRONOUS, OK),
13426 };
13427 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
13428 ssl_writes, arraysize(ssl_writes));
13429 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
13430
13431 SSLSocketDataProvider ssl(ASYNC, OK);
13432 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13433
13434 // Set up HTTP request.
13435
13436 HttpRequestInfo http_request;
13437 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2313438 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5213439
13440 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2313441 MockWrite(
13442 "GET / HTTP/1.1\r\n"
13443 "Host: www.example.org\r\n"
13444 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5213445 };
13446 MockRead http_reads[] = {
13447 MockRead("HTTP/1.1 200 OK\r\n"),
13448 MockRead("Content-Length: 7\r\n\r\n"),
13449 MockRead("falafel"),
13450 MockRead(SYNCHRONOUS, OK),
13451 };
13452 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
13453 http_writes, arraysize(http_writes));
13454 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13455
13456 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13457
13458 // Start the SSL request.
13459 TestCompletionCallback ssl_callback;
13460 scoped_ptr<HttpTransaction> ssl_trans(
13461 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13462 ASSERT_EQ(ERR_IO_PENDING,
13463 ssl_trans->Start(&ssl_request, ssl_callback.callback(),
13464 BoundNetLog()));
13465
13466 // Start the HTTP request. Pool should stall.
13467 TestCompletionCallback http_callback;
13468 scoped_ptr<HttpTransaction> http_trans(
13469 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13470 ASSERT_EQ(ERR_IO_PENDING,
13471 http_trans->Start(&http_request, http_callback.callback(),
13472 BoundNetLog()));
dcheng48459ac22014-08-26 00:46:4113473 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5213474
13475 // Wait for response from SSL request.
13476 ASSERT_EQ(OK, ssl_callback.WaitForResult());
13477 std::string response_data;
13478 ASSERT_EQ(OK, ReadTransaction(ssl_trans.get(), &response_data));
13479 EXPECT_EQ("hello world", response_data);
13480
13481 // The SSL socket should automatically be closed, so the HTTP request can
13482 // start.
dcheng48459ac22014-08-26 00:46:4113483 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
13484 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5213485
13486 // The HTTP request can now complete.
13487 ASSERT_EQ(OK, http_callback.WaitForResult());
13488 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
13489 EXPECT_EQ("falafel", response_data);
13490
dcheng48459ac22014-08-26 00:46:4113491 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5213492}
13493
13494// Tests that when a SSL connection is established but there's no corresponding
13495// request that needs it, the new socket is closed if the transport socket pool
13496// is stalled on the global socket limit.
13497TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
13498 ClientSocketPoolManager::set_max_sockets_per_group(
13499 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13500 ClientSocketPoolManager::set_max_sockets_per_pool(
13501 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13502
13503 // Set up an ssl request.
13504
13505 HttpRequestInfo ssl_request;
13506 ssl_request.method = "GET";
13507 ssl_request.url = GURL("https://www.foopy.com/");
13508
13509 // No data will be sent on the SSL socket.
13510 StaticSocketDataProvider ssl_data;
13511 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
13512
13513 SSLSocketDataProvider ssl(ASYNC, OK);
13514 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13515
13516 // Set up HTTP request.
13517
13518 HttpRequestInfo http_request;
13519 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2313520 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5213521
13522 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2313523 MockWrite(
13524 "GET / HTTP/1.1\r\n"
13525 "Host: www.example.org\r\n"
13526 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5213527 };
13528 MockRead http_reads[] = {
13529 MockRead("HTTP/1.1 200 OK\r\n"),
13530 MockRead("Content-Length: 7\r\n\r\n"),
13531 MockRead("falafel"),
13532 MockRead(SYNCHRONOUS, OK),
13533 };
13534 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
13535 http_writes, arraysize(http_writes));
13536 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13537
13538 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13539
13540 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
13541 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2913542 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
13543 SSLConfig ssl_config;
[email protected]043b68c82013-08-22 23:41:5213544 session->ssl_config_service()->GetSSLConfig(&ssl_config);
13545 http_stream_factory->PreconnectStreams(1, ssl_request, DEFAULT_PRIORITY,
13546 ssl_config, ssl_config);
dcheng48459ac22014-08-26 00:46:4113547 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5213548
13549 // Start the HTTP request. Pool should stall.
13550 TestCompletionCallback http_callback;
13551 scoped_ptr<HttpTransaction> http_trans(
13552 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13553 ASSERT_EQ(ERR_IO_PENDING,
13554 http_trans->Start(&http_request, http_callback.callback(),
13555 BoundNetLog()));
dcheng48459ac22014-08-26 00:46:4113556 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5213557
13558 // The SSL connection will automatically be closed once the connection is
13559 // established, to let the HTTP request start.
13560 ASSERT_EQ(OK, http_callback.WaitForResult());
13561 std::string response_data;
13562 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
13563 EXPECT_EQ("falafel", response_data);
13564
dcheng48459ac22014-08-26 00:46:4113565 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5213566}
13567
[email protected]02d74a02014-04-23 18:10:5413568TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
13569 ScopedVector<UploadElementReader> element_readers;
13570 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713571 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413572
13573 HttpRequestInfo request;
13574 request.method = "POST";
13575 request.url = GURL("http://www.foo.com/");
13576 request.upload_data_stream = &upload_data_stream;
13577 request.load_flags = 0;
13578
13579 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13580 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113581 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413582 // Send headers successfully, but get an error while sending the body.
13583 MockWrite data_writes[] = {
13584 MockWrite("POST / HTTP/1.1\r\n"
13585 "Host: www.foo.com\r\n"
13586 "Connection: keep-alive\r\n"
13587 "Content-Length: 3\r\n\r\n"),
13588 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13589 };
13590
13591 MockRead data_reads[] = {
13592 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
13593 MockRead("hello world"),
13594 MockRead(SYNCHRONOUS, OK),
13595 };
13596 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13597 arraysize(data_writes));
13598 session_deps_.socket_factory->AddSocketDataProvider(&data);
13599
13600 TestCompletionCallback callback;
13601
13602 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13603 EXPECT_EQ(ERR_IO_PENDING, rv);
13604
13605 rv = callback.WaitForResult();
13606 EXPECT_EQ(OK, rv);
13607
13608 const HttpResponseInfo* response = trans->GetResponseInfo();
13609 ASSERT_TRUE(response != NULL);
13610
13611 EXPECT_TRUE(response->headers.get() != NULL);
13612 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
13613
13614 std::string response_data;
13615 rv = ReadTransaction(trans.get(), &response_data);
13616 EXPECT_EQ(OK, rv);
13617 EXPECT_EQ("hello world", response_data);
13618}
13619
13620// This test makes sure the retry logic doesn't trigger when reading an error
13621// response from a server that rejected a POST with a CONNECTION_RESET.
13622TEST_P(HttpNetworkTransactionTest,
13623 PostReadsErrorResponseAfterResetOnReusedSocket) {
13624 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13625 MockWrite data_writes[] = {
13626 MockWrite("GET / HTTP/1.1\r\n"
13627 "Host: www.foo.com\r\n"
13628 "Connection: keep-alive\r\n\r\n"),
13629 MockWrite("POST / HTTP/1.1\r\n"
13630 "Host: www.foo.com\r\n"
13631 "Connection: keep-alive\r\n"
13632 "Content-Length: 3\r\n\r\n"),
13633 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13634 };
13635
13636 MockRead data_reads[] = {
13637 MockRead("HTTP/1.1 200 Peachy\r\n"
13638 "Content-Length: 14\r\n\r\n"),
13639 MockRead("first response"),
13640 MockRead("HTTP/1.1 400 Not OK\r\n"
13641 "Content-Length: 15\r\n\r\n"),
13642 MockRead("second response"),
13643 MockRead(SYNCHRONOUS, OK),
13644 };
13645 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13646 arraysize(data_writes));
13647 session_deps_.socket_factory->AddSocketDataProvider(&data);
13648
13649 TestCompletionCallback callback;
13650 HttpRequestInfo request1;
13651 request1.method = "GET";
13652 request1.url = GURL("http://www.foo.com/");
13653 request1.load_flags = 0;
13654
13655 scoped_ptr<HttpTransaction> trans1(
dcheng48459ac22014-08-26 00:46:4113656 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413657 int rv = trans1->Start(&request1, callback.callback(), BoundNetLog());
13658 EXPECT_EQ(ERR_IO_PENDING, rv);
13659
13660 rv = callback.WaitForResult();
13661 EXPECT_EQ(OK, rv);
13662
13663 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
13664 ASSERT_TRUE(response1 != NULL);
13665
13666 EXPECT_TRUE(response1->headers.get() != NULL);
13667 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
13668
13669 std::string response_data1;
13670 rv = ReadTransaction(trans1.get(), &response_data1);
13671 EXPECT_EQ(OK, rv);
13672 EXPECT_EQ("first response", response_data1);
13673 // Delete the transaction to release the socket back into the socket pool.
13674 trans1.reset();
13675
13676 ScopedVector<UploadElementReader> element_readers;
13677 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713678 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413679
13680 HttpRequestInfo request2;
13681 request2.method = "POST";
13682 request2.url = GURL("http://www.foo.com/");
13683 request2.upload_data_stream = &upload_data_stream;
13684 request2.load_flags = 0;
13685
13686 scoped_ptr<HttpTransaction> trans2(
dcheng48459ac22014-08-26 00:46:4113687 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413688 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
13689 EXPECT_EQ(ERR_IO_PENDING, rv);
13690
13691 rv = callback.WaitForResult();
13692 EXPECT_EQ(OK, rv);
13693
13694 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
13695 ASSERT_TRUE(response2 != NULL);
13696
13697 EXPECT_TRUE(response2->headers.get() != NULL);
13698 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
13699
13700 std::string response_data2;
13701 rv = ReadTransaction(trans2.get(), &response_data2);
13702 EXPECT_EQ(OK, rv);
13703 EXPECT_EQ("second response", response_data2);
13704}
13705
13706TEST_P(HttpNetworkTransactionTest,
13707 PostReadsErrorResponseAfterResetPartialBodySent) {
13708 ScopedVector<UploadElementReader> element_readers;
13709 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713710 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413711
13712 HttpRequestInfo request;
13713 request.method = "POST";
13714 request.url = GURL("http://www.foo.com/");
13715 request.upload_data_stream = &upload_data_stream;
13716 request.load_flags = 0;
13717
13718 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13719 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113720 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413721 // Send headers successfully, but get an error while sending the body.
13722 MockWrite data_writes[] = {
13723 MockWrite("POST / HTTP/1.1\r\n"
13724 "Host: www.foo.com\r\n"
13725 "Connection: keep-alive\r\n"
13726 "Content-Length: 3\r\n\r\n"
13727 "fo"),
13728 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13729 };
13730
13731 MockRead data_reads[] = {
13732 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
13733 MockRead("hello world"),
13734 MockRead(SYNCHRONOUS, OK),
13735 };
13736 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13737 arraysize(data_writes));
13738 session_deps_.socket_factory->AddSocketDataProvider(&data);
13739
13740 TestCompletionCallback callback;
13741
13742 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13743 EXPECT_EQ(ERR_IO_PENDING, rv);
13744
13745 rv = callback.WaitForResult();
13746 EXPECT_EQ(OK, rv);
13747
13748 const HttpResponseInfo* response = trans->GetResponseInfo();
13749 ASSERT_TRUE(response != NULL);
13750
13751 EXPECT_TRUE(response->headers.get() != NULL);
13752 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
13753
13754 std::string response_data;
13755 rv = ReadTransaction(trans.get(), &response_data);
13756 EXPECT_EQ(OK, rv);
13757 EXPECT_EQ("hello world", response_data);
13758}
13759
13760// This tests the more common case than the previous test, where headers and
13761// body are not merged into a single request.
13762TEST_P(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
13763 ScopedVector<UploadElementReader> element_readers;
13764 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713765 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5413766
13767 HttpRequestInfo request;
13768 request.method = "POST";
13769 request.url = GURL("http://www.foo.com/");
13770 request.upload_data_stream = &upload_data_stream;
13771 request.load_flags = 0;
13772
13773 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13774 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113775 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413776 // Send headers successfully, but get an error while sending the body.
13777 MockWrite data_writes[] = {
13778 MockWrite("POST / HTTP/1.1\r\n"
13779 "Host: www.foo.com\r\n"
13780 "Connection: keep-alive\r\n"
13781 "Transfer-Encoding: chunked\r\n\r\n"),
13782 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13783 };
13784
13785 MockRead data_reads[] = {
13786 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
13787 MockRead("hello world"),
13788 MockRead(SYNCHRONOUS, OK),
13789 };
13790 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13791 arraysize(data_writes));
13792 session_deps_.socket_factory->AddSocketDataProvider(&data);
13793
13794 TestCompletionCallback callback;
13795
13796 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13797 EXPECT_EQ(ERR_IO_PENDING, rv);
13798 // Make sure the headers are sent before adding a chunk. This ensures that
13799 // they can't be merged with the body in a single send. Not currently
13800 // necessary since a chunked body is never merged with headers, but this makes
13801 // the test more future proof.
13802 base::RunLoop().RunUntilIdle();
13803
mmenkecbc2b712014-10-09 20:29:0713804 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5413805
13806 rv = callback.WaitForResult();
13807 EXPECT_EQ(OK, rv);
13808
13809 const HttpResponseInfo* response = trans->GetResponseInfo();
13810 ASSERT_TRUE(response != NULL);
13811
13812 EXPECT_TRUE(response->headers.get() != NULL);
13813 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
13814
13815 std::string response_data;
13816 rv = ReadTransaction(trans.get(), &response_data);
13817 EXPECT_EQ(OK, rv);
13818 EXPECT_EQ("hello world", response_data);
13819}
13820
13821TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
13822 ScopedVector<UploadElementReader> element_readers;
13823 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713824 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413825
13826 HttpRequestInfo request;
13827 request.method = "POST";
13828 request.url = GURL("http://www.foo.com/");
13829 request.upload_data_stream = &upload_data_stream;
13830 request.load_flags = 0;
13831
13832 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13833 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113834 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413835
13836 MockWrite data_writes[] = {
13837 MockWrite("POST / HTTP/1.1\r\n"
13838 "Host: www.foo.com\r\n"
13839 "Connection: keep-alive\r\n"
13840 "Content-Length: 3\r\n\r\n"),
13841 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13842 };
13843
13844 MockRead data_reads[] = {
13845 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
13846 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
13847 MockRead("hello world"),
13848 MockRead(SYNCHRONOUS, OK),
13849 };
13850 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13851 arraysize(data_writes));
13852 session_deps_.socket_factory->AddSocketDataProvider(&data);
13853
13854 TestCompletionCallback callback;
13855
13856 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13857 EXPECT_EQ(ERR_IO_PENDING, rv);
13858
13859 rv = callback.WaitForResult();
13860 EXPECT_EQ(OK, rv);
13861
13862 const HttpResponseInfo* response = trans->GetResponseInfo();
13863 ASSERT_TRUE(response != NULL);
13864
13865 EXPECT_TRUE(response->headers.get() != NULL);
13866 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
13867
13868 std::string response_data;
13869 rv = ReadTransaction(trans.get(), &response_data);
13870 EXPECT_EQ(OK, rv);
13871 EXPECT_EQ("hello world", response_data);
13872}
13873
13874TEST_P(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
13875 ScopedVector<UploadElementReader> element_readers;
13876 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713877 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413878
13879 HttpRequestInfo request;
13880 request.method = "POST";
13881 request.url = GURL("http://www.foo.com/");
13882 request.upload_data_stream = &upload_data_stream;
13883 request.load_flags = 0;
13884
13885 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13886 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113887 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413888 // Send headers successfully, but get an error while sending the body.
13889 MockWrite data_writes[] = {
13890 MockWrite("POST / HTTP/1.1\r\n"
13891 "Host: www.foo.com\r\n"
13892 "Connection: keep-alive\r\n"
13893 "Content-Length: 3\r\n\r\n"),
13894 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13895 };
13896
13897 MockRead data_reads[] = {
13898 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
13899 MockRead("hello world"),
13900 MockRead(SYNCHRONOUS, OK),
13901 };
13902 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13903 arraysize(data_writes));
13904 session_deps_.socket_factory->AddSocketDataProvider(&data);
13905
13906 TestCompletionCallback callback;
13907
13908 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13909 EXPECT_EQ(ERR_IO_PENDING, rv);
13910
13911 rv = callback.WaitForResult();
13912 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5413913}
13914
13915TEST_P(HttpNetworkTransactionTest,
13916 PostIgnoresNonErrorResponseAfterResetAnd100) {
13917 ScopedVector<UploadElementReader> element_readers;
13918 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713919 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413920
13921 HttpRequestInfo request;
13922 request.method = "POST";
13923 request.url = GURL("http://www.foo.com/");
13924 request.upload_data_stream = &upload_data_stream;
13925 request.load_flags = 0;
13926
13927 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13928 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113929 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413930 // Send headers successfully, but get an error while sending the body.
13931 MockWrite data_writes[] = {
13932 MockWrite("POST / HTTP/1.1\r\n"
13933 "Host: www.foo.com\r\n"
13934 "Connection: keep-alive\r\n"
13935 "Content-Length: 3\r\n\r\n"),
13936 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13937 };
13938
13939 MockRead data_reads[] = {
13940 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
13941 MockRead("HTTP/1.0 302 Redirect\r\n"),
13942 MockRead("Location: http://somewhere-else.com/\r\n"),
13943 MockRead("Content-Length: 0\r\n\r\n"),
13944 MockRead(SYNCHRONOUS, OK),
13945 };
13946 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13947 arraysize(data_writes));
13948 session_deps_.socket_factory->AddSocketDataProvider(&data);
13949
13950 TestCompletionCallback callback;
13951
13952 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13953 EXPECT_EQ(ERR_IO_PENDING, rv);
13954
13955 rv = callback.WaitForResult();
13956 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5413957}
13958
13959TEST_P(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
13960 ScopedVector<UploadElementReader> element_readers;
13961 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713962 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413963
13964 HttpRequestInfo request;
13965 request.method = "POST";
13966 request.url = GURL("http://www.foo.com/");
13967 request.upload_data_stream = &upload_data_stream;
13968 request.load_flags = 0;
13969
13970 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13971 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113972 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413973 // Send headers successfully, but get an error while sending the body.
13974 MockWrite data_writes[] = {
13975 MockWrite("POST / HTTP/1.1\r\n"
13976 "Host: www.foo.com\r\n"
13977 "Connection: keep-alive\r\n"
13978 "Content-Length: 3\r\n\r\n"),
13979 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13980 };
13981
13982 MockRead data_reads[] = {
13983 MockRead("HTTP 0.9 rocks!"),
13984 MockRead(SYNCHRONOUS, OK),
13985 };
13986 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13987 arraysize(data_writes));
13988 session_deps_.socket_factory->AddSocketDataProvider(&data);
13989
13990 TestCompletionCallback callback;
13991
13992 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13993 EXPECT_EQ(ERR_IO_PENDING, rv);
13994
13995 rv = callback.WaitForResult();
13996 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5413997}
13998
13999TEST_P(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
14000 ScopedVector<UploadElementReader> element_readers;
14001 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714002 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5414003
14004 HttpRequestInfo request;
14005 request.method = "POST";
14006 request.url = GURL("http://www.foo.com/");
14007 request.upload_data_stream = &upload_data_stream;
14008 request.load_flags = 0;
14009
14010 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14011 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114012 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414013 // Send headers successfully, but get an error while sending the body.
14014 MockWrite data_writes[] = {
14015 MockWrite("POST / HTTP/1.1\r\n"
14016 "Host: www.foo.com\r\n"
14017 "Connection: keep-alive\r\n"
14018 "Content-Length: 3\r\n\r\n"),
14019 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14020 };
14021
14022 MockRead data_reads[] = {
14023 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
14024 MockRead(SYNCHRONOUS, OK),
14025 };
14026 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14027 arraysize(data_writes));
14028 session_deps_.socket_factory->AddSocketDataProvider(&data);
14029
14030 TestCompletionCallback callback;
14031
14032 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14033 EXPECT_EQ(ERR_IO_PENDING, rv);
14034
14035 rv = callback.WaitForResult();
14036 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5414037}
14038
Adam Rice425cf122015-01-19 06:18:2414039// Verify that proxy headers are not sent to the destination server when
14040// establishing a tunnel for a secure WebSocket connection.
14041TEST_P(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
14042 HttpRequestInfo request;
14043 request.method = "GET";
bncce36dca22015-04-21 22:11:2314044 request.url = GURL("wss://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2414045 AddWebSocketHeaders(&request.extra_headers);
14046
14047 // Configure against proxy server "myproxy:70".
14048 session_deps_.proxy_service.reset(
14049 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
14050
14051 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14052
14053 // Since a proxy is configured, try to establish a tunnel.
14054 MockWrite data_writes[] = {
14055 MockWrite(
bncce36dca22015-04-21 22:11:2314056 "CONNECT www.example.org:443 HTTP/1.1\r\n"
14057 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414058 "Proxy-Connection: keep-alive\r\n\r\n"),
14059
14060 // After calling trans->RestartWithAuth(), this is the request we should
14061 // be issuing -- the final header line contains the credentials.
14062 MockWrite(
bncce36dca22015-04-21 22:11:2314063 "CONNECT www.example.org:443 HTTP/1.1\r\n"
14064 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414065 "Proxy-Connection: keep-alive\r\n"
14066 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
14067
14068 MockWrite(
14069 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2314070 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414071 "Connection: Upgrade\r\n"
14072 "Upgrade: websocket\r\n"
bncce36dca22015-04-21 22:11:2314073 "Origin: http://www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414074 "Sec-WebSocket-Version: 13\r\n"
14075 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
14076 };
14077
14078 // The proxy responds to the connect with a 407, using a persistent
14079 // connection.
14080 MockRead data_reads[] = {
14081 // No credentials.
14082 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
14083 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
14084 MockRead("Proxy-Connection: close\r\n\r\n"),
14085
14086 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
14087
14088 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
14089 MockRead("Upgrade: websocket\r\n"),
14090 MockRead("Connection: Upgrade\r\n"),
14091 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
14092 };
14093
14094 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14095 arraysize(data_writes));
14096 session_deps_.socket_factory->AddSocketDataProvider(&data);
14097 SSLSocketDataProvider ssl(ASYNC, OK);
14098 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14099
14100 scoped_ptr<HttpTransaction> trans(
14101 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
14102 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
14103 trans->SetWebSocketHandshakeStreamCreateHelper(
14104 &websocket_stream_create_helper);
14105
14106 {
14107 TestCompletionCallback callback;
14108
14109 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14110 EXPECT_EQ(ERR_IO_PENDING, rv);
14111
14112 rv = callback.WaitForResult();
14113 EXPECT_EQ(OK, rv);
14114 }
14115
14116 const HttpResponseInfo* response = trans->GetResponseInfo();
14117 ASSERT_TRUE(response);
14118 ASSERT_TRUE(response->headers.get());
14119 EXPECT_EQ(407, response->headers->response_code());
14120
14121 {
14122 TestCompletionCallback callback;
14123
14124 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
14125 callback.callback());
14126 EXPECT_EQ(ERR_IO_PENDING, rv);
14127
14128 rv = callback.WaitForResult();
14129 EXPECT_EQ(OK, rv);
14130 }
14131
14132 response = trans->GetResponseInfo();
14133 ASSERT_TRUE(response);
14134 ASSERT_TRUE(response->headers.get());
14135
14136 EXPECT_EQ(101, response->headers->response_code());
14137
14138 trans.reset();
14139 session->CloseAllConnections();
14140}
14141
14142// Verify that proxy headers are not sent to the destination server when
14143// establishing a tunnel for an insecure WebSocket connection.
14144// This requires the authentication info to be injected into the auth cache
14145// due to crbug.com/395064
14146// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
14147TEST_P(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
14148 HttpRequestInfo request;
14149 request.method = "GET";
bncce36dca22015-04-21 22:11:2314150 request.url = GURL("ws://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2414151 AddWebSocketHeaders(&request.extra_headers);
14152
14153 // Configure against proxy server "myproxy:70".
14154 session_deps_.proxy_service.reset(
14155 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
14156
14157 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14158
14159 MockWrite data_writes[] = {
14160 // Try to establish a tunnel for the WebSocket connection, with
14161 // credentials. Because WebSockets have a separate set of socket pools,
14162 // they cannot and will not use the same TCP/IP connection as the
14163 // preflight HTTP request.
14164 MockWrite(
bncce36dca22015-04-21 22:11:2314165 "CONNECT www.example.org:80 HTTP/1.1\r\n"
14166 "Host: www.example.org:80\r\n"
Adam Rice425cf122015-01-19 06:18:2414167 "Proxy-Connection: keep-alive\r\n"
14168 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
14169
14170 MockWrite(
14171 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2314172 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414173 "Connection: Upgrade\r\n"
14174 "Upgrade: websocket\r\n"
bncce36dca22015-04-21 22:11:2314175 "Origin: http://www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414176 "Sec-WebSocket-Version: 13\r\n"
14177 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
14178 };
14179
14180 MockRead data_reads[] = {
14181 // HTTP CONNECT with credentials.
14182 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
14183
14184 // WebSocket connection established inside tunnel.
14185 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
14186 MockRead("Upgrade: websocket\r\n"),
14187 MockRead("Connection: Upgrade\r\n"),
14188 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
14189 };
14190
14191 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14192 arraysize(data_writes));
14193 session_deps_.socket_factory->AddSocketDataProvider(&data);
14194
14195 session->http_auth_cache()->Add(
14196 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
14197 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
14198
14199 scoped_ptr<HttpTransaction> trans(
14200 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
14201 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
14202 trans->SetWebSocketHandshakeStreamCreateHelper(
14203 &websocket_stream_create_helper);
14204
14205 TestCompletionCallback callback;
14206
14207 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14208 EXPECT_EQ(ERR_IO_PENDING, rv);
14209
14210 rv = callback.WaitForResult();
14211 EXPECT_EQ(OK, rv);
14212
14213 const HttpResponseInfo* response = trans->GetResponseInfo();
14214 ASSERT_TRUE(response);
14215 ASSERT_TRUE(response->headers.get());
14216
14217 EXPECT_EQ(101, response->headers->response_code());
14218
14219 trans.reset();
14220 session->CloseAllConnections();
14221}
14222
[email protected]89ceba9a2009-03-21 03:46:0614223} // namespace net