blob: ea328a5a4f27f49abc329abe5591d5f91fc43b3a [file] [log] [blame]
[email protected]23e482282013-06-14 16:08:021// Copyright 2013 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit586acc5fe2008-07-26 22:42:524
[email protected]2d731a32010-04-29 01:04:065#include "net/http/http_network_transaction.h"
6
[email protected]77848d12008-11-14 00:00:227#include <math.h> // ceil
[email protected]5285d972011-10-18 18:56:348#include <stdarg.h>
9#include <string>
[email protected]95d88ffe2010-02-04 21:25:3310#include <vector>
[email protected]77848d12008-11-14 00:00:2211
[email protected]2d731a32010-04-29 01:04:0612#include "base/basictypes.h"
[email protected]68bf9152008-09-25 19:47:3013#include "base/compiler_specific.h"
[email protected]57999812013-02-24 05:40:5214#include "base/files/file_path.h"
thestigd8df0332014-09-04 06:33:2915#include "base/files/file_util.h"
[email protected]f3da152d2012-06-02 01:00:5716#include "base/json/json_writer.h"
Adam Rice425cf122015-01-19 06:18:2417#include "base/logging.h"
[email protected]3b63f8f42011-03-28 01:54:1518#include "base/memory/scoped_ptr.h"
[email protected]bf828982013-08-14 18:01:4719#include "base/memory/weak_ptr.h"
[email protected]a34f61ee2014-03-18 20:59:4920#include "base/run_loop.h"
bnc1b0e36852015-04-28 15:32:5921#include "base/stl_util.h"
[email protected]125ef482013-06-11 18:32:4722#include "base/strings/string_util.h"
[email protected]750b2f3c2013-06-07 18:41:0523#include "base/strings/utf_string_conversions.h"
[email protected]f36a8132011-09-02 18:36:3324#include "base/test/test_file_util.h"
[email protected]277d5942010-08-11 21:02:3525#include "net/base/auth.h"
mmenkecbc2b712014-10-09 20:29:0726#include "net/base/chunked_upload_data_stream.h"
[email protected]bacff652009-03-31 17:50:3327#include "net/base/completion_callback.h"
mmenkecbc2b712014-10-09 20:29:0728#include "net/base/elements_upload_data_stream.h"
[email protected]58e32bb2013-01-21 18:23:2529#include "net/base/load_timing_info.h"
30#include "net/base/load_timing_info_test_util.h"
Adam Rice425cf122015-01-19 06:18:2431#include "net/base/net_errors.h"
[email protected]ac790b42009-12-02 04:31:3132#include "net/base/request_priority.h"
initial.commit586acc5fe2008-07-26 22:42:5233#include "net/base/test_completion_callback.h"
[email protected]42fdb452012-11-01 12:44:4034#include "net/base/test_data_directory.h"
[email protected]b2d26cfd2012-12-11 10:36:0635#include "net/base/upload_bytes_element_reader.h"
[email protected]d98961652012-09-11 20:27:2136#include "net/base/upload_file_element_reader.h"
[email protected]6e7845ae2013-03-29 21:48:1137#include "net/cert/mock_cert_verifier.h"
[email protected]bc71b8772013-04-10 20:55:1638#include "net/dns/host_cache.h"
[email protected]f2cb3cf2013-03-21 01:40:5339#include "net/dns/mock_host_resolver.h"
[email protected]df41d0d82014-03-13 00:43:2440#include "net/http/http_auth_challenge_tokenizer.h"
[email protected]3c32c5f2010-05-18 15:18:1241#include "net/http/http_auth_handler_digest.h"
[email protected]3fd9dae2010-06-21 11:39:0042#include "net/http/http_auth_handler_mock.h"
[email protected]385a4672009-03-11 22:21:2943#include "net/http/http_auth_handler_ntlm.h"
Adam Rice425cf122015-01-19 06:18:2444#include "net/http/http_basic_state.h"
[email protected]0877e3d2009-10-17 22:29:5745#include "net/http/http_basic_stream.h"
initial.commit586acc5fe2008-07-26 22:42:5246#include "net/http/http_network_session.h"
[email protected]87bfa3f2010-09-30 14:54:5647#include "net/http/http_network_session_peer.h"
Adam Rice425cf122015-01-19 06:18:2448#include "net/http/http_request_headers.h"
[email protected]17291a022011-10-10 07:32:5349#include "net/http/http_server_properties_impl.h"
[email protected]0877e3d2009-10-17 22:29:5750#include "net/http/http_stream.h"
[email protected]8e6441ca2010-08-19 05:56:3851#include "net/http/http_stream_factory.h"
Adam Rice425cf122015-01-19 06:18:2452#include "net/http/http_stream_parser.h"
[email protected]c41737d2014-05-14 07:47:1953#include "net/http/http_transaction_test_util.h"
eroman87c53d62015-04-02 06:51:0754#include "net/log/net_log.h"
vishal.b62985ca92015-04-17 08:45:5155#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4656#include "net/log/test_net_log_entry.h"
57#include "net/log/test_net_log_util.h"
sammc5dd160c2015-04-02 02:43:1358#include "net/proxy/mock_proxy_resolver.h"
[email protected]51fff29d2008-12-19 22:17:5359#include "net/proxy/proxy_config_service_fixed.h"
[email protected]e86839fd2013-08-14 18:29:0360#include "net/proxy/proxy_info.h"
[email protected]631f1322010-04-30 17:59:1161#include "net/proxy/proxy_resolver.h"
62#include "net/proxy/proxy_service.h"
[email protected]f7984fc62009-06-22 23:26:4463#include "net/socket/client_socket_factory.h"
[email protected]483fa202013-05-14 01:07:0364#include "net/socket/client_socket_pool_manager.h"
ttuttle1f2d7e92015-04-28 16:17:4765#include "net/socket/connection_attempts.h"
[email protected]a42dbd142011-11-17 16:42:0266#include "net/socket/mock_client_socket_pool_manager.h"
[email protected]bb88e1d32013-05-03 23:11:0767#include "net/socket/next_proto.h"
[email protected]f7984fc62009-06-22 23:26:4468#include "net/socket/socket_test_util.h"
69#include "net/socket/ssl_client_socket.h"
[email protected]2ff8b312010-04-26 22:20:5470#include "net/spdy/spdy_framer.h"
71#include "net/spdy/spdy_session.h"
72#include "net/spdy/spdy_session_pool.h"
[email protected]23e482282013-06-14 16:08:0273#include "net/spdy/spdy_test_util_common.h"
[email protected]536fd0b2013-03-14 17:41:5774#include "net/ssl/ssl_cert_request_info.h"
[email protected]e86839fd2013-08-14 18:29:0375#include "net/ssl/ssl_config_service.h"
[email protected]536fd0b2013-03-14 17:41:5776#include "net/ssl/ssl_config_service_defaults.h"
77#include "net/ssl/ssl_info.h"
[email protected]6e7845ae2013-03-29 21:48:1178#include "net/test/cert_test_util.h"
[email protected]831e4a32013-11-14 02:14:4479#include "net/websockets/websocket_handshake_stream_base.h"
initial.commit586acc5fe2008-07-26 22:42:5280#include "testing/gtest/include/gtest/gtest.h"
[email protected]23887f04f2008-12-02 19:20:1581#include "testing/platform_test.h"
[email protected]795cbf82013-07-22 09:37:2782#include "url/gurl.h"
initial.commit586acc5fe2008-07-26 22:42:5283
[email protected]ad65a3e2013-12-25 18:18:0184using base::ASCIIToUTF16;
85
initial.commit586acc5fe2008-07-26 22:42:5286//-----------------------------------------------------------------------------
87
ttuttle859dc7a2015-04-23 19:42:2988namespace net {
89
[email protected]13c8a092010-07-29 06:15:4490namespace {
91
[email protected]42cba2fb2013-03-29 19:58:5792const base::string16 kBar(ASCIIToUTF16("bar"));
93const base::string16 kBar2(ASCIIToUTF16("bar2"));
94const base::string16 kBar3(ASCIIToUTF16("bar3"));
95const base::string16 kBaz(ASCIIToUTF16("baz"));
96const base::string16 kFirst(ASCIIToUTF16("first"));
97const base::string16 kFoo(ASCIIToUTF16("foo"));
98const base::string16 kFoo2(ASCIIToUTF16("foo2"));
99const base::string16 kFoo3(ASCIIToUTF16("foo3"));
100const base::string16 kFou(ASCIIToUTF16("fou"));
101const base::string16 kSecond(ASCIIToUTF16("second"));
102const base::string16 kTestingNTLM(ASCIIToUTF16("testing-ntlm"));
103const base::string16 kWrongPassword(ASCIIToUTF16("wrongpassword"));
[email protected]13c8a092010-07-29 06:15:44104
ttuttle859dc7a2015-04-23 19:42:29105int GetIdleSocketCountInTransportSocketPool(HttpNetworkSession* session) {
106 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
107 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02108}
109
ttuttle859dc7a2015-04-23 19:42:29110int GetIdleSocketCountInSSLSocketPool(HttpNetworkSession* session) {
111 return session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
112 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02113}
114
ttuttle859dc7a2015-04-23 19:42:29115bool IsTransportSocketPoolStalled(HttpNetworkSession* session) {
116 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
117 ->IsStalled();
[email protected]043b68c82013-08-22 23:41:52118}
119
[email protected]f3da152d2012-06-02 01:00:57120// Takes in a Value created from a NetLogHttpResponseParameter, and returns
121// a JSONified list of headers as a single string. Uses single quotes instead
122// of double quotes for easier comparison. Returns false on failure.
[email protected]ea5ef4c2013-06-13 22:50:27123bool GetHeaders(base::DictionaryValue* params, std::string* headers) {
[email protected]f3da152d2012-06-02 01:00:57124 if (!params)
125 return false;
[email protected]ea5ef4c2013-06-13 22:50:27126 base::ListValue* header_list;
[email protected]f3da152d2012-06-02 01:00:57127 if (!params->GetList("headers", &header_list))
128 return false;
129 std::string double_quote_headers;
130 base::JSONWriter::Write(header_list, &double_quote_headers);
[email protected]466c9862013-12-03 22:05:28131 base::ReplaceChars(double_quote_headers, "\"", "'", headers);
[email protected]f3da152d2012-06-02 01:00:57132 return true;
133}
134
[email protected]029c83b62013-01-24 05:28:20135// Tests LoadTimingInfo in the case a socket is reused and no PAC script is
136// used.
ttuttle859dc7a2015-04-23 19:42:29137void TestLoadTimingReused(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20138 EXPECT_TRUE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:29139 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]58e32bb2013-01-21 18:23:25140
[email protected]029c83b62013-01-24 05:28:20141 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
142 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
143
ttuttle859dc7a2015-04-23 19:42:29144 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20145 EXPECT_FALSE(load_timing_info.send_start.is_null());
[email protected]58e32bb2013-01-21 18:23:25146
147 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]58e32bb2013-01-21 18:23:25148
[email protected]3b23a222013-05-15 21:33:25149 // Set at a higher level.
[email protected]58e32bb2013-01-21 18:23:25150 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
151 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25152 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25153}
154
[email protected]029c83b62013-01-24 05:28:20155// Tests LoadTimingInfo in the case a new socket is used and no PAC script is
156// used.
ttuttle859dc7a2015-04-23 19:42:29157void TestLoadTimingNotReused(const LoadTimingInfo& load_timing_info,
[email protected]58e32bb2013-01-21 18:23:25158 int connect_timing_flags) {
[email protected]029c83b62013-01-24 05:28:20159 EXPECT_FALSE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:29160 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20161
162 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
163 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
164
ttuttle859dc7a2015-04-23 19:42:29165 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
166 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20167 EXPECT_LE(load_timing_info.connect_timing.connect_end,
168 load_timing_info.send_start);
169
170 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20171
[email protected]3b23a222013-05-15 21:33:25172 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20173 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
174 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25175 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20176}
177
178// Tests LoadTimingInfo in the case a socket is reused and a PAC script is
179// used.
ttuttle859dc7a2015-04-23 19:42:29180void TestLoadTimingReusedWithPac(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20181 EXPECT_TRUE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:29182 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20183
ttuttle859dc7a2015-04-23 19:42:29184 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20185
186 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
187 EXPECT_LE(load_timing_info.proxy_resolve_start,
188 load_timing_info.proxy_resolve_end);
189 EXPECT_LE(load_timing_info.proxy_resolve_end,
190 load_timing_info.send_start);
191 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20192
[email protected]3b23a222013-05-15 21:33:25193 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20194 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
195 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25196 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20197}
198
199// Tests LoadTimingInfo in the case a new socket is used and a PAC script is
200// used.
ttuttle859dc7a2015-04-23 19:42:29201void TestLoadTimingNotReusedWithPac(const LoadTimingInfo& load_timing_info,
[email protected]029c83b62013-01-24 05:28:20202 int connect_timing_flags) {
203 EXPECT_FALSE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:29204 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20205
206 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
207 EXPECT_LE(load_timing_info.proxy_resolve_start,
208 load_timing_info.proxy_resolve_end);
209 EXPECT_LE(load_timing_info.proxy_resolve_end,
210 load_timing_info.connect_timing.connect_start);
ttuttle859dc7a2015-04-23 19:42:29211 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
212 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20213 EXPECT_LE(load_timing_info.connect_timing.connect_end,
214 load_timing_info.send_start);
215
216 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20217
[email protected]3b23a222013-05-15 21:33:25218 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20219 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
220 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25221 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25222}
223
ttuttle859dc7a2015-04-23 19:42:29224void AddWebSocketHeaders(HttpRequestHeaders* headers) {
Adam Rice425cf122015-01-19 06:18:24225 headers->SetHeader("Connection", "Upgrade");
226 headers->SetHeader("Upgrade", "websocket");
bncce36dca22015-04-21 22:11:23227 headers->SetHeader("Origin", "http://www.example.org");
Adam Rice425cf122015-01-19 06:18:24228 headers->SetHeader("Sec-WebSocket-Version", "13");
229 headers->SetHeader("Sec-WebSocket-Key", "dGhlIHNhbXBsZSBub25jZQ==");
230}
231
[email protected]c6bf8152012-12-02 07:43:34232HttpNetworkSession* CreateSession(SpdySessionDependencies* session_deps) {
233 return SpdySessionDependencies::SpdyCreateSession(session_deps);
[email protected]e8d536192008-10-17 22:21:14234}
235
[email protected]448d4ca52012-03-04 04:12:23236} // namespace
237
[email protected]23e482282013-06-14 16:08:02238class HttpNetworkTransactionTest
239 : public PlatformTest,
240 public ::testing::WithParamInterface<NextProto> {
[email protected]483fa202013-05-14 01:07:03241 public:
[email protected]23e482282013-06-14 16:08:02242 virtual ~HttpNetworkTransactionTest() {
[email protected]483fa202013-05-14 01:07:03243 // Important to restore the per-pool limit first, since the pool limit must
244 // always be greater than group limit, and the tests reduce both limits.
245 ClientSocketPoolManager::set_max_sockets_per_pool(
246 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
247 ClientSocketPoolManager::set_max_sockets_per_group(
248 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
249 }
250
[email protected]e3ceb682011-06-28 23:55:46251 protected:
[email protected]23e482282013-06-14 16:08:02252 HttpNetworkTransactionTest()
253 : spdy_util_(GetParam()),
254 session_deps_(GetParam()),
[email protected]483fa202013-05-14 01:07:03255 old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
256 HttpNetworkSession::NORMAL_SOCKET_POOL)),
257 old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
258 HttpNetworkSession::NORMAL_SOCKET_POOL)) {
259 }
[email protected]bb88e1d32013-05-03 23:11:07260
[email protected]e3ceb682011-06-28 23:55:46261 struct SimpleGetHelperResult {
262 int rv;
263 std::string status_line;
264 std::string response_data;
[email protected]b8015c42013-12-24 15:18:19265 int64 totalReceivedBytes;
[email protected]58e32bb2013-01-21 18:23:25266 LoadTimingInfo load_timing_info;
ttuttle1f2d7e92015-04-28 16:17:47267 ConnectionAttempts connection_attempts;
[email protected]e3ceb682011-06-28 23:55:46268 };
269
dcheng67be2b1f2014-10-27 21:47:29270 void SetUp() override {
[email protected]0b0bf032010-09-21 18:08:50271 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:34272 base::MessageLoop::current()->RunUntilIdle();
[email protected]2ff8b312010-04-26 22:20:54273 }
274
dcheng67be2b1f2014-10-27 21:47:29275 void TearDown() override {
[email protected]0b0bf032010-09-21 18:08:50276 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:34277 base::MessageLoop::current()->RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09278 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:34279 base::MessageLoop::current()->RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09280 PlatformTest::TearDown();
[email protected]0b0bf032010-09-21 18:08:50281 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:34282 base::MessageLoop::current()->RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09283 }
284
bnc33b8cef42014-11-19 17:30:38285 const char* GetAlternateProtocolFromParam() {
286 return
287 AlternateProtocolToString(AlternateProtocolFromNextProto(GetParam()));
288 }
289
[email protected]8a0fc822013-06-27 20:52:43290 // This is the expected return from a current server advertising SPDY.
291 std::string GetAlternateProtocolHttpHeader() {
bnc33b8cef42014-11-19 17:30:38292 return std::string("Alternate-Protocol: 443:") +
293 GetAlternateProtocolFromParam() + "\r\n\r\n";
[email protected]8a0fc822013-06-27 20:52:43294 }
295
[email protected]202965992011-12-07 23:04:51296 // Either |write_failure| specifies a write failure or |read_failure|
297 // specifies a read failure when using a reused socket. In either case, the
298 // failure should cause the network transaction to resend the request, and the
299 // other argument should be NULL.
300 void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
301 const MockRead* read_failure);
initial.commit586acc5fe2008-07-26 22:42:52302
[email protected]a34f61ee2014-03-18 20:59:49303 // Either |write_failure| specifies a write failure or |read_failure|
304 // specifies a read failure when using a reused socket. In either case, the
305 // failure should cause the network transaction to resend the request, and the
306 // other argument should be NULL.
307 void PreconnectErrorResendRequestTest(const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:10308 const MockRead* read_failure,
309 bool use_spdy);
[email protected]a34f61ee2014-03-18 20:59:49310
[email protected]5a60c8b2011-10-19 20:14:29311 SimpleGetHelperResult SimpleGetHelperForData(StaticSocketDataProvider* data[],
312 size_t data_count) {
[email protected]ff007e162009-05-23 09:13:15313 SimpleGetHelperResult out;
initial.commit586acc5fe2008-07-26 22:42:52314
[email protected]ff007e162009-05-23 09:13:15315 HttpRequestInfo request;
316 request.method = "GET";
bncce36dca22015-04-21 22:11:23317 request.url = GURL("http://www.example.org/");
[email protected]ff007e162009-05-23 09:13:15318 request.load_flags = 0;
initial.commit586acc5fe2008-07-26 22:42:52319
vishal.b62985ca92015-04-17 08:45:51320 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:07321 session_deps_.net_log = log.bound().net_log();
[email protected]3fe8d2f82013-10-17 08:56:07322 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:27323 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:41324 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:27325
[email protected]5a60c8b2011-10-19 20:14:29326 for (size_t i = 0; i < data_count; ++i) {
[email protected]bb88e1d32013-05-03 23:11:07327 session_deps_.socket_factory->AddSocketDataProvider(data[i]);
[email protected]5a60c8b2011-10-19 20:14:29328 }
initial.commit586acc5fe2008-07-26 22:42:52329
[email protected]49639fa2011-12-20 23:22:41330 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52331
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[] = {
dbeamcd6674c72015-05-05 01:57:543689 CreateMockWrite(*connect, 1),
3690 CreateMockWrite(*wrapped_get, 3),
3691 CreateMockWrite(*window_update_get_resp, 5),
[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[] = {
dbeamcd6674c72015-05-05 01:57:543696 CreateMockRead(*conn_resp, 2, ASYNC),
rch8e6c6c42015-05-01 14:05:133697 CreateMockRead(*wrapped_get_resp, 4, ASYNC),
dbeamcd6674c72015-05-05 01:57:543698 CreateMockRead(*wrapped_body, 6, ASYNC),
rch8e6c6c42015-05-01 14:05:133699 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:163700 };
3701
dbeamcd6674c72015-05-05 01:57:543702 OrderedSocketData spdy_data(
3703 spdy_reads, arraysize(spdy_reads),
3704 spdy_writes, 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
3719 rv = callback1.WaitForResult();
3720 EXPECT_EQ(OK, rv);
3721
[email protected]58e32bb2013-01-21 18:23:253722 LoadTimingInfo load_timing_info;
3723 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3724 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3725
[email protected]d9da5fe2010-10-13 22:37:163726 const HttpResponseInfo* response = trans->GetResponseInfo();
3727 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503728 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d9da5fe2010-10-13 22:37:163729 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3730
3731 std::string response_data;
3732 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:233733 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:163734}
3735
3736// Test a SPDY CONNECT failure through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023737TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:273738 HttpRequestInfo request;
3739 request.method = "GET";
bncce36dca22015-04-21 22:11:233740 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273741 request.load_flags = 0;
3742
[email protected]d9da5fe2010-10-13 22:37:163743 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073744 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113745 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513746 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073747 session_deps_.net_log = log.bound().net_log();
3748 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:163749
[email protected]262eec82013-03-19 21:01:363750 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503751 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:163752
bncce36dca22015-04-21 22:11:233753 // CONNECT to www.example.org:443 via SPDY
lgarrona91df87f2014-12-05 00:51:343754 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:233755 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]c10b20852013-05-15 21:29:203756 scoped_ptr<SpdyFrame> get(
3757 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:163758
3759 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:133760 CreateMockWrite(*connect, 0), CreateMockWrite(*get, 2),
[email protected]d9da5fe2010-10-13 22:37:163761 };
3762
[email protected]23e482282013-06-14 16:08:023763 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdySynReplyError(1));
3764 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:163765 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:133766 CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 3),
[email protected]d9da5fe2010-10-13 22:37:163767 };
3768
rch8e6c6c42015-05-01 14:05:133769 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3770 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073771 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163772
[email protected]8ddf8322012-02-23 18:08:063773 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023774 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073775 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063776 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023777 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073778 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163779
[email protected]49639fa2011-12-20 23:22:413780 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163781
[email protected]49639fa2011-12-20 23:22:413782 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163783 EXPECT_EQ(ERR_IO_PENDING, rv);
3784
3785 rv = callback1.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:173786 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]d9da5fe2010-10-13 22:37:163787
[email protected]4eddbc732012-08-09 05:40:173788 // TODO(ttuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:163789}
3790
[email protected]f6c63db52013-02-02 00:35:223791// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
3792// HTTPS Proxy to different servers.
[email protected]23e482282013-06-14 16:08:023793TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:223794 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
3795 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073796 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:223797 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513798 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073799 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:223800 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:073801 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:223802
3803 HttpRequestInfo request1;
3804 request1.method = "GET";
bncce36dca22015-04-21 22:11:233805 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:223806 request1.load_flags = 0;
3807
3808 HttpRequestInfo request2;
3809 request2.method = "GET";
bncce36dca22015-04-21 22:11:233810 request2.url = GURL("https://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:223811 request2.load_flags = 0;
3812
bncce36dca22015-04-21 22:11:233813 // CONNECT to www.example.org:443 via SPDY.
lgarrona91df87f2014-12-05 00:51:343814 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:233815 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]23e482282013-06-14 16:08:023816 scoped_ptr<SpdyFrame> conn_resp1(
3817 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:223818
bncce36dca22015-04-21 22:11:233819 // Fetch https://www.example.org/ via HTTP.
3820 const char get1[] =
3821 "GET / HTTP/1.1\r\n"
3822 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:223823 "Connection: keep-alive\r\n\r\n";
3824 scoped_ptr<SpdyFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:023825 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:223826 const char resp1[] = "HTTP/1.1 200 OK\r\n"
3827 "Content-Length: 1\r\n\r\n";
3828 scoped_ptr<SpdyFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:023829 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
3830 scoped_ptr<SpdyFrame> wrapped_body1(
3831 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
[email protected]f6c63db52013-02-02 00:35:223832 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203833 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:223834
bncce36dca22015-04-21 22:11:233835 // CONNECT to mail.example.org:443 via SPDY.
[email protected]745aa9c2014-06-27 02:21:293836 SpdyHeaderBlock connect2_block;
3837 connect2_block[spdy_util_.GetMethodKey()] = "CONNECT";
bncce36dca22015-04-21 22:11:233838 connect2_block[spdy_util_.GetPathKey()] = "mail.example.org:443";
3839 connect2_block[spdy_util_.GetHostKey()] = "mail.example.org";
[email protected]745aa9c2014-06-27 02:21:293840 spdy_util_.MaybeAddVersionHeader(&connect2_block);
[email protected]f6c63db52013-02-02 00:35:223841 scoped_ptr<SpdyFrame> connect2(
[email protected]745aa9c2014-06-27 02:21:293842 spdy_util_.ConstructSpdySyn(3, connect2_block, LOWEST, false, false));
[email protected]601e03f12014-04-06 16:26:393843
[email protected]23e482282013-06-14 16:08:023844 scoped_ptr<SpdyFrame> conn_resp2(
3845 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:223846
bncce36dca22015-04-21 22:11:233847 // Fetch https://mail.example.org/ via HTTP.
3848 const char get2[] =
3849 "GET / HTTP/1.1\r\n"
3850 "Host: mail.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:223851 "Connection: keep-alive\r\n\r\n";
3852 scoped_ptr<SpdyFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:023853 spdy_util_.ConstructSpdyBodyFrame(3, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:223854 const char resp2[] = "HTTP/1.1 200 OK\r\n"
3855 "Content-Length: 2\r\n\r\n";
3856 scoped_ptr<SpdyFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:023857 spdy_util_.ConstructSpdyBodyFrame(3, resp2, strlen(resp2), false));
[email protected]f6c63db52013-02-02 00:35:223858 scoped_ptr<SpdyFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:023859 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:223860
3861 MockWrite spdy_writes[] = {
3862 CreateMockWrite(*connect1, 0),
3863 CreateMockWrite(*wrapped_get1, 2),
3864 CreateMockWrite(*connect2, 5),
3865 CreateMockWrite(*wrapped_get2, 7),
3866 };
3867
3868 MockRead spdy_reads[] = {
3869 CreateMockRead(*conn_resp1, 1, ASYNC),
3870 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
3871 CreateMockRead(*wrapped_body1, 4, ASYNC),
3872 CreateMockRead(*conn_resp2, 6, ASYNC),
3873 CreateMockRead(*wrapped_get_resp2, 8, ASYNC),
3874 CreateMockRead(*wrapped_body2, 9, ASYNC),
3875 MockRead(ASYNC, 0, 10),
3876 };
3877
3878 DeterministicSocketData spdy_data(
3879 spdy_reads, arraysize(spdy_reads),
3880 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073881 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:223882
3883 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023884 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073885 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:223886 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073887 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:223888 SSLSocketDataProvider ssl3(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073889 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:223890
3891 TestCompletionCallback callback;
3892
[email protected]262eec82013-03-19 21:01:363893 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503894 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223895 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
3896 EXPECT_EQ(ERR_IO_PENDING, rv);
3897 // The first connect and request, each of their responses, and the body.
3898 spdy_data.RunFor(5);
3899
3900 rv = callback.WaitForResult();
3901 EXPECT_EQ(OK, rv);
3902
3903 LoadTimingInfo load_timing_info;
3904 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3905 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3906
3907 const HttpResponseInfo* response = trans->GetResponseInfo();
3908 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503909 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:223910 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3911
3912 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:293913 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]90499482013-06-01 00:39:503914 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223915
[email protected]262eec82013-03-19 21:01:363916 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503917 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223918 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
3919 EXPECT_EQ(ERR_IO_PENDING, rv);
3920
3921 // The second connect and request, each of their responses, and the body.
3922 spdy_data.RunFor(5);
3923 rv = callback.WaitForResult();
3924 EXPECT_EQ(OK, rv);
3925
3926 LoadTimingInfo load_timing_info2;
3927 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3928 // Even though the SPDY connection is reused, a new tunnelled connection has
3929 // to be created, so the socket's load timing looks like a fresh connection.
3930 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
3931
3932 // The requests should have different IDs, since they each are using their own
3933 // separate stream.
3934 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
3935
[email protected]90499482013-06-01 00:39:503936 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:223937}
3938
3939// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
3940// HTTPS Proxy to the same server.
[email protected]23e482282013-06-14 16:08:023941TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:223942 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
3943 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073944 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:223945 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513946 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073947 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:223948 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:073949 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:223950
3951 HttpRequestInfo request1;
3952 request1.method = "GET";
bncce36dca22015-04-21 22:11:233953 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:223954 request1.load_flags = 0;
3955
3956 HttpRequestInfo request2;
3957 request2.method = "GET";
bncce36dca22015-04-21 22:11:233958 request2.url = GURL("https://www.example.org/2");
[email protected]f6c63db52013-02-02 00:35:223959 request2.load_flags = 0;
3960
bncce36dca22015-04-21 22:11:233961 // CONNECT to www.example.org:443 via SPDY.
lgarrona91df87f2014-12-05 00:51:343962 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:233963 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]23e482282013-06-14 16:08:023964 scoped_ptr<SpdyFrame> conn_resp1(
3965 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:223966
bncce36dca22015-04-21 22:11:233967 // Fetch https://www.example.org/ via HTTP.
3968 const char get1[] =
3969 "GET / HTTP/1.1\r\n"
3970 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:223971 "Connection: keep-alive\r\n\r\n";
3972 scoped_ptr<SpdyFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:023973 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:223974 const char resp1[] = "HTTP/1.1 200 OK\r\n"
3975 "Content-Length: 1\r\n\r\n";
3976 scoped_ptr<SpdyFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:023977 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
3978 scoped_ptr<SpdyFrame> wrapped_body1(
3979 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
[email protected]f6c63db52013-02-02 00:35:223980 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203981 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:223982
bncce36dca22015-04-21 22:11:233983 // Fetch https://www.example.org/2 via HTTP.
3984 const char get2[] =
3985 "GET /2 HTTP/1.1\r\n"
3986 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:223987 "Connection: keep-alive\r\n\r\n";
3988 scoped_ptr<SpdyFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:023989 spdy_util_.ConstructSpdyBodyFrame(1, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:223990 const char resp2[] = "HTTP/1.1 200 OK\r\n"
3991 "Content-Length: 2\r\n\r\n";
3992 scoped_ptr<SpdyFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:023993 spdy_util_.ConstructSpdyBodyFrame(1, resp2, strlen(resp2), false));
[email protected]f6c63db52013-02-02 00:35:223994 scoped_ptr<SpdyFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:023995 spdy_util_.ConstructSpdyBodyFrame(1, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:223996
3997 MockWrite spdy_writes[] = {
3998 CreateMockWrite(*connect1, 0),
3999 CreateMockWrite(*wrapped_get1, 2),
4000 CreateMockWrite(*wrapped_get2, 5),
4001 };
4002
4003 MockRead spdy_reads[] = {
4004 CreateMockRead(*conn_resp1, 1, ASYNC),
4005 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
4006 CreateMockRead(*wrapped_body1, 4, ASYNC),
4007 CreateMockRead(*wrapped_get_resp2, 6, ASYNC),
4008 CreateMockRead(*wrapped_body2, 7, ASYNC),
4009 MockRead(ASYNC, 0, 8),
4010 };
4011
4012 DeterministicSocketData spdy_data(
4013 spdy_reads, arraysize(spdy_reads),
4014 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074015 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:224016
4017 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:024018 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:074019 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:224020 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074021 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:224022
4023 TestCompletionCallback callback;
4024
[email protected]262eec82013-03-19 21:01:364025 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504026 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224027 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
4028 EXPECT_EQ(ERR_IO_PENDING, rv);
4029 // The first connect and request, each of their responses, and the body.
4030 spdy_data.RunFor(5);
4031
4032 rv = callback.WaitForResult();
4033 EXPECT_EQ(OK, rv);
4034
4035 LoadTimingInfo load_timing_info;
4036 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4037 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
4038
4039 const HttpResponseInfo* response = trans->GetResponseInfo();
4040 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504041 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:224042 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4043
4044 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:294045 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]90499482013-06-01 00:39:504046 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:224047 trans.reset();
4048
[email protected]262eec82013-03-19 21:01:364049 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:504050 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224051 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
4052 EXPECT_EQ(ERR_IO_PENDING, rv);
4053
4054 // The second request, response, and body. There should not be a second
4055 // connect.
4056 spdy_data.RunFor(3);
4057 rv = callback.WaitForResult();
4058 EXPECT_EQ(OK, rv);
4059
4060 LoadTimingInfo load_timing_info2;
4061 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4062 TestLoadTimingReused(load_timing_info2);
4063
4064 // The requests should have the same ID.
4065 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
4066
[email protected]90499482013-06-01 00:39:504067 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:224068}
4069
4070// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
4071// Proxy to different servers.
[email protected]23e482282013-06-14 16:08:024072TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:224073 HttpsProxySpdyLoadTimingTwoHttpRequests) {
4074 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:074075 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:224076 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:514077 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074078 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:224079 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:074080 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:224081
4082 HttpRequestInfo request1;
4083 request1.method = "GET";
bncce36dca22015-04-21 22:11:234084 request1.url = GURL("http://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:224085 request1.load_flags = 0;
4086
4087 HttpRequestInfo request2;
4088 request2.method = "GET";
bncce36dca22015-04-21 22:11:234089 request2.url = GURL("http://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:224090 request2.load_flags = 0;
4091
bncce36dca22015-04-21 22:11:234092 // http://www.example.org/
[email protected]23e482282013-06-14 16:08:024093 scoped_ptr<SpdyHeaderBlock> headers(
bncce36dca22015-04-21 22:11:234094 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
[email protected]745aa9c2014-06-27 02:21:294095 scoped_ptr<SpdyFrame> get1(
4096 spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, false, true));
[email protected]23e482282013-06-14 16:08:024097 scoped_ptr<SpdyFrame> get_resp1(
4098 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
4099 scoped_ptr<SpdyFrame> body1(
4100 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, true));
[email protected]f6c63db52013-02-02 00:35:224101
bncce36dca22015-04-21 22:11:234102 // http://mail.example.org/
[email protected]23e482282013-06-14 16:08:024103 scoped_ptr<SpdyHeaderBlock> headers2(
bncce36dca22015-04-21 22:11:234104 spdy_util_.ConstructGetHeaderBlockForProxy("http://mail.example.org/"));
[email protected]745aa9c2014-06-27 02:21:294105 scoped_ptr<SpdyFrame> get2(
4106 spdy_util_.ConstructSpdySyn(3, *headers2, LOWEST, false, true));
[email protected]23e482282013-06-14 16:08:024107 scoped_ptr<SpdyFrame> get_resp2(
4108 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
4109 scoped_ptr<SpdyFrame> body2(
4110 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, true));
[email protected]f6c63db52013-02-02 00:35:224111
4112 MockWrite spdy_writes[] = {
4113 CreateMockWrite(*get1, 0),
4114 CreateMockWrite(*get2, 3),
4115 };
4116
4117 MockRead spdy_reads[] = {
4118 CreateMockRead(*get_resp1, 1, ASYNC),
4119 CreateMockRead(*body1, 2, ASYNC),
4120 CreateMockRead(*get_resp2, 4, ASYNC),
4121 CreateMockRead(*body2, 5, ASYNC),
4122 MockRead(ASYNC, 0, 6),
4123 };
4124
4125 DeterministicSocketData spdy_data(
4126 spdy_reads, arraysize(spdy_reads),
4127 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074128 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:224129
4130 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:024131 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:074132 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:224133
4134 TestCompletionCallback callback;
4135
[email protected]262eec82013-03-19 21:01:364136 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504137 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224138 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
4139 EXPECT_EQ(ERR_IO_PENDING, rv);
4140 spdy_data.RunFor(2);
4141
4142 rv = callback.WaitForResult();
4143 EXPECT_EQ(OK, rv);
4144
4145 LoadTimingInfo load_timing_info;
4146 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4147 TestLoadTimingNotReused(load_timing_info,
4148 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4149
4150 const HttpResponseInfo* response = trans->GetResponseInfo();
4151 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504152 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:224153 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4154
4155 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:294156 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]90499482013-06-01 00:39:504157 EXPECT_EQ(ERR_IO_PENDING, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:224158 spdy_data.RunFor(1);
4159 EXPECT_EQ(1, callback.WaitForResult());
4160 // Delete the first request, so the second one can reuse the socket.
4161 trans.reset();
4162
[email protected]262eec82013-03-19 21:01:364163 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:504164 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224165 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
4166 EXPECT_EQ(ERR_IO_PENDING, rv);
4167
4168 spdy_data.RunFor(2);
4169 rv = callback.WaitForResult();
4170 EXPECT_EQ(OK, rv);
4171
4172 LoadTimingInfo load_timing_info2;
4173 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4174 TestLoadTimingReused(load_timing_info2);
4175
4176 // The requests should have the same ID.
4177 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
4178
[email protected]90499482013-06-01 00:39:504179 EXPECT_EQ(ERR_IO_PENDING, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:224180 spdy_data.RunFor(1);
4181 EXPECT_EQ(2, callback.WaitForResult());
4182}
4183
[email protected]2df19bb2010-08-25 20:13:464184// Test the challenge-response-retry sequence through an HTTPS Proxy
[email protected]23e482282013-06-14 16:08:024185TEST_P(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:464186 HttpRequestInfo request;
4187 request.method = "GET";
bncce36dca22015-04-21 22:11:234188 request.url = GURL("http://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:464189 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:294190 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]2df19bb2010-08-25 20:13:464191
[email protected]79cb5c12011-09-12 13:12:044192 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:074193 session_deps_.proxy_service.reset(
[email protected]79cb5c12011-09-12 13:12:044194 ProxyService::CreateFixed("https://myproxy:70"));
vishal.b62985ca92015-04-17 08:45:514195 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074196 session_deps_.net_log = log.bound().net_log();
4197 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274198
[email protected]2df19bb2010-08-25 20:13:464199 // Since we have proxy, should use full url
4200 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:234201 MockWrite(
4202 "GET http://www.example.org/ HTTP/1.1\r\n"
4203 "Host: www.example.org\r\n"
4204 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:464205
bncce36dca22015-04-21 22:11:234206 // After calling trans->RestartWithAuth(), this is the request we should
4207 // be issuing -- the final header line contains the credentials.
4208 MockWrite(
4209 "GET http://www.example.org/ HTTP/1.1\r\n"
4210 "Host: www.example.org\r\n"
4211 "Proxy-Connection: keep-alive\r\n"
4212 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:464213 };
4214
4215 // The proxy responds to the GET with a 407, using a persistent
4216 // connection.
4217 MockRead data_reads1[] = {
4218 // No credentials.
4219 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4220 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4221 MockRead("Proxy-Connection: keep-alive\r\n"),
4222 MockRead("Content-Length: 0\r\n\r\n"),
4223
4224 MockRead("HTTP/1.1 200 OK\r\n"),
4225 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4226 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064227 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:464228 };
4229
4230 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4231 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074232 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:064233 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074234 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:464235
[email protected]49639fa2011-12-20 23:22:414236 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:464237
[email protected]262eec82013-03-19 21:01:364238 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504239 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504240
[email protected]49639fa2011-12-20 23:22:414241 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:464242 EXPECT_EQ(ERR_IO_PENDING, rv);
4243
4244 rv = callback1.WaitForResult();
4245 EXPECT_EQ(OK, rv);
4246
[email protected]58e32bb2013-01-21 18:23:254247 LoadTimingInfo load_timing_info;
4248 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4249 TestLoadTimingNotReused(load_timing_info,
4250 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4251
[email protected]2df19bb2010-08-25 20:13:464252 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504253 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504254 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]2df19bb2010-08-25 20:13:464255 EXPECT_EQ(407, response->headers->response_code());
4256 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:044257 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:464258
[email protected]49639fa2011-12-20 23:22:414259 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:464260
[email protected]49639fa2011-12-20 23:22:414261 rv = trans->RestartWithAuth(
4262 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]2df19bb2010-08-25 20:13:464263 EXPECT_EQ(ERR_IO_PENDING, rv);
4264
4265 rv = callback2.WaitForResult();
4266 EXPECT_EQ(OK, rv);
4267
[email protected]58e32bb2013-01-21 18:23:254268 load_timing_info = LoadTimingInfo();
4269 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4270 // Retrying with HTTP AUTH is considered to be reusing a socket.
4271 TestLoadTimingReused(load_timing_info);
4272
[email protected]2df19bb2010-08-25 20:13:464273 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504274 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:464275
4276 EXPECT_TRUE(response->headers->IsKeepAlive());
4277 EXPECT_EQ(200, response->headers->response_code());
4278 EXPECT_EQ(100, response->headers->GetContentLength());
4279 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4280
4281 // The password prompt info should not be set.
4282 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4283}
4284
[email protected]23e482282013-06-14 16:08:024285void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:084286 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:424287 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:084288 request.method = "GET";
bncce36dca22015-04-21 22:11:234289 request.url = GURL("https://www.example.org/");
[email protected]c744cf22009-02-27 07:28:084290 request.load_flags = 0;
4291
[email protected]cb9bf6ca2011-01-28 13:15:274292 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:074293 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]bb88e1d32013-05-03 23:11:074294 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274295
[email protected]c744cf22009-02-27 07:28:084296 // Since we have proxy, should try to establish tunnel.
4297 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:234298 MockWrite(
4299 "CONNECT www.example.org:443 HTTP/1.1\r\n"
4300 "Host: www.example.org\r\n"
4301 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:084302 };
4303
4304 MockRead data_reads[] = {
4305 status,
4306 MockRead("Content-Length: 10\r\n\r\n"),
4307 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:064308 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]c744cf22009-02-27 07:28:084309 };
4310
[email protected]31a2bfe2010-02-09 08:03:394311 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
4312 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:074313 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:084314
[email protected]49639fa2011-12-20 23:22:414315 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:084316
[email protected]262eec82013-03-19 21:01:364317 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504318 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504319
[email protected]49639fa2011-12-20 23:22:414320 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424321 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]c744cf22009-02-27 07:28:084322
4323 rv = callback.WaitForResult();
4324 EXPECT_EQ(expected_status, rv);
4325}
4326
[email protected]23e482282013-06-14 16:08:024327void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:234328 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:084329 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:424330 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:084331}
4332
[email protected]23e482282013-06-14 16:08:024333TEST_P(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:084334 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
4335}
4336
[email protected]23e482282013-06-14 16:08:024337TEST_P(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:084338 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
4339}
4340
[email protected]23e482282013-06-14 16:08:024341TEST_P(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:084342 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
4343}
4344
[email protected]23e482282013-06-14 16:08:024345TEST_P(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:084346 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
4347}
4348
[email protected]23e482282013-06-14 16:08:024349TEST_P(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:084350 ConnectStatusHelper(
4351 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
4352}
4353
[email protected]23e482282013-06-14 16:08:024354TEST_P(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:084355 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
4356}
4357
[email protected]23e482282013-06-14 16:08:024358TEST_P(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:084359 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
4360}
4361
[email protected]23e482282013-06-14 16:08:024362TEST_P(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:084363 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
4364}
4365
[email protected]23e482282013-06-14 16:08:024366TEST_P(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:084367 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
4368}
4369
[email protected]23e482282013-06-14 16:08:024370TEST_P(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:084371 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
4372}
4373
[email protected]23e482282013-06-14 16:08:024374TEST_P(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:084375 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
4376}
4377
[email protected]23e482282013-06-14 16:08:024378TEST_P(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:084379 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
4380}
4381
[email protected]23e482282013-06-14 16:08:024382TEST_P(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:084383 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
4384}
4385
[email protected]23e482282013-06-14 16:08:024386TEST_P(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:084387 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
4388}
4389
[email protected]23e482282013-06-14 16:08:024390TEST_P(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:084391 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
4392}
4393
[email protected]23e482282013-06-14 16:08:024394TEST_P(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:084395 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
4396}
4397
[email protected]0a17aab32014-04-24 03:32:374398TEST_P(HttpNetworkTransactionTest, ConnectStatus308) {
4399 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
4400}
4401
[email protected]23e482282013-06-14 16:08:024402TEST_P(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:084403 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
4404}
4405
[email protected]23e482282013-06-14 16:08:024406TEST_P(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:084407 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
4408}
4409
[email protected]23e482282013-06-14 16:08:024410TEST_P(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:084411 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
4412}
4413
[email protected]23e482282013-06-14 16:08:024414TEST_P(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:084415 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
4416}
4417
[email protected]23e482282013-06-14 16:08:024418TEST_P(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:084419 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
4420}
4421
[email protected]23e482282013-06-14 16:08:024422TEST_P(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:084423 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
4424}
4425
[email protected]23e482282013-06-14 16:08:024426TEST_P(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:084427 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
4428}
4429
[email protected]23e482282013-06-14 16:08:024430TEST_P(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:084431 ConnectStatusHelperWithExpectedStatus(
4432 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:544433 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:084434}
4435
[email protected]23e482282013-06-14 16:08:024436TEST_P(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:084437 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
4438}
4439
[email protected]23e482282013-06-14 16:08:024440TEST_P(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:084441 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
4442}
4443
[email protected]23e482282013-06-14 16:08:024444TEST_P(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:084445 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
4446}
4447
[email protected]23e482282013-06-14 16:08:024448TEST_P(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:084449 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
4450}
4451
[email protected]23e482282013-06-14 16:08:024452TEST_P(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:084453 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
4454}
4455
[email protected]23e482282013-06-14 16:08:024456TEST_P(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:084457 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
4458}
4459
[email protected]23e482282013-06-14 16:08:024460TEST_P(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:084461 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
4462}
4463
[email protected]23e482282013-06-14 16:08:024464TEST_P(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:084465 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
4466}
4467
[email protected]23e482282013-06-14 16:08:024468TEST_P(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:084469 ConnectStatusHelper(
4470 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
4471}
4472
[email protected]23e482282013-06-14 16:08:024473TEST_P(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:084474 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
4475}
4476
[email protected]23e482282013-06-14 16:08:024477TEST_P(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:084478 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
4479}
4480
[email protected]23e482282013-06-14 16:08:024481TEST_P(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:084482 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
4483}
4484
[email protected]23e482282013-06-14 16:08:024485TEST_P(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:084486 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
4487}
4488
[email protected]23e482282013-06-14 16:08:024489TEST_P(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:084490 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
4491}
4492
[email protected]23e482282013-06-14 16:08:024493TEST_P(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:084494 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
4495}
4496
[email protected]23e482282013-06-14 16:08:024497TEST_P(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:084498 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
4499}
4500
[email protected]038e9a32008-10-08 22:40:164501// Test the flow when both the proxy server AND origin server require
4502// authentication. Again, this uses basic auth for both since that is
4503// the simplest to mock.
[email protected]23e482282013-06-14 16:08:024504TEST_P(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:274505 HttpRequestInfo request;
4506 request.method = "GET";
bncce36dca22015-04-21 22:11:234507 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274508 request.load_flags = 0;
4509
[email protected]038e9a32008-10-08 22:40:164510 // Configure against proxy server "myproxy:70".
[email protected]3fe8d2f82013-10-17 08:56:074511 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
4512 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4513
4514 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:414515 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]038e9a32008-10-08 22:40:164516
[email protected]f9ee6b52008-11-08 06:46:234517 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:234518 MockWrite(
4519 "GET http://www.example.org/ HTTP/1.1\r\n"
4520 "Host: www.example.org\r\n"
4521 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:234522 };
4523
[email protected]038e9a32008-10-08 22:40:164524 MockRead data_reads1[] = {
4525 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
4526 // Give a couple authenticate options (only the middle one is actually
4527 // supported).
[email protected]22927ad2009-09-21 19:56:194528 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:164529 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4530 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
4531 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4532 // Large content-length -- won't matter, as connection will be reset.
4533 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064534 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:164535 };
4536
4537 // After calling trans->RestartWithAuth() the first time, this is the
4538 // request we should be issuing -- the final header line contains the
4539 // proxy's credentials.
4540 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:234541 MockWrite(
4542 "GET http://www.example.org/ HTTP/1.1\r\n"
4543 "Host: www.example.org\r\n"
4544 "Proxy-Connection: keep-alive\r\n"
4545 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:164546 };
4547
4548 // Now the proxy server lets the request pass through to origin server.
4549 // The origin server responds with a 401.
4550 MockRead data_reads2[] = {
4551 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4552 // Note: We are using the same realm-name as the proxy server. This is
4553 // completely valid, as realms are unique across hosts.
4554 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4555 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4556 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064557 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:164558 };
4559
4560 // After calling trans->RestartWithAuth() the second time, we should send
4561 // the credentials for both the proxy and origin server.
4562 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:234563 MockWrite(
4564 "GET http://www.example.org/ HTTP/1.1\r\n"
4565 "Host: www.example.org\r\n"
4566 "Proxy-Connection: keep-alive\r\n"
4567 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
4568 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:164569 };
4570
4571 // Lastly we get the desired content.
4572 MockRead data_reads3[] = {
4573 MockRead("HTTP/1.0 200 OK\r\n"),
4574 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4575 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064576 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:164577 };
4578
[email protected]31a2bfe2010-02-09 08:03:394579 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4580 data_writes1, arraysize(data_writes1));
4581 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4582 data_writes2, arraysize(data_writes2));
4583 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4584 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:074585 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4586 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4587 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:164588
[email protected]49639fa2011-12-20 23:22:414589 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:164590
[email protected]49639fa2011-12-20 23:22:414591 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424592 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:164593
4594 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424595 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:164596
[email protected]1c773ea12009-04-28 19:58:424597 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504598 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044599 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:164600
[email protected]49639fa2011-12-20 23:22:414601 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:164602
[email protected]49639fa2011-12-20 23:22:414603 rv = trans->RestartWithAuth(
4604 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:424605 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:164606
4607 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424608 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:164609
4610 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504611 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044612 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:164613
[email protected]49639fa2011-12-20 23:22:414614 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:164615
[email protected]49639fa2011-12-20 23:22:414616 rv = trans->RestartWithAuth(
4617 AuthCredentials(kFoo2, kBar2), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424618 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:164619
4620 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424621 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:164622
4623 response = trans->GetResponseInfo();
4624 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4625 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:164626}
[email protected]4ddaf2502008-10-23 18:26:194627
[email protected]ea9dc9a2009-09-05 00:43:324628// For the NTLM implementation using SSPI, we skip the NTLM tests since we
4629// can't hook into its internals to cause it to generate predictable NTLM
4630// authorization headers.
4631#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:294632// The NTLM authentication unit tests were generated by capturing the HTTP
4633// requests and responses using Fiddler 2 and inspecting the generated random
4634// bytes in the debugger.
4635
4636// Enter the correct password and authenticate successfully.
[email protected]23e482282013-06-14 16:08:024637TEST_P(HttpNetworkTransactionTest, NTLMAuth1) {
[email protected]1c773ea12009-04-28 19:58:424638 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:244639 request.method = "GET";
4640 request.url = GURL("http://172.22.68.17/kids/login.aspx");
[email protected]2217aa22013-10-11 03:03:544641
4642 // Ensure load is not disrupted by flags which suppress behaviour specific
4643 // to other auth schemes.
4644 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:244645
[email protected]cb9bf6ca2011-01-28 13:15:274646 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
4647 MockGetHostName);
[email protected]bb88e1d32013-05-03 23:11:074648 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274649
[email protected]3f918782009-02-28 01:29:244650 MockWrite data_writes1[] = {
4651 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4652 "Host: 172.22.68.17\r\n"
4653 "Connection: keep-alive\r\n\r\n"),
4654 };
4655
4656 MockRead data_reads1[] = {
4657 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:044658 // Negotiate and NTLM are often requested together. However, we only want
4659 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
4660 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:244661 MockRead("WWW-Authenticate: NTLM\r\n"),
4662 MockRead("Connection: close\r\n"),
4663 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364664 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:244665 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064666 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]3f918782009-02-28 01:29:244667 };
4668
4669 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:224670 // After restarting with a null identity, this is the
[email protected]3f918782009-02-28 01:29:244671 // request we should be issuing -- the final header line contains a Type
4672 // 1 message.
4673 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4674 "Host: 172.22.68.17\r\n"
4675 "Connection: keep-alive\r\n"
4676 "Authorization: NTLM "
4677 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4678
4679 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4680 // (the credentials for the origin server). The second request continues
4681 // on the same connection.
4682 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4683 "Host: 172.22.68.17\r\n"
4684 "Connection: keep-alive\r\n"
[email protected]385a4672009-03-11 22:21:294685 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4686 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4687 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
4688 "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
4689 "ahlhx5I=\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:244690 };
4691
4692 MockRead data_reads2[] = {
4693 // The origin server responds with a Type 2 message.
4694 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4695 MockRead("WWW-Authenticate: NTLM "
[email protected]385a4672009-03-11 22:21:294696 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
[email protected]3f918782009-02-28 01:29:244697 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4698 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4699 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4700 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4701 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4702 "BtAAAAAAA=\r\n"),
4703 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364704 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:244705 MockRead("You are not authorized to view this page\r\n"),
4706
4707 // Lastly we get the desired content.
4708 MockRead("HTTP/1.1 200 OK\r\n"),
4709 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
4710 MockRead("Content-Length: 13\r\n\r\n"),
4711 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:064712 MockRead(SYNCHRONOUS, OK),
[email protected]3f918782009-02-28 01:29:244713 };
4714
[email protected]31a2bfe2010-02-09 08:03:394715 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4716 data_writes1, arraysize(data_writes1));
4717 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4718 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:074719 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4720 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:244721
[email protected]49639fa2011-12-20 23:22:414722 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:244723
[email protected]262eec82013-03-19 21:01:364724 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504725 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504726
[email protected]49639fa2011-12-20 23:22:414727 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424728 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:244729
4730 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424731 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:244732
[email protected]0757e7702009-03-27 04:00:224733 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4734
[email protected]1c773ea12009-04-28 19:58:424735 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:044736 ASSERT_FALSE(response == NULL);
4737 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:244738
[email protected]49639fa2011-12-20 23:22:414739 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:254740
[email protected]f3cf9802011-10-28 18:44:584741 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:414742 callback2.callback());
[email protected]10af5fe72011-01-31 16:17:254743 EXPECT_EQ(ERR_IO_PENDING, rv);
4744
4745 rv = callback2.WaitForResult();
4746 EXPECT_EQ(OK, rv);
4747
4748 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4749
4750 response = trans->GetResponseInfo();
4751 ASSERT_TRUE(response != NULL);
[email protected]10af5fe72011-01-31 16:17:254752 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4753
[email protected]49639fa2011-12-20 23:22:414754 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:244755
[email protected]49639fa2011-12-20 23:22:414756 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424757 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:244758
[email protected]0757e7702009-03-27 04:00:224759 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424760 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:244761
4762 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504763 ASSERT_TRUE(response != NULL);
[email protected]3f918782009-02-28 01:29:244764 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4765 EXPECT_EQ(13, response->headers->GetContentLength());
4766}
4767
[email protected]385a4672009-03-11 22:21:294768// Enter a wrong password, and then the correct one.
[email protected]23e482282013-06-14 16:08:024769TEST_P(HttpNetworkTransactionTest, NTLMAuth2) {
[email protected]1c773ea12009-04-28 19:58:424770 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:294771 request.method = "GET";
4772 request.url = GURL("http://172.22.68.17/kids/login.aspx");
4773 request.load_flags = 0;
4774
[email protected]cb9bf6ca2011-01-28 13:15:274775 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
4776 MockGetHostName);
[email protected]bb88e1d32013-05-03 23:11:074777 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274778
[email protected]385a4672009-03-11 22:21:294779 MockWrite data_writes1[] = {
4780 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4781 "Host: 172.22.68.17\r\n"
4782 "Connection: keep-alive\r\n\r\n"),
4783 };
4784
4785 MockRead data_reads1[] = {
4786 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:044787 // Negotiate and NTLM are often requested together. However, we only want
4788 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
4789 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:294790 MockRead("WWW-Authenticate: NTLM\r\n"),
4791 MockRead("Connection: close\r\n"),
4792 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364793 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294794 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064795 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:294796 };
4797
4798 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:224799 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:294800 // request we should be issuing -- the final header line contains a Type
4801 // 1 message.
4802 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4803 "Host: 172.22.68.17\r\n"
4804 "Connection: keep-alive\r\n"
4805 "Authorization: NTLM "
4806 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4807
4808 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4809 // (the credentials for the origin server). The second request continues
4810 // on the same connection.
4811 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4812 "Host: 172.22.68.17\r\n"
4813 "Connection: keep-alive\r\n"
4814 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4815 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4816 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
4817 "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
4818 "4Ww7b7E=\r\n\r\n"),
4819 };
4820
4821 MockRead data_reads2[] = {
4822 // The origin server responds with a Type 2 message.
4823 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4824 MockRead("WWW-Authenticate: NTLM "
4825 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
4826 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4827 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4828 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4829 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4830 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4831 "BtAAAAAAA=\r\n"),
4832 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364833 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294834 MockRead("You are not authorized to view this page\r\n"),
4835
4836 // Wrong password.
4837 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]385a4672009-03-11 22:21:294838 MockRead("WWW-Authenticate: NTLM\r\n"),
4839 MockRead("Connection: close\r\n"),
4840 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364841 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294842 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064843 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:294844 };
4845
4846 MockWrite data_writes3[] = {
[email protected]0757e7702009-03-27 04:00:224847 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:294848 // request we should be issuing -- the final header line contains a Type
4849 // 1 message.
4850 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4851 "Host: 172.22.68.17\r\n"
4852 "Connection: keep-alive\r\n"
4853 "Authorization: NTLM "
4854 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4855
4856 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4857 // (the credentials for the origin server). The second request continues
4858 // on the same connection.
4859 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4860 "Host: 172.22.68.17\r\n"
4861 "Connection: keep-alive\r\n"
4862 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4863 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4864 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
4865 "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
4866 "+4MUm7c=\r\n\r\n"),
4867 };
4868
4869 MockRead data_reads3[] = {
4870 // The origin server responds with a Type 2 message.
4871 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4872 MockRead("WWW-Authenticate: NTLM "
4873 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
4874 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4875 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4876 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4877 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4878 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4879 "BtAAAAAAA=\r\n"),
4880 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364881 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294882 MockRead("You are not authorized to view this page\r\n"),
4883
4884 // Lastly we get the desired content.
4885 MockRead("HTTP/1.1 200 OK\r\n"),
4886 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
4887 MockRead("Content-Length: 13\r\n\r\n"),
4888 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:064889 MockRead(SYNCHRONOUS, OK),
[email protected]385a4672009-03-11 22:21:294890 };
4891
[email protected]31a2bfe2010-02-09 08:03:394892 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4893 data_writes1, arraysize(data_writes1));
4894 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4895 data_writes2, arraysize(data_writes2));
4896 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4897 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:074898 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4899 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4900 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:294901
[email protected]49639fa2011-12-20 23:22:414902 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:294903
[email protected]262eec82013-03-19 21:01:364904 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504905 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504906
[email protected]49639fa2011-12-20 23:22:414907 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424908 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:294909
4910 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424911 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:294912
[email protected]0757e7702009-03-27 04:00:224913 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:294914
[email protected]1c773ea12009-04-28 19:58:424915 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504916 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044917 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:294918
[email protected]49639fa2011-12-20 23:22:414919 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:294920
[email protected]0757e7702009-03-27 04:00:224921 // Enter the wrong password.
[email protected]f3cf9802011-10-28 18:44:584922 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword),
[email protected]49639fa2011-12-20 23:22:414923 callback2.callback());
[email protected]1c773ea12009-04-28 19:58:424924 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:294925
[email protected]10af5fe72011-01-31 16:17:254926 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424927 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:294928
[email protected]0757e7702009-03-27 04:00:224929 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:414930 TestCompletionCallback callback3;
4931 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424932 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]10af5fe72011-01-31 16:17:254933 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424934 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:224935 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4936
4937 response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:044938 ASSERT_FALSE(response == NULL);
4939 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:224940
[email protected]49639fa2011-12-20 23:22:414941 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:224942
4943 // Now enter the right password.
[email protected]f3cf9802011-10-28 18:44:584944 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:414945 callback4.callback());
[email protected]10af5fe72011-01-31 16:17:254946 EXPECT_EQ(ERR_IO_PENDING, rv);
4947
4948 rv = callback4.WaitForResult();
4949 EXPECT_EQ(OK, rv);
4950
4951 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4952
[email protected]49639fa2011-12-20 23:22:414953 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:254954
4955 // One more roundtrip
[email protected]49639fa2011-12-20 23:22:414956 rv = trans->RestartWithAuth(AuthCredentials(), callback5.callback());
[email protected]1c773ea12009-04-28 19:58:424957 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:224958
4959 rv = callback5.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424960 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:224961
[email protected]385a4672009-03-11 22:21:294962 response = trans->GetResponseInfo();
4963 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4964 EXPECT_EQ(13, response->headers->GetContentLength());
4965}
[email protected]ea9dc9a2009-09-05 00:43:324966#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:294967
[email protected]4ddaf2502008-10-23 18:26:194968// Test reading a server response which has only headers, and no body.
4969// After some maximum number of bytes is consumed, the transaction should
4970// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
[email protected]23e482282013-06-14 16:08:024971TEST_P(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:424972 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:194973 request.method = "GET";
bncce36dca22015-04-21 22:11:234974 request.url = GURL("http://www.example.org/");
[email protected]4ddaf2502008-10-23 18:26:194975 request.load_flags = 0;
4976
[email protected]3fe8d2f82013-10-17 08:56:074977 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274978 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:414979 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:274980
[email protected]b75b7b2f2009-10-06 00:54:534981 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:434982 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:534983 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:194984
4985 MockRead data_reads[] = {
4986 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:064987 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:194988 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:064989 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:194990 };
[email protected]31a2bfe2010-02-09 08:03:394991 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:074992 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:194993
[email protected]49639fa2011-12-20 23:22:414994 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:194995
[email protected]49639fa2011-12-20 23:22:414996 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424997 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]4ddaf2502008-10-23 18:26:194998
4999 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425000 EXPECT_EQ(ERR_RESPONSE_HEADERS_TOO_BIG, rv);
[email protected]4ddaf2502008-10-23 18:26:195001}
[email protected]f4e426b2008-11-05 00:24:495002
5003// Make sure that we don't try to reuse a TCPClientSocket when failing to
5004// establish tunnel.
5005// http://code.google.com/p/chromium/issues/detail?id=3772
[email protected]23e482282013-06-14 16:08:025006TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:235007 DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:275008 HttpRequestInfo request;
5009 request.method = "GET";
bncce36dca22015-04-21 22:11:235010 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275011 request.load_flags = 0;
5012
[email protected]f4e426b2008-11-05 00:24:495013 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:075014 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]db8f44c2008-12-13 04:52:015015
[email protected]bb88e1d32013-05-03 23:11:075016 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:495017
[email protected]262eec82013-03-19 21:01:365018 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505019 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f4e426b2008-11-05 00:24:495020
[email protected]f4e426b2008-11-05 00:24:495021 // Since we have proxy, should try to establish tunnel.
5022 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235023 MockWrite(
5024 "CONNECT www.example.org:443 HTTP/1.1\r\n"
5025 "Host: www.example.org\r\n"
5026 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:495027 };
5028
[email protected]77848d12008-11-14 00:00:225029 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:495030 // connection. Usually a proxy would return 501 (not implemented),
5031 // or 200 (tunnel established).
5032 MockRead data_reads1[] = {
5033 MockRead("HTTP/1.1 404 Not Found\r\n"),
5034 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065035 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]f4e426b2008-11-05 00:24:495036 };
5037
[email protected]31a2bfe2010-02-09 08:03:395038 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5039 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075040 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:495041
[email protected]49639fa2011-12-20 23:22:415042 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:495043
[email protected]49639fa2011-12-20 23:22:415044 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425045 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f4e426b2008-11-05 00:24:495046
5047 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425048 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]f4e426b2008-11-05 00:24:495049
[email protected]b4404c02009-04-10 16:38:525050 // Empty the current queue. This is necessary because idle sockets are
5051 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345052 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:525053
[email protected]f4e426b2008-11-05 00:24:495054 // We now check to make sure the TCPClientSocket was not added back to
5055 // the pool.
[email protected]90499482013-06-01 00:39:505056 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:495057 trans.reset();
[email protected]2da659e2013-05-23 20:51:345058 base::MessageLoop::current()->RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:495059 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:505060 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:495061}
[email protected]372d34a2008-11-05 21:30:515062
[email protected]1b157c02009-04-21 01:55:405063// Make sure that we recycle a socket after reading all of the response body.
[email protected]23e482282013-06-14 16:08:025064TEST_P(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:425065 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:405066 request.method = "GET";
bncce36dca22015-04-21 22:11:235067 request.url = GURL("http://www.example.org/");
[email protected]1b157c02009-04-21 01:55:405068 request.load_flags = 0;
5069
[email protected]bb88e1d32013-05-03 23:11:075070 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275071
[email protected]262eec82013-03-19 21:01:365072 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505073 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275074
[email protected]1b157c02009-04-21 01:55:405075 MockRead data_reads[] = {
5076 // A part of the response body is received with the response headers.
5077 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
5078 // The rest of the response body is received in two parts.
5079 MockRead("lo"),
5080 MockRead(" world"),
5081 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:065082 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:405083 };
5084
[email protected]31a2bfe2010-02-09 08:03:395085 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:075086 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:405087
[email protected]49639fa2011-12-20 23:22:415088 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:405089
[email protected]49639fa2011-12-20 23:22:415090 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425091 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]1b157c02009-04-21 01:55:405092
5093 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425094 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:405095
[email protected]1c773ea12009-04-28 19:58:425096 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505097 ASSERT_TRUE(response != NULL);
[email protected]1b157c02009-04-21 01:55:405098
[email protected]90499482013-06-01 00:39:505099 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]1b157c02009-04-21 01:55:405100 std::string status_line = response->headers->GetStatusLine();
5101 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
5102
[email protected]90499482013-06-01 00:39:505103 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:405104
5105 std::string response_data;
5106 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:425107 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:405108 EXPECT_EQ("hello world", response_data);
5109
5110 // Empty the current queue. This is necessary because idle sockets are
5111 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345112 base::MessageLoop::current()->RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:405113
5114 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505115 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:405116}
5117
[email protected]76a505b2010-08-25 06:23:005118// Make sure that we recycle a SSL socket after reading all of the response
5119// body.
[email protected]23e482282013-06-14 16:08:025120TEST_P(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:005121 HttpRequestInfo request;
5122 request.method = "GET";
bncce36dca22015-04-21 22:11:235123 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:005124 request.load_flags = 0;
5125
5126 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:235127 MockWrite(
5128 "GET / HTTP/1.1\r\n"
5129 "Host: www.example.org\r\n"
5130 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:005131 };
5132
5133 MockRead data_reads[] = {
5134 MockRead("HTTP/1.1 200 OK\r\n"),
5135 MockRead("Content-Length: 11\r\n\r\n"),
5136 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:065137 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:005138 };
5139
[email protected]8ddf8322012-02-23 18:08:065140 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075141 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:005142
5143 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5144 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:075145 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:005146
[email protected]49639fa2011-12-20 23:22:415147 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:005148
[email protected]bb88e1d32013-05-03 23:11:075149 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:365150 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505151 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:005152
[email protected]49639fa2011-12-20 23:22:415153 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:005154
5155 EXPECT_EQ(ERR_IO_PENDING, rv);
5156 EXPECT_EQ(OK, callback.WaitForResult());
5157
5158 const HttpResponseInfo* response = trans->GetResponseInfo();
5159 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:505160 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:005161 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5162
[email protected]90499482013-06-01 00:39:505163 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005164
5165 std::string response_data;
5166 rv = ReadTransaction(trans.get(), &response_data);
5167 EXPECT_EQ(OK, rv);
5168 EXPECT_EQ("hello world", response_data);
5169
5170 // Empty the current queue. This is necessary because idle sockets are
5171 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345172 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:005173
5174 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505175 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005176}
5177
5178// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
5179// from the pool and make sure that we recover okay.
[email protected]23e482282013-06-14 16:08:025180TEST_P(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:005181 HttpRequestInfo request;
5182 request.method = "GET";
bncce36dca22015-04-21 22:11:235183 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:005184 request.load_flags = 0;
5185
5186 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:235187 MockWrite(
5188 "GET / HTTP/1.1\r\n"
5189 "Host: www.example.org\r\n"
5190 "Connection: keep-alive\r\n\r\n"),
5191 MockWrite(
5192 "GET / HTTP/1.1\r\n"
5193 "Host: www.example.org\r\n"
5194 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:005195 };
5196
5197 MockRead data_reads[] = {
5198 MockRead("HTTP/1.1 200 OK\r\n"),
5199 MockRead("Content-Length: 11\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065200 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:005201 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:065202 MockRead(ASYNC, 0, 0) // EOF
[email protected]76a505b2010-08-25 06:23:005203 };
5204
[email protected]8ddf8322012-02-23 18:08:065205 SSLSocketDataProvider ssl(ASYNC, OK);
5206 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075207 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5208 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:005209
5210 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5211 data_writes, arraysize(data_writes));
5212 StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
5213 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:075214 session_deps_.socket_factory->AddSocketDataProvider(&data);
5215 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:005216
[email protected]49639fa2011-12-20 23:22:415217 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:005218
[email protected]bb88e1d32013-05-03 23:11:075219 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:365220 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505221 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:005222
[email protected]49639fa2011-12-20 23:22:415223 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:005224
5225 EXPECT_EQ(ERR_IO_PENDING, rv);
5226 EXPECT_EQ(OK, callback.WaitForResult());
5227
5228 const HttpResponseInfo* response = trans->GetResponseInfo();
5229 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:505230 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:005231 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5232
[email protected]90499482013-06-01 00:39:505233 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005234
5235 std::string response_data;
5236 rv = ReadTransaction(trans.get(), &response_data);
5237 EXPECT_EQ(OK, rv);
5238 EXPECT_EQ("hello world", response_data);
5239
5240 // Empty the current queue. This is necessary because idle sockets are
5241 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345242 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:005243
5244 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505245 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005246
5247 // Now start the second transaction, which should reuse the previous socket.
5248
[email protected]90499482013-06-01 00:39:505249 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:005250
[email protected]49639fa2011-12-20 23:22:415251 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:005252
5253 EXPECT_EQ(ERR_IO_PENDING, rv);
5254 EXPECT_EQ(OK, callback.WaitForResult());
5255
5256 response = trans->GetResponseInfo();
5257 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:505258 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:005259 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5260
[email protected]90499482013-06-01 00:39:505261 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005262
5263 rv = ReadTransaction(trans.get(), &response_data);
5264 EXPECT_EQ(OK, rv);
5265 EXPECT_EQ("hello world", response_data);
5266
5267 // Empty the current queue. This is necessary because idle sockets are
5268 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345269 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:005270
5271 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505272 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005273}
5274
[email protected]b4404c02009-04-10 16:38:525275// Make sure that we recycle a socket after a zero-length response.
5276// http://crbug.com/9880
[email protected]23e482282013-06-14 16:08:025277TEST_P(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:425278 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:525279 request.method = "GET";
bncce36dca22015-04-21 22:11:235280 request.url = GURL(
5281 "http://www.example.org/csi?v=3&s=web&action=&"
5282 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
5283 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
5284 "rt=prt.2642,ol.2649,xjs.2951");
[email protected]b4404c02009-04-10 16:38:525285 request.load_flags = 0;
5286
[email protected]bb88e1d32013-05-03 23:11:075287 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275288
[email protected]262eec82013-03-19 21:01:365289 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505290 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275291
[email protected]b4404c02009-04-10 16:38:525292 MockRead data_reads[] = {
5293 MockRead("HTTP/1.1 204 No Content\r\n"
5294 "Content-Length: 0\r\n"
5295 "Content-Type: text/html\r\n\r\n"),
5296 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:065297 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:525298 };
5299
[email protected]31a2bfe2010-02-09 08:03:395300 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:075301 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:525302
[email protected]49639fa2011-12-20 23:22:415303 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:525304
[email protected]49639fa2011-12-20 23:22:415305 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425306 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]b4404c02009-04-10 16:38:525307
5308 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425309 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:525310
[email protected]1c773ea12009-04-28 19:58:425311 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505312 ASSERT_TRUE(response != NULL);
[email protected]b4404c02009-04-10 16:38:525313
[email protected]90499482013-06-01 00:39:505314 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]b4404c02009-04-10 16:38:525315 std::string status_line = response->headers->GetStatusLine();
5316 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
5317
[email protected]90499482013-06-01 00:39:505318 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:525319
5320 std::string response_data;
5321 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:425322 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:525323 EXPECT_EQ("", response_data);
5324
5325 // Empty the current queue. This is necessary because idle sockets are
5326 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345327 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:525328
5329 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505330 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:525331}
5332
[email protected]23e482282013-06-14 16:08:025333TEST_P(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
[email protected]b2d26cfd2012-12-11 10:36:065334 ScopedVector<UploadElementReader> element_readers;
5335 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:075336 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:275337
[email protected]1c773ea12009-04-28 19:58:425338 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:515339 // Transaction 1: a GET request that succeeds. The socket is recycled
5340 // after use.
5341 request[0].method = "GET";
5342 request[0].url = GURL("http://www.google.com/");
5343 request[0].load_flags = 0;
5344 // Transaction 2: a POST request. Reuses the socket kept alive from
5345 // transaction 1. The first attempts fails when writing the POST data.
5346 // This causes the transaction to retry with a new socket. The second
5347 // attempt succeeds.
5348 request[1].method = "POST";
5349 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:275350 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:515351 request[1].load_flags = 0;
5352
[email protected]bb88e1d32013-05-03 23:11:075353 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:515354
5355 // The first socket is used for transaction 1 and the first attempt of
5356 // transaction 2.
5357
5358 // The response of transaction 1.
5359 MockRead data_reads1[] = {
5360 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
5361 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:065362 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:515363 };
5364 // The mock write results of transaction 1 and the first attempt of
5365 // transaction 2.
5366 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:065367 MockWrite(SYNCHRONOUS, 64), // GET
5368 MockWrite(SYNCHRONOUS, 93), // POST
5369 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:515370 };
[email protected]31a2bfe2010-02-09 08:03:395371 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5372 data_writes1, arraysize(data_writes1));
[email protected]372d34a2008-11-05 21:30:515373
5374 // The second socket is used for the second attempt of transaction 2.
5375
5376 // The response of transaction 2.
5377 MockRead data_reads2[] = {
5378 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
5379 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:065380 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:515381 };
5382 // The mock write results of the second attempt of transaction 2.
5383 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:065384 MockWrite(SYNCHRONOUS, 93), // POST
5385 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:515386 };
[email protected]31a2bfe2010-02-09 08:03:395387 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5388 data_writes2, arraysize(data_writes2));
[email protected]372d34a2008-11-05 21:30:515389
[email protected]bb88e1d32013-05-03 23:11:075390 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5391 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:515392
thestig9d3bb0c2015-01-24 00:49:515393 const char* const kExpectedResponseData[] = {
[email protected]372d34a2008-11-05 21:30:515394 "hello world", "welcome"
5395 };
5396
5397 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:425398 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505399 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]372d34a2008-11-05 21:30:515400
[email protected]49639fa2011-12-20 23:22:415401 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:515402
[email protected]49639fa2011-12-20 23:22:415403 int rv = trans->Start(&request[i], callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425404 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]372d34a2008-11-05 21:30:515405
5406 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425407 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:515408
[email protected]1c773ea12009-04-28 19:58:425409 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505410 ASSERT_TRUE(response != NULL);
[email protected]372d34a2008-11-05 21:30:515411
[email protected]90499482013-06-01 00:39:505412 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]372d34a2008-11-05 21:30:515413 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5414
5415 std::string response_data;
5416 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:425417 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:515418 EXPECT_EQ(kExpectedResponseData[i], response_data);
5419 }
5420}
[email protected]f9ee6b52008-11-08 06:46:235421
5422// Test the request-challenge-retry sequence for basic auth when there is
5423// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:165424// it fails the identity from the URL is used to answer the challenge.
[email protected]23e482282013-06-14 16:08:025425TEST_P(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:425426 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235427 request.method = "GET";
bncce36dca22015-04-21 22:11:235428 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:415429 request.load_flags = LOAD_NORMAL;
[email protected]a97cca42009-08-14 01:00:295430
[email protected]3fe8d2f82013-10-17 08:56:075431 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275432 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415433 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275434
[email protected]a97cca42009-08-14 01:00:295435 // The password contains an escaped character -- for this test to pass it
5436 // will need to be unescaped by HttpNetworkTransaction.
5437 EXPECT_EQ("b%40r", request.url.password());
5438
[email protected]f9ee6b52008-11-08 06:46:235439 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235440 MockWrite(
5441 "GET / HTTP/1.1\r\n"
5442 "Host: www.example.org\r\n"
5443 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235444 };
5445
5446 MockRead data_reads1[] = {
5447 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5448 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5449 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065450 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235451 };
5452
[email protected]2262e3a2012-05-22 16:08:165453 // After the challenge above, the transaction will be restarted using the
5454 // identity from the url (foo, b@r) to answer the challenge.
5455 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235456 MockWrite(
5457 "GET / HTTP/1.1\r\n"
5458 "Host: www.example.org\r\n"
5459 "Connection: keep-alive\r\n"
5460 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:165461 };
5462
5463 MockRead data_reads2[] = {
5464 MockRead("HTTP/1.0 200 OK\r\n"),
5465 MockRead("Content-Length: 100\r\n\r\n"),
5466 MockRead(SYNCHRONOUS, OK),
5467 };
5468
[email protected]31a2bfe2010-02-09 08:03:395469 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5470 data_writes1, arraysize(data_writes1));
[email protected]2262e3a2012-05-22 16:08:165471 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5472 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075473 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5474 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235475
[email protected]49639fa2011-12-20 23:22:415476 TestCompletionCallback callback1;
[email protected]49639fa2011-12-20 23:22:415477 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425478 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235479 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425480 EXPECT_EQ(OK, rv);
[email protected]2262e3a2012-05-22 16:08:165481 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5482
5483 TestCompletionCallback callback2;
5484 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
5485 EXPECT_EQ(ERR_IO_PENDING, rv);
5486 rv = callback2.WaitForResult();
5487 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225488 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5489
[email protected]2262e3a2012-05-22 16:08:165490 const HttpResponseInfo* response = trans->GetResponseInfo();
5491 ASSERT_TRUE(response != NULL);
5492
5493 // There is no challenge info, since the identity in URL worked.
5494 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5495
5496 EXPECT_EQ(100, response->headers->GetContentLength());
5497
5498 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:345499 base::MessageLoop::current()->RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:165500}
5501
5502// Test the request-challenge-retry sequence for basic auth when there is an
5503// incorrect identity in the URL. The identity from the URL should be used only
5504// once.
[email protected]23e482282013-06-14 16:08:025505TEST_P(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:165506 HttpRequestInfo request;
5507 request.method = "GET";
5508 // Note: the URL has a username:password in it. The password "baz" is
5509 // wrong (should be "bar").
bncce36dca22015-04-21 22:11:235510 request.url = GURL("http://foo:[email protected]/");
[email protected]2262e3a2012-05-22 16:08:165511
5512 request.load_flags = LOAD_NORMAL;
5513
[email protected]3fe8d2f82013-10-17 08:56:075514 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2262e3a2012-05-22 16:08:165515 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415516 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2262e3a2012-05-22 16:08:165517
5518 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235519 MockWrite(
5520 "GET / HTTP/1.1\r\n"
5521 "Host: www.example.org\r\n"
5522 "Connection: keep-alive\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:165523 };
5524
5525 MockRead data_reads1[] = {
5526 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5527 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5528 MockRead("Content-Length: 10\r\n\r\n"),
5529 MockRead(SYNCHRONOUS, ERR_FAILED),
5530 };
5531
5532 // After the challenge above, the transaction will be restarted using the
5533 // identity from the url (foo, baz) to answer the challenge.
5534 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235535 MockWrite(
5536 "GET / HTTP/1.1\r\n"
5537 "Host: www.example.org\r\n"
5538 "Connection: keep-alive\r\n"
5539 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:165540 };
5541
5542 MockRead data_reads2[] = {
5543 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5544 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5545 MockRead("Content-Length: 10\r\n\r\n"),
5546 MockRead(SYNCHRONOUS, ERR_FAILED),
5547 };
5548
5549 // After the challenge above, the transaction will be restarted using the
5550 // identity supplied by the user (foo, bar) to answer the challenge.
5551 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:235552 MockWrite(
5553 "GET / HTTP/1.1\r\n"
5554 "Host: www.example.org\r\n"
5555 "Connection: keep-alive\r\n"
5556 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:165557 };
5558
5559 MockRead data_reads3[] = {
5560 MockRead("HTTP/1.0 200 OK\r\n"),
5561 MockRead("Content-Length: 100\r\n\r\n"),
5562 MockRead(SYNCHRONOUS, OK),
5563 };
5564
5565 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5566 data_writes1, arraysize(data_writes1));
5567 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5568 data_writes2, arraysize(data_writes2));
5569 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5570 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075571 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5572 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5573 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:165574
5575 TestCompletionCallback callback1;
5576
5577 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5578 EXPECT_EQ(ERR_IO_PENDING, rv);
5579
5580 rv = callback1.WaitForResult();
5581 EXPECT_EQ(OK, rv);
5582
5583 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5584 TestCompletionCallback callback2;
5585 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
5586 EXPECT_EQ(ERR_IO_PENDING, rv);
5587 rv = callback2.WaitForResult();
5588 EXPECT_EQ(OK, rv);
5589 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5590
5591 const HttpResponseInfo* response = trans->GetResponseInfo();
5592 ASSERT_TRUE(response != NULL);
5593 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
5594
5595 TestCompletionCallback callback3;
5596 rv = trans->RestartWithAuth(
5597 AuthCredentials(kFoo, kBar), callback3.callback());
5598 EXPECT_EQ(ERR_IO_PENDING, rv);
5599 rv = callback3.WaitForResult();
5600 EXPECT_EQ(OK, rv);
5601 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5602
5603 response = trans->GetResponseInfo();
5604 ASSERT_TRUE(response != NULL);
5605
5606 // There is no challenge info, since the identity worked.
5607 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5608
5609 EXPECT_EQ(100, response->headers->GetContentLength());
5610
[email protected]ea9dc9a2009-09-05 00:43:325611 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:345612 base::MessageLoop::current()->RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:325613}
5614
[email protected]2217aa22013-10-11 03:03:545615
5616// Test the request-challenge-retry sequence for basic auth when there is a
5617// correct identity in the URL, but its use is being suppressed. The identity
5618// from the URL should never be used.
5619TEST_P(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
5620 HttpRequestInfo request;
5621 request.method = "GET";
bncce36dca22015-04-21 22:11:235622 request.url = GURL("http://foo:[email protected]/");
[email protected]2217aa22013-10-11 03:03:545623 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
5624
[email protected]3fe8d2f82013-10-17 08:56:075625 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2217aa22013-10-11 03:03:545626 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415627 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2217aa22013-10-11 03:03:545628
5629 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235630 MockWrite(
5631 "GET / HTTP/1.1\r\n"
5632 "Host: www.example.org\r\n"
5633 "Connection: keep-alive\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:545634 };
5635
5636 MockRead data_reads1[] = {
5637 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5638 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5639 MockRead("Content-Length: 10\r\n\r\n"),
5640 MockRead(SYNCHRONOUS, ERR_FAILED),
5641 };
5642
5643 // After the challenge above, the transaction will be restarted using the
5644 // identity supplied by the user, not the one in the URL, to answer the
5645 // challenge.
5646 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:235647 MockWrite(
5648 "GET / HTTP/1.1\r\n"
5649 "Host: www.example.org\r\n"
5650 "Connection: keep-alive\r\n"
5651 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:545652 };
5653
5654 MockRead data_reads3[] = {
5655 MockRead("HTTP/1.0 200 OK\r\n"),
5656 MockRead("Content-Length: 100\r\n\r\n"),
5657 MockRead(SYNCHRONOUS, OK),
5658 };
5659
5660 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5661 data_writes1, arraysize(data_writes1));
5662 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5663 data_writes3, arraysize(data_writes3));
5664 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5665 session_deps_.socket_factory->AddSocketDataProvider(&data3);
5666
5667 TestCompletionCallback callback1;
5668 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5669 EXPECT_EQ(ERR_IO_PENDING, rv);
5670 rv = callback1.WaitForResult();
5671 EXPECT_EQ(OK, rv);
5672 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5673
5674 const HttpResponseInfo* response = trans->GetResponseInfo();
5675 ASSERT_TRUE(response != NULL);
5676 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
5677
5678 TestCompletionCallback callback3;
5679 rv = trans->RestartWithAuth(
5680 AuthCredentials(kFoo, kBar), callback3.callback());
5681 EXPECT_EQ(ERR_IO_PENDING, rv);
5682 rv = callback3.WaitForResult();
5683 EXPECT_EQ(OK, rv);
5684 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5685
5686 response = trans->GetResponseInfo();
5687 ASSERT_TRUE(response != NULL);
5688
5689 // There is no challenge info, since the identity worked.
5690 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5691 EXPECT_EQ(100, response->headers->GetContentLength());
5692
5693 // Empty the current queue.
5694 base::MessageLoop::current()->RunUntilIdle();
5695}
5696
[email protected]f9ee6b52008-11-08 06:46:235697// Test that previously tried username/passwords for a realm get re-used.
[email protected]23e482282013-06-14 16:08:025698TEST_P(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
[email protected]bb88e1d32013-05-03 23:11:075699 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:235700
5701 // Transaction 1: authenticate (foo, bar) on MyRealm1
5702 {
[email protected]1c773ea12009-04-28 19:58:425703 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235704 request.method = "GET";
bncce36dca22015-04-21 22:11:235705 request.url = GURL("http://www.example.org/x/y/z");
[email protected]f9ee6b52008-11-08 06:46:235706 request.load_flags = 0;
5707
[email protected]262eec82013-03-19 21:01:365708 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505709 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275710
[email protected]f9ee6b52008-11-08 06:46:235711 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235712 MockWrite(
5713 "GET /x/y/z HTTP/1.1\r\n"
5714 "Host: www.example.org\r\n"
5715 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235716 };
5717
5718 MockRead data_reads1[] = {
5719 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5720 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5721 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065722 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235723 };
5724
5725 // Resend with authorization (username=foo, password=bar)
5726 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235727 MockWrite(
5728 "GET /x/y/z HTTP/1.1\r\n"
5729 "Host: www.example.org\r\n"
5730 "Connection: keep-alive\r\n"
5731 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235732 };
5733
5734 // Sever accepts the authorization.
5735 MockRead data_reads2[] = {
5736 MockRead("HTTP/1.0 200 OK\r\n"),
5737 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065738 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235739 };
5740
[email protected]31a2bfe2010-02-09 08:03:395741 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5742 data_writes1, arraysize(data_writes1));
5743 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5744 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075745 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5746 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235747
[email protected]49639fa2011-12-20 23:22:415748 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235749
[email protected]49639fa2011-12-20 23:22:415750 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425751 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235752
5753 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425754 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235755
[email protected]1c773ea12009-04-28 19:58:425756 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505757 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045758 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:235759
[email protected]49639fa2011-12-20 23:22:415760 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:235761
[email protected]49639fa2011-12-20 23:22:415762 rv = trans->RestartWithAuth(
5763 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425764 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235765
5766 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425767 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235768
5769 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505770 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235771 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5772 EXPECT_EQ(100, response->headers->GetContentLength());
5773 }
5774
5775 // ------------------------------------------------------------------------
5776
5777 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
5778 {
[email protected]1c773ea12009-04-28 19:58:425779 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235780 request.method = "GET";
5781 // Note that Transaction 1 was at /x/y/z, so this is in the same
5782 // protection space as MyRealm1.
bncce36dca22015-04-21 22:11:235783 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]f9ee6b52008-11-08 06:46:235784 request.load_flags = 0;
5785
[email protected]262eec82013-03-19 21:01:365786 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505787 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275788
[email protected]f9ee6b52008-11-08 06:46:235789 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235790 MockWrite(
5791 "GET /x/y/a/b HTTP/1.1\r\n"
5792 "Host: www.example.org\r\n"
5793 "Connection: keep-alive\r\n"
5794 // Send preemptive authorization for MyRealm1
5795 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235796 };
5797
5798 // The server didn't like the preemptive authorization, and
5799 // challenges us for a different realm (MyRealm2).
5800 MockRead data_reads1[] = {
5801 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5802 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
5803 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065804 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235805 };
5806
5807 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
5808 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235809 MockWrite(
5810 "GET /x/y/a/b HTTP/1.1\r\n"
5811 "Host: www.example.org\r\n"
5812 "Connection: keep-alive\r\n"
5813 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235814 };
5815
5816 // Sever accepts the authorization.
5817 MockRead data_reads2[] = {
5818 MockRead("HTTP/1.0 200 OK\r\n"),
5819 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065820 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235821 };
5822
[email protected]31a2bfe2010-02-09 08:03:395823 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5824 data_writes1, arraysize(data_writes1));
5825 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5826 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075827 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5828 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235829
[email protected]49639fa2011-12-20 23:22:415830 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235831
[email protected]49639fa2011-12-20 23:22:415832 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425833 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235834
5835 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425836 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235837
[email protected]1c773ea12009-04-28 19:58:425838 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505839 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045840 ASSERT_TRUE(response->auth_challenge.get());
5841 EXPECT_FALSE(response->auth_challenge->is_proxy);
bncce36dca22015-04-21 22:11:235842 EXPECT_EQ("www.example.org:80",
[email protected]79cb5c12011-09-12 13:12:045843 response->auth_challenge->challenger.ToString());
5844 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
5845 EXPECT_EQ("basic", response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:235846
[email protected]49639fa2011-12-20 23:22:415847 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:235848
[email protected]49639fa2011-12-20 23:22:415849 rv = trans->RestartWithAuth(
5850 AuthCredentials(kFoo2, kBar2), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425851 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235852
5853 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425854 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235855
5856 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505857 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235858 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5859 EXPECT_EQ(100, response->headers->GetContentLength());
5860 }
5861
5862 // ------------------------------------------------------------------------
5863
5864 // Transaction 3: Resend a request in MyRealm's protection space --
5865 // succeed with preemptive authorization.
5866 {
[email protected]1c773ea12009-04-28 19:58:425867 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235868 request.method = "GET";
bncce36dca22015-04-21 22:11:235869 request.url = GURL("http://www.example.org/x/y/z2");
[email protected]f9ee6b52008-11-08 06:46:235870 request.load_flags = 0;
5871
[email protected]262eec82013-03-19 21:01:365872 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505873 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275874
[email protected]f9ee6b52008-11-08 06:46:235875 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235876 MockWrite(
5877 "GET /x/y/z2 HTTP/1.1\r\n"
5878 "Host: www.example.org\r\n"
5879 "Connection: keep-alive\r\n"
5880 // The authorization for MyRealm1 gets sent preemptively
5881 // (since the url is in the same protection space)
5882 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235883 };
5884
5885 // Sever accepts the preemptive authorization
5886 MockRead data_reads1[] = {
5887 MockRead("HTTP/1.0 200 OK\r\n"),
5888 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065889 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235890 };
5891
[email protected]31a2bfe2010-02-09 08:03:395892 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5893 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075894 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:235895
[email protected]49639fa2011-12-20 23:22:415896 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235897
[email protected]49639fa2011-12-20 23:22:415898 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425899 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235900
5901 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425902 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235903
[email protected]1c773ea12009-04-28 19:58:425904 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505905 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235906
5907 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5908 EXPECT_EQ(100, response->headers->GetContentLength());
5909 }
5910
5911 // ------------------------------------------------------------------------
5912
5913 // Transaction 4: request another URL in MyRealm (however the
5914 // url is not known to belong to the protection space, so no pre-auth).
5915 {
[email protected]1c773ea12009-04-28 19:58:425916 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235917 request.method = "GET";
bncce36dca22015-04-21 22:11:235918 request.url = GURL("http://www.example.org/x/1");
[email protected]f9ee6b52008-11-08 06:46:235919 request.load_flags = 0;
5920
[email protected]262eec82013-03-19 21:01:365921 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505922 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275923
[email protected]f9ee6b52008-11-08 06:46:235924 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235925 MockWrite(
5926 "GET /x/1 HTTP/1.1\r\n"
5927 "Host: www.example.org\r\n"
5928 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235929 };
5930
5931 MockRead data_reads1[] = {
5932 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5933 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5934 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065935 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235936 };
5937
5938 // Resend with authorization from MyRealm's cache.
5939 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235940 MockWrite(
5941 "GET /x/1 HTTP/1.1\r\n"
5942 "Host: www.example.org\r\n"
5943 "Connection: keep-alive\r\n"
5944 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235945 };
5946
5947 // Sever accepts the authorization.
5948 MockRead data_reads2[] = {
5949 MockRead("HTTP/1.0 200 OK\r\n"),
5950 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065951 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235952 };
5953
[email protected]31a2bfe2010-02-09 08:03:395954 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5955 data_writes1, arraysize(data_writes1));
5956 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5957 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075958 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5959 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235960
[email protected]49639fa2011-12-20 23:22:415961 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235962
[email protected]49639fa2011-12-20 23:22:415963 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425964 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235965
5966 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425967 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235968
[email protected]0757e7702009-03-27 04:00:225969 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:415970 TestCompletionCallback callback2;
5971 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425972 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:225973 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425974 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225975 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5976
[email protected]1c773ea12009-04-28 19:58:425977 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505978 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235979 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5980 EXPECT_EQ(100, response->headers->GetContentLength());
5981 }
5982
5983 // ------------------------------------------------------------------------
5984
5985 // Transaction 5: request a URL in MyRealm, but the server rejects the
5986 // cached identity. Should invalidate and re-prompt.
5987 {
[email protected]1c773ea12009-04-28 19:58:425988 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235989 request.method = "GET";
bncce36dca22015-04-21 22:11:235990 request.url = GURL("http://www.example.org/p/q/t");
[email protected]f9ee6b52008-11-08 06:46:235991 request.load_flags = 0;
5992
[email protected]262eec82013-03-19 21:01:365993 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505994 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275995
[email protected]f9ee6b52008-11-08 06:46:235996 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235997 MockWrite(
5998 "GET /p/q/t HTTP/1.1\r\n"
5999 "Host: www.example.org\r\n"
6000 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236001 };
6002
6003 MockRead data_reads1[] = {
6004 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6005 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6006 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066007 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236008 };
6009
6010 // Resend with authorization from cache for MyRealm.
6011 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236012 MockWrite(
6013 "GET /p/q/t HTTP/1.1\r\n"
6014 "Host: www.example.org\r\n"
6015 "Connection: keep-alive\r\n"
6016 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236017 };
6018
6019 // Sever rejects the authorization.
6020 MockRead data_reads2[] = {
6021 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6022 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6023 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066024 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236025 };
6026
6027 // At this point we should prompt for new credentials for MyRealm.
6028 // Restart with username=foo3, password=foo4.
6029 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236030 MockWrite(
6031 "GET /p/q/t HTTP/1.1\r\n"
6032 "Host: www.example.org\r\n"
6033 "Connection: keep-alive\r\n"
6034 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236035 };
6036
6037 // Sever accepts the authorization.
6038 MockRead data_reads3[] = {
6039 MockRead("HTTP/1.0 200 OK\r\n"),
6040 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066041 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:236042 };
6043
[email protected]31a2bfe2010-02-09 08:03:396044 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6045 data_writes1, arraysize(data_writes1));
6046 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6047 data_writes2, arraysize(data_writes2));
6048 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6049 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076050 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6051 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6052 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:236053
[email protected]49639fa2011-12-20 23:22:416054 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:236055
[email protected]49639fa2011-12-20 23:22:416056 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426057 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236058
6059 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426060 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236061
[email protected]0757e7702009-03-27 04:00:226062 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:416063 TestCompletionCallback callback2;
6064 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:426065 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:226066 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426067 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:226068 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6069
[email protected]1c773ea12009-04-28 19:58:426070 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506071 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:046072 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:236073
[email protected]49639fa2011-12-20 23:22:416074 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:236075
[email protected]49639fa2011-12-20 23:22:416076 rv = trans->RestartWithAuth(
6077 AuthCredentials(kFoo3, kBar3), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:426078 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236079
[email protected]0757e7702009-03-27 04:00:226080 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426081 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236082
6083 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506084 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:236085 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6086 EXPECT_EQ(100, response->headers->GetContentLength());
6087 }
6088}
[email protected]89ceba9a2009-03-21 03:46:066089
[email protected]3c32c5f2010-05-18 15:18:126090// Tests that nonce count increments when multiple auth attempts
6091// are started with the same nonce.
[email protected]23e482282013-06-14 16:08:026092TEST_P(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:446093 HttpAuthHandlerDigest::Factory* digest_factory =
6094 new HttpAuthHandlerDigest::Factory();
6095 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
6096 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
6097 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:076098 session_deps_.http_auth_handler_factory.reset(digest_factory);
6099 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:126100
6101 // Transaction 1: authenticate (foo, bar) on MyRealm1
6102 {
[email protected]3c32c5f2010-05-18 15:18:126103 HttpRequestInfo request;
6104 request.method = "GET";
bncce36dca22015-04-21 22:11:236105 request.url = GURL("http://www.example.org/x/y/z");
[email protected]3c32c5f2010-05-18 15:18:126106 request.load_flags = 0;
6107
[email protected]262eec82013-03-19 21:01:366108 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506109 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276110
[email protected]3c32c5f2010-05-18 15:18:126111 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236112 MockWrite(
6113 "GET /x/y/z HTTP/1.1\r\n"
6114 "Host: www.example.org\r\n"
6115 "Connection: keep-alive\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:126116 };
6117
6118 MockRead data_reads1[] = {
6119 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6120 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
6121 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066122 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:126123 };
6124
6125 // Resend with authorization (username=foo, password=bar)
6126 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236127 MockWrite(
6128 "GET /x/y/z HTTP/1.1\r\n"
6129 "Host: www.example.org\r\n"
6130 "Connection: keep-alive\r\n"
6131 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
6132 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
6133 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
6134 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:126135 };
6136
6137 // Sever accepts the authorization.
6138 MockRead data_reads2[] = {
6139 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:066140 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:126141 };
6142
6143 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6144 data_writes1, arraysize(data_writes1));
6145 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6146 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076147 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6148 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:126149
[email protected]49639fa2011-12-20 23:22:416150 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:126151
[email protected]49639fa2011-12-20 23:22:416152 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:126153 EXPECT_EQ(ERR_IO_PENDING, rv);
6154
6155 rv = callback1.WaitForResult();
6156 EXPECT_EQ(OK, rv);
6157
6158 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506159 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:046160 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:126161
[email protected]49639fa2011-12-20 23:22:416162 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:126163
[email protected]49639fa2011-12-20 23:22:416164 rv = trans->RestartWithAuth(
6165 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]3c32c5f2010-05-18 15:18:126166 EXPECT_EQ(ERR_IO_PENDING, rv);
6167
6168 rv = callback2.WaitForResult();
6169 EXPECT_EQ(OK, rv);
6170
6171 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506172 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:126173 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6174 }
6175
6176 // ------------------------------------------------------------------------
6177
6178 // Transaction 2: Request another resource in digestive's protection space.
6179 // This will preemptively add an Authorization header which should have an
6180 // "nc" value of 2 (as compared to 1 in the first use.
6181 {
[email protected]3c32c5f2010-05-18 15:18:126182 HttpRequestInfo request;
6183 request.method = "GET";
6184 // Note that Transaction 1 was at /x/y/z, so this is in the same
6185 // protection space as digest.
bncce36dca22015-04-21 22:11:236186 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]3c32c5f2010-05-18 15:18:126187 request.load_flags = 0;
6188
[email protected]262eec82013-03-19 21:01:366189 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506190 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276191
[email protected]3c32c5f2010-05-18 15:18:126192 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236193 MockWrite(
6194 "GET /x/y/a/b HTTP/1.1\r\n"
6195 "Host: www.example.org\r\n"
6196 "Connection: keep-alive\r\n"
6197 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
6198 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
6199 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
6200 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:126201 };
6202
6203 // Sever accepts the authorization.
6204 MockRead data_reads1[] = {
6205 MockRead("HTTP/1.0 200 OK\r\n"),
6206 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066207 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:126208 };
6209
6210 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6211 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:076212 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:126213
[email protected]49639fa2011-12-20 23:22:416214 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:126215
[email protected]49639fa2011-12-20 23:22:416216 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:126217 EXPECT_EQ(ERR_IO_PENDING, rv);
6218
6219 rv = callback1.WaitForResult();
6220 EXPECT_EQ(OK, rv);
6221
6222 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506223 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:126224 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6225 }
6226}
6227
[email protected]89ceba9a2009-03-21 03:46:066228// Test the ResetStateForRestart() private method.
[email protected]23e482282013-06-14 16:08:026229TEST_P(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:066230 // Create a transaction (the dependencies aren't important).
[email protected]3fe8d2f82013-10-17 08:56:076231 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:406232 scoped_ptr<HttpNetworkTransaction> trans(
dcheng48459ac22014-08-26 00:46:416233 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]89ceba9a2009-03-21 03:46:066234
6235 // Setup some state (which we expect ResetStateForRestart() will clear).
[email protected]89ceba9a2009-03-21 03:46:066236 trans->read_buf_ = new IOBuffer(15);
6237 trans->read_buf_len_ = 15;
[email protected]b94f92d2010-10-27 16:45:206238 trans->request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:066239
6240 // Setup state in response_
[email protected]a7e41312009-12-16 23:18:146241 HttpResponseInfo* response = &trans->response_;
[email protected]0877e3d2009-10-17 22:29:576242 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:086243 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:576244 response->response_time = base::Time::Now();
6245 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:066246
6247 { // Setup state for response_.vary_data
6248 HttpRequestInfo request;
6249 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
6250 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:276251 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:436252 request.extra_headers.SetHeader("Foo", "1");
6253 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:506254 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:066255 }
6256
6257 // Cause the above state to be reset.
6258 trans->ResetStateForRestart();
6259
6260 // Verify that the state that needed to be reset, has been reset.
[email protected]9b6fee12009-09-29 18:13:076261 EXPECT_TRUE(trans->read_buf_.get() == NULL);
[email protected]89ceba9a2009-03-21 03:46:066262 EXPECT_EQ(0, trans->read_buf_len_);
[email protected]b94f92d2010-10-27 16:45:206263 EXPECT_TRUE(trans->request_headers_.IsEmpty());
[email protected]0877e3d2009-10-17 22:29:576264 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6265 EXPECT_TRUE(response->headers.get() == NULL);
[email protected]34f40942010-10-04 00:34:046266 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:086267 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:576268 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:066269}
6270
[email protected]bacff652009-03-31 17:50:336271// Test HTTPS connections to a site with a bad certificate
[email protected]23e482282013-06-14 16:08:026272TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:336273 HttpRequestInfo request;
6274 request.method = "GET";
bncce36dca22015-04-21 22:11:236275 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:336276 request.load_flags = 0;
6277
[email protected]3fe8d2f82013-10-17 08:56:076278 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276279 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416280 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276281
[email protected]bacff652009-03-31 17:50:336282 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236283 MockWrite(
6284 "GET / HTTP/1.1\r\n"
6285 "Host: www.example.org\r\n"
6286 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:336287 };
6288
6289 MockRead data_reads[] = {
6290 MockRead("HTTP/1.0 200 OK\r\n"),
6291 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6292 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066293 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:336294 };
6295
[email protected]5ecc992a42009-11-11 01:41:596296 StaticSocketDataProvider ssl_bad_certificate;
[email protected]31a2bfe2010-02-09 08:03:396297 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6298 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066299 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
6300 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:336301
[email protected]bb88e1d32013-05-03 23:11:076302 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
6303 session_deps_.socket_factory->AddSocketDataProvider(&data);
6304 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
6305 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:336306
[email protected]49639fa2011-12-20 23:22:416307 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:336308
[email protected]49639fa2011-12-20 23:22:416309 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:336310 EXPECT_EQ(ERR_IO_PENDING, rv);
6311
6312 rv = callback.WaitForResult();
6313 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
6314
[email protected]49639fa2011-12-20 23:22:416315 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:336316 EXPECT_EQ(ERR_IO_PENDING, rv);
6317
6318 rv = callback.WaitForResult();
6319 EXPECT_EQ(OK, rv);
6320
6321 const HttpResponseInfo* response = trans->GetResponseInfo();
6322
[email protected]fe2255a2011-09-20 19:37:506323 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:336324 EXPECT_EQ(100, response->headers->GetContentLength());
6325}
6326
6327// Test HTTPS connections to a site with a bad certificate, going through a
6328// proxy
[email protected]23e482282013-06-14 16:08:026329TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
[email protected]bb88e1d32013-05-03 23:11:076330 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]bacff652009-03-31 17:50:336331
6332 HttpRequestInfo request;
6333 request.method = "GET";
bncce36dca22015-04-21 22:11:236334 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:336335 request.load_flags = 0;
6336
6337 MockWrite proxy_writes[] = {
bncce36dca22015-04-21 22:11:236338 MockWrite(
6339 "CONNECT www.example.org:443 HTTP/1.1\r\n"
6340 "Host: www.example.org\r\n"
6341 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:336342 };
6343
6344 MockRead proxy_reads[] = {
6345 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066346 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:336347 };
6348
6349 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236350 MockWrite(
6351 "CONNECT www.example.org:443 HTTP/1.1\r\n"
6352 "Host: www.example.org\r\n"
6353 "Proxy-Connection: keep-alive\r\n\r\n"),
6354 MockWrite(
6355 "GET / HTTP/1.1\r\n"
6356 "Host: www.example.org\r\n"
6357 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:336358 };
6359
6360 MockRead data_reads[] = {
6361 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
6362 MockRead("HTTP/1.0 200 OK\r\n"),
6363 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6364 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066365 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:336366 };
6367
[email protected]31a2bfe2010-02-09 08:03:396368 StaticSocketDataProvider ssl_bad_certificate(
6369 proxy_reads, arraysize(proxy_reads),
6370 proxy_writes, arraysize(proxy_writes));
6371 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6372 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066373 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
6374 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:336375
[email protected]bb88e1d32013-05-03 23:11:076376 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
6377 session_deps_.socket_factory->AddSocketDataProvider(&data);
6378 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
6379 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:336380
[email protected]49639fa2011-12-20 23:22:416381 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:336382
6383 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:076384 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:336385
[email protected]3fe8d2f82013-10-17 08:56:076386 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:406387 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416388 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bacff652009-03-31 17:50:336389
[email protected]49639fa2011-12-20 23:22:416390 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:336391 EXPECT_EQ(ERR_IO_PENDING, rv);
6392
6393 rv = callback.WaitForResult();
6394 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
6395
[email protected]49639fa2011-12-20 23:22:416396 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:336397 EXPECT_EQ(ERR_IO_PENDING, rv);
6398
6399 rv = callback.WaitForResult();
6400 EXPECT_EQ(OK, rv);
6401
6402 const HttpResponseInfo* response = trans->GetResponseInfo();
6403
[email protected]fe2255a2011-09-20 19:37:506404 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:336405 EXPECT_EQ(100, response->headers->GetContentLength());
6406 }
6407}
6408
[email protected]2df19bb2010-08-25 20:13:466409
6410// Test HTTPS connections to a site, going through an HTTPS proxy
[email protected]23e482282013-06-14 16:08:026411TEST_P(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076412 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206413 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
vishal.b62985ca92015-04-17 08:45:516414 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076415 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:466416
6417 HttpRequestInfo request;
6418 request.method = "GET";
bncce36dca22015-04-21 22:11:236419 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:466420 request.load_flags = 0;
6421
6422 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236423 MockWrite(
6424 "CONNECT www.example.org:443 HTTP/1.1\r\n"
6425 "Host: www.example.org\r\n"
6426 "Proxy-Connection: keep-alive\r\n\r\n"),
6427 MockWrite(
6428 "GET / HTTP/1.1\r\n"
6429 "Host: www.example.org\r\n"
6430 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:466431 };
6432
6433 MockRead data_reads[] = {
6434 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
6435 MockRead("HTTP/1.1 200 OK\r\n"),
6436 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6437 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066438 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:466439 };
6440
6441 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6442 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066443 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
6444 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:466445
[email protected]bb88e1d32013-05-03 23:11:076446 session_deps_.socket_factory->AddSocketDataProvider(&data);
6447 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
6448 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:466449
[email protected]49639fa2011-12-20 23:22:416450 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:466451
[email protected]3fe8d2f82013-10-17 08:56:076452 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:466453 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416454 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2df19bb2010-08-25 20:13:466455
[email protected]49639fa2011-12-20 23:22:416456 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:466457 EXPECT_EQ(ERR_IO_PENDING, rv);
6458
6459 rv = callback.WaitForResult();
6460 EXPECT_EQ(OK, rv);
6461 const HttpResponseInfo* response = trans->GetResponseInfo();
6462
[email protected]fe2255a2011-09-20 19:37:506463 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:466464
6465 EXPECT_TRUE(response->headers->IsKeepAlive());
6466 EXPECT_EQ(200, response->headers->response_code());
6467 EXPECT_EQ(100, response->headers->GetContentLength());
6468 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:206469
6470 LoadTimingInfo load_timing_info;
6471 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6472 TestLoadTimingNotReusedWithPac(load_timing_info,
6473 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:466474}
6475
[email protected]511f6f52010-12-17 03:58:296476// Test an HTTPS Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:026477TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076478 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206479 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
vishal.b62985ca92015-04-17 08:45:516480 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076481 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:296482
6483 HttpRequestInfo request;
6484 request.method = "GET";
bncce36dca22015-04-21 22:11:236485 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:296486 request.load_flags = 0;
6487
6488 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236489 MockWrite(
6490 "CONNECT www.example.org:443 HTTP/1.1\r\n"
6491 "Host: www.example.org\r\n"
6492 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:296493 };
6494
6495 MockRead data_reads[] = {
6496 MockRead("HTTP/1.1 302 Redirect\r\n"),
6497 MockRead("Location: http://login.example.com/\r\n"),
6498 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066499 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:296500 };
6501
6502 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6503 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066504 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:296505
[email protected]bb88e1d32013-05-03 23:11:076506 session_deps_.socket_factory->AddSocketDataProvider(&data);
6507 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296508
[email protected]49639fa2011-12-20 23:22:416509 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296510
[email protected]3fe8d2f82013-10-17 08:56:076511 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296512 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416513 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:296514
[email protected]49639fa2011-12-20 23:22:416515 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296516 EXPECT_EQ(ERR_IO_PENDING, rv);
6517
6518 rv = callback.WaitForResult();
6519 EXPECT_EQ(OK, rv);
6520 const HttpResponseInfo* response = trans->GetResponseInfo();
6521
[email protected]fe2255a2011-09-20 19:37:506522 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:296523
6524 EXPECT_EQ(302, response->headers->response_code());
6525 std::string url;
6526 EXPECT_TRUE(response->headers->IsRedirect(&url));
6527 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:206528
6529 // In the case of redirects from proxies, HttpNetworkTransaction returns
6530 // timing for the proxy connection instead of the connection to the host,
6531 // and no send / receive times.
6532 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
6533 LoadTimingInfo load_timing_info;
6534 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6535
6536 EXPECT_FALSE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:296537 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:206538
6539 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
6540 EXPECT_LE(load_timing_info.proxy_resolve_start,
6541 load_timing_info.proxy_resolve_end);
6542 EXPECT_LE(load_timing_info.proxy_resolve_end,
6543 load_timing_info.connect_timing.connect_start);
6544 ExpectConnectTimingHasTimes(
6545 load_timing_info.connect_timing,
6546 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
6547
6548 EXPECT_TRUE(load_timing_info.send_start.is_null());
6549 EXPECT_TRUE(load_timing_info.send_end.is_null());
6550 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:296551}
6552
6553// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:026554TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
[email protected]bb88e1d32013-05-03 23:11:076555 session_deps_.proxy_service.reset(
[email protected]511f6f52010-12-17 03:58:296556 ProxyService::CreateFixed("https://proxy:70"));
6557
6558 HttpRequestInfo request;
6559 request.method = "GET";
bncce36dca22015-04-21 22:11:236560 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:296561 request.load_flags = 0;
6562
lgarrona91df87f2014-12-05 00:51:346563 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:236564 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]c10b20852013-05-15 21:29:206565 scoped_ptr<SpdyFrame> goaway(
6566 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:296567 MockWrite data_writes[] = {
rch8e6c6c42015-05-01 14:05:136568 CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
6569 CreateMockWrite(*goaway.get(), 2, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:296570 };
6571
6572 static const char* const kExtraHeaders[] = {
6573 "location",
6574 "http://login.example.com/",
6575 };
[email protected]ff98d7f02012-03-22 21:44:196576 scoped_ptr<SpdyFrame> resp(
[email protected]23e482282013-06-14 16:08:026577 spdy_util_.ConstructSpdySynReplyError("302 Redirect", kExtraHeaders,
[email protected]511f6f52010-12-17 03:58:296578 arraysize(kExtraHeaders)/2, 1));
6579 MockRead data_reads[] = {
rch8e6c6c42015-05-01 14:05:136580 CreateMockRead(*resp.get(), 1), MockRead(ASYNC, 0, 3), // EOF
[email protected]511f6f52010-12-17 03:58:296581 };
6582
rch8e6c6c42015-05-01 14:05:136583 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
6584 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066585 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]23e482282013-06-14 16:08:026586 proxy_ssl.SetNextProto(GetParam());
[email protected]511f6f52010-12-17 03:58:296587
[email protected]bb88e1d32013-05-03 23:11:076588 session_deps_.socket_factory->AddSocketDataProvider(&data);
6589 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296590
[email protected]49639fa2011-12-20 23:22:416591 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296592
[email protected]3fe8d2f82013-10-17 08:56:076593 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296594 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416595 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:296596
[email protected]49639fa2011-12-20 23:22:416597 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296598 EXPECT_EQ(ERR_IO_PENDING, rv);
6599
6600 rv = callback.WaitForResult();
6601 EXPECT_EQ(OK, rv);
6602 const HttpResponseInfo* response = trans->GetResponseInfo();
6603
[email protected]fe2255a2011-09-20 19:37:506604 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:296605
6606 EXPECT_EQ(302, response->headers->response_code());
6607 std::string url;
6608 EXPECT_TRUE(response->headers->IsRedirect(&url));
6609 EXPECT_EQ("http://login.example.com/", url);
6610}
6611
[email protected]4eddbc732012-08-09 05:40:176612// Test that an HTTPS proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:026613TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:176614 ErrorResponseToHttpsConnectViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076615 session_deps_.proxy_service.reset(
[email protected]511f6f52010-12-17 03:58:296616 ProxyService::CreateFixed("https://proxy:70"));
6617
6618 HttpRequestInfo request;
6619 request.method = "GET";
bncce36dca22015-04-21 22:11:236620 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:296621 request.load_flags = 0;
6622
6623 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236624 MockWrite(
6625 "CONNECT www.example.org:443 HTTP/1.1\r\n"
6626 "Host: www.example.org\r\n"
6627 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:296628 };
6629
6630 MockRead data_reads[] = {
6631 MockRead("HTTP/1.1 404 Not Found\r\n"),
6632 MockRead("Content-Length: 23\r\n\r\n"),
6633 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:066634 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:296635 };
6636
6637 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6638 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066639 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:296640
[email protected]bb88e1d32013-05-03 23:11:076641 session_deps_.socket_factory->AddSocketDataProvider(&data);
6642 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296643
[email protected]49639fa2011-12-20 23:22:416644 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296645
[email protected]3fe8d2f82013-10-17 08:56:076646 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296647 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416648 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:296649
[email protected]49639fa2011-12-20 23:22:416650 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296651 EXPECT_EQ(ERR_IO_PENDING, rv);
6652
6653 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:176654 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:296655
[email protected]4eddbc732012-08-09 05:40:176656 // TODO(ttuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:296657}
6658
[email protected]4eddbc732012-08-09 05:40:176659// Test that a SPDY proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:026660TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:176661 ErrorResponseToHttpsConnectViaSpdyProxy) {
[email protected]bb88e1d32013-05-03 23:11:076662 session_deps_.proxy_service.reset(
6663 ProxyService::CreateFixed("https://proxy:70"));
[email protected]511f6f52010-12-17 03:58:296664
6665 HttpRequestInfo request;
6666 request.method = "GET";
bncce36dca22015-04-21 22:11:236667 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:296668 request.load_flags = 0;
6669
lgarrona91df87f2014-12-05 00:51:346670 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:236671 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]c10b20852013-05-15 21:29:206672 scoped_ptr<SpdyFrame> rst(
6673 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:296674 MockWrite data_writes[] = {
rch8e6c6c42015-05-01 14:05:136675 CreateMockWrite(*conn.get(), 0), CreateMockWrite(*rst.get(), 3),
[email protected]511f6f52010-12-17 03:58:296676 };
6677
6678 static const char* const kExtraHeaders[] = {
6679 "location",
6680 "http://login.example.com/",
6681 };
[email protected]ff98d7f02012-03-22 21:44:196682 scoped_ptr<SpdyFrame> resp(
[email protected]23e482282013-06-14 16:08:026683 spdy_util_.ConstructSpdySynReplyError("404 Not Found", kExtraHeaders,
[email protected]511f6f52010-12-17 03:58:296684 arraysize(kExtraHeaders)/2, 1));
[email protected]ff98d7f02012-03-22 21:44:196685 scoped_ptr<SpdyFrame> body(
[email protected]23e482282013-06-14 16:08:026686 spdy_util_.ConstructSpdyBodyFrame(
6687 1, "The host does not exist", 23, true));
[email protected]511f6f52010-12-17 03:58:296688 MockRead data_reads[] = {
rch8e6c6c42015-05-01 14:05:136689 CreateMockRead(*resp.get(), 1),
6690 CreateMockRead(*body.get(), 2),
6691 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:296692 };
6693
rch8e6c6c42015-05-01 14:05:136694 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
6695 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066696 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]23e482282013-06-14 16:08:026697 proxy_ssl.SetNextProto(GetParam());
[email protected]511f6f52010-12-17 03:58:296698
[email protected]bb88e1d32013-05-03 23:11:076699 session_deps_.socket_factory->AddSocketDataProvider(&data);
6700 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296701
[email protected]49639fa2011-12-20 23:22:416702 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296703
[email protected]3fe8d2f82013-10-17 08:56:076704 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296705 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416706 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:296707
[email protected]49639fa2011-12-20 23:22:416708 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296709 EXPECT_EQ(ERR_IO_PENDING, rv);
6710
6711 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:176712 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:296713
[email protected]4eddbc732012-08-09 05:40:176714 // TODO(ttuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:296715}
6716
[email protected]0c5fb722012-02-28 11:50:356717// Test the request-challenge-retry sequence for basic auth, through
6718// a SPDY proxy over a single SPDY session.
[email protected]23e482282013-06-14 16:08:026719TEST_P(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:356720 HttpRequestInfo request;
6721 request.method = "GET";
bncce36dca22015-04-21 22:11:236722 request.url = GURL("https://www.example.org/");
[email protected]0c5fb722012-02-28 11:50:356723 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:296724 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]0c5fb722012-02-28 11:50:356725
6726 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076727 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206728 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
vishal.b62985ca92015-04-17 08:45:516729 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076730 session_deps_.net_log = log.bound().net_log();
6731 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:356732
6733 // Since we have proxy, should try to establish tunnel.
lgarrona91df87f2014-12-05 00:51:346734 scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:236735 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]c10b20852013-05-15 21:29:206736 scoped_ptr<SpdyFrame> rst(
6737 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]0c5fb722012-02-28 11:50:356738
6739 // After calling trans->RestartWithAuth(), this is the request we should
6740 // be issuing -- the final header line contains the credentials.
6741 const char* const kAuthCredentials[] = {
6742 "proxy-authorization", "Basic Zm9vOmJhcg==",
6743 };
[email protected]fba2dbde2013-05-24 16:09:016744 scoped_ptr<SpdyFrame> connect2(spdy_util_.ConstructSpdyConnect(
lgarrona91df87f2014-12-05 00:51:346745 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST,
bncce36dca22015-04-21 22:11:236746 HostPortPair("www.example.org", 443)));
6747 // fetch https://www.example.org/ via HTTP
6748 const char get[] =
6749 "GET / HTTP/1.1\r\n"
6750 "Host: www.example.org\r\n"
6751 "Connection: keep-alive\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:196752 scoped_ptr<SpdyFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:026753 spdy_util_.ConstructSpdyBodyFrame(3, get, strlen(get), false));
[email protected]0c5fb722012-02-28 11:50:356754
6755 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:136756 CreateMockWrite(*req, 0, ASYNC),
6757 CreateMockWrite(*rst, 2, ASYNC),
6758 CreateMockWrite(*connect2, 3),
6759 CreateMockWrite(*wrapped_get, 5),
[email protected]0c5fb722012-02-28 11:50:356760 };
6761
6762 // The proxy responds to the connect with a 407, using a persistent
6763 // connection.
thestig9d3bb0c2015-01-24 00:49:516764 const char kAuthStatus[] = "407";
[email protected]0c5fb722012-02-28 11:50:356765 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:356766 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
6767 };
[email protected]745aa9c2014-06-27 02:21:296768 scoped_ptr<SpdyFrame> conn_auth_resp(spdy_util_.ConstructSpdySynReplyError(
6769 kAuthStatus, kAuthChallenge, arraysize(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:356770
[email protected]23e482282013-06-14 16:08:026771 scoped_ptr<SpdyFrame> conn_resp(
6772 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:356773 const char resp[] = "HTTP/1.1 200 OK\r\n"
6774 "Content-Length: 5\r\n\r\n";
6775
[email protected]ff98d7f02012-03-22 21:44:196776 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:026777 spdy_util_.ConstructSpdyBodyFrame(3, resp, strlen(resp), false));
[email protected]ff98d7f02012-03-22 21:44:196778 scoped_ptr<SpdyFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:026779 spdy_util_.ConstructSpdyBodyFrame(3, "hello", 5, false));
[email protected]0c5fb722012-02-28 11:50:356780 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:136781 CreateMockRead(*conn_auth_resp, 1, ASYNC),
6782 CreateMockRead(*conn_resp, 4, ASYNC),
6783 CreateMockRead(*wrapped_get_resp, 6, ASYNC),
6784 CreateMockRead(*wrapped_body, 7, ASYNC),
6785 MockRead(ASYNC, OK, 8), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:356786 };
6787
rch8e6c6c42015-05-01 14:05:136788 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
6789 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:076790 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:356791 // Negotiate SPDY to the proxy
6792 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:026793 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:076794 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:356795 // Vanilla SSL to the server
6796 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076797 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:356798
6799 TestCompletionCallback callback1;
6800
[email protected]262eec82013-03-19 21:01:366801 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506802 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0c5fb722012-02-28 11:50:356803
6804 int rv = trans->Start(&request, callback1.callback(), log.bound());
6805 EXPECT_EQ(ERR_IO_PENDING, rv);
6806
6807 rv = callback1.WaitForResult();
6808 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:466809 TestNetLogEntry::List entries;
[email protected]0c5fb722012-02-28 11:50:356810 log.GetEntries(&entries);
6811 size_t pos = ExpectLogContainsSomewhere(
6812 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
6813 NetLog::PHASE_NONE);
6814 ExpectLogContainsSomewhere(
6815 entries, pos,
6816 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
6817 NetLog::PHASE_NONE);
6818
6819 const HttpResponseInfo* response = trans->GetResponseInfo();
6820 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:506821 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]0c5fb722012-02-28 11:50:356822 EXPECT_EQ(407, response->headers->response_code());
6823 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6824 EXPECT_TRUE(response->auth_challenge.get() != NULL);
6825 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
6826
6827 TestCompletionCallback callback2;
6828
6829 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
6830 callback2.callback());
6831 EXPECT_EQ(ERR_IO_PENDING, rv);
6832
6833 rv = callback2.WaitForResult();
6834 EXPECT_EQ(OK, rv);
6835
6836 response = trans->GetResponseInfo();
6837 ASSERT_TRUE(response != NULL);
6838
6839 EXPECT_TRUE(response->headers->IsKeepAlive());
6840 EXPECT_EQ(200, response->headers->response_code());
6841 EXPECT_EQ(5, response->headers->GetContentLength());
6842 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6843
6844 // The password prompt info should not be set.
6845 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6846
[email protected]029c83b62013-01-24 05:28:206847 LoadTimingInfo load_timing_info;
6848 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6849 TestLoadTimingNotReusedWithPac(load_timing_info,
6850 CONNECT_TIMING_HAS_SSL_TIMES);
6851
[email protected]0c5fb722012-02-28 11:50:356852 trans.reset();
6853 session->CloseAllConnections();
6854}
6855
[email protected]7c6f7ba2012-04-03 04:09:296856// Test that an explicitly trusted SPDY proxy can push a resource from an
6857// origin that is different from that of its associated resource.
[email protected]23e482282013-06-14 16:08:026858TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPush) {
[email protected]7c6f7ba2012-04-03 04:09:296859 HttpRequestInfo request;
6860 HttpRequestInfo push_request;
6861
[email protected]7c6f7ba2012-04-03 04:09:296862 request.method = "GET";
bncce36dca22015-04-21 22:11:236863 request.url = GURL("http://www.example.org/");
[email protected]7c6f7ba2012-04-03 04:09:296864 push_request.method = "GET";
6865 push_request.url = GURL("http://www.another-origin.com/foo.dat");
6866
[email protected]7c6f7ba2012-04-03 04:09:296867 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076868 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206869 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
vishal.b62985ca92015-04-17 08:45:516870 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076871 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:506872
6873 // Enable cross-origin push.
[email protected]bb88e1d32013-05-03 23:11:076874 session_deps_.trusted_spdy_proxy = "myproxy:70";
[email protected]61b4efc2012-04-27 18:12:506875
[email protected]bb88e1d32013-05-03 23:11:076876 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:296877
[email protected]cdf8f7e72013-05-23 10:56:466878 scoped_ptr<SpdyFrame> stream1_syn(
6879 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]7c6f7ba2012-04-03 04:09:296880
6881 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:136882 CreateMockWrite(*stream1_syn, 0, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:296883 };
6884
6885 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026886 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:296887
6888 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026889 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:296890
6891 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026892 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
[email protected]7c6f7ba2012-04-03 04:09:296893 0,
6894 2,
6895 1,
6896 "http://www.another-origin.com/foo.dat"));
[email protected]8a0fc822013-06-27 20:52:436897 const char kPushedData[] = "pushed";
6898 scoped_ptr<SpdyFrame> stream2_body(
6899 spdy_util_.ConstructSpdyBodyFrame(
6900 2, kPushedData, strlen(kPushedData), true));
[email protected]7c6f7ba2012-04-03 04:09:296901
6902 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:136903 CreateMockRead(*stream1_reply, 1, ASYNC),
6904 CreateMockRead(*stream2_syn, 2, ASYNC),
6905 CreateMockRead(*stream1_body, 3, ASYNC),
6906 CreateMockRead(*stream2_body, 4, ASYNC),
6907 MockRead(ASYNC, ERR_IO_PENDING, 5), // Force a pause
[email protected]7c6f7ba2012-04-03 04:09:296908 };
6909
rch8e6c6c42015-05-01 14:05:136910 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
6911 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:076912 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:296913 // Negotiate SPDY to the proxy
6914 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:026915 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:076916 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:296917
[email protected]262eec82013-03-19 21:01:366918 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506919 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7c6f7ba2012-04-03 04:09:296920 TestCompletionCallback callback;
6921 int rv = trans->Start(&request, callback.callback(), log.bound());
6922 EXPECT_EQ(ERR_IO_PENDING, rv);
6923
6924 rv = callback.WaitForResult();
6925 EXPECT_EQ(OK, rv);
6926 const HttpResponseInfo* response = trans->GetResponseInfo();
6927
[email protected]262eec82013-03-19 21:01:366928 scoped_ptr<HttpTransaction> push_trans(
[email protected]90499482013-06-01 00:39:506929 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
6930 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
[email protected]7c6f7ba2012-04-03 04:09:296931 EXPECT_EQ(ERR_IO_PENDING, rv);
6932
6933 rv = callback.WaitForResult();
6934 EXPECT_EQ(OK, rv);
6935 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
6936
6937 ASSERT_TRUE(response != NULL);
6938 EXPECT_TRUE(response->headers->IsKeepAlive());
6939
6940 EXPECT_EQ(200, response->headers->response_code());
6941 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6942
6943 std::string response_data;
6944 rv = ReadTransaction(trans.get(), &response_data);
6945 EXPECT_EQ(OK, rv);
6946 EXPECT_EQ("hello!", response_data);
6947
[email protected]029c83b62013-01-24 05:28:206948 LoadTimingInfo load_timing_info;
6949 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6950 TestLoadTimingNotReusedWithPac(load_timing_info,
6951 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6952
[email protected]7c6f7ba2012-04-03 04:09:296953 // Verify the pushed stream.
[email protected]90499482013-06-01 00:39:506954 EXPECT_TRUE(push_response->headers.get() != NULL);
[email protected]7c6f7ba2012-04-03 04:09:296955 EXPECT_EQ(200, push_response->headers->response_code());
6956
6957 rv = ReadTransaction(push_trans.get(), &response_data);
6958 EXPECT_EQ(OK, rv);
6959 EXPECT_EQ("pushed", response_data);
6960
[email protected]029c83b62013-01-24 05:28:206961 LoadTimingInfo push_load_timing_info;
6962 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
6963 TestLoadTimingReusedWithPac(push_load_timing_info);
6964 // The transactions should share a socket ID, despite being for different
6965 // origins.
6966 EXPECT_EQ(load_timing_info.socket_log_id,
6967 push_load_timing_info.socket_log_id);
6968
[email protected]7c6f7ba2012-04-03 04:09:296969 trans.reset();
6970 push_trans.reset();
6971 session->CloseAllConnections();
6972}
6973
[email protected]8c843192012-04-05 07:15:006974// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
[email protected]23e482282013-06-14 16:08:026975TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
[email protected]8c843192012-04-05 07:15:006976 HttpRequestInfo request;
6977
6978 request.method = "GET";
bncce36dca22015-04-21 22:11:236979 request.url = GURL("http://www.example.org/");
[email protected]8c843192012-04-05 07:15:006980
[email protected]8c843192012-04-05 07:15:006981 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076982 session_deps_.proxy_service.reset(
[email protected]8c843192012-04-05 07:15:006983 ProxyService::CreateFixed("https://myproxy:70"));
vishal.b62985ca92015-04-17 08:45:516984 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076985 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:506986
6987 // Enable cross-origin push.
[email protected]bb88e1d32013-05-03 23:11:076988 session_deps_.trusted_spdy_proxy = "myproxy:70";
[email protected]61b4efc2012-04-27 18:12:506989
[email protected]bb88e1d32013-05-03 23:11:076990 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:006991
[email protected]cdf8f7e72013-05-23 10:56:466992 scoped_ptr<SpdyFrame> stream1_syn(
6993 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]8c843192012-04-05 07:15:006994
6995 scoped_ptr<SpdyFrame> push_rst(
[email protected]c10b20852013-05-15 21:29:206996 spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:006997
6998 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:136999 CreateMockWrite(*stream1_syn, 0, ASYNC), CreateMockWrite(*push_rst, 3),
[email protected]8c843192012-04-05 07:15:007000 };
7001
7002 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:027003 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:007004
7005 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:027006 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8c843192012-04-05 07:15:007007
7008 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:027009 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
[email protected]8c843192012-04-05 07:15:007010 0,
7011 2,
7012 1,
7013 "https://www.another-origin.com/foo.dat"));
7014
7015 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:137016 CreateMockRead(*stream1_reply, 1, ASYNC),
7017 CreateMockRead(*stream2_syn, 2, ASYNC),
7018 CreateMockRead(*stream1_body, 4, ASYNC),
7019 MockRead(ASYNC, ERR_IO_PENDING, 5), // Force a pause
[email protected]8c843192012-04-05 07:15:007020 };
7021
rch8e6c6c42015-05-01 14:05:137022 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
7023 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:077024 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:007025 // Negotiate SPDY to the proxy
7026 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:027027 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:077028 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:007029
[email protected]262eec82013-03-19 21:01:367030 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507031 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c843192012-04-05 07:15:007032 TestCompletionCallback callback;
7033 int rv = trans->Start(&request, callback.callback(), log.bound());
7034 EXPECT_EQ(ERR_IO_PENDING, rv);
7035
7036 rv = callback.WaitForResult();
7037 EXPECT_EQ(OK, rv);
7038 const HttpResponseInfo* response = trans->GetResponseInfo();
7039
7040 ASSERT_TRUE(response != NULL);
7041 EXPECT_TRUE(response->headers->IsKeepAlive());
7042
7043 EXPECT_EQ(200, response->headers->response_code());
7044 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
7045
7046 std::string response_data;
7047 rv = ReadTransaction(trans.get(), &response_data);
7048 EXPECT_EQ(OK, rv);
7049 EXPECT_EQ("hello!", response_data);
7050
7051 trans.reset();
7052 session->CloseAllConnections();
7053}
7054
[email protected]2df19bb2010-08-25 20:13:467055// Test HTTPS connections to a site with a bad certificate, going through an
7056// HTTPS proxy
[email protected]23e482282013-06-14 16:08:027057TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:077058 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:117059 "https://proxy:70"));
[email protected]2df19bb2010-08-25 20:13:467060
7061 HttpRequestInfo request;
7062 request.method = "GET";
bncce36dca22015-04-21 22:11:237063 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:467064 request.load_flags = 0;
7065
7066 // Attempt to fetch the URL from a server with a bad cert
7067 MockWrite bad_cert_writes[] = {
bncce36dca22015-04-21 22:11:237068 MockWrite(
7069 "CONNECT www.example.org:443 HTTP/1.1\r\n"
7070 "Host: www.example.org\r\n"
7071 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:467072 };
7073
7074 MockRead bad_cert_reads[] = {
7075 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067076 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:467077 };
7078
7079 // Attempt to fetch the URL with a good cert
7080 MockWrite good_data_writes[] = {
bncce36dca22015-04-21 22:11:237081 MockWrite(
7082 "CONNECT www.example.org:443 HTTP/1.1\r\n"
7083 "Host: www.example.org\r\n"
7084 "Proxy-Connection: keep-alive\r\n\r\n"),
7085 MockWrite(
7086 "GET / HTTP/1.1\r\n"
7087 "Host: www.example.org\r\n"
7088 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:467089 };
7090
7091 MockRead good_cert_reads[] = {
7092 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
7093 MockRead("HTTP/1.0 200 OK\r\n"),
7094 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7095 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067096 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:467097 };
7098
7099 StaticSocketDataProvider ssl_bad_certificate(
7100 bad_cert_reads, arraysize(bad_cert_reads),
7101 bad_cert_writes, arraysize(bad_cert_writes));
7102 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
7103 good_data_writes, arraysize(good_data_writes));
[email protected]8ddf8322012-02-23 18:08:067104 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
7105 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:467106
7107 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:077108 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7109 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
7110 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:467111
7112 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:077113 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7114 session_deps_.socket_factory->AddSocketDataProvider(&data);
7115 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:467116
[email protected]49639fa2011-12-20 23:22:417117 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:467118
[email protected]3fe8d2f82013-10-17 08:56:077119 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:467120 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417121 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2df19bb2010-08-25 20:13:467122
[email protected]49639fa2011-12-20 23:22:417123 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:467124 EXPECT_EQ(ERR_IO_PENDING, rv);
7125
7126 rv = callback.WaitForResult();
7127 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
7128
[email protected]49639fa2011-12-20 23:22:417129 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]2df19bb2010-08-25 20:13:467130 EXPECT_EQ(ERR_IO_PENDING, rv);
7131
7132 rv = callback.WaitForResult();
7133 EXPECT_EQ(OK, rv);
7134
7135 const HttpResponseInfo* response = trans->GetResponseInfo();
7136
[email protected]fe2255a2011-09-20 19:37:507137 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:467138 EXPECT_EQ(100, response->headers->GetContentLength());
7139}
7140
[email protected]23e482282013-06-14 16:08:027141TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:427142 HttpRequestInfo request;
7143 request.method = "GET";
bncce36dca22015-04-21 22:11:237144 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:437145 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
7146 "Chromium Ultra Awesome X Edition");
[email protected]1c773ea12009-04-28 19:58:427147
[email protected]3fe8d2f82013-10-17 08:56:077148 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277149 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417150 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277151
[email protected]1c773ea12009-04-28 19:58:427152 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237153 MockWrite(
7154 "GET / HTTP/1.1\r\n"
7155 "Host: www.example.org\r\n"
7156 "Connection: keep-alive\r\n"
7157 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427158 };
7159
7160 // Lastly, the server responds with the actual content.
7161 MockRead data_reads[] = {
7162 MockRead("HTTP/1.0 200 OK\r\n"),
7163 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7164 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067165 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427166 };
7167
[email protected]31a2bfe2010-02-09 08:03:397168 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7169 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077170 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427171
[email protected]49639fa2011-12-20 23:22:417172 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427173
[email protected]49639fa2011-12-20 23:22:417174 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427175 EXPECT_EQ(ERR_IO_PENDING, rv);
7176
7177 rv = callback.WaitForResult();
7178 EXPECT_EQ(OK, rv);
7179}
7180
[email protected]23e482282013-06-14 16:08:027181TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:297182 HttpRequestInfo request;
7183 request.method = "GET";
bncce36dca22015-04-21 22:11:237184 request.url = GURL("https://www.example.org/");
[email protected]da81f132010-08-18 23:39:297185 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
7186 "Chromium Ultra Awesome X Edition");
7187
[email protected]bb88e1d32013-05-03 23:11:077188 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]3fe8d2f82013-10-17 08:56:077189 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277190 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417191 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277192
[email protected]da81f132010-08-18 23:39:297193 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237194 MockWrite(
7195 "CONNECT www.example.org:443 HTTP/1.1\r\n"
7196 "Host: www.example.org\r\n"
7197 "Proxy-Connection: keep-alive\r\n"
7198 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]da81f132010-08-18 23:39:297199 };
7200 MockRead data_reads[] = {
7201 // Return an error, so the transaction stops here (this test isn't
7202 // interested in the rest).
7203 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
7204 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7205 MockRead("Proxy-Connection: close\r\n\r\n"),
7206 };
7207
7208 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7209 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077210 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:297211
[email protected]49639fa2011-12-20 23:22:417212 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:297213
[email protected]49639fa2011-12-20 23:22:417214 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]da81f132010-08-18 23:39:297215 EXPECT_EQ(ERR_IO_PENDING, rv);
7216
7217 rv = callback.WaitForResult();
7218 EXPECT_EQ(OK, rv);
7219}
7220
[email protected]23e482282013-06-14 16:08:027221TEST_P(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:427222 HttpRequestInfo request;
7223 request.method = "GET";
bncce36dca22015-04-21 22:11:237224 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427225 request.load_flags = 0;
[email protected]c10450102011-06-27 09:06:167226 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
7227 "http://the.previous.site.com/");
[email protected]1c773ea12009-04-28 19:58:427228
[email protected]3fe8d2f82013-10-17 08:56:077229 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277230 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417231 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277232
[email protected]1c773ea12009-04-28 19:58:427233 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237234 MockWrite(
7235 "GET / HTTP/1.1\r\n"
7236 "Host: www.example.org\r\n"
7237 "Connection: keep-alive\r\n"
7238 "Referer: http://the.previous.site.com/\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427239 };
7240
7241 // Lastly, the server responds with the actual content.
7242 MockRead data_reads[] = {
7243 MockRead("HTTP/1.0 200 OK\r\n"),
7244 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7245 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067246 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427247 };
7248
[email protected]31a2bfe2010-02-09 08:03:397249 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7250 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077251 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427252
[email protected]49639fa2011-12-20 23:22:417253 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427254
[email protected]49639fa2011-12-20 23:22:417255 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427256 EXPECT_EQ(ERR_IO_PENDING, rv);
7257
7258 rv = callback.WaitForResult();
7259 EXPECT_EQ(OK, rv);
7260}
7261
[email protected]23e482282013-06-14 16:08:027262TEST_P(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:427263 HttpRequestInfo request;
7264 request.method = "POST";
bncce36dca22015-04-21 22:11:237265 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427266
[email protected]3fe8d2f82013-10-17 08:56:077267 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277268 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417269 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277270
[email protected]1c773ea12009-04-28 19:58:427271 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237272 MockWrite(
7273 "POST / HTTP/1.1\r\n"
7274 "Host: www.example.org\r\n"
7275 "Connection: keep-alive\r\n"
7276 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427277 };
7278
7279 // Lastly, the server responds with the actual content.
7280 MockRead data_reads[] = {
7281 MockRead("HTTP/1.0 200 OK\r\n"),
7282 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7283 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067284 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427285 };
7286
[email protected]31a2bfe2010-02-09 08:03:397287 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7288 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077289 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427290
[email protected]49639fa2011-12-20 23:22:417291 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427292
[email protected]49639fa2011-12-20 23:22:417293 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427294 EXPECT_EQ(ERR_IO_PENDING, rv);
7295
7296 rv = callback.WaitForResult();
7297 EXPECT_EQ(OK, rv);
7298}
7299
[email protected]23e482282013-06-14 16:08:027300TEST_P(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:427301 HttpRequestInfo request;
7302 request.method = "PUT";
bncce36dca22015-04-21 22:11:237303 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427304
[email protected]3fe8d2f82013-10-17 08:56:077305 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277306 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417307 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277308
[email protected]1c773ea12009-04-28 19:58:427309 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237310 MockWrite(
7311 "PUT / HTTP/1.1\r\n"
7312 "Host: www.example.org\r\n"
7313 "Connection: keep-alive\r\n"
7314 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427315 };
7316
7317 // Lastly, the server responds with the actual content.
7318 MockRead data_reads[] = {
7319 MockRead("HTTP/1.0 200 OK\r\n"),
7320 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7321 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067322 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427323 };
7324
[email protected]31a2bfe2010-02-09 08:03:397325 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7326 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077327 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427328
[email protected]49639fa2011-12-20 23:22:417329 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427330
[email protected]49639fa2011-12-20 23:22:417331 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427332 EXPECT_EQ(ERR_IO_PENDING, rv);
7333
7334 rv = callback.WaitForResult();
7335 EXPECT_EQ(OK, rv);
7336}
7337
[email protected]23e482282013-06-14 16:08:027338TEST_P(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:427339 HttpRequestInfo request;
7340 request.method = "HEAD";
bncce36dca22015-04-21 22:11:237341 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427342
[email protected]3fe8d2f82013-10-17 08:56:077343 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277344 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417345 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277346
[email protected]1c773ea12009-04-28 19:58:427347 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237348 MockWrite(
7349 "HEAD / HTTP/1.1\r\n"
7350 "Host: www.example.org\r\n"
7351 "Connection: keep-alive\r\n"
7352 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427353 };
7354
7355 // Lastly, the server responds with the actual content.
7356 MockRead data_reads[] = {
7357 MockRead("HTTP/1.0 200 OK\r\n"),
7358 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7359 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067360 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427361 };
7362
[email protected]31a2bfe2010-02-09 08:03:397363 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7364 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077365 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427366
[email protected]49639fa2011-12-20 23:22:417367 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427368
[email protected]49639fa2011-12-20 23:22:417369 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427370 EXPECT_EQ(ERR_IO_PENDING, rv);
7371
7372 rv = callback.WaitForResult();
7373 EXPECT_EQ(OK, rv);
7374}
7375
[email protected]23e482282013-06-14 16:08:027376TEST_P(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:427377 HttpRequestInfo request;
7378 request.method = "GET";
bncce36dca22015-04-21 22:11:237379 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427380 request.load_flags = LOAD_BYPASS_CACHE;
7381
[email protected]3fe8d2f82013-10-17 08:56:077382 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277383 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417384 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277385
[email protected]1c773ea12009-04-28 19:58:427386 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237387 MockWrite(
7388 "GET / HTTP/1.1\r\n"
7389 "Host: www.example.org\r\n"
7390 "Connection: keep-alive\r\n"
7391 "Pragma: no-cache\r\n"
7392 "Cache-Control: no-cache\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427393 };
7394
7395 // Lastly, the server responds with the actual content.
7396 MockRead data_reads[] = {
7397 MockRead("HTTP/1.0 200 OK\r\n"),
7398 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7399 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067400 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427401 };
7402
[email protected]31a2bfe2010-02-09 08:03:397403 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7404 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077405 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427406
[email protected]49639fa2011-12-20 23:22:417407 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427408
[email protected]49639fa2011-12-20 23:22:417409 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427410 EXPECT_EQ(ERR_IO_PENDING, rv);
7411
7412 rv = callback.WaitForResult();
7413 EXPECT_EQ(OK, rv);
7414}
7415
[email protected]23e482282013-06-14 16:08:027416TEST_P(HttpNetworkTransactionTest,
[email protected]1c773ea12009-04-28 19:58:427417 BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:427418 HttpRequestInfo request;
7419 request.method = "GET";
bncce36dca22015-04-21 22:11:237420 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427421 request.load_flags = LOAD_VALIDATE_CACHE;
7422
[email protected]3fe8d2f82013-10-17 08:56:077423 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277424 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417425 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277426
[email protected]1c773ea12009-04-28 19:58:427427 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237428 MockWrite(
7429 "GET / HTTP/1.1\r\n"
7430 "Host: www.example.org\r\n"
7431 "Connection: keep-alive\r\n"
7432 "Cache-Control: max-age=0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427433 };
7434
7435 // Lastly, the server responds with the actual content.
7436 MockRead data_reads[] = {
7437 MockRead("HTTP/1.0 200 OK\r\n"),
7438 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7439 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067440 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427441 };
7442
[email protected]31a2bfe2010-02-09 08:03:397443 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7444 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077445 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427446
[email protected]49639fa2011-12-20 23:22:417447 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427448
[email protected]49639fa2011-12-20 23:22:417449 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427450 EXPECT_EQ(ERR_IO_PENDING, rv);
7451
7452 rv = callback.WaitForResult();
7453 EXPECT_EQ(OK, rv);
7454}
7455
[email protected]23e482282013-06-14 16:08:027456TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:427457 HttpRequestInfo request;
7458 request.method = "GET";
bncce36dca22015-04-21 22:11:237459 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:437460 request.extra_headers.SetHeader("FooHeader", "Bar");
[email protected]1c773ea12009-04-28 19:58:427461
[email protected]3fe8d2f82013-10-17 08:56:077462 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277463 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417464 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277465
[email protected]1c773ea12009-04-28 19:58:427466 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237467 MockWrite(
7468 "GET / HTTP/1.1\r\n"
7469 "Host: www.example.org\r\n"
7470 "Connection: keep-alive\r\n"
7471 "FooHeader: Bar\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427472 };
7473
7474 // Lastly, the server responds with the actual content.
7475 MockRead data_reads[] = {
7476 MockRead("HTTP/1.0 200 OK\r\n"),
7477 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7478 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067479 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427480 };
7481
[email protected]31a2bfe2010-02-09 08:03:397482 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7483 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077484 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427485
[email protected]49639fa2011-12-20 23:22:417486 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427487
[email protected]49639fa2011-12-20 23:22:417488 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427489 EXPECT_EQ(ERR_IO_PENDING, rv);
7490
7491 rv = callback.WaitForResult();
7492 EXPECT_EQ(OK, rv);
7493}
7494
[email protected]23e482282013-06-14 16:08:027495TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:477496 HttpRequestInfo request;
7497 request.method = "GET";
bncce36dca22015-04-21 22:11:237498 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:437499 request.extra_headers.SetHeader("referer", "www.foo.com");
7500 request.extra_headers.SetHeader("hEllo", "Kitty");
7501 request.extra_headers.SetHeader("FoO", "bar");
[email protected]270c6412010-03-29 22:02:477502
[email protected]3fe8d2f82013-10-17 08:56:077503 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277504 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417505 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277506
[email protected]270c6412010-03-29 22:02:477507 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237508 MockWrite(
7509 "GET / HTTP/1.1\r\n"
7510 "Host: www.example.org\r\n"
7511 "Connection: keep-alive\r\n"
7512 "referer: www.foo.com\r\n"
7513 "hEllo: Kitty\r\n"
7514 "FoO: bar\r\n\r\n"),
[email protected]270c6412010-03-29 22:02:477515 };
7516
7517 // Lastly, the server responds with the actual content.
7518 MockRead data_reads[] = {
7519 MockRead("HTTP/1.0 200 OK\r\n"),
7520 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7521 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067522 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:477523 };
7524
7525 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7526 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077527 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:477528
[email protected]49639fa2011-12-20 23:22:417529 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:477530
[email protected]49639fa2011-12-20 23:22:417531 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]270c6412010-03-29 22:02:477532 EXPECT_EQ(ERR_IO_PENDING, rv);
7533
7534 rv = callback.WaitForResult();
7535 EXPECT_EQ(OK, rv);
7536}
7537
[email protected]23e482282013-06-14 16:08:027538TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277539 HttpRequestInfo request;
7540 request.method = "GET";
bncce36dca22015-04-21 22:11:237541 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:277542 request.load_flags = 0;
7543
[email protected]bb88e1d32013-05-03 23:11:077544 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207545 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
vishal.b62985ca92015-04-17 08:45:517546 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077547 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:027548
[email protected]3fe8d2f82013-10-17 08:56:077549 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3cd17242009-06-23 02:59:027550 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417551 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3cd17242009-06-23 02:59:027552
[email protected]3cd17242009-06-23 02:59:027553 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
7554 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7555
7556 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237557 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
7558 MockWrite(
7559 "GET / HTTP/1.1\r\n"
7560 "Host: www.example.org\r\n"
7561 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:027562
7563 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:067564 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:027565 MockRead("HTTP/1.0 200 OK\r\n"),
7566 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7567 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067568 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:027569 };
7570
[email protected]31a2bfe2010-02-09 08:03:397571 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7572 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077573 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:027574
[email protected]49639fa2011-12-20 23:22:417575 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:027576
[email protected]49639fa2011-12-20 23:22:417577 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:027578 EXPECT_EQ(ERR_IO_PENDING, rv);
7579
7580 rv = callback.WaitForResult();
7581 EXPECT_EQ(OK, rv);
7582
7583 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507584 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:027585
[email protected]029c83b62013-01-24 05:28:207586 LoadTimingInfo load_timing_info;
7587 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7588 TestLoadTimingNotReusedWithPac(load_timing_info,
7589 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7590
[email protected]3cd17242009-06-23 02:59:027591 std::string response_text;
7592 rv = ReadTransaction(trans.get(), &response_text);
7593 EXPECT_EQ(OK, rv);
7594 EXPECT_EQ("Payload", response_text);
7595}
7596
[email protected]23e482282013-06-14 16:08:027597TEST_P(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277598 HttpRequestInfo request;
7599 request.method = "GET";
bncce36dca22015-04-21 22:11:237600 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:277601 request.load_flags = 0;
7602
[email protected]bb88e1d32013-05-03 23:11:077603 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207604 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
vishal.b62985ca92015-04-17 08:45:517605 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077606 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:027607
[email protected]3fe8d2f82013-10-17 08:56:077608 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3cd17242009-06-23 02:59:027609 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417610 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3cd17242009-06-23 02:59:027611
[email protected]3cd17242009-06-23 02:59:027612 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
7613 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7614
7615 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237616 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
7617 arraysize(write_buffer)),
7618 MockWrite(
7619 "GET / HTTP/1.1\r\n"
7620 "Host: www.example.org\r\n"
7621 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:027622
7623 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:017624 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
7625 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:357626 MockRead("HTTP/1.0 200 OK\r\n"),
7627 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7628 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067629 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:357630 };
7631
[email protected]31a2bfe2010-02-09 08:03:397632 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7633 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077634 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:357635
[email protected]8ddf8322012-02-23 18:08:067636 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077637 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:357638
[email protected]49639fa2011-12-20 23:22:417639 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:357640
[email protected]49639fa2011-12-20 23:22:417641 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:357642 EXPECT_EQ(ERR_IO_PENDING, rv);
7643
7644 rv = callback.WaitForResult();
7645 EXPECT_EQ(OK, rv);
7646
[email protected]029c83b62013-01-24 05:28:207647 LoadTimingInfo load_timing_info;
7648 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7649 TestLoadTimingNotReusedWithPac(load_timing_info,
7650 CONNECT_TIMING_HAS_SSL_TIMES);
7651
[email protected]e0c27be2009-07-15 13:09:357652 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507653 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:357654
7655 std::string response_text;
7656 rv = ReadTransaction(trans.get(), &response_text);
7657 EXPECT_EQ(OK, rv);
7658 EXPECT_EQ("Payload", response_text);
7659}
7660
[email protected]23e482282013-06-14 16:08:027661TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:207662 HttpRequestInfo request;
7663 request.method = "GET";
bncce36dca22015-04-21 22:11:237664 request.url = GURL("http://www.example.org/");
[email protected]029c83b62013-01-24 05:28:207665 request.load_flags = 0;
7666
[email protected]bb88e1d32013-05-03 23:11:077667 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207668 ProxyService::CreateFixed("socks4://myproxy:1080"));
vishal.b62985ca92015-04-17 08:45:517669 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077670 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:207671
[email protected]3fe8d2f82013-10-17 08:56:077672 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:207673 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417674 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:207675
7676 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
7677 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7678
7679 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237680 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
7681 MockWrite(
7682 "GET / HTTP/1.1\r\n"
7683 "Host: www.example.org\r\n"
7684 "Connection: keep-alive\r\n\r\n")};
[email protected]029c83b62013-01-24 05:28:207685
7686 MockRead data_reads[] = {
7687 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
7688 MockRead("HTTP/1.0 200 OK\r\n"),
7689 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7690 MockRead("Payload"),
7691 MockRead(SYNCHRONOUS, OK)
7692 };
7693
7694 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7695 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077696 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:207697
7698 TestCompletionCallback callback;
7699
7700 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7701 EXPECT_EQ(ERR_IO_PENDING, rv);
7702
7703 rv = callback.WaitForResult();
7704 EXPECT_EQ(OK, rv);
7705
7706 const HttpResponseInfo* response = trans->GetResponseInfo();
7707 ASSERT_TRUE(response != NULL);
7708
7709 LoadTimingInfo load_timing_info;
7710 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7711 TestLoadTimingNotReused(load_timing_info,
7712 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7713
7714 std::string response_text;
7715 rv = ReadTransaction(trans.get(), &response_text);
7716 EXPECT_EQ(OK, rv);
7717 EXPECT_EQ("Payload", response_text);
7718}
7719
[email protected]23e482282013-06-14 16:08:027720TEST_P(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277721 HttpRequestInfo request;
7722 request.method = "GET";
bncce36dca22015-04-21 22:11:237723 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:277724 request.load_flags = 0;
7725
[email protected]bb88e1d32013-05-03 23:11:077726 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207727 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
vishal.b62985ca92015-04-17 08:45:517728 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077729 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:357730
[email protected]3fe8d2f82013-10-17 08:56:077731 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e0c27be2009-07-15 13:09:357732 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417733 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]e0c27be2009-07-15 13:09:357734
[email protected]e0c27be2009-07-15 13:09:357735 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
7736 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:377737 const char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:237738 0x05, // Version
7739 0x01, // Command (CONNECT)
7740 0x00, // Reserved.
7741 0x03, // Address type (DOMAINNAME).
7742 0x0F, // Length of domain (15)
7743 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
7744 '.', 'o', 'r', 'g', 0x00, 0x50, // 16-bit port (80)
[email protected]f209dba2009-12-18 00:24:377745 };
[email protected]e0c27be2009-07-15 13:09:357746 const char kSOCKS5OkResponse[] =
7747 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
7748
7749 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237750 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
7751 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
7752 MockWrite(
7753 "GET / HTTP/1.1\r\n"
7754 "Host: www.example.org\r\n"
7755 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:357756
7757 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:017758 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
7759 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:357760 MockRead("HTTP/1.0 200 OK\r\n"),
7761 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7762 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067763 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:357764 };
7765
[email protected]31a2bfe2010-02-09 08:03:397766 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7767 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077768 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:357769
[email protected]49639fa2011-12-20 23:22:417770 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:357771
[email protected]49639fa2011-12-20 23:22:417772 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:357773 EXPECT_EQ(ERR_IO_PENDING, rv);
7774
7775 rv = callback.WaitForResult();
7776 EXPECT_EQ(OK, rv);
7777
7778 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507779 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:357780
[email protected]029c83b62013-01-24 05:28:207781 LoadTimingInfo load_timing_info;
7782 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7783 TestLoadTimingNotReusedWithPac(load_timing_info,
7784 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7785
[email protected]e0c27be2009-07-15 13:09:357786 std::string response_text;
7787 rv = ReadTransaction(trans.get(), &response_text);
7788 EXPECT_EQ(OK, rv);
7789 EXPECT_EQ("Payload", response_text);
7790}
7791
[email protected]23e482282013-06-14 16:08:027792TEST_P(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277793 HttpRequestInfo request;
7794 request.method = "GET";
bncce36dca22015-04-21 22:11:237795 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:277796 request.load_flags = 0;
7797
[email protected]bb88e1d32013-05-03 23:11:077798 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207799 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
vishal.b62985ca92015-04-17 08:45:517800 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077801 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:357802
[email protected]3fe8d2f82013-10-17 08:56:077803 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e0c27be2009-07-15 13:09:357804 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417805 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]e0c27be2009-07-15 13:09:357806
[email protected]e0c27be2009-07-15 13:09:357807 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
7808 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:377809 const unsigned char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:237810 0x05, // Version
7811 0x01, // Command (CONNECT)
7812 0x00, // Reserved.
7813 0x03, // Address type (DOMAINNAME).
7814 0x0F, // Length of domain (15)
7815 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
7816 '.', 'o', 'r', 'g', 0x01, 0xBB, // 16-bit port (443)
[email protected]f209dba2009-12-18 00:24:377817 };
7818
[email protected]e0c27be2009-07-15 13:09:357819 const char kSOCKS5OkResponse[] =
7820 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
7821
7822 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237823 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
7824 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
7825 arraysize(kSOCKS5OkRequest)),
7826 MockWrite(
7827 "GET / HTTP/1.1\r\n"
7828 "Host: www.example.org\r\n"
7829 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:357830
7831 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:017832 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
7833 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:027834 MockRead("HTTP/1.0 200 OK\r\n"),
7835 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7836 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067837 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:027838 };
7839
[email protected]31a2bfe2010-02-09 08:03:397840 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7841 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077842 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:027843
[email protected]8ddf8322012-02-23 18:08:067844 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077845 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:027846
[email protected]49639fa2011-12-20 23:22:417847 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:027848
[email protected]49639fa2011-12-20 23:22:417849 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:027850 EXPECT_EQ(ERR_IO_PENDING, rv);
7851
7852 rv = callback.WaitForResult();
7853 EXPECT_EQ(OK, rv);
7854
7855 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507856 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:027857
[email protected]029c83b62013-01-24 05:28:207858 LoadTimingInfo load_timing_info;
7859 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7860 TestLoadTimingNotReusedWithPac(load_timing_info,
7861 CONNECT_TIMING_HAS_SSL_TIMES);
7862
[email protected]3cd17242009-06-23 02:59:027863 std::string response_text;
7864 rv = ReadTransaction(trans.get(), &response_text);
7865 EXPECT_EQ(OK, rv);
7866 EXPECT_EQ("Payload", response_text);
7867}
7868
[email protected]448d4ca52012-03-04 04:12:237869namespace {
7870
[email protected]04e5be32009-06-26 20:00:317871// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:067872
7873struct GroupNameTest {
7874 std::string proxy_server;
7875 std::string url;
7876 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:187877 bool ssl;
[email protected]2d731a32010-04-29 01:04:067878};
7879
7880scoped_refptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]8a0fc822013-06-27 20:52:437881 NextProto next_proto,
[email protected]bb88e1d32013-05-03 23:11:077882 SpdySessionDependencies* session_deps_) {
7883 scoped_refptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:067884
[email protected]30d4c022013-07-18 22:58:167885 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:537886 session->http_server_properties();
bnccacc0992015-03-20 20:22:227887 AlternativeService alternative_service(
bnc4988e432015-03-31 03:06:257888 AlternateProtocolFromNextProto(next_proto), "", 443);
bnccacc0992015-03-20 20:22:227889 http_server_properties->SetAlternativeService(
7890 HostPortPair("host.with.alternate", 80), alternative_service, 1.0);
[email protected]2d731a32010-04-29 01:04:067891
7892 return session;
7893}
7894
7895int GroupNameTransactionHelper(
7896 const std::string& url,
7897 const scoped_refptr<HttpNetworkSession>& session) {
[email protected]2d731a32010-04-29 01:04:067898 HttpRequestInfo request;
7899 request.method = "GET";
7900 request.url = GURL(url);
7901 request.load_flags = 0;
7902
[email protected]262eec82013-03-19 21:01:367903 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507904 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277905
[email protected]49639fa2011-12-20 23:22:417906 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:067907
7908 // We do not complete this request, the dtor will clean the transaction up.
[email protected]49639fa2011-12-20 23:22:417909 return trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d731a32010-04-29 01:04:067910}
7911
[email protected]448d4ca52012-03-04 04:12:237912} // namespace
7913
[email protected]23e482282013-06-14 16:08:027914TEST_P(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:067915 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:237916 {
7917 "", // unused
7918 "http://www.example.org/direct",
7919 "www.example.org:80",
7920 false,
7921 },
7922 {
7923 "", // unused
7924 "http://[2001:1418:13:1::25]/direct",
7925 "[2001:1418:13:1::25]:80",
7926 false,
7927 },
[email protected]04e5be32009-06-26 20:00:317928
bncce36dca22015-04-21 22:11:237929 // SSL Tests
7930 {
7931 "", // unused
7932 "https://www.example.org/direct_ssl",
7933 "ssl/www.example.org:443",
7934 true,
7935 },
7936 {
7937 "", // unused
7938 "https://[2001:1418:13:1::25]/direct",
7939 "ssl/[2001:1418:13:1::25]:443",
7940 true,
7941 },
7942 {
7943 "", // unused
7944 "http://host.with.alternate/direct",
7945 "ssl/host.with.alternate:443",
7946 true,
7947 },
[email protected]2d731a32010-04-29 01:04:067948 };
[email protected]2ff8b312010-04-26 22:20:547949
[email protected]d7599122014-05-24 03:37:237950 session_deps_.use_alternate_protocols = true;
[email protected]2d731a32010-04-29 01:04:067951
viettrungluue4a8b882014-10-16 06:17:387952 for (size_t i = 0; i < arraysize(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:077953 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:027954 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:067955 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:437956 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:067957
7958 HttpNetworkSessionPeer peer(session);
[email protected]ab739042011-04-07 15:22:287959 CaptureGroupNameTransportSocketPool* transport_conn_pool =
7960 new CaptureGroupNameTransportSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:137961 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347962 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]831e4a32013-11-14 02:14:447963 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
7964 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:027965 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
7966 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
dchenge3d1ddc2014-10-15 19:30:517967 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]2d731a32010-04-29 01:04:067968
7969 EXPECT_EQ(ERR_IO_PENDING,
7970 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:187971 if (tests[i].ssl)
7972 EXPECT_EQ(tests[i].expected_group_name,
7973 ssl_conn_pool->last_group_name_received());
7974 else
7975 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:287976 transport_conn_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:067977 }
7978
[email protected]2d731a32010-04-29 01:04:067979}
7980
[email protected]23e482282013-06-14 16:08:027981TEST_P(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:067982 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:237983 {
7984 "http_proxy",
7985 "http://www.example.org/http_proxy_normal",
7986 "www.example.org:80",
7987 false,
7988 },
[email protected]2d731a32010-04-29 01:04:067989
bncce36dca22015-04-21 22:11:237990 // SSL Tests
7991 {
7992 "http_proxy",
7993 "https://www.example.org/http_connect_ssl",
7994 "ssl/www.example.org:443",
7995 true,
7996 },
[email protected]af3490e2010-10-16 21:02:297997
bncce36dca22015-04-21 22:11:237998 {
7999 "http_proxy",
8000 "http://host.with.alternate/direct",
8001 "ssl/host.with.alternate:443",
8002 true,
8003 },
[email protected]45499252013-01-23 17:12:568004
bncce36dca22015-04-21 22:11:238005 {
8006 "http_proxy",
8007 "ftp://ftp.google.com/http_proxy_normal",
8008 "ftp/ftp.google.com:21",
8009 false,
8010 },
[email protected]2d731a32010-04-29 01:04:068011 };
8012
[email protected]d7599122014-05-24 03:37:238013 session_deps_.use_alternate_protocols = true;
[email protected]2d731a32010-04-29 01:04:068014
viettrungluue4a8b882014-10-16 06:17:388015 for (size_t i = 0; i < arraysize(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:078016 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:028017 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:068018 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:438019 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:068020
8021 HttpNetworkSessionPeer peer(session);
8022
[email protected]e60e47a2010-07-14 03:37:188023 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:138024 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:348025 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:138026 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:348027 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:028028
[email protected]831e4a32013-11-14 02:14:448029 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
8030 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:028031 mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool);
8032 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
dchenge3d1ddc2014-10-15 19:30:518033 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]2d731a32010-04-29 01:04:068034
8035 EXPECT_EQ(ERR_IO_PENDING,
8036 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:188037 if (tests[i].ssl)
8038 EXPECT_EQ(tests[i].expected_group_name,
8039 ssl_conn_pool->last_group_name_received());
8040 else
8041 EXPECT_EQ(tests[i].expected_group_name,
8042 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:068043 }
[email protected]2d731a32010-04-29 01:04:068044}
8045
[email protected]23e482282013-06-14 16:08:028046TEST_P(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:068047 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:238048 {
8049 "socks4://socks_proxy:1080",
8050 "http://www.example.org/socks4_direct",
8051 "socks4/www.example.org:80",
8052 false,
8053 },
8054 {
8055 "socks5://socks_proxy:1080",
8056 "http://www.example.org/socks5_direct",
8057 "socks5/www.example.org:80",
8058 false,
8059 },
[email protected]2d731a32010-04-29 01:04:068060
bncce36dca22015-04-21 22:11:238061 // SSL Tests
8062 {
8063 "socks4://socks_proxy:1080",
8064 "https://www.example.org/socks4_ssl",
8065 "socks4/ssl/www.example.org:443",
8066 true,
8067 },
8068 {
8069 "socks5://socks_proxy:1080",
8070 "https://www.example.org/socks5_ssl",
8071 "socks5/ssl/www.example.org:443",
8072 true,
8073 },
[email protected]af3490e2010-10-16 21:02:298074
bncce36dca22015-04-21 22:11:238075 {
8076 "socks4://socks_proxy:1080",
8077 "http://host.with.alternate/direct",
8078 "socks4/ssl/host.with.alternate:443",
8079 true,
8080 },
[email protected]04e5be32009-06-26 20:00:318081 };
8082
[email protected]d7599122014-05-24 03:37:238083 session_deps_.use_alternate_protocols = true;
[email protected]2ff8b312010-04-26 22:20:548084
viettrungluue4a8b882014-10-16 06:17:388085 for (size_t i = 0; i < arraysize(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:078086 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:028087 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:068088 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:438089 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]8b114dd72011-03-25 05:33:028090
[email protected]2d731a32010-04-29 01:04:068091 HttpNetworkSessionPeer peer(session);
[email protected]04e5be32009-06-26 20:00:318092
[email protected]e60e47a2010-07-14 03:37:188093 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:138094 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:348095 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:138096 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:348097 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:028098
[email protected]831e4a32013-11-14 02:14:448099 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
8100 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:028101 mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_conn_pool);
8102 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
dchenge3d1ddc2014-10-15 19:30:518103 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]04e5be32009-06-26 20:00:318104
[email protected]262eec82013-03-19 21:01:368105 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508106 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]04e5be32009-06-26 20:00:318107
[email protected]2d731a32010-04-29 01:04:068108 EXPECT_EQ(ERR_IO_PENDING,
8109 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:188110 if (tests[i].ssl)
8111 EXPECT_EQ(tests[i].expected_group_name,
8112 ssl_conn_pool->last_group_name_received());
8113 else
8114 EXPECT_EQ(tests[i].expected_group_name,
8115 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:318116 }
8117}
8118
[email protected]23e482282013-06-14 16:08:028119TEST_P(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:278120 HttpRequestInfo request;
8121 request.method = "GET";
bncce36dca22015-04-21 22:11:238122 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278123
[email protected]bb88e1d32013-05-03 23:11:078124 session_deps_.proxy_service.reset(
[email protected]81cdfcd2010-10-16 00:49:008125 ProxyService::CreateFixed("myproxy:70;foobar:80"));
[email protected]b59ff372009-07-15 22:04:328126
[email protected]69719062010-01-05 20:09:218127 // This simulates failure resolving all hostnames; that means we will fail
8128 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:078129 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:328130
[email protected]3fe8d2f82013-10-17 08:56:078131 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]9172a982009-06-06 00:30:258132 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418133 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]9172a982009-06-06 00:30:258134
[email protected]49639fa2011-12-20 23:22:418135 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:258136
[email protected]49639fa2011-12-20 23:22:418137 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9172a982009-06-06 00:30:258138 EXPECT_EQ(ERR_IO_PENDING, rv);
8139
[email protected]9172a982009-06-06 00:30:258140 rv = callback.WaitForResult();
[email protected]f7fccee2010-09-16 20:53:018141 EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
[email protected]9172a982009-06-06 00:30:258142}
8143
[email protected]685af592010-05-11 19:31:248144// Base test to make sure that when the load flags for a request specify to
8145// bypass the cache, the DNS cache is not used.
[email protected]23e482282013-06-14 16:08:028146void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
[email protected]bb88e1d32013-05-03 23:11:078147 int load_flags) {
[email protected]cb9bf6ca2011-01-28 13:15:278148 // Issue a request, asking to bypass the cache(s).
8149 HttpRequestInfo request;
8150 request.method = "GET";
8151 request.load_flags = load_flags;
bncce36dca22015-04-21 22:11:238152 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278153
[email protected]a2c2fb92009-07-18 07:31:048154 // Select a host resolver that does caching.
[email protected]bb88e1d32013-05-03 23:11:078155 session_deps_.host_resolver.reset(new MockCachingHostResolver);
[email protected]b59ff372009-07-15 22:04:328156
[email protected]3fe8d2f82013-10-17 08:56:078157 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8158 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418159 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3b9cca42009-06-16 01:08:288160
bncce36dca22015-04-21 22:11:238161 // Warm up the host cache so it has an entry for "www.example.org".
[email protected]3b9cca42009-06-16 01:08:288162 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:298163 TestCompletionCallback callback;
[email protected]bb88e1d32013-05-03 23:11:078164 int rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:238165 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
8166 DEFAULT_PRIORITY, &addrlist, callback.callback(), NULL, BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:478167 EXPECT_EQ(ERR_IO_PENDING, rv);
8168 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:288169 EXPECT_EQ(OK, rv);
8170
8171 // Verify that it was added to host cache, by doing a subsequent async lookup
8172 // and confirming it completes synchronously.
[email protected]bb88e1d32013-05-03 23:11:078173 rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:238174 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
8175 DEFAULT_PRIORITY, &addrlist, callback.callback(), NULL, BoundNetLog());
[email protected]b59ff372009-07-15 22:04:328176 ASSERT_EQ(OK, rv);
[email protected]3b9cca42009-06-16 01:08:288177
bncce36dca22015-04-21 22:11:238178 // Inject a failure the next time that "www.example.org" is resolved. This way
[email protected]3b9cca42009-06-16 01:08:288179 // we can tell if the next lookup hit the cache, or the "network".
8180 // (cache --> success, "network" --> failure).
bncce36dca22015-04-21 22:11:238181 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.example.org");
[email protected]3b9cca42009-06-16 01:08:288182
8183 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
8184 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:068185 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
[email protected]31a2bfe2010-02-09 08:03:398186 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078187 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:288188
[email protected]3b9cca42009-06-16 01:08:288189 // Run the request.
[email protected]49639fa2011-12-20 23:22:418190 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3b9cca42009-06-16 01:08:288191 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:418192 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:288193
8194 // If we bypassed the cache, we would have gotten a failure while resolving
bncce36dca22015-04-21 22:11:238195 // "www.example.org".
[email protected]3b9cca42009-06-16 01:08:288196 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
8197}
8198
[email protected]685af592010-05-11 19:31:248199// There are multiple load flags that should trigger the host cache bypass.
8200// Test each in isolation:
[email protected]23e482282013-06-14 16:08:028201TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
[email protected]685af592010-05-11 19:31:248202 BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
8203}
8204
[email protected]23e482282013-06-14 16:08:028205TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
[email protected]685af592010-05-11 19:31:248206 BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
8207}
8208
[email protected]23e482282013-06-14 16:08:028209TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
[email protected]685af592010-05-11 19:31:248210 BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
8211}
8212
[email protected]0877e3d2009-10-17 22:29:578213// Make sure we can handle an error when writing the request.
[email protected]23e482282013-06-14 16:08:028214TEST_P(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:578215 HttpRequestInfo request;
8216 request.method = "GET";
8217 request.url = GURL("http://www.foo.com/");
8218 request.load_flags = 0;
8219
8220 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:068221 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:578222 };
[email protected]31a2bfe2010-02-09 08:03:398223 StaticSocketDataProvider data(NULL, 0,
8224 write_failure, arraysize(write_failure));
[email protected]bb88e1d32013-05-03 23:11:078225 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3fe8d2f82013-10-17 08:56:078226 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578227
[email protected]49639fa2011-12-20 23:22:418228 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:578229
8230 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418231 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:578232
[email protected]49639fa2011-12-20 23:22:418233 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578234 EXPECT_EQ(ERR_IO_PENDING, rv);
8235
8236 rv = callback.WaitForResult();
8237 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
8238}
8239
8240// Check that a connection closed after the start of the headers finishes ok.
[email protected]23e482282013-06-14 16:08:028241TEST_P(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:578242 HttpRequestInfo request;
8243 request.method = "GET";
8244 request.url = GURL("http://www.foo.com/");
8245 request.load_flags = 0;
8246
8247 MockRead data_reads[] = {
8248 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:068249 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:578250 };
8251
[email protected]31a2bfe2010-02-09 08:03:398252 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078253 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3fe8d2f82013-10-17 08:56:078254 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578255
[email protected]49639fa2011-12-20 23:22:418256 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:578257
8258 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418259 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:578260
[email protected]49639fa2011-12-20 23:22:418261 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578262 EXPECT_EQ(ERR_IO_PENDING, rv);
8263
8264 rv = callback.WaitForResult();
8265 EXPECT_EQ(OK, rv);
8266
8267 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508268 ASSERT_TRUE(response != NULL);
[email protected]0877e3d2009-10-17 22:29:578269
[email protected]90499482013-06-01 00:39:508270 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]0877e3d2009-10-17 22:29:578271 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
8272
8273 std::string response_data;
8274 rv = ReadTransaction(trans.get(), &response_data);
8275 EXPECT_EQ(OK, rv);
8276 EXPECT_EQ("", response_data);
8277}
8278
8279// Make sure that a dropped connection while draining the body for auth
8280// restart does the right thing.
[email protected]23e482282013-06-14 16:08:028281TEST_P(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:578282 HttpRequestInfo request;
8283 request.method = "GET";
bncce36dca22015-04-21 22:11:238284 request.url = GURL("http://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:578285 request.load_flags = 0;
8286
8287 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238288 MockWrite(
8289 "GET / HTTP/1.1\r\n"
8290 "Host: www.example.org\r\n"
8291 "Connection: keep-alive\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:578292 };
8293
8294 MockRead data_reads1[] = {
8295 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
8296 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8297 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8298 MockRead("Content-Length: 14\r\n\r\n"),
8299 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:068300 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:578301 };
8302
[email protected]31a2bfe2010-02-09 08:03:398303 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8304 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:078305 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:578306
8307 // After calling trans->RestartWithAuth(), this is the request we should
8308 // be issuing -- the final header line contains the credentials.
8309 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238310 MockWrite(
8311 "GET / HTTP/1.1\r\n"
8312 "Host: www.example.org\r\n"
8313 "Connection: keep-alive\r\n"
8314 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:578315 };
8316
8317 // Lastly, the server responds with the actual content.
8318 MockRead data_reads2[] = {
8319 MockRead("HTTP/1.1 200 OK\r\n"),
8320 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8321 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068322 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:578323 };
8324
[email protected]31a2bfe2010-02-09 08:03:398325 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8326 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:078327 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3fe8d2f82013-10-17 08:56:078328 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578329
[email protected]49639fa2011-12-20 23:22:418330 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:578331
[email protected]262eec82013-03-19 21:01:368332 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508333 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:508334
[email protected]49639fa2011-12-20 23:22:418335 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578336 EXPECT_EQ(ERR_IO_PENDING, rv);
8337
8338 rv = callback1.WaitForResult();
8339 EXPECT_EQ(OK, rv);
8340
8341 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508342 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048343 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:578344
[email protected]49639fa2011-12-20 23:22:418345 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:578346
[email protected]49639fa2011-12-20 23:22:418347 rv = trans->RestartWithAuth(
8348 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]0877e3d2009-10-17 22:29:578349 EXPECT_EQ(ERR_IO_PENDING, rv);
8350
8351 rv = callback2.WaitForResult();
8352 EXPECT_EQ(OK, rv);
8353
8354 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508355 ASSERT_TRUE(response != NULL);
[email protected]0877e3d2009-10-17 22:29:578356 EXPECT_TRUE(response->auth_challenge.get() == NULL);
8357 EXPECT_EQ(100, response->headers->GetContentLength());
8358}
8359
8360// Test HTTPS connections going through a proxy that sends extra data.
[email protected]23e482282013-06-14 16:08:028361TEST_P(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
[email protected]bb88e1d32013-05-03 23:11:078362 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]0877e3d2009-10-17 22:29:578363
8364 HttpRequestInfo request;
8365 request.method = "GET";
bncce36dca22015-04-21 22:11:238366 request.url = GURL("https://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:578367 request.load_flags = 0;
8368
8369 MockRead proxy_reads[] = {
8370 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:068371 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:578372 };
8373
[email protected]31a2bfe2010-02-09 08:03:398374 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
[email protected]8ddf8322012-02-23 18:08:068375 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:578376
[email protected]bb88e1d32013-05-03 23:11:078377 session_deps_.socket_factory->AddSocketDataProvider(&data);
8378 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:578379
[email protected]49639fa2011-12-20 23:22:418380 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:578381
[email protected]bb88e1d32013-05-03 23:11:078382 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:578383
[email protected]3fe8d2f82013-10-17 08:56:078384 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578385 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418386 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:578387
[email protected]49639fa2011-12-20 23:22:418388 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578389 EXPECT_EQ(ERR_IO_PENDING, rv);
8390
8391 rv = callback.WaitForResult();
8392 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
8393}
8394
[email protected]23e482282013-06-14 16:08:028395TEST_P(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:468396 HttpRequestInfo request;
8397 request.method = "GET";
bncce36dca22015-04-21 22:11:238398 request.url = GURL("http://www.example.org/");
[email protected]9492e4a2010-02-24 00:58:468399 request.load_flags = 0;
8400
[email protected]3fe8d2f82013-10-17 08:56:078401 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:278402 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418403 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278404
[email protected]e22e1362009-11-23 21:31:128405 MockRead data_reads[] = {
8406 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068407 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:128408 };
[email protected]9492e4a2010-02-24 00:58:468409
8410 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078411 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:468412
[email protected]49639fa2011-12-20 23:22:418413 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:468414
[email protected]49639fa2011-12-20 23:22:418415 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9492e4a2010-02-24 00:58:468416 EXPECT_EQ(ERR_IO_PENDING, rv);
8417
8418 EXPECT_EQ(OK, callback.WaitForResult());
8419
8420 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508421 ASSERT_TRUE(response != NULL);
[email protected]9492e4a2010-02-24 00:58:468422
[email protected]90499482013-06-01 00:39:508423 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]9492e4a2010-02-24 00:58:468424 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
8425
8426 std::string response_data;
8427 rv = ReadTransaction(trans.get(), &response_data);
[email protected]5543cbb2012-04-20 16:35:238428 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
[email protected]e22e1362009-11-23 21:31:128429}
8430
[email protected]23e482282013-06-14 16:08:028431TEST_P(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:158432 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:528433 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
[email protected]95d88ffe2010-02-04 21:25:338434 const uint64 kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:218435 UploadFileElementReader::ScopedOverridingContentLengthForTests
8436 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:338437
[email protected]b2d26cfd2012-12-11 10:36:068438 ScopedVector<UploadElementReader> element_readers;
8439 element_readers.push_back(
[email protected]cadac622013-06-11 16:46:368440 new UploadFileElementReader(base::MessageLoopProxy::current().get(),
8441 temp_file_path,
8442 0,
8443 kuint64max,
8444 base::Time()));
mmenkecbc2b712014-10-09 20:29:078445 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:278446
8447 HttpRequestInfo request;
8448 request.method = "POST";
bncce36dca22015-04-21 22:11:238449 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:278450 request.upload_data_stream = &upload_data_stream;
8451 request.load_flags = 0;
8452
[email protected]3fe8d2f82013-10-17 08:56:078453 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]329b68b2012-11-14 17:54:278454 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418455 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]95d88ffe2010-02-04 21:25:338456
8457 MockRead data_reads[] = {
8458 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
8459 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068460 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:338461 };
[email protected]31a2bfe2010-02-09 08:03:398462 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078463 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:338464
[email protected]49639fa2011-12-20 23:22:418465 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:338466
[email protected]49639fa2011-12-20 23:22:418467 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]95d88ffe2010-02-04 21:25:338468 EXPECT_EQ(ERR_IO_PENDING, rv);
8469
8470 rv = callback.WaitForResult();
8471 EXPECT_EQ(OK, rv);
8472
8473 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508474 ASSERT_TRUE(response != NULL);
[email protected]95d88ffe2010-02-04 21:25:338475
[email protected]90499482013-06-01 00:39:508476 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]95d88ffe2010-02-04 21:25:338477 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
8478
8479 std::string response_data;
8480 rv = ReadTransaction(trans.get(), &response_data);
8481 EXPECT_EQ(OK, rv);
8482 EXPECT_EQ("hello world", response_data);
8483
[email protected]dd3aa792013-07-16 19:10:238484 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:338485}
8486
[email protected]23e482282013-06-14 16:08:028487TEST_P(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:158488 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:528489 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:368490 std::string temp_file_content("Unreadable file.");
[email protected]e5c2a22e2014-03-06 20:42:308491 ASSERT_TRUE(base::WriteFile(temp_file, temp_file_content.c_str(),
[email protected]6624b4622010-03-29 19:58:368492 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:118493 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:368494
[email protected]b2d26cfd2012-12-11 10:36:068495 ScopedVector<UploadElementReader> element_readers;
8496 element_readers.push_back(
[email protected]cadac622013-06-11 16:46:368497 new UploadFileElementReader(base::MessageLoopProxy::current().get(),
8498 temp_file,
8499 0,
8500 kuint64max,
8501 base::Time()));
mmenkecbc2b712014-10-09 20:29:078502 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:278503
8504 HttpRequestInfo request;
8505 request.method = "POST";
bncce36dca22015-04-21 22:11:238506 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:278507 request.upload_data_stream = &upload_data_stream;
8508 request.load_flags = 0;
8509
[email protected]999dd8c2013-11-12 06:45:548510 // If we try to upload an unreadable file, the transaction should fail.
[email protected]3fe8d2f82013-10-17 08:56:078511 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]329b68b2012-11-14 17:54:278512 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418513 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]6624b4622010-03-29 19:58:368514
[email protected]999dd8c2013-11-12 06:45:548515 StaticSocketDataProvider data(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078516 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:368517
[email protected]49639fa2011-12-20 23:22:418518 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:368519
[email protected]49639fa2011-12-20 23:22:418520 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]6624b4622010-03-29 19:58:368521 EXPECT_EQ(ERR_IO_PENDING, rv);
8522
8523 rv = callback.WaitForResult();
[email protected]999dd8c2013-11-12 06:45:548524 EXPECT_EQ(ERR_ACCESS_DENIED, rv);
[email protected]6624b4622010-03-29 19:58:368525
[email protected]dd3aa792013-07-16 19:10:238526 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:368527}
8528
[email protected]02cad5d2013-10-02 08:14:038529TEST_P(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
8530 class FakeUploadElementReader : public UploadElementReader {
8531 public:
8532 FakeUploadElementReader() {}
dchengb03027d2014-10-21 12:00:208533 ~FakeUploadElementReader() override {}
[email protected]02cad5d2013-10-02 08:14:038534
8535 const CompletionCallback& callback() const { return callback_; }
8536
8537 // UploadElementReader overrides:
dchengb03027d2014-10-21 12:00:208538 int Init(const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:038539 callback_ = callback;
8540 return ERR_IO_PENDING;
8541 }
dchengb03027d2014-10-21 12:00:208542 uint64 GetContentLength() const override { return 0; }
8543 uint64 BytesRemaining() const override { return 0; }
8544 int Read(IOBuffer* buf,
8545 int buf_length,
8546 const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:038547 return ERR_FAILED;
8548 }
8549
8550 private:
8551 CompletionCallback callback_;
8552 };
8553
8554 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
8555 ScopedVector<UploadElementReader> element_readers;
8556 element_readers.push_back(fake_reader);
mmenkecbc2b712014-10-09 20:29:078557 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02cad5d2013-10-02 08:14:038558
8559 HttpRequestInfo request;
8560 request.method = "POST";
bncce36dca22015-04-21 22:11:238561 request.url = GURL("http://www.example.org/upload");
[email protected]02cad5d2013-10-02 08:14:038562 request.upload_data_stream = &upload_data_stream;
8563 request.load_flags = 0;
8564
[email protected]3fe8d2f82013-10-17 08:56:078565 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02cad5d2013-10-02 08:14:038566 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418567 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02cad5d2013-10-02 08:14:038568
8569 StaticSocketDataProvider data;
8570 session_deps_.socket_factory->AddSocketDataProvider(&data);
8571
8572 TestCompletionCallback callback;
8573 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8574 EXPECT_EQ(ERR_IO_PENDING, rv);
8575 base::MessageLoop::current()->RunUntilIdle();
8576
8577 // Transaction is pending on request body initialization.
8578 ASSERT_FALSE(fake_reader->callback().is_null());
8579
8580 // Return Init()'s result after the transaction gets destroyed.
8581 trans.reset();
8582 fake_reader->callback().Run(OK); // Should not crash.
8583}
8584
[email protected]aeefc9e82010-02-19 16:18:278585// Tests that changes to Auth realms are treated like auth rejections.
[email protected]23e482282013-06-14 16:08:028586TEST_P(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:278587
8588 HttpRequestInfo request;
8589 request.method = "GET";
bncce36dca22015-04-21 22:11:238590 request.url = GURL("http://www.example.org/");
[email protected]aeefc9e82010-02-19 16:18:278591 request.load_flags = 0;
8592
8593 // First transaction will request a resource and receive a Basic challenge
8594 // with realm="first_realm".
8595 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238596 MockWrite(
8597 "GET / HTTP/1.1\r\n"
8598 "Host: www.example.org\r\n"
8599 "Connection: keep-alive\r\n"
8600 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:278601 };
8602 MockRead data_reads1[] = {
8603 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8604 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
8605 "\r\n"),
8606 };
8607
8608 // After calling trans->RestartWithAuth(), provide an Authentication header
8609 // for first_realm. The server will reject and provide a challenge with
8610 // second_realm.
8611 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238612 MockWrite(
8613 "GET / HTTP/1.1\r\n"
8614 "Host: www.example.org\r\n"
8615 "Connection: keep-alive\r\n"
8616 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
8617 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:278618 };
8619 MockRead data_reads2[] = {
8620 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8621 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
8622 "\r\n"),
8623 };
8624
8625 // This again fails, and goes back to first_realm. Make sure that the
8626 // entry is removed from cache.
8627 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:238628 MockWrite(
8629 "GET / HTTP/1.1\r\n"
8630 "Host: www.example.org\r\n"
8631 "Connection: keep-alive\r\n"
8632 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
8633 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:278634 };
8635 MockRead data_reads3[] = {
8636 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8637 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
8638 "\r\n"),
8639 };
8640
8641 // Try one last time (with the correct password) and get the resource.
8642 MockWrite data_writes4[] = {
bncce36dca22015-04-21 22:11:238643 MockWrite(
8644 "GET / HTTP/1.1\r\n"
8645 "Host: www.example.org\r\n"
8646 "Connection: keep-alive\r\n"
8647 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
8648 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:278649 };
8650 MockRead data_reads4[] = {
8651 MockRead("HTTP/1.1 200 OK\r\n"
8652 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:508653 "Content-Length: 5\r\n"
8654 "\r\n"
8655 "hello"),
[email protected]aeefc9e82010-02-19 16:18:278656 };
8657
8658 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8659 data_writes1, arraysize(data_writes1));
8660 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8661 data_writes2, arraysize(data_writes2));
8662 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
8663 data_writes3, arraysize(data_writes3));
8664 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
8665 data_writes4, arraysize(data_writes4));
[email protected]bb88e1d32013-05-03 23:11:078666 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8667 session_deps_.socket_factory->AddSocketDataProvider(&data2);
8668 session_deps_.socket_factory->AddSocketDataProvider(&data3);
8669 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:278670
[email protected]49639fa2011-12-20 23:22:418671 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:278672
[email protected]3fe8d2f82013-10-17 08:56:078673 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0b0bf032010-09-21 18:08:508674 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418675 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:508676
[email protected]aeefc9e82010-02-19 16:18:278677 // Issue the first request with Authorize headers. There should be a
8678 // password prompt for first_realm waiting to be filled in after the
8679 // transaction completes.
[email protected]49639fa2011-12-20 23:22:418680 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]aeefc9e82010-02-19 16:18:278681 EXPECT_EQ(ERR_IO_PENDING, rv);
8682 rv = callback1.WaitForResult();
8683 EXPECT_EQ(OK, rv);
8684 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508685 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048686 const AuthChallengeInfo* challenge = response->auth_challenge.get();
8687 ASSERT_FALSE(challenge == NULL);
8688 EXPECT_FALSE(challenge->is_proxy);
bncce36dca22015-04-21 22:11:238689 EXPECT_EQ("www.example.org:80", challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:048690 EXPECT_EQ("first_realm", challenge->realm);
8691 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278692
8693 // Issue the second request with an incorrect password. There should be a
8694 // password prompt for second_realm waiting to be filled in after the
8695 // transaction completes.
[email protected]49639fa2011-12-20 23:22:418696 TestCompletionCallback callback2;
8697 rv = trans->RestartWithAuth(
8698 AuthCredentials(kFirst, kBaz), callback2.callback());
[email protected]aeefc9e82010-02-19 16:18:278699 EXPECT_EQ(ERR_IO_PENDING, rv);
8700 rv = callback2.WaitForResult();
8701 EXPECT_EQ(OK, rv);
8702 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508703 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048704 challenge = response->auth_challenge.get();
8705 ASSERT_FALSE(challenge == NULL);
8706 EXPECT_FALSE(challenge->is_proxy);
bncce36dca22015-04-21 22:11:238707 EXPECT_EQ("www.example.org:80", challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:048708 EXPECT_EQ("second_realm", challenge->realm);
8709 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278710
8711 // Issue the third request with another incorrect password. There should be
8712 // a password prompt for first_realm waiting to be filled in. If the password
8713 // prompt is not present, it indicates that the HttpAuthCacheEntry for
8714 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:418715 TestCompletionCallback callback3;
8716 rv = trans->RestartWithAuth(
8717 AuthCredentials(kSecond, kFou), callback3.callback());
[email protected]aeefc9e82010-02-19 16:18:278718 EXPECT_EQ(ERR_IO_PENDING, rv);
8719 rv = callback3.WaitForResult();
8720 EXPECT_EQ(OK, rv);
8721 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508722 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048723 challenge = response->auth_challenge.get();
8724 ASSERT_FALSE(challenge == NULL);
8725 EXPECT_FALSE(challenge->is_proxy);
bncce36dca22015-04-21 22:11:238726 EXPECT_EQ("www.example.org:80", challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:048727 EXPECT_EQ("first_realm", challenge->realm);
8728 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278729
8730 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:418731 TestCompletionCallback callback4;
8732 rv = trans->RestartWithAuth(
8733 AuthCredentials(kFirst, kBar), callback4.callback());
[email protected]aeefc9e82010-02-19 16:18:278734 EXPECT_EQ(ERR_IO_PENDING, rv);
8735 rv = callback4.WaitForResult();
8736 EXPECT_EQ(OK, rv);
8737 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508738 ASSERT_TRUE(response != NULL);
[email protected]aeefc9e82010-02-19 16:18:278739 EXPECT_TRUE(response->auth_challenge.get() == NULL);
8740}
8741
[email protected]23e482282013-06-14 16:08:028742TEST_P(HttpNetworkTransactionTest, HonorAlternateProtocolHeader) {
[email protected]d7599122014-05-24 03:37:238743 session_deps_.next_protos = SpdyNextProtos();
8744 session_deps_.use_alternate_protocols = true;
[email protected]a2cb8122010-03-10 17:22:428745
[email protected]8a0fc822013-06-27 20:52:438746 std::string alternate_protocol_http_header =
8747 GetAlternateProtocolHttpHeader();
8748
[email protected]564b4912010-03-09 16:30:428749 MockRead data_reads[] = {
8750 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438751 MockRead(alternate_protocol_http_header.c_str()),
[email protected]564b4912010-03-09 16:30:428752 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068753 MockRead(SYNCHRONOUS, OK),
[email protected]564b4912010-03-09 16:30:428754 };
8755
8756 HttpRequestInfo request;
8757 request.method = "GET";
bncce36dca22015-04-21 22:11:238758 request.url = GURL("http://www.example.org/");
[email protected]564b4912010-03-09 16:30:428759 request.load_flags = 0;
8760
8761 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
8762
[email protected]bb88e1d32013-05-03 23:11:078763 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]564b4912010-03-09 16:30:428764
[email protected]49639fa2011-12-20 23:22:418765 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:428766
[email protected]bb88e1d32013-05-03 23:11:078767 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:368768 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508769 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]564b4912010-03-09 16:30:428770
[email protected]49639fa2011-12-20 23:22:418771 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:428772 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]9e743cd2010-03-16 07:03:538773
bncce36dca22015-04-21 22:11:238774 HostPortPair http_host_port_pair("www.example.org", 80);
[email protected]9801e3702014-03-07 09:33:558775 HttpServerProperties& http_server_properties =
[email protected]17291a022011-10-10 07:32:538776 *session->http_server_properties();
bnc181b39a2015-03-17 21:36:478777 AlternativeService alternative_service =
8778 http_server_properties.GetAlternativeService(http_host_port_pair);
8779 EXPECT_EQ(alternative_service.protocol, UNINITIALIZED_ALTERNATE_PROTOCOL);
[email protected]564b4912010-03-09 16:30:428780
8781 EXPECT_EQ(OK, callback.WaitForResult());
8782
8783 const HttpResponseInfo* response = trans->GetResponseInfo();
8784 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508785 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:428786 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:538787 EXPECT_FALSE(response->was_fetched_via_spdy);
8788 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]564b4912010-03-09 16:30:428789
8790 std::string response_data;
8791 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8792 EXPECT_EQ("hello world", response_data);
8793
bnc181b39a2015-03-17 21:36:478794 alternative_service =
8795 http_server_properties.GetAlternativeService(http_host_port_pair);
8796 EXPECT_EQ(443, alternative_service.port);
8797 EXPECT_EQ(AlternateProtocolFromNextProto(GetParam()),
8798 alternative_service.protocol);
[email protected]564b4912010-03-09 16:30:428799}
8800
rch89c6e102015-03-18 18:56:528801TEST_P(HttpNetworkTransactionTest, EmptyAlternateProtocolHeader) {
8802 session_deps_.next_protos = SpdyNextProtos();
8803 session_deps_.use_alternate_protocols = true;
8804
8805 MockRead data_reads[] = {
8806 MockRead("HTTP/1.1 200 OK\r\n"),
8807 MockRead("Alternate-Protocol: \r\n\r\n"),
8808 MockRead("hello world"),
8809 MockRead(SYNCHRONOUS, OK),
8810 };
8811
8812 HttpRequestInfo request;
8813 request.method = "GET";
bncce36dca22015-04-21 22:11:238814 request.url = GURL("http://www.example.org/");
rch89c6e102015-03-18 18:56:528815 request.load_flags = 0;
8816
8817 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
8818
8819 session_deps_.socket_factory->AddSocketDataProvider(&data);
8820
8821 TestCompletionCallback callback;
8822
8823 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8824
bncce36dca22015-04-21 22:11:238825 HostPortPair http_host_port_pair("www.example.org", 80);
rch89c6e102015-03-18 18:56:528826 HttpServerProperties& http_server_properties =
8827 *session->http_server_properties();
bnccacc0992015-03-20 20:22:228828 AlternativeService alternative_service(QUIC, "", 80);
8829 http_server_properties.SetAlternativeService(http_host_port_pair,
8830 alternative_service, 1.0);
8831
8832 alternative_service =
rch89c6e102015-03-18 18:56:528833 http_server_properties.GetAlternativeService(http_host_port_pair);
8834 EXPECT_EQ(alternative_service.protocol, QUIC);
8835
8836 scoped_ptr<HttpTransaction> trans(
8837 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8838
8839 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8840 EXPECT_EQ(ERR_IO_PENDING, rv);
8841
8842 EXPECT_EQ(OK, callback.WaitForResult());
8843
8844 const HttpResponseInfo* response = trans->GetResponseInfo();
8845 ASSERT_TRUE(response != NULL);
8846 ASSERT_TRUE(response->headers.get() != NULL);
8847 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8848 EXPECT_FALSE(response->was_fetched_via_spdy);
8849 EXPECT_FALSE(response->was_npn_negotiated);
8850
8851 std::string response_data;
8852 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8853 EXPECT_EQ("hello world", response_data);
8854
8855 alternative_service =
8856 http_server_properties.GetAlternativeService(http_host_port_pair);
8857 EXPECT_EQ(alternative_service.protocol, UNINITIALIZED_ALTERNATE_PROTOCOL);
8858}
8859
[email protected]23e482282013-06-14 16:08:028860TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238861 MarkBrokenAlternateProtocolAndFallback) {
[email protected]d7599122014-05-24 03:37:238862 session_deps_.use_alternate_protocols = true;
[email protected]564b4912010-03-09 16:30:428863
8864 HttpRequestInfo request;
8865 request.method = "GET";
bncce36dca22015-04-21 22:11:238866 request.url = GURL("http://www.example.org/");
[email protected]564b4912010-03-09 16:30:428867 request.load_flags = 0;
8868
[email protected]d973e99a2012-02-17 21:02:368869 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:428870 StaticSocketDataProvider first_data;
8871 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078872 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]564b4912010-03-09 16:30:428873
8874 MockRead data_reads[] = {
8875 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8876 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068877 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:428878 };
8879 StaticSocketDataProvider second_data(
8880 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078881 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:428882
[email protected]bb88e1d32013-05-03 23:11:078883 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:428884
[email protected]30d4c022013-07-18 22:58:168885 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538886 session->http_server_properties();
bnc8445b3002015-03-13 01:57:098887 const HostPortPair host_port_pair = HostPortPair::FromURL(request.url);
[email protected]3912662a32011-10-04 00:51:118888 // Port must be < 1024, or the header will be ignored (since initial port was
8889 // port 80 (another restricted port).
bnccacc0992015-03-20 20:22:228890 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:238891 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:228892 666); /* port is ignored by MockConnect anyway */
8893 http_server_properties->SetAlternativeService(host_port_pair,
8894 alternative_service, 1.0);
[email protected]564b4912010-03-09 16:30:428895
[email protected]262eec82013-03-19 21:01:368896 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508897 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418898 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:428899
[email protected]49639fa2011-12-20 23:22:418900 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:428901 EXPECT_EQ(ERR_IO_PENDING, rv);
8902 EXPECT_EQ(OK, callback.WaitForResult());
8903
8904 const HttpResponseInfo* response = trans->GetResponseInfo();
8905 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508906 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:428907 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8908
8909 std::string response_data;
8910 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8911 EXPECT_EQ("hello world", response_data);
8912
bnccacc0992015-03-20 20:22:228913 alternative_service =
bnc181b39a2015-03-17 21:36:478914 http_server_properties->GetAlternativeService(host_port_pair);
8915 EXPECT_NE(UNINITIALIZED_ALTERNATE_PROTOCOL, alternative_service.protocol);
bnc8445b3002015-03-13 01:57:098916 EXPECT_TRUE(
8917 http_server_properties->IsAlternativeServiceBroken(alternative_service));
[email protected]564b4912010-03-09 16:30:428918}
8919
[email protected]23e482282013-06-14 16:08:028920TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238921 AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:118922 // Ensure that we're not allowed to redirect traffic via an alternate
8923 // protocol to an unrestricted (port >= 1024) when the original traffic was
8924 // on a restricted port (port < 1024). Ensure that we can redirect in all
8925 // other cases.
[email protected]d7599122014-05-24 03:37:238926 session_deps_.use_alternate_protocols = true;
[email protected]3912662a32011-10-04 00:51:118927
8928 HttpRequestInfo restricted_port_request;
8929 restricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:238930 restricted_port_request.url = GURL("http://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:118931 restricted_port_request.load_flags = 0;
8932
[email protected]d973e99a2012-02-17 21:02:368933 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118934 StaticSocketDataProvider first_data;
8935 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078936 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118937
8938 MockRead data_reads[] = {
8939 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8940 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068941 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118942 };
8943 StaticSocketDataProvider second_data(
8944 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078945 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118946
[email protected]bb88e1d32013-05-03 23:11:078947 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118948
[email protected]30d4c022013-07-18 22:58:168949 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538950 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118951 const int kUnrestrictedAlternatePort = 1024;
bnccacc0992015-03-20 20:22:228952 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:238953 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:228954 kUnrestrictedAlternatePort);
8955 http_server_properties->SetAlternativeService(
8956 HostPortPair::FromURL(restricted_port_request.url), alternative_service,
bnc1102b552015-01-30 20:11:018957 1.0);
[email protected]3912662a32011-10-04 00:51:118958
[email protected]262eec82013-03-19 21:01:368959 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508960 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418961 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118962
[email protected]49639fa2011-12-20 23:22:418963 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:368964 &restricted_port_request,
8965 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118966 EXPECT_EQ(ERR_IO_PENDING, rv);
8967 // Invalid change to unrestricted port should fail.
8968 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.WaitForResult());
[email protected]c54c6962013-02-01 04:53:198969}
[email protected]3912662a32011-10-04 00:51:118970
[email protected]23e482282013-06-14 16:08:028971TEST_P(HttpNetworkTransactionTest,
[email protected]c54c6962013-02-01 04:53:198972 AlternateProtocolPortRestrictedPermitted) {
8973 // Ensure that we're allowed to redirect traffic via an alternate
8974 // protocol to an unrestricted (port >= 1024) when the original traffic was
8975 // on a restricted port (port < 1024) if we set
8976 // enable_user_alternate_protocol_ports.
8977
[email protected]d7599122014-05-24 03:37:238978 session_deps_.use_alternate_protocols = true;
[email protected]bb88e1d32013-05-03 23:11:078979 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:198980
8981 HttpRequestInfo restricted_port_request;
8982 restricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:238983 restricted_port_request.url = GURL("http://www.example.org:1023/");
[email protected]c54c6962013-02-01 04:53:198984 restricted_port_request.load_flags = 0;
8985
8986 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
8987 StaticSocketDataProvider first_data;
8988 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078989 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:198990
8991 MockRead data_reads[] = {
8992 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8993 MockRead("hello world"),
8994 MockRead(ASYNC, OK),
8995 };
8996 StaticSocketDataProvider second_data(
8997 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078998 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]c54c6962013-02-01 04:53:198999
[email protected]bb88e1d32013-05-03 23:11:079000 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:199001
[email protected]30d4c022013-07-18 22:58:169002 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]c54c6962013-02-01 04:53:199003 session->http_server_properties();
9004 const int kUnrestrictedAlternatePort = 1024;
bnccacc0992015-03-20 20:22:229005 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239006 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229007 kUnrestrictedAlternatePort);
9008 http_server_properties->SetAlternativeService(
9009 HostPortPair::FromURL(restricted_port_request.url), alternative_service,
bnc1102b552015-01-30 20:11:019010 1.0);
[email protected]c54c6962013-02-01 04:53:199011
[email protected]262eec82013-03-19 21:01:369012 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509013 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]c54c6962013-02-01 04:53:199014 TestCompletionCallback callback;
9015
9016 EXPECT_EQ(ERR_IO_PENDING, trans->Start(
[email protected]262eec82013-03-19 21:01:369017 &restricted_port_request,
9018 callback.callback(), BoundNetLog()));
[email protected]c54c6962013-02-01 04:53:199019 // Change to unrestricted port should succeed.
9020 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:119021}
9022
[email protected]23e482282013-06-14 16:08:029023TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239024 AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:119025 // Ensure that we're not allowed to redirect traffic via an alternate
9026 // protocol to an unrestricted (port >= 1024) when the original traffic was
9027 // on a restricted port (port < 1024). Ensure that we can redirect in all
9028 // other cases.
[email protected]d7599122014-05-24 03:37:239029 session_deps_.use_alternate_protocols = true;
[email protected]3912662a32011-10-04 00:51:119030
9031 HttpRequestInfo restricted_port_request;
9032 restricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:239033 restricted_port_request.url = GURL("http://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:119034 restricted_port_request.load_flags = 0;
9035
[email protected]d973e99a2012-02-17 21:02:369036 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:119037 StaticSocketDataProvider first_data;
9038 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079039 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:119040
9041 MockRead data_reads[] = {
9042 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9043 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069044 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:119045 };
9046 StaticSocketDataProvider second_data(
9047 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079048 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:119049
[email protected]bb88e1d32013-05-03 23:11:079050 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:119051
[email protected]30d4c022013-07-18 22:58:169052 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:539053 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:119054 const int kRestrictedAlternatePort = 80;
bnccacc0992015-03-20 20:22:229055 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239056 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229057 kRestrictedAlternatePort);
9058 http_server_properties->SetAlternativeService(
9059 HostPortPair::FromURL(restricted_port_request.url), alternative_service,
bnc1102b552015-01-30 20:11:019060 1.0);
[email protected]3912662a32011-10-04 00:51:119061
[email protected]262eec82013-03-19 21:01:369062 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509063 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419064 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:119065
[email protected]49639fa2011-12-20 23:22:419066 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:369067 &restricted_port_request,
9068 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:119069 EXPECT_EQ(ERR_IO_PENDING, rv);
9070 // Valid change to restricted port should pass.
9071 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:119072}
9073
[email protected]23e482282013-06-14 16:08:029074TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239075 AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:119076 // Ensure that we're not allowed to redirect traffic via an alternate
9077 // protocol to an unrestricted (port >= 1024) when the original traffic was
9078 // on a restricted port (port < 1024). Ensure that we can redirect in all
9079 // other cases.
[email protected]d7599122014-05-24 03:37:239080 session_deps_.use_alternate_protocols = true;
[email protected]3912662a32011-10-04 00:51:119081
9082 HttpRequestInfo unrestricted_port_request;
9083 unrestricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:239084 unrestricted_port_request.url = GURL("http://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:119085 unrestricted_port_request.load_flags = 0;
9086
[email protected]d973e99a2012-02-17 21:02:369087 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:119088 StaticSocketDataProvider first_data;
9089 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079090 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:119091
9092 MockRead data_reads[] = {
9093 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9094 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069095 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:119096 };
9097 StaticSocketDataProvider second_data(
9098 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079099 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:119100
[email protected]bb88e1d32013-05-03 23:11:079101 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:119102
[email protected]30d4c022013-07-18 22:58:169103 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:539104 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:119105 const int kRestrictedAlternatePort = 80;
bnccacc0992015-03-20 20:22:229106 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239107 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229108 kRestrictedAlternatePort);
9109 http_server_properties->SetAlternativeService(
9110 HostPortPair::FromURL(unrestricted_port_request.url), alternative_service,
bnc1102b552015-01-30 20:11:019111 1.0);
[email protected]3912662a32011-10-04 00:51:119112
[email protected]262eec82013-03-19 21:01:369113 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509114 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419115 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:119116
[email protected]49639fa2011-12-20 23:22:419117 int rv = trans->Start(
9118 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:119119 EXPECT_EQ(ERR_IO_PENDING, rv);
9120 // Valid change to restricted port should pass.
9121 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:119122}
9123
[email protected]23e482282013-06-14 16:08:029124TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239125 AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:119126 // Ensure that we're not allowed to redirect traffic via an alternate
9127 // protocol to an unrestricted (port >= 1024) when the original traffic was
9128 // on a restricted port (port < 1024). Ensure that we can redirect in all
9129 // other cases.
[email protected]d7599122014-05-24 03:37:239130 session_deps_.use_alternate_protocols = true;
[email protected]3912662a32011-10-04 00:51:119131
9132 HttpRequestInfo unrestricted_port_request;
9133 unrestricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:239134 unrestricted_port_request.url = GURL("http://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:119135 unrestricted_port_request.load_flags = 0;
9136
[email protected]d973e99a2012-02-17 21:02:369137 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:119138 StaticSocketDataProvider first_data;
9139 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079140 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:119141
9142 MockRead data_reads[] = {
9143 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9144 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069145 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:119146 };
9147 StaticSocketDataProvider second_data(
9148 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079149 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:119150
[email protected]bb88e1d32013-05-03 23:11:079151 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:119152
[email protected]30d4c022013-07-18 22:58:169153 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:539154 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:119155 const int kUnrestrictedAlternatePort = 1024;
bnccacc0992015-03-20 20:22:229156 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239157 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229158 kUnrestrictedAlternatePort);
9159 http_server_properties->SetAlternativeService(
9160 HostPortPair::FromURL(unrestricted_port_request.url), alternative_service,
bnc1102b552015-01-30 20:11:019161 1.0);
[email protected]3912662a32011-10-04 00:51:119162
[email protected]262eec82013-03-19 21:01:369163 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509164 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419165 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:119166
[email protected]49639fa2011-12-20 23:22:419167 int rv = trans->Start(
9168 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:119169 EXPECT_EQ(ERR_IO_PENDING, rv);
9170 // Valid change to an unrestricted port should pass.
9171 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:119172}
9173
[email protected]d7599122014-05-24 03:37:239174TEST_P(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:029175 // Ensure that we're not allowed to redirect traffic via an alternate
9176 // protocol to an unsafe port, and that we resume the second
9177 // HttpStreamFactoryImpl::Job once the alternate protocol request fails.
[email protected]d7599122014-05-24 03:37:239178 session_deps_.use_alternate_protocols = true;
[email protected]eb6234e2012-01-19 01:50:029179
9180 HttpRequestInfo request;
9181 request.method = "GET";
bncce36dca22015-04-21 22:11:239182 request.url = GURL("http://www.example.org/");
[email protected]eb6234e2012-01-19 01:50:029183 request.load_flags = 0;
9184
9185 // The alternate protocol request will error out before we attempt to connect,
9186 // so only the standard HTTP request will try to connect.
9187 MockRead data_reads[] = {
9188 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9189 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069190 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:029191 };
9192 StaticSocketDataProvider data(
9193 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079194 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:029195
[email protected]bb88e1d32013-05-03 23:11:079196 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:029197
[email protected]30d4c022013-07-18 22:58:169198 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]eb6234e2012-01-19 01:50:029199 session->http_server_properties();
9200 const int kUnsafePort = 7;
bnccacc0992015-03-20 20:22:229201 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239202 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229203 kUnsafePort);
9204 http_server_properties->SetAlternativeService(
9205 HostPortPair::FromURL(request.url), alternative_service, 1.0);
[email protected]eb6234e2012-01-19 01:50:029206
[email protected]262eec82013-03-19 21:01:369207 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509208 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]eb6234e2012-01-19 01:50:029209 TestCompletionCallback callback;
9210
9211 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9212 EXPECT_EQ(ERR_IO_PENDING, rv);
9213 // The HTTP request should succeed.
9214 EXPECT_EQ(OK, callback.WaitForResult());
9215
9216 // Disable alternate protocol before the asserts.
[email protected]d7599122014-05-24 03:37:239217 // HttpStreamFactory::set_use_alternate_protocols(false);
[email protected]eb6234e2012-01-19 01:50:029218
9219 const HttpResponseInfo* response = trans->GetResponseInfo();
9220 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509221 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]eb6234e2012-01-19 01:50:029222 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9223
9224 std::string response_data;
9225 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9226 EXPECT_EQ("hello world", response_data);
9227}
9228
[email protected]23e482282013-06-14 16:08:029229TEST_P(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]d7599122014-05-24 03:37:239230 session_deps_.use_alternate_protocols = true;
9231 session_deps_.next_protos = SpdyNextProtos();
[email protected]2ff8b312010-04-26 22:20:549232
9233 HttpRequestInfo request;
9234 request.method = "GET";
bncce36dca22015-04-21 22:11:239235 request.url = GURL("http://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:549236 request.load_flags = 0;
9237
[email protected]8a0fc822013-06-27 20:52:439238 std::string alternate_protocol_http_header =
9239 GetAlternateProtocolHttpHeader();
9240
[email protected]2ff8b312010-04-26 22:20:549241 MockRead data_reads[] = {
9242 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439243 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2ff8b312010-04-26 22:20:549244 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:179245 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
9246 MockRead(ASYNC, OK)
[email protected]2ff8b312010-04-26 22:20:549247 };
9248
9249 StaticSocketDataProvider first_transaction(
9250 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079251 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:549252
[email protected]8ddf8322012-02-23 18:08:069253 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029254 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:239255 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
9256 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:079257 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:549258
[email protected]cdf8f7e72013-05-23 10:56:469259 scoped_ptr<SpdyFrame> req(
9260 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
rch8e6c6c42015-05-01 14:05:139261 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]2ff8b312010-04-26 22:20:549262
[email protected]23e482282013-06-14 16:08:029263 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9264 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:549265 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:139266 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:549267 };
9268
rch8e6c6c42015-05-01 14:05:139269 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9270 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079271 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:549272
[email protected]d973e99a2012-02-17 21:02:369273 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559274 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
9275 NULL, 0, NULL, 0);
9276 hanging_non_alternate_protocol_socket.set_connect_data(
9277 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:079278 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:559279 &hanging_non_alternate_protocol_socket);
9280
[email protected]49639fa2011-12-20 23:22:419281 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:549282
[email protected]bb88e1d32013-05-03 23:11:079283 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369284 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509285 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:549286
[email protected]49639fa2011-12-20 23:22:419287 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:549288 EXPECT_EQ(ERR_IO_PENDING, rv);
9289 EXPECT_EQ(OK, callback.WaitForResult());
9290
9291 const HttpResponseInfo* response = trans->GetResponseInfo();
9292 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509293 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:549294 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9295
9296 std::string response_data;
9297 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9298 EXPECT_EQ("hello world", response_data);
9299
[email protected]90499482013-06-01 00:39:509300 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:549301
[email protected]49639fa2011-12-20 23:22:419302 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:549303 EXPECT_EQ(ERR_IO_PENDING, rv);
9304 EXPECT_EQ(OK, callback.WaitForResult());
9305
9306 response = trans->GetResponseInfo();
9307 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509308 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:549309 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539310 EXPECT_TRUE(response->was_fetched_via_spdy);
9311 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:549312
9313 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9314 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:549315}
9316
[email protected]23e482282013-06-14 16:08:029317TEST_P(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]d7599122014-05-24 03:37:239318 session_deps_.use_alternate_protocols = true;
9319 session_deps_.next_protos = SpdyNextProtos();
[email protected]2d6728692011-03-12 01:39:559320
9321 HttpRequestInfo request;
9322 request.method = "GET";
bncce36dca22015-04-21 22:11:239323 request.url = GURL("http://www.example.org/");
[email protected]2d6728692011-03-12 01:39:559324 request.load_flags = 0;
9325
[email protected]8a0fc822013-06-27 20:52:439326 std::string alternate_protocol_http_header =
9327 GetAlternateProtocolHttpHeader();
9328
[email protected]2d6728692011-03-12 01:39:559329 MockRead data_reads[] = {
9330 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439331 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2d6728692011-03-12 01:39:559332 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:179333 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:069334 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:559335 };
9336
9337 StaticSocketDataProvider first_transaction(
9338 data_reads, arraysize(data_reads), NULL, 0);
9339 // Socket 1 is the HTTP transaction with the Alternate-Protocol header.
[email protected]bb88e1d32013-05-03 23:11:079340 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:559341
[email protected]d973e99a2012-02-17 21:02:369342 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559343 StaticSocketDataProvider hanging_socket(
9344 NULL, 0, NULL, 0);
9345 hanging_socket.set_connect_data(never_finishing_connect);
9346 // Socket 2 and 3 are the hanging Alternate-Protocol and
9347 // non-Alternate-Protocol jobs from the 2nd transaction.
[email protected]bb88e1d32013-05-03 23:11:079348 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
9349 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
[email protected]2d6728692011-03-12 01:39:559350
[email protected]8ddf8322012-02-23 18:08:069351 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029352 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:239353 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
9354 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:079355 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:559356
[email protected]cdf8f7e72013-05-23 10:56:469357 scoped_ptr<SpdyFrame> req1(
9358 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
9359 scoped_ptr<SpdyFrame> req2(
9360 spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
[email protected]2d6728692011-03-12 01:39:559361 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:139362 CreateMockWrite(*req1, 0), CreateMockWrite(*req2, 1),
[email protected]2d6728692011-03-12 01:39:559363 };
[email protected]23e482282013-06-14 16:08:029364 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9365 scoped_ptr<SpdyFrame> data1(spdy_util_.ConstructSpdyBodyFrame(1, true));
9366 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
9367 scoped_ptr<SpdyFrame> data2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]2d6728692011-03-12 01:39:559368 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:139369 CreateMockRead(*resp1, 2),
9370 CreateMockRead(*data1, 3),
9371 CreateMockRead(*resp2, 4),
9372 CreateMockRead(*data2, 5),
9373 MockRead(ASYNC, 0, 6),
[email protected]2d6728692011-03-12 01:39:559374 };
9375
rch8e6c6c42015-05-01 14:05:139376 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9377 arraysize(spdy_writes));
[email protected]2d6728692011-03-12 01:39:559378 // Socket 4 is the successful Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:079379 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:559380
9381 // Socket 5 is the unsuccessful non-Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:079382 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
[email protected]2d6728692011-03-12 01:39:559383
[email protected]bb88e1d32013-05-03 23:11:079384 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:419385 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:509386 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:559387
[email protected]49639fa2011-12-20 23:22:419388 int rv = trans1.Start(&request, callback1.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559389 EXPECT_EQ(ERR_IO_PENDING, rv);
9390 EXPECT_EQ(OK, callback1.WaitForResult());
9391
9392 const HttpResponseInfo* response = trans1.GetResponseInfo();
9393 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509394 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559395 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9396
9397 std::string response_data;
9398 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
9399 EXPECT_EQ("hello world", response_data);
9400
[email protected]49639fa2011-12-20 23:22:419401 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:509402 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:419403 rv = trans2.Start(&request, callback2.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559404 EXPECT_EQ(ERR_IO_PENDING, rv);
9405
[email protected]49639fa2011-12-20 23:22:419406 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:509407 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:419408 rv = trans3.Start(&request, callback3.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559409 EXPECT_EQ(ERR_IO_PENDING, rv);
9410
9411 EXPECT_EQ(OK, callback2.WaitForResult());
9412 EXPECT_EQ(OK, callback3.WaitForResult());
9413
9414 response = trans2.GetResponseInfo();
9415 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509416 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559417 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9418 EXPECT_TRUE(response->was_fetched_via_spdy);
9419 EXPECT_TRUE(response->was_npn_negotiated);
9420 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
9421 EXPECT_EQ("hello!", response_data);
9422
9423 response = trans3.GetResponseInfo();
9424 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509425 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559426 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9427 EXPECT_TRUE(response->was_fetched_via_spdy);
9428 EXPECT_TRUE(response->was_npn_negotiated);
9429 ASSERT_EQ(OK, ReadTransaction(&trans3, &response_data));
9430 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:559431}
9432
[email protected]23e482282013-06-14 16:08:029433TEST_P(HttpNetworkTransactionTest, StallAlternateProtocolForNpnSpdy) {
[email protected]d7599122014-05-24 03:37:239434 session_deps_.use_alternate_protocols = true;
9435 session_deps_.next_protos = SpdyNextProtos();
[email protected]2d6728692011-03-12 01:39:559436
9437 HttpRequestInfo request;
9438 request.method = "GET";
bncce36dca22015-04-21 22:11:239439 request.url = GURL("http://www.example.org/");
[email protected]2d6728692011-03-12 01:39:559440 request.load_flags = 0;
9441
[email protected]8a0fc822013-06-27 20:52:439442 std::string alternate_protocol_http_header =
9443 GetAlternateProtocolHttpHeader();
9444
[email protected]2d6728692011-03-12 01:39:559445 MockRead data_reads[] = {
9446 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439447 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2d6728692011-03-12 01:39:559448 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:179449 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:069450 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:559451 };
9452
9453 StaticSocketDataProvider first_transaction(
9454 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079455 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:559456
[email protected]8ddf8322012-02-23 18:08:069457 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029458 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:079459 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:559460
[email protected]d973e99a2012-02-17 21:02:369461 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559462 StaticSocketDataProvider hanging_alternate_protocol_socket(
9463 NULL, 0, NULL, 0);
9464 hanging_alternate_protocol_socket.set_connect_data(
9465 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:079466 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:559467 &hanging_alternate_protocol_socket);
9468
9469 // 2nd request is just a copy of the first one, over HTTP again.
[email protected]bb88e1d32013-05-03 23:11:079470 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:559471
[email protected]49639fa2011-12-20 23:22:419472 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:559473
[email protected]bb88e1d32013-05-03 23:11:079474 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369475 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509476 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:559477
[email protected]49639fa2011-12-20 23:22:419478 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559479 EXPECT_EQ(ERR_IO_PENDING, rv);
9480 EXPECT_EQ(OK, callback.WaitForResult());
9481
9482 const HttpResponseInfo* response = trans->GetResponseInfo();
9483 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509484 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559485 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9486
9487 std::string response_data;
9488 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9489 EXPECT_EQ("hello world", response_data);
9490
[email protected]90499482013-06-01 00:39:509491 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:559492
[email protected]49639fa2011-12-20 23:22:419493 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559494 EXPECT_EQ(ERR_IO_PENDING, rv);
9495 EXPECT_EQ(OK, callback.WaitForResult());
9496
9497 response = trans->GetResponseInfo();
9498 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509499 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559500 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9501 EXPECT_FALSE(response->was_fetched_via_spdy);
9502 EXPECT_FALSE(response->was_npn_negotiated);
9503
9504 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9505 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:559506}
9507
[email protected]631f1322010-04-30 17:59:119508class CapturingProxyResolver : public ProxyResolver {
9509 public:
9510 CapturingProxyResolver() : ProxyResolver(false /* expects_pac_bytes */) {}
dchengb03027d2014-10-21 12:00:209511 ~CapturingProxyResolver() override {}
[email protected]631f1322010-04-30 17:59:119512
dchengb03027d2014-10-21 12:00:209513 int GetProxyForURL(const GURL& url,
9514 ProxyInfo* results,
9515 const CompletionCallback& callback,
9516 RequestHandle* request,
9517 const BoundNetLog& net_log) override {
[email protected]fae7669f2010-08-02 21:49:409518 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
9519 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:429520 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:119521 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:429522 return OK;
[email protected]631f1322010-04-30 17:59:119523 }
9524
dchengb03027d2014-10-21 12:00:209525 void CancelRequest(RequestHandle request) override { NOTREACHED(); }
[email protected]631f1322010-04-30 17:59:119526
dchengb03027d2014-10-21 12:00:209527 LoadState GetLoadState(RequestHandle request) const override {
[email protected]f2c971f2011-11-08 00:33:179528 NOTREACHED();
9529 return LOAD_STATE_IDLE;
9530 }
9531
dchengb03027d2014-10-21 12:00:209532 void CancelSetPacScript() override { NOTREACHED(); }
[email protected]1e605472010-12-16 21:41:409533
dchengb03027d2014-10-21 12:00:209534 int SetPacScript(const scoped_refptr<ProxyResolverScriptData>&,
9535 const CompletionCallback& /*callback*/) override {
[email protected]d911f1b2010-05-05 22:39:429536 return OK;
[email protected]631f1322010-04-30 17:59:119537 }
9538
[email protected]24476402010-07-20 20:55:179539 const std::vector<GURL>& resolved() const { return resolved_; }
9540
9541 private:
[email protected]631f1322010-04-30 17:59:119542 std::vector<GURL> resolved_;
9543
9544 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
9545};
9546
sammce64b2362015-04-29 03:50:239547class CapturingProxyResolverFactory : public ProxyResolverFactory {
9548 public:
9549 explicit CapturingProxyResolverFactory(CapturingProxyResolver* resolver)
9550 : ProxyResolverFactory(false), resolver_(resolver) {}
9551
9552 int CreateProxyResolver(
9553 const scoped_refptr<ProxyResolverScriptData>& pac_script,
9554 scoped_ptr<ProxyResolver>* resolver,
9555 const net::CompletionCallback& callback,
9556 scoped_ptr<Request>* request) override {
9557 resolver->reset(new ForwardingProxyResolver(resolver_));
9558 return OK;
9559 }
9560
9561 private:
9562 ProxyResolver* resolver_;
9563};
9564
[email protected]23e482282013-06-14 16:08:029565TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239566 UseAlternateProtocolForTunneledNpnSpdy) {
[email protected]d7599122014-05-24 03:37:239567 session_deps_.use_alternate_protocols = true;
9568 session_deps_.next_protos = SpdyNextProtos();
[email protected]631f1322010-04-30 17:59:119569
9570 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:429571 proxy_config.set_auto_detect(true);
9572 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:119573
sammc5dd160c2015-04-02 02:43:139574 CapturingProxyResolver capturing_proxy_resolver;
[email protected]bb88e1d32013-05-03 23:11:079575 session_deps_.proxy_service.reset(new ProxyService(
sammc5dd160c2015-04-02 02:43:139576 new ProxyConfigServiceFixed(proxy_config),
9577 make_scoped_ptr(
sammce64b2362015-04-29 03:50:239578 new CapturingProxyResolverFactory(&capturing_proxy_resolver)),
[email protected]66761b952010-06-25 21:30:389579 NULL));
vishal.b62985ca92015-04-17 08:45:519580 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079581 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:119582
9583 HttpRequestInfo request;
9584 request.method = "GET";
bncce36dca22015-04-21 22:11:239585 request.url = GURL("http://www.example.org/");
[email protected]631f1322010-04-30 17:59:119586 request.load_flags = 0;
9587
[email protected]8a0fc822013-06-27 20:52:439588 std::string alternate_protocol_http_header =
9589 GetAlternateProtocolHttpHeader();
9590
[email protected]631f1322010-04-30 17:59:119591 MockRead data_reads[] = {
9592 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439593 MockRead(alternate_protocol_http_header.c_str()),
[email protected]631f1322010-04-30 17:59:119594 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:179595 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:069596 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:119597 };
9598
9599 StaticSocketDataProvider first_transaction(
9600 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079601 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]631f1322010-04-30 17:59:119602
[email protected]8ddf8322012-02-23 18:08:069603 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029604 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:239605 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
9606 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:079607 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]631f1322010-04-30 17:59:119608
[email protected]cdf8f7e72013-05-23 10:56:469609 scoped_ptr<SpdyFrame> req(
9610 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]631f1322010-04-30 17:59:119611 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:139612 MockWrite(ASYNC, 0,
9613 "CONNECT www.example.org:443 HTTP/1.1\r\n"
9614 "Host: www.example.org\r\n"
9615 "Proxy-Connection: keep-alive\r\n\r\n"),
9616 CreateMockWrite(*req, 2),
[email protected]631f1322010-04-30 17:59:119617 };
9618
[email protected]d911f1b2010-05-05 22:39:429619 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
9620
[email protected]23e482282013-06-14 16:08:029621 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9622 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]631f1322010-04-30 17:59:119623 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:139624 MockRead(ASYNC, 1, kCONNECTResponse),
9625 CreateMockRead(*resp.get(), 3),
9626 CreateMockRead(*data.get(), 4),
9627 MockRead(ASYNC, ERR_IO_PENDING, 5),
[email protected]631f1322010-04-30 17:59:119628 };
9629
rch8e6c6c42015-05-01 14:05:139630 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9631 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079632 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:119633
[email protected]d973e99a2012-02-17 21:02:369634 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559635 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
9636 NULL, 0, NULL, 0);
9637 hanging_non_alternate_protocol_socket.set_connect_data(
9638 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:079639 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:559640 &hanging_non_alternate_protocol_socket);
9641
[email protected]49639fa2011-12-20 23:22:419642 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:119643
[email protected]bb88e1d32013-05-03 23:11:079644 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369645 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509646 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:119647
[email protected]49639fa2011-12-20 23:22:419648 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:119649 EXPECT_EQ(ERR_IO_PENDING, rv);
9650 EXPECT_EQ(OK, callback.WaitForResult());
9651
9652 const HttpResponseInfo* response = trans->GetResponseInfo();
9653 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509654 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]631f1322010-04-30 17:59:119655 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539656 EXPECT_FALSE(response->was_fetched_via_spdy);
9657 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:119658
9659 std::string response_data;
9660 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9661 EXPECT_EQ("hello world", response_data);
9662
[email protected]90499482013-06-01 00:39:509663 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:119664
[email protected]49639fa2011-12-20 23:22:419665 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:119666 EXPECT_EQ(ERR_IO_PENDING, rv);
9667 EXPECT_EQ(OK, callback.WaitForResult());
9668
9669 response = trans->GetResponseInfo();
9670 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509671 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]631f1322010-04-30 17:59:119672 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539673 EXPECT_TRUE(response->was_fetched_via_spdy);
9674 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:119675
9676 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9677 EXPECT_EQ("hello!", response_data);
sammc5dd160c2015-04-02 02:43:139678 ASSERT_EQ(3u, capturing_proxy_resolver.resolved().size());
bncce36dca22015-04-21 22:11:239679 EXPECT_EQ("http://www.example.org/",
sammc5dd160c2015-04-02 02:43:139680 capturing_proxy_resolver.resolved()[0].spec());
bncce36dca22015-04-21 22:11:239681 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:139682 capturing_proxy_resolver.resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:119683
[email protected]029c83b62013-01-24 05:28:209684 LoadTimingInfo load_timing_info;
9685 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
9686 TestLoadTimingNotReusedWithPac(load_timing_info,
9687 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:119688}
[email protected]631f1322010-04-30 17:59:119689
[email protected]23e482282013-06-14 16:08:029690TEST_P(HttpNetworkTransactionTest,
[email protected]2ff8b312010-04-26 22:20:549691 UseAlternateProtocolForNpnSpdyWithExistingSpdySession) {
[email protected]d7599122014-05-24 03:37:239692 session_deps_.use_alternate_protocols = true;
9693 session_deps_.next_protos = SpdyNextProtos();
[email protected]2ff8b312010-04-26 22:20:549694
9695 HttpRequestInfo request;
9696 request.method = "GET";
bncce36dca22015-04-21 22:11:239697 request.url = GURL("http://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:549698 request.load_flags = 0;
9699
[email protected]8a0fc822013-06-27 20:52:439700 std::string alternate_protocol_http_header =
9701 GetAlternateProtocolHttpHeader();
9702
[email protected]2ff8b312010-04-26 22:20:549703 MockRead data_reads[] = {
9704 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439705 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2ff8b312010-04-26 22:20:549706 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069707 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:549708 };
9709
9710 StaticSocketDataProvider first_transaction(
9711 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079712 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:549713
[email protected]8ddf8322012-02-23 18:08:069714 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029715 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:239716 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
9717 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:079718 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:549719
[email protected]cdf8f7e72013-05-23 10:56:469720 scoped_ptr<SpdyFrame> req(
9721 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
rch8e6c6c42015-05-01 14:05:139722 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]2ff8b312010-04-26 22:20:549723
[email protected]23e482282013-06-14 16:08:029724 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9725 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:549726 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:139727 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:549728 };
9729
rch8e6c6c42015-05-01 14:05:139730 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9731 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079732 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:549733
[email protected]83039bb2011-12-09 18:43:559734 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:549735
[email protected]bb88e1d32013-05-03 23:11:079736 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:549737
[email protected]262eec82013-03-19 21:01:369738 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509739 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:549740
[email protected]49639fa2011-12-20 23:22:419741 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:549742 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:419743 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:549744
9745 const HttpResponseInfo* response = trans->GetResponseInfo();
9746 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509747 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:549748 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9749
9750 std::string response_data;
9751 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9752 EXPECT_EQ("hello world", response_data);
9753
9754 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:239755 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:409756 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:539757 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:279758 base::WeakPtr<SpdySession> spdy_session =
[email protected]41d64e82013-07-03 22:44:269759 CreateSecureSpdySession(session, key, BoundNetLog());
[email protected]02b0c342010-09-25 21:09:389760
[email protected]90499482013-06-01 00:39:509761 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:549762
[email protected]49639fa2011-12-20 23:22:419763 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:549764 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:419765 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:549766
9767 response = trans->GetResponseInfo();
9768 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509769 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:549770 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539771 EXPECT_TRUE(response->was_fetched_via_spdy);
9772 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:549773
9774 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9775 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:429776}
9777
[email protected]044de0642010-06-17 10:42:159778// GenerateAuthToken is a mighty big test.
9779// It tests all permutation of GenerateAuthToken behavior:
9780// - Synchronous and Asynchronous completion.
9781// - OK or error on completion.
9782// - Direct connection, non-authenticating proxy, and authenticating proxy.
9783// - HTTP or HTTPS backend (to include proxy tunneling).
9784// - Non-authenticating and authenticating backend.
9785//
[email protected]fe3b7dc2012-02-03 19:52:099786// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:159787// problems generating an auth token for an authenticating proxy, we don't
9788// need to test all permutations of the backend server).
9789//
9790// The test proceeds by going over each of the configuration cases, and
9791// potentially running up to three rounds in each of the tests. The TestConfig
9792// specifies both the configuration for the test as well as the expectations
9793// for the results.
[email protected]23e482282013-06-14 16:08:029794TEST_P(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:509795 static const char kServer[] = "http://www.example.com";
9796 static const char kSecureServer[] = "https://www.example.com";
9797 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:159798 const int kAuthErr = ERR_INVALID_AUTH_CREDENTIALS;
9799
9800 enum AuthTiming {
9801 AUTH_NONE,
9802 AUTH_SYNC,
9803 AUTH_ASYNC,
9804 };
9805
9806 const MockWrite kGet(
9807 "GET / HTTP/1.1\r\n"
9808 "Host: www.example.com\r\n"
9809 "Connection: keep-alive\r\n\r\n");
9810 const MockWrite kGetProxy(
9811 "GET http://www.example.com/ HTTP/1.1\r\n"
9812 "Host: www.example.com\r\n"
9813 "Proxy-Connection: keep-alive\r\n\r\n");
9814 const MockWrite kGetAuth(
9815 "GET / HTTP/1.1\r\n"
9816 "Host: www.example.com\r\n"
9817 "Connection: keep-alive\r\n"
9818 "Authorization: auth_token\r\n\r\n");
9819 const MockWrite kGetProxyAuth(
9820 "GET http://www.example.com/ HTTP/1.1\r\n"
9821 "Host: www.example.com\r\n"
9822 "Proxy-Connection: keep-alive\r\n"
9823 "Proxy-Authorization: auth_token\r\n\r\n");
9824 const MockWrite kGetAuthThroughProxy(
9825 "GET http://www.example.com/ HTTP/1.1\r\n"
9826 "Host: www.example.com\r\n"
9827 "Proxy-Connection: keep-alive\r\n"
9828 "Authorization: auth_token\r\n\r\n");
9829 const MockWrite kGetAuthWithProxyAuth(
9830 "GET http://www.example.com/ HTTP/1.1\r\n"
9831 "Host: www.example.com\r\n"
9832 "Proxy-Connection: keep-alive\r\n"
9833 "Proxy-Authorization: auth_token\r\n"
9834 "Authorization: auth_token\r\n\r\n");
9835 const MockWrite kConnect(
9836 "CONNECT www.example.com:443 HTTP/1.1\r\n"
9837 "Host: www.example.com\r\n"
9838 "Proxy-Connection: keep-alive\r\n\r\n");
9839 const MockWrite kConnectProxyAuth(
9840 "CONNECT www.example.com:443 HTTP/1.1\r\n"
9841 "Host: www.example.com\r\n"
9842 "Proxy-Connection: keep-alive\r\n"
9843 "Proxy-Authorization: auth_token\r\n\r\n");
9844
9845 const MockRead kSuccess(
9846 "HTTP/1.1 200 OK\r\n"
9847 "Content-Type: text/html; charset=iso-8859-1\r\n"
9848 "Content-Length: 3\r\n\r\n"
9849 "Yes");
9850 const MockRead kFailure(
9851 "Should not be called.");
9852 const MockRead kServerChallenge(
9853 "HTTP/1.1 401 Unauthorized\r\n"
9854 "WWW-Authenticate: Mock realm=server\r\n"
9855 "Content-Type: text/html; charset=iso-8859-1\r\n"
9856 "Content-Length: 14\r\n\r\n"
9857 "Unauthorized\r\n");
9858 const MockRead kProxyChallenge(
9859 "HTTP/1.1 407 Unauthorized\r\n"
9860 "Proxy-Authenticate: Mock realm=proxy\r\n"
9861 "Proxy-Connection: close\r\n"
9862 "Content-Type: text/html; charset=iso-8859-1\r\n"
9863 "Content-Length: 14\r\n\r\n"
9864 "Unauthorized\r\n");
9865 const MockRead kProxyConnected(
9866 "HTTP/1.1 200 Connection Established\r\n\r\n");
9867
9868 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
9869 // no constructors, but the C++ compiler on Windows warns about
9870 // unspecified data in compound literals. So, moved to using constructors,
9871 // and TestRound's created with the default constructor should not be used.
9872 struct TestRound {
9873 TestRound()
9874 : expected_rv(ERR_UNEXPECTED),
9875 extra_write(NULL),
9876 extra_read(NULL) {
9877 }
9878 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
9879 int expected_rv_arg)
9880 : write(write_arg),
9881 read(read_arg),
9882 expected_rv(expected_rv_arg),
9883 extra_write(NULL),
9884 extra_read(NULL) {
9885 }
9886 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
9887 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:019888 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:159889 : write(write_arg),
9890 read(read_arg),
9891 expected_rv(expected_rv_arg),
9892 extra_write(extra_write_arg),
9893 extra_read(extra_read_arg) {
9894 }
9895 MockWrite write;
9896 MockRead read;
9897 int expected_rv;
9898 const MockWrite* extra_write;
9899 const MockRead* extra_read;
9900 };
9901
9902 static const int kNoSSL = 500;
9903
9904 struct TestConfig {
thestig9d3bb0c2015-01-24 00:49:519905 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:159906 AuthTiming proxy_auth_timing;
9907 int proxy_auth_rv;
thestig9d3bb0c2015-01-24 00:49:519908 const char* const server_url;
[email protected]044de0642010-06-17 10:42:159909 AuthTiming server_auth_timing;
9910 int server_auth_rv;
9911 int num_auth_rounds;
9912 int first_ssl_round;
9913 TestRound rounds[3];
9914 } test_configs[] = {
9915 // Non-authenticating HTTP server with a direct connection.
9916 { NULL, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
9917 { TestRound(kGet, kSuccess, OK)}},
9918 // Authenticating HTTP server with a direct connection.
9919 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
9920 { TestRound(kGet, kServerChallenge, OK),
9921 TestRound(kGetAuth, kSuccess, OK)}},
9922 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
9923 { TestRound(kGet, kServerChallenge, OK),
9924 TestRound(kGetAuth, kFailure, kAuthErr)}},
9925 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
9926 { TestRound(kGet, kServerChallenge, OK),
9927 TestRound(kGetAuth, kSuccess, OK)}},
9928 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
9929 { TestRound(kGet, kServerChallenge, OK),
9930 TestRound(kGetAuth, kFailure, kAuthErr)}},
9931 // Non-authenticating HTTP server through a non-authenticating proxy.
9932 { kProxy, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
9933 { TestRound(kGetProxy, kSuccess, OK)}},
9934 // Authenticating HTTP server through a non-authenticating proxy.
9935 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
9936 { TestRound(kGetProxy, kServerChallenge, OK),
9937 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
9938 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
9939 { TestRound(kGetProxy, kServerChallenge, OK),
9940 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
9941 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
9942 { TestRound(kGetProxy, kServerChallenge, OK),
9943 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
9944 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
9945 { TestRound(kGetProxy, kServerChallenge, OK),
9946 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
9947 // Non-authenticating HTTP server through an authenticating proxy.
9948 { kProxy, AUTH_SYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
9949 { TestRound(kGetProxy, kProxyChallenge, OK),
9950 TestRound(kGetProxyAuth, kSuccess, OK)}},
9951 { kProxy, AUTH_SYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
9952 { TestRound(kGetProxy, kProxyChallenge, OK),
9953 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
9954 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
9955 { TestRound(kGetProxy, kProxyChallenge, OK),
9956 TestRound(kGetProxyAuth, kSuccess, OK)}},
9957 { kProxy, AUTH_ASYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
9958 { TestRound(kGetProxy, kProxyChallenge, OK),
9959 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
9960 // Authenticating HTTP server through an authenticating proxy.
9961 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
9962 { TestRound(kGetProxy, kProxyChallenge, OK),
9963 TestRound(kGetProxyAuth, kServerChallenge, OK),
9964 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9965 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
9966 { TestRound(kGetProxy, kProxyChallenge, OK),
9967 TestRound(kGetProxyAuth, kServerChallenge, OK),
9968 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9969 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
9970 { TestRound(kGetProxy, kProxyChallenge, OK),
9971 TestRound(kGetProxyAuth, kServerChallenge, OK),
9972 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9973 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
9974 { TestRound(kGetProxy, kProxyChallenge, OK),
9975 TestRound(kGetProxyAuth, kServerChallenge, OK),
9976 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9977 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
9978 { TestRound(kGetProxy, kProxyChallenge, OK),
9979 TestRound(kGetProxyAuth, kServerChallenge, OK),
9980 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9981 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
9982 { TestRound(kGetProxy, kProxyChallenge, OK),
9983 TestRound(kGetProxyAuth, kServerChallenge, OK),
9984 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9985 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
9986 { TestRound(kGetProxy, kProxyChallenge, OK),
9987 TestRound(kGetProxyAuth, kServerChallenge, OK),
9988 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9989 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
9990 { TestRound(kGetProxy, kProxyChallenge, OK),
9991 TestRound(kGetProxyAuth, kServerChallenge, OK),
9992 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9993 // Non-authenticating HTTPS server with a direct connection.
9994 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
9995 { TestRound(kGet, kSuccess, OK)}},
9996 // Authenticating HTTPS server with a direct connection.
9997 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
9998 { TestRound(kGet, kServerChallenge, OK),
9999 TestRound(kGetAuth, kSuccess, OK)}},
10000 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
10001 { TestRound(kGet, kServerChallenge, OK),
10002 TestRound(kGetAuth, kFailure, kAuthErr)}},
10003 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
10004 { TestRound(kGet, kServerChallenge, OK),
10005 TestRound(kGetAuth, kSuccess, OK)}},
10006 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
10007 { TestRound(kGet, kServerChallenge, OK),
10008 TestRound(kGetAuth, kFailure, kAuthErr)}},
10009 // Non-authenticating HTTPS server with a non-authenticating proxy.
10010 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
10011 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
10012 // Authenticating HTTPS server through a non-authenticating proxy.
10013 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
10014 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
10015 TestRound(kGetAuth, kSuccess, OK)}},
10016 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
10017 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
10018 TestRound(kGetAuth, kFailure, kAuthErr)}},
10019 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
10020 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
10021 TestRound(kGetAuth, kSuccess, OK)}},
10022 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
10023 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
10024 TestRound(kGetAuth, kFailure, kAuthErr)}},
10025 // Non-Authenticating HTTPS server through an authenticating proxy.
10026 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
10027 { TestRound(kConnect, kProxyChallenge, OK),
10028 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
10029 { kProxy, AUTH_SYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
10030 { TestRound(kConnect, kProxyChallenge, OK),
10031 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
10032 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
10033 { TestRound(kConnect, kProxyChallenge, OK),
10034 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
10035 { kProxy, AUTH_ASYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
10036 { TestRound(kConnect, kProxyChallenge, OK),
10037 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
10038 // Authenticating HTTPS server through an authenticating proxy.
10039 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
10040 { TestRound(kConnect, kProxyChallenge, OK),
10041 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10042 &kGet, &kServerChallenge),
10043 TestRound(kGetAuth, kSuccess, OK)}},
10044 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
10045 { TestRound(kConnect, kProxyChallenge, OK),
10046 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10047 &kGet, &kServerChallenge),
10048 TestRound(kGetAuth, kFailure, kAuthErr)}},
10049 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
10050 { TestRound(kConnect, kProxyChallenge, OK),
10051 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10052 &kGet, &kServerChallenge),
10053 TestRound(kGetAuth, kSuccess, OK)}},
10054 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
10055 { TestRound(kConnect, kProxyChallenge, OK),
10056 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10057 &kGet, &kServerChallenge),
10058 TestRound(kGetAuth, kFailure, kAuthErr)}},
10059 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
10060 { TestRound(kConnect, kProxyChallenge, OK),
10061 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10062 &kGet, &kServerChallenge),
10063 TestRound(kGetAuth, kSuccess, OK)}},
10064 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
10065 { TestRound(kConnect, kProxyChallenge, OK),
10066 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10067 &kGet, &kServerChallenge),
10068 TestRound(kGetAuth, kFailure, kAuthErr)}},
10069 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
10070 { TestRound(kConnect, kProxyChallenge, OK),
10071 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10072 &kGet, &kServerChallenge),
10073 TestRound(kGetAuth, kSuccess, OK)}},
10074 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
10075 { TestRound(kConnect, kProxyChallenge, OK),
10076 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10077 &kGet, &kServerChallenge),
10078 TestRound(kGetAuth, kFailure, kAuthErr)}},
10079 };
10080
viettrungluue4a8b882014-10-16 06:17:3810081 for (size_t i = 0; i < arraysize(test_configs); ++i) {
[email protected]2d01c262011-08-11 23:07:0810082 HttpAuthHandlerMock::Factory* auth_factory(
10083 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0710084 session_deps_.http_auth_handler_factory.reset(auth_factory);
[email protected]044de0642010-06-17 10:42:1510085 const TestConfig& test_config = test_configs[i];
[email protected]65d34382010-07-01 18:12:2610086
10087 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:1510088 if (test_config.proxy_auth_timing != AUTH_NONE) {
[email protected]2d01c262011-08-11 23:07:0810089 for (int n = 0; n < 2; n++) {
10090 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
10091 std::string auth_challenge = "Mock realm=proxy";
10092 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:2410093 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
10094 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:0810095 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
10096 origin, BoundNetLog());
10097 auth_handler->SetGenerateExpectation(
10098 test_config.proxy_auth_timing == AUTH_ASYNC,
10099 test_config.proxy_auth_rv);
10100 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
10101 }
[email protected]044de0642010-06-17 10:42:1510102 }
10103 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:0010104 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:1510105 std::string auth_challenge = "Mock realm=server";
10106 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:2410107 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
10108 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:1510109 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
10110 origin, BoundNetLog());
10111 auth_handler->SetGenerateExpectation(
10112 test_config.server_auth_timing == AUTH_ASYNC,
10113 test_config.server_auth_rv);
[email protected]2d01c262011-08-11 23:07:0810114 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:1510115 }
10116 if (test_config.proxy_url) {
[email protected]bb88e1d32013-05-03 23:11:0710117 session_deps_.proxy_service.reset(
[email protected]6104ea5d2011-04-27 21:37:1210118 ProxyService::CreateFixed(test_config.proxy_url));
[email protected]044de0642010-06-17 10:42:1510119 } else {
[email protected]bb88e1d32013-05-03 23:11:0710120 session_deps_.proxy_service.reset(ProxyService::CreateDirect());
[email protected]044de0642010-06-17 10:42:1510121 }
10122
10123 HttpRequestInfo request;
10124 request.method = "GET";
10125 request.url = GURL(test_config.server_url);
10126 request.load_flags = 0;
10127
[email protected]bb88e1d32013-05-03 23:11:0710128 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
dcheng48459ac22014-08-26 00:46:4110129 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]044de0642010-06-17 10:42:1510130
10131 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
10132 const TestRound& read_write_round = test_config.rounds[round];
10133
10134 // Set up expected reads and writes.
10135 MockRead reads[2];
10136 reads[0] = read_write_round.read;
10137 size_t length_reads = 1;
10138 if (read_write_round.extra_read) {
10139 reads[1] = *read_write_round.extra_read;
10140 length_reads = 2;
10141 }
10142
10143 MockWrite writes[2];
10144 writes[0] = read_write_round.write;
10145 size_t length_writes = 1;
10146 if (read_write_round.extra_write) {
10147 writes[1] = *read_write_round.extra_write;
10148 length_writes = 2;
10149 }
10150 StaticSocketDataProvider data_provider(
10151 reads, length_reads, writes, length_writes);
[email protected]bb88e1d32013-05-03 23:11:0710152 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]044de0642010-06-17 10:42:1510153
10154 // Add an SSL sequence if necessary.
[email protected]8ddf8322012-02-23 18:08:0610155 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
[email protected]044de0642010-06-17 10:42:1510156 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0710157 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1510158 &ssl_socket_data_provider);
10159
10160 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4110161 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1510162 int rv;
10163 if (round == 0) {
[email protected]49639fa2011-12-20 23:22:4110164 rv = trans.Start(&request, callback.callback(), BoundNetLog());
[email protected]044de0642010-06-17 10:42:1510165 } else {
[email protected]49639fa2011-12-20 23:22:4110166 rv = trans.RestartWithAuth(
10167 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1510168 }
10169 if (rv == ERR_IO_PENDING)
10170 rv = callback.WaitForResult();
10171
10172 // Compare results with expected data.
10173 EXPECT_EQ(read_write_round.expected_rv, rv);
[email protected]0b0bf032010-09-21 18:08:5010174 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttlec0c828492015-05-15 01:25:5510175 if (read_write_round.expected_rv != OK) {
[email protected]044de0642010-06-17 10:42:1510176 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
10177 continue;
10178 }
10179 if (round + 1 < test_config.num_auth_rounds) {
10180 EXPECT_FALSE(response->auth_challenge.get() == NULL);
10181 } else {
10182 EXPECT_TRUE(response->auth_challenge.get() == NULL);
10183 }
10184 }
[email protected]e5ae96a2010-04-14 20:12:4510185 }
10186}
10187
[email protected]23e482282013-06-14 16:08:0210188TEST_P(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1410189 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1410190 HttpAuthHandlerMock::Factory* auth_factory(
10191 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0710192 session_deps_.http_auth_handler_factory.reset(auth_factory);
10193 session_deps_.proxy_service.reset(ProxyService::CreateDirect());
10194 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
10195 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:1410196
10197 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
10198 auth_handler->set_connection_based(true);
10199 std::string auth_challenge = "Mock realm=server";
10200 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2410201 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
10202 auth_challenge.end());
[email protected]c871bce92010-07-15 21:51:1410203 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
10204 origin, BoundNetLog());
[email protected]2d01c262011-08-11 23:07:0810205 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1410206
[email protected]c871bce92010-07-15 21:51:1410207 int rv = OK;
10208 const HttpResponseInfo* response = NULL;
10209 HttpRequestInfo request;
10210 request.method = "GET";
10211 request.url = origin;
10212 request.load_flags = 0;
[email protected]cb9bf6ca2011-01-28 13:15:2710213
[email protected]bb88e1d32013-05-03 23:11:0710214 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1010215
10216 // Use a TCP Socket Pool with only one connection per group. This is used
10217 // to validate that the TCP socket is not released to the pool between
10218 // each round of multi-round authentication.
10219 HttpNetworkSessionPeer session_peer(session);
[email protected]ab739042011-04-07 15:22:2810220 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:1010221 50, // Max sockets for pool
10222 1, // Max sockets per group
[email protected]bb88e1d32013-05-03 23:11:0710223 session_deps_.host_resolver.get(),
10224 session_deps_.socket_factory.get(),
10225 session_deps_.net_log);
[email protected]831e4a32013-11-14 02:14:4410226 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
10227 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:0210228 mock_pool_manager->SetTransportSocketPool(transport_pool);
dchenge3d1ddc2014-10-15 19:30:5110229 session_peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]7ef4cbbb2011-02-06 11:19:1010230
[email protected]262eec82013-03-19 21:01:3610231 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010232 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110233 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1410234
10235 const MockWrite kGet(
10236 "GET / HTTP/1.1\r\n"
10237 "Host: www.example.com\r\n"
10238 "Connection: keep-alive\r\n\r\n");
10239 const MockWrite kGetAuth(
10240 "GET / HTTP/1.1\r\n"
10241 "Host: www.example.com\r\n"
10242 "Connection: keep-alive\r\n"
10243 "Authorization: auth_token\r\n\r\n");
10244
10245 const MockRead kServerChallenge(
10246 "HTTP/1.1 401 Unauthorized\r\n"
10247 "WWW-Authenticate: Mock realm=server\r\n"
10248 "Content-Type: text/html; charset=iso-8859-1\r\n"
10249 "Content-Length: 14\r\n\r\n"
10250 "Unauthorized\r\n");
10251 const MockRead kSuccess(
10252 "HTTP/1.1 200 OK\r\n"
10253 "Content-Type: text/html; charset=iso-8859-1\r\n"
10254 "Content-Length: 3\r\n\r\n"
10255 "Yes");
10256
10257 MockWrite writes[] = {
10258 // First round
10259 kGet,
10260 // Second round
10261 kGetAuth,
10262 // Third round
10263 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3010264 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1010265 kGetAuth,
10266 // Competing request
10267 kGet,
[email protected]c871bce92010-07-15 21:51:1410268 };
10269 MockRead reads[] = {
10270 // First round
10271 kServerChallenge,
10272 // Second round
10273 kServerChallenge,
10274 // Third round
[email protected]eca50e122010-09-11 14:03:3010275 kServerChallenge,
10276 // Fourth round
[email protected]c871bce92010-07-15 21:51:1410277 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1010278 // Competing response
10279 kSuccess,
[email protected]c871bce92010-07-15 21:51:1410280 };
10281 StaticSocketDataProvider data_provider(reads, arraysize(reads),
10282 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:0710283 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1410284
thestig9d3bb0c2015-01-24 00:49:5110285 const char kSocketGroup[] = "www.example.com:80";
[email protected]7ef4cbbb2011-02-06 11:19:1010286
10287 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1410288 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4110289 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]c871bce92010-07-15 21:51:1410290 if (rv == ERR_IO_PENDING)
10291 rv = callback.WaitForResult();
10292 EXPECT_EQ(OK, rv);
10293 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010294 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:1410295 EXPECT_FALSE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2810296 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1410297
[email protected]7ef4cbbb2011-02-06 11:19:1010298 // In between rounds, another request comes in for the same domain.
10299 // It should not be able to grab the TCP socket that trans has already
10300 // claimed.
10301 scoped_ptr<HttpTransaction> trans_compete(
[email protected]90499482013-06-01 00:39:5010302 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110303 TestCompletionCallback callback_compete;
10304 rv = trans_compete->Start(
10305 &request, callback_compete.callback(), BoundNetLog());
[email protected]7ef4cbbb2011-02-06 11:19:1010306 EXPECT_EQ(ERR_IO_PENDING, rv);
10307 // callback_compete.WaitForResult at this point would stall forever,
10308 // since the HttpNetworkTransaction does not release the request back to
10309 // the pool until after authentication completes.
10310
10311 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1410312 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4110313 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1410314 if (rv == ERR_IO_PENDING)
10315 rv = callback.WaitForResult();
10316 EXPECT_EQ(OK, rv);
10317 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010318 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:1410319 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2810320 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1410321
[email protected]7ef4cbbb2011-02-06 11:19:1010322 // Third 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(), 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]eca50e122010-09-11 14:03:3010332
[email protected]7ef4cbbb2011-02-06 11:19:1010333 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3010334 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4110335 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3010336 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]eca50e122010-09-11 14:03:3010341 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2810342 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1010343
10344 // Read the body since the fourth round was successful. This will also
10345 // release the socket back to the pool.
10346 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
[email protected]90499482013-06-01 00:39:5010347 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1010348 if (rv == ERR_IO_PENDING)
10349 rv = callback.WaitForResult();
10350 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:5010351 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1010352 EXPECT_EQ(0, rv);
10353 // There are still 0 idle sockets, since the trans_compete transaction
10354 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:2810355 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1010356
10357 // The competing request can now finish. Wait for the headers and then
10358 // read the body.
10359 rv = callback_compete.WaitForResult();
10360 EXPECT_EQ(OK, rv);
[email protected]90499482013-06-01 00:39:5010361 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1010362 if (rv == ERR_IO_PENDING)
10363 rv = callback.WaitForResult();
10364 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:5010365 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1010366 EXPECT_EQ(0, rv);
10367
10368 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:2810369 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1410370}
10371
[email protected]65041fa2010-05-21 06:56:5310372// This tests the case that a request is issued via http instead of spdy after
10373// npn is negotiated.
[email protected]23e482282013-06-14 16:08:0210374TEST_P(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]d7599122014-05-24 03:37:2310375 session_deps_.use_alternate_protocols = true;
10376 NextProtoVector next_protos;
[email protected]0ce3af82013-07-22 16:17:1610377 next_protos.push_back(kProtoHTTP11);
[email protected]d7599122014-05-24 03:37:2310378 session_deps_.next_protos = next_protos;
10379
[email protected]65041fa2010-05-21 06:56:5310380 HttpRequestInfo request;
10381 request.method = "GET";
bncce36dca22015-04-21 22:11:2310382 request.url = GURL("https://www.example.org/");
[email protected]65041fa2010-05-21 06:56:5310383 request.load_flags = 0;
10384
10385 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310386 MockWrite(
10387 "GET / HTTP/1.1\r\n"
10388 "Host: www.example.org\r\n"
10389 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5310390 };
10391
[email protected]8a0fc822013-06-27 20:52:4310392 std::string alternate_protocol_http_header =
10393 GetAlternateProtocolHttpHeader();
10394
[email protected]65041fa2010-05-21 06:56:5310395 MockRead data_reads[] = {
10396 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:4310397 MockRead(alternate_protocol_http_header.c_str()),
[email protected]65041fa2010-05-21 06:56:5310398 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610399 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5310400 };
10401
[email protected]8ddf8322012-02-23 18:08:0610402 SSLSocketDataProvider ssl(ASYNC, OK);
davidben6974bf72015-04-27 17:52:4810403 ssl.SetNextProto(kProtoHTTP11);
[email protected]65041fa2010-05-21 06:56:5310404
[email protected]bb88e1d32013-05-03 23:11:0710405 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5310406
10407 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
10408 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0710409 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5310410
[email protected]49639fa2011-12-20 23:22:4110411 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5310412
[email protected]bb88e1d32013-05-03 23:11:0710413 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610414 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010415 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]65041fa2010-05-21 06:56:5310416
[email protected]49639fa2011-12-20 23:22:4110417 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]65041fa2010-05-21 06:56:5310418
10419 EXPECT_EQ(ERR_IO_PENDING, rv);
10420 EXPECT_EQ(OK, callback.WaitForResult());
10421
10422 const HttpResponseInfo* response = trans->GetResponseInfo();
10423 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010424 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]65041fa2010-05-21 06:56:5310425 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10426
10427 std::string response_data;
10428 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10429 EXPECT_EQ("hello world", response_data);
10430
10431 EXPECT_FALSE(response->was_fetched_via_spdy);
10432 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]65041fa2010-05-21 06:56:5310433}
[email protected]26ef6582010-06-24 02:30:4710434
[email protected]23e482282013-06-14 16:08:0210435TEST_P(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:4710436 // Simulate the SSL handshake completing with an NPN negotiation
10437 // followed by an immediate server closing of the socket.
10438 // Fix crash: http://crbug.com/46369
[email protected]d7599122014-05-24 03:37:2310439 session_deps_.use_alternate_protocols = true;
10440 session_deps_.next_protos = SpdyNextProtos();
[email protected]26ef6582010-06-24 02:30:4710441
10442 HttpRequestInfo request;
10443 request.method = "GET";
bncce36dca22015-04-21 22:11:2310444 request.url = GURL("https://www.example.org/");
[email protected]26ef6582010-06-24 02:30:4710445 request.load_flags = 0;
10446
[email protected]8ddf8322012-02-23 18:08:0610447 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210448 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710449 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4710450
[email protected]cdf8f7e72013-05-23 10:56:4610451 scoped_ptr<SpdyFrame> req(
10452 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
rch8e6c6c42015-05-01 14:05:1310453 MockWrite spdy_writes[] = {CreateMockWrite(*req, 1)};
[email protected]26ef6582010-06-24 02:30:4710454
10455 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0610456 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4710457 };
10458
rch8e6c6c42015-05-01 14:05:1310459 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10460 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710461 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4710462
[email protected]49639fa2011-12-20 23:22:4110463 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4710464
[email protected]bb88e1d32013-05-03 23:11:0710465 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610466 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010467 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]26ef6582010-06-24 02:30:4710468
[email protected]49639fa2011-12-20 23:22:4110469 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]26ef6582010-06-24 02:30:4710470 EXPECT_EQ(ERR_IO_PENDING, rv);
10471 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult());
[email protected]26ef6582010-06-24 02:30:4710472}
[email protected]65d34382010-07-01 18:12:2610473
[email protected]795cbf82013-07-22 09:37:2710474// A subclass of HttpAuthHandlerMock that records the request URL when
10475// it gets it. This is needed since the auth handler may get destroyed
10476// before we get a chance to query it.
10477class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
10478 public:
10479 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
10480
dchengb03027d2014-10-21 12:00:2010481 ~UrlRecordingHttpAuthHandlerMock() override {}
[email protected]795cbf82013-07-22 09:37:2710482
10483 protected:
dchengb03027d2014-10-21 12:00:2010484 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
10485 const HttpRequestInfo* request,
10486 const CompletionCallback& callback,
10487 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2710488 *url_ = request->url;
10489 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
10490 credentials, request, callback, auth_token);
10491 }
10492
10493 private:
10494 GURL* url_;
10495};
10496
[email protected]23e482282013-06-14 16:08:0210497TEST_P(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) {
[email protected]f45c1ee2010-08-03 00:54:3010498 // This test ensures that the URL passed into the proxy is upgraded
10499 // to https when doing an Alternate Protocol upgrade.
[email protected]d7599122014-05-24 03:37:2310500 session_deps_.use_alternate_protocols = true;
10501 session_deps_.next_protos = SpdyNextProtos();
[email protected]f45c1ee2010-08-03 00:54:3010502
[email protected]bb88e1d32013-05-03 23:11:0710503 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:2010504 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
vishal.b62985ca92015-04-17 08:45:5110505 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710506 session_deps_.net_log = &net_log;
[email protected]795cbf82013-07-22 09:37:2710507 GURL request_url;
10508 {
10509 HttpAuthHandlerMock::Factory* auth_factory =
10510 new HttpAuthHandlerMock::Factory();
10511 UrlRecordingHttpAuthHandlerMock* auth_handler =
10512 new UrlRecordingHttpAuthHandlerMock(&request_url);
10513 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
10514 auth_factory->set_do_init_from_challenge(true);
10515 session_deps_.http_auth_handler_factory.reset(auth_factory);
10516 }
[email protected]f45c1ee2010-08-03 00:54:3010517
10518 HttpRequestInfo request;
10519 request.method = "GET";
bncce36dca22015-04-21 22:11:2310520 request.url = GURL("http://www.example.org");
[email protected]f45c1ee2010-08-03 00:54:3010521 request.load_flags = 0;
10522
10523 // First round goes unauthenticated through the proxy.
10524 MockWrite data_writes_1[] = {
bncce36dca22015-04-21 22:11:2310525 MockWrite(
10526 "GET http://www.example.org/ HTTP/1.1\r\n"
10527 "Host: www.example.org\r\n"
10528 "Proxy-Connection: keep-alive\r\n"
10529 "\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3010530 };
10531 MockRead data_reads_1[] = {
[email protected]8ddf8322012-02-23 18:08:0610532 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
bnc33b8cef42014-11-19 17:30:3810533 MockRead("HTTP/1.1 200 OK\r\n"),
10534 MockRead("Alternate-Protocol: 443:"),
10535 MockRead(GetAlternateProtocolFromParam()),
10536 MockRead("\r\n"),
10537 MockRead("Proxy-Connection: close\r\n"),
10538 MockRead("\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3010539 };
10540 StaticSocketDataProvider data_1(data_reads_1, arraysize(data_reads_1),
10541 data_writes_1, arraysize(data_writes_1));
10542
bncce36dca22015-04-21 22:11:2310543 // Second round tries to tunnel to www.example.org due to the
[email protected]f45c1ee2010-08-03 00:54:3010544 // Alternate-Protocol announcement in the first round. It fails due
10545 // to a proxy authentication challenge.
bncce36dca22015-04-21 22:11:2310546 // After the failure, a tunnel is established to www.example.org using
[email protected]394816e92010-08-03 07:38:5910547 // Proxy-Authorization headers. There is then a SPDY request round.
10548 //
[email protected]fe3b7dc2012-02-03 19:52:0910549 // NOTE: Despite the "Proxy-Connection: Close", these are done on the
10550 // same MockTCPClientSocket since the underlying HttpNetworkClientSocket
10551 // does a Disconnect and Connect on the same socket, rather than trying
10552 // to obtain a new one.
10553 //
[email protected]394816e92010-08-03 07:38:5910554 // NOTE: Originally, the proxy response to the second CONNECT request
10555 // simply returned another 407 so the unit test could skip the SSL connection
10556 // establishment and SPDY framing issues. Alas, the
10557 // retry-http-when-alternate-protocol fails logic kicks in, which was more
[email protected]f45c1ee2010-08-03 00:54:3010558 // complicated to set up expectations for than the SPDY session.
[email protected]394816e92010-08-03 07:38:5910559
[email protected]cdf8f7e72013-05-23 10:56:4610560 scoped_ptr<SpdyFrame> req(
10561 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]23e482282013-06-14 16:08:0210562 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10563 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]f45c1ee2010-08-03 00:54:3010564
[email protected]394816e92010-08-03 07:38:5910565 MockWrite data_writes_2[] = {
bncce36dca22015-04-21 22:11:2310566 // First connection attempt without Proxy-Authorization.
rch8e6c6c42015-05-01 14:05:1310567 MockWrite(ASYNC, 0,
10568 "CONNECT www.example.org:443 HTTP/1.1\r\n"
10569 "Host: www.example.org\r\n"
10570 "Proxy-Connection: keep-alive\r\n"
10571 "\r\n"),
[email protected]394816e92010-08-03 07:38:5910572
bncce36dca22015-04-21 22:11:2310573 // Second connection attempt with Proxy-Authorization.
rch8e6c6c42015-05-01 14:05:1310574 MockWrite(ASYNC, 2,
10575 "CONNECT www.example.org:443 HTTP/1.1\r\n"
10576 "Host: www.example.org\r\n"
10577 "Proxy-Connection: keep-alive\r\n"
10578 "Proxy-Authorization: auth_token\r\n"
10579 "\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3010580
bncce36dca22015-04-21 22:11:2310581 // SPDY request
rch8e6c6c42015-05-01 14:05:1310582 CreateMockWrite(*req, 4),
[email protected]f45c1ee2010-08-03 00:54:3010583 };
[email protected]394816e92010-08-03 07:38:5910584 const char kRejectConnectResponse[] = ("HTTP/1.1 407 Unauthorized\r\n"
10585 "Proxy-Authenticate: Mock\r\n"
10586 "Proxy-Connection: close\r\n"
10587 "\r\n");
10588 const char kAcceptConnectResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
10589 MockRead data_reads_2[] = {
rch8e6c6c42015-05-01 14:05:1310590 // First connection attempt fails
10591 MockRead(ASYNC, kRejectConnectResponse,
10592 arraysize(kRejectConnectResponse) - 1, 1),
[email protected]394816e92010-08-03 07:38:5910593
rch8e6c6c42015-05-01 14:05:1310594 // Second connection attempt passes
10595 MockRead(ASYNC, kAcceptConnectResponse,
10596 arraysize(kAcceptConnectResponse) - 1, 3),
[email protected]394816e92010-08-03 07:38:5910597
rch8e6c6c42015-05-01 14:05:1310598 // SPDY response
10599 CreateMockRead(*resp.get(), 5),
10600 CreateMockRead(*data.get(), 6),
10601 MockRead(ASYNC, 0, 0, 7),
[email protected]394816e92010-08-03 07:38:5910602 };
rch8e6c6c42015-05-01 14:05:1310603 SequencedSocketData data_2(data_reads_2, arraysize(data_reads_2),
10604 data_writes_2, arraysize(data_writes_2));
[email protected]f45c1ee2010-08-03 00:54:3010605
[email protected]8ddf8322012-02-23 18:08:0610606 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210607 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:2310608 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
10609 ASSERT_TRUE(ssl.cert.get());
[email protected]f45c1ee2010-08-03 00:54:3010610
[email protected]d973e99a2012-02-17 21:02:3610611 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5510612 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
10613 NULL, 0, NULL, 0);
10614 hanging_non_alternate_protocol_socket.set_connect_data(
10615 never_finishing_connect);
10616
[email protected]bb88e1d32013-05-03 23:11:0710617 session_deps_.socket_factory->AddSocketDataProvider(&data_1);
10618 session_deps_.socket_factory->AddSocketDataProvider(&data_2);
10619 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10620 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5510621 &hanging_non_alternate_protocol_socket);
[email protected]bb88e1d32013-05-03 23:11:0710622 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f45c1ee2010-08-03 00:54:3010623
10624 // First round should work and provide the Alternate-Protocol state.
[email protected]49639fa2011-12-20 23:22:4110625 TestCompletionCallback callback_1;
[email protected]262eec82013-03-19 21:01:3610626 scoped_ptr<HttpTransaction> trans_1(
[email protected]90499482013-06-01 00:39:5010627 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110628 int rv = trans_1->Start(&request, callback_1.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:3010629 EXPECT_EQ(ERR_IO_PENDING, rv);
10630 EXPECT_EQ(OK, callback_1.WaitForResult());
10631
10632 // Second round should attempt a tunnel connect and get an auth challenge.
[email protected]49639fa2011-12-20 23:22:4110633 TestCompletionCallback callback_2;
[email protected]262eec82013-03-19 21:01:3610634 scoped_ptr<HttpTransaction> trans_2(
[email protected]90499482013-06-01 00:39:5010635 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110636 rv = trans_2->Start(&request, callback_2.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:3010637 EXPECT_EQ(ERR_IO_PENDING, rv);
10638 EXPECT_EQ(OK, callback_2.WaitForResult());
10639 const HttpResponseInfo* response = trans_2->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010640 ASSERT_TRUE(response != NULL);
[email protected]f45c1ee2010-08-03 00:54:3010641 ASSERT_FALSE(response->auth_challenge.get() == NULL);
10642
10643 // Restart with auth. Tunnel should work and response received.
[email protected]49639fa2011-12-20 23:22:4110644 TestCompletionCallback callback_3;
10645 rv = trans_2->RestartWithAuth(
10646 AuthCredentials(kFoo, kBar), callback_3.callback());
[email protected]f45c1ee2010-08-03 00:54:3010647 EXPECT_EQ(ERR_IO_PENDING, rv);
10648 EXPECT_EQ(OK, callback_3.WaitForResult());
10649
10650 // After all that work, these two lines (or actually, just the scheme) are
10651 // what this test is all about. Make sure it happens correctly.
[email protected]f45c1ee2010-08-03 00:54:3010652 EXPECT_EQ("https", request_url.scheme());
bncce36dca22015-04-21 22:11:2310653 EXPECT_EQ("www.example.org", request_url.host());
[email protected]f45c1ee2010-08-03 00:54:3010654
[email protected]029c83b62013-01-24 05:28:2010655 LoadTimingInfo load_timing_info;
10656 EXPECT_TRUE(trans_2->GetLoadTimingInfo(&load_timing_info));
10657 TestLoadTimingNotReusedWithPac(load_timing_info,
10658 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]8e6441ca2010-08-19 05:56:3810659}
10660
10661// Test that if we cancel the transaction as the connection is completing, that
10662// everything tears down correctly.
[email protected]23e482282013-06-14 16:08:0210663TEST_P(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3810664 // Setup everything about the connection to complete synchronously, so that
10665 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
10666 // for is the callback from the HttpStreamRequest.
10667 // Then cancel the transaction.
10668 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3610669 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3810670 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0610671 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
10672 MockRead(SYNCHRONOUS, "hello world"),
10673 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3810674 };
10675
[email protected]8e6441ca2010-08-19 05:56:3810676 HttpRequestInfo request;
10677 request.method = "GET";
bncce36dca22015-04-21 22:11:2310678 request.url = GURL("http://www.example.org/");
[email protected]8e6441ca2010-08-19 05:56:3810679 request.load_flags = 0;
10680
[email protected]bb88e1d32013-05-03 23:11:0710681 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]3fe8d2f82013-10-17 08:56:0710682 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:2710683 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4110684 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:2710685
[email protected]8e6441ca2010-08-19 05:56:3810686 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10687 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710688 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3810689
[email protected]49639fa2011-12-20 23:22:4110690 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3810691
vishal.b62985ca92015-04-17 08:45:5110692 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4110693 int rv = trans->Start(&request, callback.callback(), log.bound());
[email protected]8e6441ca2010-08-19 05:56:3810694 EXPECT_EQ(ERR_IO_PENDING, rv);
10695 trans.reset(); // Cancel the transaction here.
10696
[email protected]2da659e2013-05-23 20:51:3410697 base::MessageLoop::current()->RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3010698}
10699
[email protected]ecab6e052014-05-16 14:58:1210700// Test that if a transaction is cancelled after receiving the headers, the
10701// stream is drained properly and added back to the socket pool. The main
10702// purpose of this test is to make sure that an HttpStreamParser can be read
10703// from after the HttpNetworkTransaction and the objects it owns have been
10704// deleted.
10705// See http://crbug.com/368418
10706TEST_P(HttpNetworkTransactionTest, CancelAfterHeaders) {
10707 MockRead data_reads[] = {
10708 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
10709 MockRead(ASYNC, "Content-Length: 2\r\n"),
10710 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
10711 MockRead(ASYNC, "1"),
10712 // 2 async reads are necessary to trigger a ReadResponseBody call after the
10713 // HttpNetworkTransaction has been deleted.
10714 MockRead(ASYNC, "2"),
10715 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
10716 };
10717 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10718 session_deps_.socket_factory->AddSocketDataProvider(&data);
10719
10720 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10721
10722 {
10723 HttpRequestInfo request;
10724 request.method = "GET";
bncce36dca22015-04-21 22:11:2310725 request.url = GURL("http://www.example.org/");
[email protected]ecab6e052014-05-16 14:58:1210726 request.load_flags = 0;
10727
dcheng48459ac22014-08-26 00:46:4110728 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1210729 TestCompletionCallback callback;
10730
10731 int rv = trans.Start(&request, callback.callback(), BoundNetLog());
10732 EXPECT_EQ(ERR_IO_PENDING, rv);
10733 callback.WaitForResult();
10734
10735 const HttpResponseInfo* response = trans.GetResponseInfo();
10736 ASSERT_TRUE(response != NULL);
10737 EXPECT_TRUE(response->headers.get() != NULL);
10738 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10739
10740 // The transaction and HttpRequestInfo are deleted.
10741 }
10742
10743 // Let the HttpResponseBodyDrainer drain the socket.
10744 base::MessageLoop::current()->RunUntilIdle();
10745
10746 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4110747 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1210748}
10749
[email protected]76a505b2010-08-25 06:23:0010750// Test a basic GET request through a proxy.
[email protected]23e482282013-06-14 16:08:0210751TEST_P(HttpNetworkTransactionTest, ProxyGet) {
[email protected]bb88e1d32013-05-03 23:11:0710752 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:2010753 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
vishal.b62985ca92015-04-17 08:45:5110754 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710755 session_deps_.net_log = log.bound().net_log();
10756 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0010757
[email protected]76a505b2010-08-25 06:23:0010758 HttpRequestInfo request;
10759 request.method = "GET";
bncce36dca22015-04-21 22:11:2310760 request.url = GURL("http://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0010761
10762 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2310763 MockWrite(
10764 "GET http://www.example.org/ HTTP/1.1\r\n"
10765 "Host: www.example.org\r\n"
10766 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0010767 };
10768
10769 MockRead data_reads1[] = {
10770 MockRead("HTTP/1.1 200 OK\r\n"),
10771 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10772 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610773 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0010774 };
10775
10776 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10777 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710778 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0010779
[email protected]49639fa2011-12-20 23:22:4110780 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0010781
[email protected]262eec82013-03-19 21:01:3610782 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010783 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]597a1ab2014-06-26 08:12:2710784 BeforeProxyHeadersSentHandler proxy_headers_handler;
10785 trans->SetBeforeProxyHeadersSentCallback(
10786 base::Bind(&BeforeProxyHeadersSentHandler::OnBeforeProxyHeadersSent,
10787 base::Unretained(&proxy_headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5010788
[email protected]49639fa2011-12-20 23:22:4110789 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0010790 EXPECT_EQ(ERR_IO_PENDING, rv);
10791
10792 rv = callback1.WaitForResult();
10793 EXPECT_EQ(OK, rv);
10794
10795 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010796 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:0010797
10798 EXPECT_TRUE(response->headers->IsKeepAlive());
10799 EXPECT_EQ(200, response->headers->response_code());
10800 EXPECT_EQ(100, response->headers->GetContentLength());
10801 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]d8fc4722014-06-13 13:17:1510802 EXPECT_TRUE(
10803 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
[email protected]597a1ab2014-06-26 08:12:2710804 EXPECT_TRUE(proxy_headers_handler.observed_before_proxy_headers_sent());
10805 EXPECT_EQ("myproxy:70", proxy_headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0010806 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2010807
10808 LoadTimingInfo load_timing_info;
10809 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10810 TestLoadTimingNotReusedWithPac(load_timing_info,
10811 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0010812}
10813
10814// Test a basic HTTPS GET request through a proxy.
[email protected]23e482282013-06-14 16:08:0210815TEST_P(HttpNetworkTransactionTest, ProxyTunnelGet) {
[email protected]bb88e1d32013-05-03 23:11:0710816 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:2010817 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
vishal.b62985ca92015-04-17 08:45:5110818 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710819 session_deps_.net_log = log.bound().net_log();
10820 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0010821
[email protected]76a505b2010-08-25 06:23:0010822 HttpRequestInfo request;
10823 request.method = "GET";
bncce36dca22015-04-21 22:11:2310824 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0010825
10826 // Since we have proxy, should try to establish tunnel.
10827 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2310828 MockWrite(
10829 "CONNECT www.example.org:443 HTTP/1.1\r\n"
10830 "Host: www.example.org\r\n"
10831 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0010832
bncce36dca22015-04-21 22:11:2310833 MockWrite(
10834 "GET / HTTP/1.1\r\n"
10835 "Host: www.example.org\r\n"
10836 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0010837 };
10838
10839 MockRead data_reads1[] = {
10840 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
10841
10842 MockRead("HTTP/1.1 200 OK\r\n"),
10843 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10844 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610845 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0010846 };
10847
10848 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10849 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710850 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0610851 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710852 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0010853
[email protected]49639fa2011-12-20 23:22:4110854 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0010855
[email protected]262eec82013-03-19 21:01:3610856 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010857 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5010858
[email protected]49639fa2011-12-20 23:22:4110859 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0010860 EXPECT_EQ(ERR_IO_PENDING, rv);
10861
10862 rv = callback1.WaitForResult();
10863 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:4610864 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4010865 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0010866 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010867 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0010868 NetLog::PHASE_NONE);
10869 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010870 entries, pos,
[email protected]76a505b2010-08-25 06:23:0010871 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
10872 NetLog::PHASE_NONE);
10873
10874 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010875 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:0010876
10877 EXPECT_TRUE(response->headers->IsKeepAlive());
10878 EXPECT_EQ(200, response->headers->response_code());
10879 EXPECT_EQ(100, response->headers->GetContentLength());
10880 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10881 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]d8fc4722014-06-13 13:17:1510882 EXPECT_TRUE(
10883 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
[email protected]029c83b62013-01-24 05:28:2010884
10885 LoadTimingInfo load_timing_info;
10886 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10887 TestLoadTimingNotReusedWithPac(load_timing_info,
10888 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0010889}
10890
10891// Test a basic HTTPS GET request through a proxy, but the server hangs up
10892// while establishing the tunnel.
[email protected]23e482282013-06-14 16:08:0210893TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
[email protected]bb88e1d32013-05-03 23:11:0710894 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
vishal.b62985ca92015-04-17 08:45:5110895 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710896 session_deps_.net_log = log.bound().net_log();
10897 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0010898
[email protected]76a505b2010-08-25 06:23:0010899 HttpRequestInfo request;
10900 request.method = "GET";
bncce36dca22015-04-21 22:11:2310901 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0010902
10903 // Since we have proxy, should try to establish tunnel.
10904 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2310905 MockWrite(
10906 "CONNECT www.example.org:443 HTTP/1.1\r\n"
10907 "Host: www.example.org\r\n"
10908 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0010909
bncce36dca22015-04-21 22:11:2310910 MockWrite(
10911 "GET / HTTP/1.1\r\n"
10912 "Host: www.example.org\r\n"
10913 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0010914 };
10915
10916 MockRead data_reads1[] = {
[email protected]8ddf8322012-02-23 18:08:0610917 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:0010918 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610919 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0010920 };
10921
10922 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10923 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710924 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0610925 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710926 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0010927
[email protected]49639fa2011-12-20 23:22:4110928 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0010929
[email protected]262eec82013-03-19 21:01:3610930 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010931 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5010932
[email protected]49639fa2011-12-20 23:22:4110933 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0010934 EXPECT_EQ(ERR_IO_PENDING, rv);
10935
10936 rv = callback1.WaitForResult();
10937 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
mmenke43758e62015-05-04 21:09:4610938 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4010939 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0010940 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010941 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0010942 NetLog::PHASE_NONE);
10943 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010944 entries, pos,
[email protected]76a505b2010-08-25 06:23:0010945 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
10946 NetLog::PHASE_NONE);
10947}
10948
[email protected]749eefa82010-09-13 22:14:0310949// Test for crbug.com/55424.
[email protected]23e482282013-06-14 16:08:0210950TEST_P(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
[email protected]cdf8f7e72013-05-23 10:56:4610951 scoped_ptr<SpdyFrame> req(
bncce36dca22015-04-21 22:11:2310952 spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
rch8e6c6c42015-05-01 14:05:1310953 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]749eefa82010-09-13 22:14:0310954
[email protected]23e482282013-06-14 16:08:0210955 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10956 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0310957 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1310958 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0310959 };
10960
rch8e6c6c42015-05-01 14:05:1310961 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10962 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710963 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0310964
[email protected]8ddf8322012-02-23 18:08:0610965 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210966 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710967 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0310968
[email protected]bb88e1d32013-05-03 23:11:0710969 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0310970
10971 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2310972 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4010973 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5310974 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2710975 base::WeakPtr<SpdySession> spdy_session =
[email protected]41d64e82013-07-03 22:44:2610976 CreateInsecureSpdySession(session, key, BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0310977
10978 HttpRequestInfo request;
10979 request.method = "GET";
bncce36dca22015-04-21 22:11:2310980 request.url = GURL("https://www.example.org/");
[email protected]749eefa82010-09-13 22:14:0310981 request.load_flags = 0;
10982
10983 // This is the important line that marks this as a preconnect.
10984 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
10985
[email protected]262eec82013-03-19 21:01:3610986 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010987 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]749eefa82010-09-13 22:14:0310988
[email protected]41d64e82013-07-03 22:44:2610989 TestCompletionCallback callback;
[email protected]49639fa2011-12-20 23:22:4110990 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0310991 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110992 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]749eefa82010-09-13 22:14:0310993}
10994
[email protected]73b8dd222010-11-11 19:55:2410995// Given a net error, cause that error to be returned from the first Write()
10996// call and verify that the HttpTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0210997void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0710998 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2910999 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2711000 request_info.url = GURL("https://www.example.com/");
11001 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2911002 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2711003
[email protected]8ddf8322012-02-23 18:08:0611004 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2911005 MockWrite data_writes[] = {
11006 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2411007 };
ttuttle859dc7a2015-04-23 19:42:2911008 StaticSocketDataProvider data(NULL, 0, data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0711009 session_deps_.socket_factory->AddSocketDataProvider(&data);
11010 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2411011
[email protected]bb88e1d32013-05-03 23:11:0711012 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3611013 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011014 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]73b8dd222010-11-11 19:55:2411015
[email protected]49639fa2011-12-20 23:22:4111016 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2911017 int rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
11018 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2411019 rv = callback.WaitForResult();
11020 ASSERT_EQ(error, rv);
11021}
11022
[email protected]23e482282013-06-14 16:08:0211023TEST_P(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2411024 // Just check a grab bag of cert errors.
11025 static const int kErrors[] = {
11026 ERR_CERT_COMMON_NAME_INVALID,
11027 ERR_CERT_AUTHORITY_INVALID,
11028 ERR_CERT_DATE_INVALID,
11029 };
11030 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0611031 CheckErrorIsPassedBack(kErrors[i], ASYNC);
11032 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2411033 }
11034}
11035
[email protected]bd0b6772011-01-11 19:59:3011036// Ensure that a client certificate is removed from the SSL client auth
11037// cache when:
11038// 1) No proxy is involved.
11039// 2) TLS False Start is disabled.
11040// 3) The initial TLS handshake requests a client certificate.
11041// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0211042TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2311043 ClientAuthCertCache_Direct_NoFalseStart) {
ttuttle859dc7a2015-04-23 19:42:2911044 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2711045 request_info.url = GURL("https://www.example.com/");
11046 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2911047 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2711048
[email protected]bd0b6772011-01-11 19:59:3011049 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4111050 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3011051
11052 // [ssl_]data1 contains the data for the first SSL handshake. When a
11053 // CertificateRequest is received for the first time, the handshake will
11054 // be aborted to allow the caller to provide a certificate.
ttuttle859dc7a2015-04-23 19:42:2911055 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3011056 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711057 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2911058 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711059 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3011060
11061 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
11062 // False Start is not being used, the result of the SSL handshake will be
11063 // returned as part of the SSLClientSocket::Connect() call. This test
11064 // matches the result of a server sending a handshake_failure alert,
11065 // rather than a Finished message, because it requires a client
11066 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2911067 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3011068 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711069 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2911070 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711071 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3011072
11073 // [ssl_]data3 contains the data for the third SSL handshake. When a
11074 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4211075 // HttpNetworkTransaction will attempt to fallback to TLSv1.1 if the previous
11076 // connection was attempted with TLSv1.2. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3011077 // of the HttpNetworkTransaction. Because this test failure is due to
11078 // requiring a client certificate, this fallback handshake should also
11079 // fail.
ttuttle859dc7a2015-04-23 19:42:2911080 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3011081 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711082 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2911083 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711084 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3011085
[email protected]80c75f682012-05-26 16:22:1711086 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
11087 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4211088 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
11089 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]80c75f682012-05-26 16:22:1711090 // of the HttpNetworkTransaction. Because this test failure is due to
11091 // requiring a client certificate, this fallback handshake should also
11092 // fail.
ttuttle859dc7a2015-04-23 19:42:2911093 SSLSocketDataProvider ssl_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1711094 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711095 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2911096 StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711097 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1711098
[email protected]bb88e1d32013-05-03 23:11:0711099 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3611100 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011101 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3011102
[email protected]bd0b6772011-01-11 19:59:3011103 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4111104 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2911105 int rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
11106 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3011107
11108 // Complete the SSL handshake, which should abort due to requiring a
11109 // client certificate.
11110 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911111 ASSERT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
[email protected]bd0b6772011-01-11 19:59:3011112
11113 // Indicate that no certificate should be supplied. From the perspective
11114 // of SSLClientCertCache, NULL is just as meaningful as a real
11115 // certificate, so this is the same as supply a
11116 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4111117 rv = trans->RestartWithCertificate(NULL, callback.callback());
ttuttle859dc7a2015-04-23 19:42:2911118 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3011119
11120 // Ensure the certificate was added to the client auth cache before
11121 // allowing the connection to continue restarting.
11122 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4111123 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
11124 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3011125 ASSERT_EQ(NULL, client_cert.get());
11126
11127 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1711128 // then consume ssl_data3 and ssl_data4, both of which should also fail.
11129 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3011130 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911131 ASSERT_EQ(ERR_SSL_PROTOCOL_ERROR, rv);
[email protected]bd0b6772011-01-11 19:59:3011132
11133 // Ensure that the client certificate is removed from the cache on a
11134 // handshake failure.
[email protected]791879c2013-12-17 07:22:4111135 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11136 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3011137}
11138
11139// Ensure that a client certificate is removed from the SSL client auth
11140// cache when:
11141// 1) No proxy is involved.
11142// 2) TLS False Start is enabled.
11143// 3) The initial TLS handshake requests a client certificate.
11144// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0211145TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2311146 ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2911147 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2711148 request_info.url = GURL("https://www.example.com/");
11149 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2911150 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2711151
[email protected]bd0b6772011-01-11 19:59:3011152 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4111153 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3011154
11155 // When TLS False Start is used, SSLClientSocket::Connect() calls will
11156 // return successfully after reading up to the peer's Certificate message.
11157 // This is to allow the caller to call SSLClientSocket::Write(), which can
11158 // enqueue application data to be sent in the same packet as the
11159 // ChangeCipherSpec and Finished messages.
11160 // The actual handshake will be finished when SSLClientSocket::Read() is
11161 // called, which expects to process the peer's ChangeCipherSpec and
11162 // Finished messages. If there was an error negotiating with the peer,
11163 // such as due to the peer requiring a client certificate when none was
11164 // supplied, the alert sent by the peer won't be processed until Read() is
11165 // called.
11166
11167 // Like the non-False Start case, when a client certificate is requested by
11168 // the peer, the handshake is aborted during the Connect() call.
11169 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2911170 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3011171 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711172 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2911173 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711174 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3011175
11176 // When a client certificate is supplied, Connect() will not be aborted
11177 // when the peer requests the certificate. Instead, the handshake will
11178 // artificially succeed, allowing the caller to write the HTTP request to
11179 // the socket. The handshake messages are not processed until Read() is
11180 // called, which then detects that the handshake was aborted, due to the
11181 // peer sending a handshake_failure because it requires a client
11182 // certificate.
ttuttle859dc7a2015-04-23 19:42:2911183 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3011184 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711185 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2911186 MockRead data2_reads[] = {
11187 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3011188 };
ttuttle859dc7a2015-04-23 19:42:2911189 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711190 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3011191
11192 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1711193 // the data for the SSL handshake once the TLSv1.1 connection falls back to
11194 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2911195 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3011196 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711197 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2911198 StaticSocketDataProvider data3(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711199 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3011200
[email protected]80c75f682012-05-26 16:22:1711201 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
11202 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2911203 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1711204 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711205 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2911206 StaticSocketDataProvider data4(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711207 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1711208
[email protected]7799de12013-05-30 05:52:5111209 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2911210 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5111211 ssl_data5.cert_request_info = cert_request.get();
11212 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
ttuttle859dc7a2015-04-23 19:42:2911213 StaticSocketDataProvider data5(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]7799de12013-05-30 05:52:5111214 session_deps_.socket_factory->AddSocketDataProvider(&data5);
11215
[email protected]bb88e1d32013-05-03 23:11:0711216 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3611217 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011218 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3011219
[email protected]bd0b6772011-01-11 19:59:3011220 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4111221 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2911222 int rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
11223 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3011224
11225 // Complete the SSL handshake, which should abort due to requiring a
11226 // client certificate.
11227 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911228 ASSERT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
[email protected]bd0b6772011-01-11 19:59:3011229
11230 // Indicate that no certificate should be supplied. From the perspective
11231 // of SSLClientCertCache, NULL is just as meaningful as a real
11232 // certificate, so this is the same as supply a
11233 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4111234 rv = trans->RestartWithCertificate(NULL, callback.callback());
ttuttle859dc7a2015-04-23 19:42:2911235 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3011236
11237 // Ensure the certificate was added to the client auth cache before
11238 // allowing the connection to continue restarting.
11239 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4111240 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
11241 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3011242 ASSERT_EQ(NULL, client_cert.get());
11243
[email protected]bd0b6772011-01-11 19:59:3011244 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1711245 // then consume ssl_data3 and ssl_data4, both of which should also fail.
11246 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3011247 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911248 ASSERT_EQ(ERR_SSL_PROTOCOL_ERROR, rv);
[email protected]bd0b6772011-01-11 19:59:3011249
11250 // Ensure that the client certificate is removed from the cache on a
11251 // handshake failure.
[email protected]791879c2013-12-17 07:22:4111252 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11253 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3011254}
11255
[email protected]8c405132011-01-11 22:03:1811256// Ensure that a client certificate is removed from the SSL client auth
11257// cache when:
11258// 1) An HTTPS proxy is involved.
11259// 3) The HTTPS proxy requests a client certificate.
11260// 4) The client supplies an invalid/unacceptable certificate for the
11261// proxy.
11262// The test is repeated twice, first for connecting to an HTTPS endpoint,
11263// then for connecting to an HTTP endpoint.
[email protected]23e482282013-06-14 16:08:0211264TEST_P(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
[email protected]bb88e1d32013-05-03 23:11:0711265 session_deps_.proxy_service.reset(
[email protected]8c405132011-01-11 22:03:1811266 ProxyService::CreateFixed("https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:5111267 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0711268 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1811269
11270 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4111271 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1811272
11273 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
11274 // [ssl_]data[1-3]. Rather than represending the endpoint
11275 // (www.example.com:443), they represent failures with the HTTPS proxy
11276 // (proxy:70).
ttuttle859dc7a2015-04-23 19:42:2911277 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1811278 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711279 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2911280 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711281 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1811282
ttuttle859dc7a2015-04-23 19:42:2911283 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1811284 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711285 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2911286 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711287 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1811288
[email protected]80c75f682012-05-26 16:22:1711289 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
11290#if 0
ttuttle859dc7a2015-04-23 19:42:2911291 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1811292 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711293 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2911294 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711295 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1711296#endif
[email protected]8c405132011-01-11 22:03:1811297
ttuttle859dc7a2015-04-23 19:42:2911298 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1811299 requests[0].url = GURL("https://www.example.com/");
11300 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2911301 requests[0].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1811302
11303 requests[1].url = GURL("http://www.example.com/");
11304 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2911305 requests[1].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1811306
11307 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0711308 session_deps_.socket_factory->ResetNextMockIndexes();
11309 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c405132011-01-11 22:03:1811310 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5011311 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c405132011-01-11 22:03:1811312
11313 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4111314 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2911315 int rv = trans->Start(&requests[i], callback.callback(), BoundNetLog());
11316 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]8c405132011-01-11 22:03:1811317
11318 // Complete the SSL handshake, which should abort due to requiring a
11319 // client certificate.
11320 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911321 ASSERT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
[email protected]8c405132011-01-11 22:03:1811322
11323 // Indicate that no certificate should be supplied. From the perspective
11324 // of SSLClientCertCache, NULL is just as meaningful as a real
11325 // certificate, so this is the same as supply a
11326 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4111327 rv = trans->RestartWithCertificate(NULL, callback.callback());
ttuttle859dc7a2015-04-23 19:42:2911328 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]8c405132011-01-11 22:03:1811329
11330 // Ensure the certificate was added to the client auth cache before
11331 // allowing the connection to continue restarting.
11332 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4111333 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
11334 HostPortPair("proxy", 70), &client_cert));
[email protected]8c405132011-01-11 22:03:1811335 ASSERT_EQ(NULL, client_cert.get());
11336 // Ensure the certificate was NOT cached for the endpoint. This only
11337 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4111338 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11339 HostPortPair("www.example.com", 443), &client_cert));
[email protected]8c405132011-01-11 22:03:1811340
11341 // Restart the handshake. This will consume ssl_data2, which fails, and
11342 // then consume ssl_data3, which should also fail. The result code is
11343 // checked against what ssl_data3 should return.
11344 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911345 ASSERT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
[email protected]8c405132011-01-11 22:03:1811346
11347 // Now that the new handshake has failed, ensure that the client
11348 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4111349 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11350 HostPortPair("proxy", 70), &client_cert));
11351 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11352 HostPortPair("www.example.com", 443), &client_cert));
[email protected]8c405132011-01-11 22:03:1811353 }
11354}
11355
[email protected]23e482282013-06-14 16:08:0211356// Unlike TEST/TEST_F, which are macros that expand to further macros,
11357// TEST_P is a macro that expands directly to code that stringizes the
11358// arguments. As a result, macros passed as parameters (such as prefix
11359// or test_case_name) will not be expanded by the preprocessor. To
11360// work around this, indirect the macro for TEST_P, so that the
11361// pre-processor will expand macros such as MAYBE_test_name before
11362// instantiating the test.
11363#define WRAPPED_TEST_P(test_case_name, test_name) \
11364 TEST_P(test_case_name, test_name)
11365
[email protected]45b170822012-05-04 21:18:1411366// Times out on Win7 dbg(2) bot. http://crbug.com/124776
11367#if defined(OS_WIN)
11368#define MAYBE_UseIPConnectionPooling DISABLED_UseIPConnectionPooling
11369#else
11370#define MAYBE_UseIPConnectionPooling UseIPConnectionPooling
11371#endif
[email protected]23e482282013-06-14 16:08:0211372WRAPPED_TEST_P(HttpNetworkTransactionTest, MAYBE_UseIPConnectionPooling) {
[email protected]d7599122014-05-24 03:37:2311373 session_deps_.use_alternate_protocols = true;
11374 session_deps_.next_protos = SpdyNextProtos();
[email protected]e3ceb682011-06-28 23:55:4611375
11376 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0711377 session_deps_.host_resolver.reset(new MockCachingHostResolver());
11378 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2611379 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
11380 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4611381
[email protected]8ddf8322012-02-23 18:08:0611382 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211383 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711384 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4611385
[email protected]cdf8f7e72013-05-23 10:56:4611386 scoped_ptr<SpdyFrame> host1_req(
bncce36dca22015-04-21 22:11:2311387 spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
[email protected]cdf8f7e72013-05-23 10:56:4611388 scoped_ptr<SpdyFrame> host2_req(
11389 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4611390 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1311391 CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4611392 };
[email protected]23e482282013-06-14 16:08:0211393 scoped_ptr<SpdyFrame> host1_resp(
11394 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11395 scoped_ptr<SpdyFrame> host1_resp_body(
11396 spdy_util_.ConstructSpdyBodyFrame(1, true));
11397 scoped_ptr<SpdyFrame> host2_resp(
11398 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11399 scoped_ptr<SpdyFrame> host2_resp_body(
11400 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4611401 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1311402 CreateMockRead(*host1_resp, 1),
11403 CreateMockRead(*host1_resp_body, 2),
11404 CreateMockRead(*host2_resp, 4),
11405 CreateMockRead(*host2_resp_body, 5),
11406 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4611407 };
11408
[email protected]d2b5f092012-06-08 23:55:0211409 IPAddressNumber ip;
11410 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
11411 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11412 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1311413 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
11414 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711415 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4611416
[email protected]aa22b242011-11-16 18:58:2911417 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4611418 HttpRequestInfo request1;
11419 request1.method = "GET";
bncce36dca22015-04-21 22:11:2311420 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4611421 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011422 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611423
[email protected]49639fa2011-12-20 23:22:4111424 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611425 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111426 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611427
11428 const HttpResponseInfo* response = trans1.GetResponseInfo();
11429 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011430 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611431 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11432
11433 std::string response_data;
11434 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
11435 EXPECT_EQ("hello!", response_data);
11436
11437 // Preload www.gmail.com into HostCache.
11438 HostPortPair host_port("www.gmail.com", 443);
[email protected]5109c1952013-08-20 18:44:1011439 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4611440 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1011441 rv = session_deps_.host_resolver->Resolve(resolve_info,
11442 DEFAULT_PRIORITY,
11443 &ignored,
11444 callback.callback(),
11445 NULL,
11446 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4711447 EXPECT_EQ(ERR_IO_PENDING, rv);
11448 rv = callback.WaitForResult();
11449 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4611450
11451 HttpRequestInfo request2;
11452 request2.method = "GET";
11453 request2.url = GURL("https://www.gmail.com/");
11454 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011455 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611456
[email protected]49639fa2011-12-20 23:22:4111457 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611458 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111459 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611460
11461 response = trans2.GetResponseInfo();
11462 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011463 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611464 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11465 EXPECT_TRUE(response->was_fetched_via_spdy);
11466 EXPECT_TRUE(response->was_npn_negotiated);
11467 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
11468 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4611469}
[email protected]45b170822012-05-04 21:18:1411470#undef MAYBE_UseIPConnectionPooling
[email protected]e3ceb682011-06-28 23:55:4611471
[email protected]23e482282013-06-14 16:08:0211472TEST_P(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d7599122014-05-24 03:37:2311473 session_deps_.use_alternate_protocols = true;
11474 session_deps_.next_protos = SpdyNextProtos();
[email protected]d2b5f092012-06-08 23:55:0211475
11476 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0711477 session_deps_.host_resolver.reset(new MockCachingHostResolver());
11478 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0211479 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
11480 pool_peer.DisableDomainAuthenticationVerification();
11481
11482 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211483 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711484 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]d2b5f092012-06-08 23:55:0211485
[email protected]cdf8f7e72013-05-23 10:56:4611486 scoped_ptr<SpdyFrame> host1_req(
bncce36dca22015-04-21 22:11:2311487 spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
[email protected]cdf8f7e72013-05-23 10:56:4611488 scoped_ptr<SpdyFrame> host2_req(
11489 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0211490 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1311491 CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0211492 };
[email protected]23e482282013-06-14 16:08:0211493 scoped_ptr<SpdyFrame> host1_resp(
11494 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11495 scoped_ptr<SpdyFrame> host1_resp_body(
11496 spdy_util_.ConstructSpdyBodyFrame(1, true));
11497 scoped_ptr<SpdyFrame> host2_resp(
11498 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11499 scoped_ptr<SpdyFrame> host2_resp_body(
11500 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0211501 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1311502 CreateMockRead(*host1_resp, 1),
11503 CreateMockRead(*host1_resp_body, 2),
11504 CreateMockRead(*host2_resp, 4),
11505 CreateMockRead(*host2_resp_body, 5),
11506 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0211507 };
11508
11509 IPAddressNumber ip;
11510 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
11511 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11512 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1311513 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
11514 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711515 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0211516
11517 TestCompletionCallback callback;
11518 HttpRequestInfo request1;
11519 request1.method = "GET";
bncce36dca22015-04-21 22:11:2311520 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0211521 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011522 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0211523
11524 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
11525 EXPECT_EQ(ERR_IO_PENDING, rv);
11526 EXPECT_EQ(OK, callback.WaitForResult());
11527
11528 const HttpResponseInfo* response = trans1.GetResponseInfo();
11529 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011530 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d2b5f092012-06-08 23:55:0211531 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11532
11533 std::string response_data;
11534 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
11535 EXPECT_EQ("hello!", response_data);
11536
11537 HttpRequestInfo request2;
11538 request2.method = "GET";
11539 request2.url = GURL("https://www.gmail.com/");
11540 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011541 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0211542
11543 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
11544 EXPECT_EQ(ERR_IO_PENDING, rv);
11545 EXPECT_EQ(OK, callback.WaitForResult());
11546
11547 response = trans2.GetResponseInfo();
11548 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011549 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d2b5f092012-06-08 23:55:0211550 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11551 EXPECT_TRUE(response->was_fetched_via_spdy);
11552 EXPECT_TRUE(response->was_npn_negotiated);
11553 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
11554 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0211555}
11556
ttuttle859dc7a2015-04-23 19:42:2911557class OneTimeCachingHostResolver : public HostResolver {
[email protected]e3ceb682011-06-28 23:55:4611558 public:
11559 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
11560 : host_port_(host_port) {}
dchengb03027d2014-10-21 12:00:2011561 ~OneTimeCachingHostResolver() override {}
[email protected]e3ceb682011-06-28 23:55:4611562
11563 RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); }
11564
11565 // HostResolver methods:
dchengb03027d2014-10-21 12:00:2011566 int Resolve(const RequestInfo& info,
11567 RequestPriority priority,
11568 AddressList* addresses,
11569 const CompletionCallback& callback,
11570 RequestHandle* out_req,
11571 const BoundNetLog& net_log) override {
[email protected]95a214c2011-08-04 21:50:4011572 return host_resolver_.Resolve(
[email protected]5109c1952013-08-20 18:44:1011573 info, priority, addresses, callback, out_req, net_log);
[email protected]95a214c2011-08-04 21:50:4011574 }
11575
dchengb03027d2014-10-21 12:00:2011576 int ResolveFromCache(const RequestInfo& info,
11577 AddressList* addresses,
11578 const BoundNetLog& net_log) override {
[email protected]95a214c2011-08-04 21:50:4011579 int rv = host_resolver_.ResolveFromCache(info, addresses, net_log);
11580 if (rv == OK && info.host_port_pair().Equals(host_port_))
[email protected]98e1cd012011-11-08 15:33:0911581 host_resolver_.GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4611582 return rv;
11583 }
11584
dchengb03027d2014-10-21 12:00:2011585 void CancelRequest(RequestHandle req) override {
[email protected]e3ceb682011-06-28 23:55:4611586 host_resolver_.CancelRequest(req);
11587 }
11588
[email protected]46da33be2011-07-19 21:58:0411589 MockCachingHostResolver* GetMockHostResolver() {
11590 return &host_resolver_;
11591 }
11592
[email protected]e3ceb682011-06-28 23:55:4611593 private:
11594 MockCachingHostResolver host_resolver_;
11595 const HostPortPair host_port_;
11596};
11597
[email protected]45b170822012-05-04 21:18:1411598// Times out on Win7 dbg(2) bot. http://crbug.com/124776
11599#if defined(OS_WIN)
[email protected]bb88e1d32013-05-03 23:11:0711600#define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \
11601 DISABLED_UseIPConnectionPoolingWithHostCacheExpiration
[email protected]45b170822012-05-04 21:18:1411602#else
[email protected]bb88e1d32013-05-03 23:11:0711603#define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \
11604 UseIPConnectionPoolingWithHostCacheExpiration
[email protected]45b170822012-05-04 21:18:1411605#endif
[email protected]23e482282013-06-14 16:08:0211606WRAPPED_TEST_P(HttpNetworkTransactionTest,
11607 MAYBE_UseIPConnectionPoolingWithHostCacheExpiration) {
[email protected]23e482282013-06-14 16:08:0211608// Times out on Win7 dbg(2) bot. http://crbug.com/124776 . (MAYBE_
11609// prefix doesn't work with parametrized tests).
11610#if defined(OS_WIN)
11611 return;
[email protected]88c7b4be2014-03-19 23:04:0111612#else
[email protected]d7599122014-05-24 03:37:2311613 session_deps_.use_alternate_protocols = true;
11614 session_deps_.next_protos = SpdyNextProtos();
[email protected]e3ceb682011-06-28 23:55:4611615
11616 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
[email protected]e3ceb682011-06-28 23:55:4611617 OneTimeCachingHostResolver host_resolver(HostPortPair("www.gmail.com", 443));
[email protected]c6bf8152012-12-02 07:43:3411618 HttpNetworkSession::Params params =
[email protected]bb88e1d32013-05-03 23:11:0711619 SpdySessionDependencies::CreateSessionParams(&session_deps_);
[email protected]e3ceb682011-06-28 23:55:4611620 params.host_resolver = &host_resolver;
[email protected]bb88e1d32013-05-03 23:11:0711621 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2611622 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
11623 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4611624
[email protected]8ddf8322012-02-23 18:08:0611625 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211626 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711627 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4611628
[email protected]cdf8f7e72013-05-23 10:56:4611629 scoped_ptr<SpdyFrame> host1_req(
bncce36dca22015-04-21 22:11:2311630 spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
[email protected]cdf8f7e72013-05-23 10:56:4611631 scoped_ptr<SpdyFrame> host2_req(
11632 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4611633 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1311634 CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4611635 };
[email protected]23e482282013-06-14 16:08:0211636 scoped_ptr<SpdyFrame> host1_resp(
11637 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11638 scoped_ptr<SpdyFrame> host1_resp_body(
11639 spdy_util_.ConstructSpdyBodyFrame(1, true));
11640 scoped_ptr<SpdyFrame> host2_resp(
11641 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11642 scoped_ptr<SpdyFrame> host2_resp_body(
11643 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4611644 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1311645 CreateMockRead(*host1_resp, 1),
11646 CreateMockRead(*host1_resp_body, 2),
11647 CreateMockRead(*host2_resp, 4),
11648 CreateMockRead(*host2_resp_body, 5),
11649 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4611650 };
11651
[email protected]d2b5f092012-06-08 23:55:0211652 IPAddressNumber ip;
11653 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
11654 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11655 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1311656 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
11657 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711658 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4611659
[email protected]aa22b242011-11-16 18:58:2911660 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4611661 HttpRequestInfo request1;
11662 request1.method = "GET";
bncce36dca22015-04-21 22:11:2311663 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4611664 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011665 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611666
[email protected]49639fa2011-12-20 23:22:4111667 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611668 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111669 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611670
11671 const HttpResponseInfo* response = trans1.GetResponseInfo();
11672 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011673 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611674 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11675
11676 std::string response_data;
11677 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
11678 EXPECT_EQ("hello!", response_data);
11679
11680 // Preload cache entries into HostCache.
[email protected]5109c1952013-08-20 18:44:1011681 HostResolver::RequestInfo resolve_info(HostPortPair("www.gmail.com", 443));
[email protected]e3ceb682011-06-28 23:55:4611682 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1011683 rv = host_resolver.Resolve(resolve_info,
11684 DEFAULT_PRIORITY,
11685 &ignored,
11686 callback.callback(),
11687 NULL,
11688 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4711689 EXPECT_EQ(ERR_IO_PENDING, rv);
11690 rv = callback.WaitForResult();
11691 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4611692
11693 HttpRequestInfo request2;
11694 request2.method = "GET";
11695 request2.url = GURL("https://www.gmail.com/");
11696 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011697 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611698
[email protected]49639fa2011-12-20 23:22:4111699 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611700 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111701 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611702
11703 response = trans2.GetResponseInfo();
11704 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011705 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611706 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11707 EXPECT_TRUE(response->was_fetched_via_spdy);
11708 EXPECT_TRUE(response->was_npn_negotiated);
11709 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
11710 EXPECT_EQ("hello!", response_data);
[email protected]88c7b4be2014-03-19 23:04:0111711#endif
[email protected]e3ceb682011-06-28 23:55:4611712}
[email protected]45b170822012-05-04 21:18:1411713#undef MAYBE_UseIPConnectionPoolingWithHostCacheExpiration
[email protected]e3ceb682011-06-28 23:55:4611714
[email protected]23e482282013-06-14 16:08:0211715TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2311716 const std::string https_url = "https://www.example.org:8080/";
11717 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0411718
11719 // SPDY GET for HTTPS URL
[email protected]cdf8f7e72013-05-23 10:56:4611720 scoped_ptr<SpdyFrame> req1(
11721 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0411722
11723 MockWrite writes1[] = {
11724 CreateMockWrite(*req1, 0),
11725 };
11726
[email protected]23e482282013-06-14 16:08:0211727 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11728 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8450d722012-07-02 19:14:0411729 MockRead reads1[] = {
11730 CreateMockRead(*resp1, 1),
11731 CreateMockRead(*body1, 2),
11732 MockRead(ASYNC, ERR_IO_PENDING, 3)
11733 };
11734
rch8e6c6c42015-05-01 14:05:1311735 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
11736 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0411737 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5711738 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0411739
11740 // HTTP GET for the HTTP URL
11741 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1311742 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3411743 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2311744 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3411745 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0411746 };
11747
11748 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1311749 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
11750 MockRead(ASYNC, 2, "hello"),
11751 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0411752 };
11753
rch8e6c6c42015-05-01 14:05:1311754 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
11755 arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0411756
[email protected]8450d722012-07-02 19:14:0411757 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211758 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711759 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11760 session_deps_.socket_factory->AddSocketDataProvider(&data1);
11761 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0411762
[email protected]bb88e1d32013-05-03 23:11:0711763 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0411764
11765 // Start the first transaction to set up the SpdySession
11766 HttpRequestInfo request1;
11767 request1.method = "GET";
11768 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0411769 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011770 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0411771 TestCompletionCallback callback1;
11772 EXPECT_EQ(ERR_IO_PENDING,
11773 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411774 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411775
11776 EXPECT_EQ(OK, callback1.WaitForResult());
11777 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11778
11779 // Now, start the HTTP request
11780 HttpRequestInfo request2;
11781 request2.method = "GET";
11782 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0411783 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011784 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0411785 TestCompletionCallback callback2;
11786 EXPECT_EQ(ERR_IO_PENDING,
11787 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411788 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411789
11790 EXPECT_EQ(OK, callback2.WaitForResult());
11791 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11792}
11793
bnc1b0e36852015-04-28 15:32:5911794class AltSvcCertificateVerificationTest : public HttpNetworkTransactionTest {
11795 public:
11796 void Run(bool pooling, bool valid) {
11797 HostPortPair origin(valid ? "mail.example.org" : "invalid.example.org",
11798 443);
11799 HostPortPair alternative("www.example.org", 443);
11800
11801 base::FilePath certs_dir = GetTestCertsDirectory();
11802 scoped_refptr<X509Certificate> cert(
11803 ImportCertFromFile(certs_dir, "spdy_pooling.pem"));
11804 ASSERT_TRUE(cert.get());
11805 bool common_name_fallback_used;
11806 EXPECT_EQ(valid,
11807 cert->VerifyNameMatch(origin.host(), &common_name_fallback_used));
11808 EXPECT_TRUE(
11809 cert->VerifyNameMatch(alternative.host(), &common_name_fallback_used));
11810 SSLSocketDataProvider ssl(ASYNC, OK);
11811 ssl.SetNextProto(GetParam());
11812 ssl.cert = cert;
11813 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11814
11815 // If pooling, then start a request to alternative first to create a
11816 // SpdySession.
11817 std::string url0 = "https://www.example.org:443";
11818 // Second request to origin, which has an alternative service, and could
11819 // open a connection to the alternative host or pool to the existing one.
11820 std::string url1("https://");
11821 url1.append(origin.host());
11822 url1.append(":443");
11823
11824 scoped_ptr<SpdyFrame> req0;
11825 scoped_ptr<SpdyFrame> req1;
11826 scoped_ptr<SpdyFrame> resp0;
11827 scoped_ptr<SpdyFrame> body0;
11828 scoped_ptr<SpdyFrame> resp1;
11829 scoped_ptr<SpdyFrame> body1;
11830 std::vector<MockWrite> writes;
11831 std::vector<MockRead> reads;
11832
11833 if (pooling) {
11834 req0.reset(spdy_util_.ConstructSpdyGet(url0.c_str(), false, 1, LOWEST));
11835 req1.reset(spdy_util_.ConstructSpdyGet(url1.c_str(), false, 3, LOWEST));
11836
11837 writes.push_back(CreateMockWrite(*req0, 0));
11838 writes.push_back(CreateMockWrite(*req1, 3));
11839
11840 resp0.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11841 body0.reset(spdy_util_.ConstructSpdyBodyFrame(1, true));
11842 resp1.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11843 body1.reset(spdy_util_.ConstructSpdyBodyFrame(3, true));
11844
11845 reads.push_back(CreateMockRead(*resp0, 1));
11846 reads.push_back(CreateMockRead(*body0, 2));
11847 reads.push_back(MockRead(ASYNC, ERR_IO_PENDING, 4));
11848 reads.push_back(CreateMockRead(*resp1, 5));
11849 reads.push_back(CreateMockRead(*body1, 6));
11850 reads.push_back(MockRead(ASYNC, OK, 7));
11851 } else {
11852 req1.reset(spdy_util_.ConstructSpdyGet(url1.c_str(), false, 1, LOWEST));
11853
11854 writes.push_back(CreateMockWrite(*req1, 0));
11855
11856 resp1.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11857 body1.reset(spdy_util_.ConstructSpdyBodyFrame(1, true));
11858
11859 reads.push_back(CreateMockRead(*resp1, 1));
11860 reads.push_back(CreateMockRead(*body1, 2));
11861 reads.push_back(MockRead(ASYNC, OK, 3));
11862 }
11863
dbeamcd6674c72015-05-05 01:57:5411864 OrderedSocketData data(vector_as_array(&reads), reads.size(),
11865 vector_as_array(&writes), writes.size());
bnc1b0e36852015-04-28 15:32:5911866 session_deps_.socket_factory->AddSocketDataProvider(&data);
11867
11868 // Connection to the origin fails.
11869 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11870 StaticSocketDataProvider data_refused;
11871 data_refused.set_connect_data(mock_connect);
11872 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
11873
11874 session_deps_.use_alternate_protocols = true;
11875 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11876 base::WeakPtr<HttpServerProperties> http_server_properties =
11877 session->http_server_properties();
11878 AlternativeService alternative_service(
11879 AlternateProtocolFromNextProto(GetParam()), alternative);
11880 http_server_properties->SetAlternativeService(origin, alternative_service,
11881 1.0);
11882
11883 // First request to alternative.
11884 if (pooling) {
11885 scoped_ptr<HttpTransaction> trans0(
11886 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
11887 HttpRequestInfo request0;
11888 request0.method = "GET";
11889 request0.url = GURL(url0);
11890 request0.load_flags = 0;
11891 TestCompletionCallback callback0;
11892
11893 int rv = trans0->Start(&request0, callback0.callback(), BoundNetLog());
11894 EXPECT_EQ(ERR_IO_PENDING, rv);
11895 rv = callback0.WaitForResult();
11896 EXPECT_EQ(OK, rv);
11897 }
11898
11899 // Second request to origin.
11900 scoped_ptr<HttpTransaction> trans1(
11901 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
11902 HttpRequestInfo request1;
11903 request1.method = "GET";
11904 request1.url = GURL(url1);
11905 request1.load_flags = 0;
11906 TestCompletionCallback callback1;
11907
11908 int rv = trans1->Start(&request1, callback1.callback(), BoundNetLog());
11909 EXPECT_EQ(ERR_IO_PENDING, rv);
11910 rv = callback1.WaitForResult();
11911 if (valid) {
11912 EXPECT_EQ(OK, rv);
11913 } else {
11914 if (pooling) {
11915 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
11916 } else {
11917 EXPECT_EQ(ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN, rv);
11918 }
11919 }
11920 }
11921};
11922
11923INSTANTIATE_TEST_CASE_P(NextProto,
11924 AltSvcCertificateVerificationTest,
11925 testing::Values(kProtoSPDY31,
11926 kProtoSPDY4_14,
11927 kProtoSPDY4));
11928
11929// The alternative service host must exhibit a certificate that is valid for the
11930// origin host. Test that this is enforced when pooling to an existing
11931// connection.
11932TEST_P(AltSvcCertificateVerificationTest, PoolingValid) {
11933 Run(true, true);
11934}
11935
11936TEST_P(AltSvcCertificateVerificationTest, PoolingInvalid) {
11937 Run(true, false);
11938}
11939
11940// The alternative service host must exhibit a certificate that is valid for the
11941// origin host. Test that this is enforced when opening a new connection.
11942TEST_P(AltSvcCertificateVerificationTest, NewConnectionValid) {
11943 Run(false, true);
11944}
11945
11946TEST_P(AltSvcCertificateVerificationTest, NewConnectionInvalid) {
11947 Run(false, false);
11948}
11949
bnc5452e2a2015-05-08 16:27:4211950// Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
11951// with the alternative server. That connection should not be used.
11952TEST_P(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
11953 HostPortPair origin("origin.example.org", 443);
11954 HostPortPair alternative("alternative.example.org", 443);
11955
11956 // Negotiate HTTP/1.1 with alternative.example.org.
11957 SSLSocketDataProvider ssl(ASYNC, OK);
11958 ssl.SetNextProto(kProtoHTTP11);
11959 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11960
11961 // No data should be read from the alternative, because HTTP/1.1 is
11962 // negotiated.
11963 StaticSocketDataProvider data;
11964 session_deps_.socket_factory->AddSocketDataProvider(&data);
11965
11966 // This test documents that an alternate Job should not be used if HTTP/1.1 is
11967 // negotiated. In order to test this, a failed connection to the origin is
11968 // mocked. This way the request relies on the alternate Job.
11969 StaticSocketDataProvider data_refused;
11970 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
11971 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
11972
11973 // Set up alternative service for origin.
11974 session_deps_.use_alternate_protocols = true;
11975 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11976 base::WeakPtr<HttpServerProperties> http_server_properties =
11977 session->http_server_properties();
11978 AlternativeService alternative_service(
11979 AlternateProtocolFromNextProto(GetParam()), alternative);
11980 http_server_properties->SetAlternativeService(origin, alternative_service,
11981 1.0);
11982
11983 scoped_ptr<HttpTransaction> trans(
11984 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
11985 HttpRequestInfo request;
11986 request.method = "GET";
11987 request.url = GURL("https://origin.example.org:443");
11988 request.load_flags = 0;
11989 TestCompletionCallback callback;
11990
11991 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
11992 // negotiated, the alternate Job should fail with ERR_NPN_NEGOTIATION_FAILED.
11993 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11994 EXPECT_EQ(ERR_NPN_NEGOTIATION_FAILED, callback.GetResult(rv));
11995}
11996
bnc40448a532015-05-11 19:13:1411997// A request to a server with an alternative service fires two Jobs: one to the
11998// origin, and an alternate one to the alternative server. If the former
11999// succeeds, the request should succeed, even if the latter fails because
12000// HTTP/1.1 is negotiated which is insufficient for alternative service.
12001TEST_P(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
12002 HostPortPair origin("origin.example.org", 443);
12003 HostPortPair alternative("alternative.example.org", 443);
12004
12005 // Negotiate HTTP/1.1 with alternative.
12006 SSLSocketDataProvider alternative_ssl(ASYNC, OK);
12007 alternative_ssl.SetNextProto(kProtoHTTP11);
12008 session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
12009
12010 // No data should be read from the alternative, because HTTP/1.1 is
12011 // negotiated.
12012 StaticSocketDataProvider data;
12013 session_deps_.socket_factory->AddSocketDataProvider(&data);
12014
12015 // Negotiate HTTP/1.1 with origin.
12016 SSLSocketDataProvider origin_ssl(ASYNC, OK);
12017 origin_ssl.SetNextProto(kProtoHTTP11);
12018 session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
12019
12020 MockWrite http_writes[] = {
12021 MockWrite(
12022 "GET / HTTP/1.1\r\n"
12023 "Host: origin.example.org\r\n"
12024 "Connection: keep-alive\r\n\r\n"),
12025 MockWrite(
12026 "GET /second HTTP/1.1\r\n"
12027 "Host: origin.example.org\r\n"
12028 "Connection: keep-alive\r\n\r\n"),
12029 };
12030
12031 MockRead http_reads[] = {
12032 MockRead("HTTP/1.1 200 OK\r\n"),
12033 MockRead("Content-Type: text/html\r\n"),
12034 MockRead("Content-Length: 6\r\n\r\n"),
12035 MockRead("foobar"),
12036 MockRead("HTTP/1.1 200 OK\r\n"),
12037 MockRead("Content-Type: text/html\r\n"),
12038 MockRead("Content-Length: 7\r\n\r\n"),
12039 MockRead("another"),
12040 };
12041 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
12042 http_writes, arraysize(http_writes));
12043 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12044
12045 // Set up alternative service for origin.
12046 session_deps_.use_alternate_protocols = true;
12047 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12048 base::WeakPtr<HttpServerProperties> http_server_properties =
12049 session->http_server_properties();
12050 AlternativeService alternative_service(
12051 AlternateProtocolFromNextProto(GetParam()), alternative);
12052 http_server_properties->SetAlternativeService(origin, alternative_service,
12053 1.0);
12054
12055 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
12056 HttpRequestInfo request1;
12057 request1.method = "GET";
12058 request1.url = GURL("https://origin.example.org:443");
12059 request1.load_flags = 0;
12060 TestCompletionCallback callback1;
12061
12062 int rv = trans1.Start(&request1, callback1.callback(), BoundNetLog());
12063 rv = callback1.GetResult(rv);
12064 EXPECT_EQ(OK, rv);
12065
12066 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
12067 ASSERT_TRUE(response1 != nullptr);
12068 ASSERT_TRUE(response1->headers.get() != nullptr);
12069 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
12070
12071 std::string response_data1;
12072 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data1));
12073 EXPECT_EQ("foobar", response_data1);
12074
12075 // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
12076 // for alternative service.
12077 EXPECT_TRUE(
12078 http_server_properties->IsAlternativeServiceBroken(alternative_service));
12079
12080 // Since |alternative_service| is broken, a second transaction to origin
12081 // should not start an alternate Job. It should pool to existing connection
12082 // to origin.
12083 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
12084 HttpRequestInfo request2;
12085 request2.method = "GET";
12086 request2.url = GURL("https://origin.example.org:443/second");
12087 request2.load_flags = 0;
12088 TestCompletionCallback callback2;
12089
12090 rv = trans2.Start(&request2, callback2.callback(), BoundNetLog());
12091 rv = callback2.GetResult(rv);
12092 EXPECT_EQ(OK, rv);
12093
12094 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
12095 ASSERT_TRUE(response2 != nullptr);
12096 ASSERT_TRUE(response2->headers.get() != nullptr);
12097 EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
12098
12099 std::string response_data2;
12100 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data2));
12101 EXPECT_EQ("another", response_data2);
12102}
12103
bnc5452e2a2015-05-08 16:27:4212104// Alternative service requires HTTP/2 (or SPDY), but there is already a
12105// HTTP/1.1 socket open to the alternative server. That socket should not be
12106// used.
12107TEST_P(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
12108 HostPortPair origin("origin.example.org", 443);
12109 HostPortPair alternative("alternative.example.org", 443);
12110 std::string origin_url = "https://origin.example.org:443";
12111 std::string alternative_url = "https://alternative.example.org:443";
12112
12113 // Negotiate HTTP/1.1 with alternative.example.org.
12114 SSLSocketDataProvider ssl(ASYNC, OK);
12115 ssl.SetNextProto(kProtoHTTP11);
12116 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12117
12118 // HTTP/1.1 data for |request1| and |request2|.
12119 MockWrite http_writes[] = {
12120 MockWrite(
12121 "GET / HTTP/1.1\r\n"
12122 "Host: alternative.example.org\r\n"
12123 "Connection: keep-alive\r\n\r\n"),
12124 MockWrite(
12125 "GET / HTTP/1.1\r\n"
12126 "Host: alternative.example.org\r\n"
12127 "Connection: keep-alive\r\n\r\n"),
12128 };
12129
12130 MockRead http_reads[] = {
12131 MockRead(
12132 "HTTP/1.1 200 OK\r\n"
12133 "Content-Type: text/html; charset=iso-8859-1\r\n"
12134 "Content-Length: 40\r\n\r\n"
12135 "first HTTP/1.1 response from alternative"),
12136 MockRead(
12137 "HTTP/1.1 200 OK\r\n"
12138 "Content-Type: text/html; charset=iso-8859-1\r\n"
12139 "Content-Length: 41\r\n\r\n"
12140 "second HTTP/1.1 response from alternative"),
12141 };
12142 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
12143 http_writes, arraysize(http_writes));
12144 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12145
12146 // This test documents that an alternate Job should not pool to an already
12147 // existing HTTP/1.1 connection. In order to test this, a failed connection
12148 // to the origin is mocked. This way |request2| relies on the alternate Job.
12149 StaticSocketDataProvider data_refused;
12150 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
12151 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
12152
12153 // Set up alternative service for origin.
12154 session_deps_.use_alternate_protocols = true;
12155 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12156 base::WeakPtr<HttpServerProperties> http_server_properties =
12157 session->http_server_properties();
12158 AlternativeService alternative_service(
12159 AlternateProtocolFromNextProto(GetParam()), alternative);
12160 http_server_properties->SetAlternativeService(origin, alternative_service,
12161 1.0);
12162
12163 // First transaction to alternative to open an HTTP/1.1 socket.
12164 scoped_ptr<HttpTransaction> trans1(
12165 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12166 HttpRequestInfo request1;
12167 request1.method = "GET";
12168 request1.url = GURL(alternative_url);
12169 request1.load_flags = 0;
12170 TestCompletionCallback callback1;
12171
12172 int rv = trans1->Start(&request1, callback1.callback(), BoundNetLog());
12173 EXPECT_EQ(OK, callback1.GetResult(rv));
12174 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
12175 ASSERT_TRUE(response1);
12176 ASSERT_TRUE(response1->headers.get());
12177 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
12178 EXPECT_TRUE(response1->was_npn_negotiated);
12179 EXPECT_FALSE(response1->was_fetched_via_spdy);
12180 std::string response_data1;
12181 ASSERT_EQ(OK, ReadTransaction(trans1.get(), &response_data1));
12182 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
12183
12184 // Request for origin.example.org, which has an alternative service. This
12185 // will start two Jobs: the alternative looks for connections to pool to,
12186 // finds one which is HTTP/1.1, and should ignore it, and should not try to
12187 // open other connections to alternative server. The Job to origin fails, so
12188 // this request fails.
12189 scoped_ptr<HttpTransaction> trans2(
12190 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12191 HttpRequestInfo request2;
12192 request2.method = "GET";
12193 request2.url = GURL(origin_url);
12194 request2.load_flags = 0;
12195 TestCompletionCallback callback2;
12196
12197 rv = trans2->Start(&request2, callback2.callback(), BoundNetLog());
12198 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback2.GetResult(rv));
12199
12200 // Another transaction to alternative. This is to test that the HTTP/1.1
12201 // socket is still open and in the pool.
12202 scoped_ptr<HttpTransaction> trans3(
12203 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12204 HttpRequestInfo request3;
12205 request3.method = "GET";
12206 request3.url = GURL(alternative_url);
12207 request3.load_flags = 0;
12208 TestCompletionCallback callback3;
12209
12210 rv = trans3->Start(&request3, callback3.callback(), BoundNetLog());
12211 EXPECT_EQ(OK, callback3.GetResult(rv));
12212 const HttpResponseInfo* response3 = trans3->GetResponseInfo();
12213 ASSERT_TRUE(response3);
12214 ASSERT_TRUE(response3->headers.get());
12215 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
12216 EXPECT_TRUE(response3->was_npn_negotiated);
12217 EXPECT_FALSE(response3->was_fetched_via_spdy);
12218 std::string response_data3;
12219 ASSERT_EQ(OK, ReadTransaction(trans3.get(), &response_data3));
12220 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
12221}
12222
[email protected]23e482282013-06-14 16:08:0212223TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2312224 const std::string https_url = "https://www.example.org:8080/";
12225 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0412226
12227 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2312228 const HostPortPair host_port_pair("www.example.org", 8080);
lgarrona91df87f2014-12-05 00:51:3412229 scoped_ptr<SpdyFrame> connect(
12230 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
[email protected]cdf8f7e72013-05-23 10:56:4612231 scoped_ptr<SpdyFrame> req1(
12232 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]23e482282013-06-14 16:08:0212233 scoped_ptr<SpdyFrame> wrapped_req1(
12234 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3912235
12236 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
[email protected]745aa9c2014-06-27 02:21:2912237 SpdyHeaderBlock req2_block;
12238 req2_block[spdy_util_.GetMethodKey()] = "GET";
bnc33b8cef42014-11-19 17:30:3812239 req2_block[spdy_util_.GetPathKey()] = "/";
bncce36dca22015-04-21 22:11:2312240 req2_block[spdy_util_.GetHostKey()] = "www.example.org:8080";
[email protected]745aa9c2014-06-27 02:21:2912241 req2_block[spdy_util_.GetSchemeKey()] = "http";
12242 spdy_util_.MaybeAddVersionHeader(&req2_block);
[email protected]601e03f12014-04-06 16:26:3912243 scoped_ptr<SpdyFrame> req2(
[email protected]745aa9c2014-06-27 02:21:2912244 spdy_util_.ConstructSpdySyn(3, req2_block, MEDIUM, false, true));
[email protected]8450d722012-07-02 19:14:0412245
12246 MockWrite writes1[] = {
12247 CreateMockWrite(*connect, 0),
12248 CreateMockWrite(*wrapped_req1, 2),
12249 CreateMockWrite(*req2, 5),
12250 };
12251
[email protected]23e482282013-06-14 16:08:0212252 scoped_ptr<SpdyFrame> conn_resp(
12253 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12254 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12255 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
12256 scoped_ptr<SpdyFrame> wrapped_resp1(
12257 spdy_util_.ConstructWrappedSpdyFrame(resp1, 1));
12258 scoped_ptr<SpdyFrame> wrapped_body1(
12259 spdy_util_.ConstructWrappedSpdyFrame(body1, 1));
12260 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
12261 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]8450d722012-07-02 19:14:0412262 MockRead reads1[] = {
12263 CreateMockRead(*conn_resp, 1),
12264 CreateMockRead(*wrapped_resp1, 3),
12265 CreateMockRead(*wrapped_body1, 4),
12266 CreateMockRead(*resp2, 6),
12267 CreateMockRead(*body2, 7),
12268 MockRead(ASYNC, ERR_IO_PENDING, 8)
12269 };
12270
[email protected]dd54bd82012-07-19 23:44:5712271 DeterministicSocketData data1(reads1, arraysize(reads1),
12272 writes1, arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0412273 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5712274 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0412275
[email protected]bb88e1d32013-05-03 23:11:0712276 session_deps_.proxy_service.reset(
[email protected]f6c63db52013-02-02 00:35:2212277 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
vishal.b62985ca92015-04-17 08:45:5112278 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712279 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0412280 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
[email protected]23e482282013-06-14 16:08:0212281 ssl1.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0712282 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0412283 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
[email protected]23e482282013-06-14 16:08:0212284 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0712285 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
12286 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0412287
12288 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0712289 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]8450d722012-07-02 19:14:0412290
12291 // Start the first transaction to set up the SpdySession
12292 HttpRequestInfo request1;
12293 request1.method = "GET";
12294 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0412295 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012296 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0412297 TestCompletionCallback callback1;
12298 EXPECT_EQ(ERR_IO_PENDING,
12299 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412300 base::MessageLoop::current()->RunUntilIdle();
[email protected]dd54bd82012-07-19 23:44:5712301 data1.RunFor(4);
[email protected]8450d722012-07-02 19:14:0412302
12303 EXPECT_EQ(OK, callback1.WaitForResult());
12304 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
12305
[email protected]f6c63db52013-02-02 00:35:2212306 LoadTimingInfo load_timing_info1;
12307 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
12308 TestLoadTimingNotReusedWithPac(load_timing_info1,
12309 CONNECT_TIMING_HAS_SSL_TIMES);
12310
[email protected]8450d722012-07-02 19:14:0412311 // Now, start the HTTP request
12312 HttpRequestInfo request2;
12313 request2.method = "GET";
12314 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0412315 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012316 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0412317 TestCompletionCallback callback2;
12318 EXPECT_EQ(ERR_IO_PENDING,
12319 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412320 base::MessageLoop::current()->RunUntilIdle();
[email protected]dd54bd82012-07-19 23:44:5712321 data1.RunFor(3);
[email protected]8450d722012-07-02 19:14:0412322
12323 EXPECT_EQ(OK, callback2.WaitForResult());
12324 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2212325
12326 LoadTimingInfo load_timing_info2;
12327 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
12328 // The established SPDY sessions is considered reused by the HTTP request.
12329 TestLoadTimingReusedWithPac(load_timing_info2);
12330 // HTTP requests over a SPDY session should have a different connection
12331 // socket_log_id than requests over a tunnel.
12332 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0412333}
12334
[email protected]2d88e7d2012-07-19 17:55:1712335// Test that in the case where we have a SPDY session to a SPDY proxy
12336// that we do not pool other origins that resolve to the same IP when
12337// the certificate does not match the new origin.
12338// http://crbug.com/134690
[email protected]23e482282013-06-14 16:08:0212339TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2312340 const std::string url1 = "http://www.example.org/";
12341 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1712342 const std::string ip_addr = "1.2.3.4";
12343
12344 // SPDY GET for HTTP URL (through SPDY proxy)
[email protected]23e482282013-06-14 16:08:0212345 scoped_ptr<SpdyHeaderBlock> headers(
bncce36dca22015-04-21 22:11:2312346 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
[email protected]745aa9c2014-06-27 02:21:2912347 scoped_ptr<SpdyFrame> req1(
12348 spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, false, true));
[email protected]2d88e7d2012-07-19 17:55:1712349
12350 MockWrite writes1[] = {
12351 CreateMockWrite(*req1, 0),
12352 };
12353
[email protected]23e482282013-06-14 16:08:0212354 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12355 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1712356 MockRead reads1[] = {
12357 CreateMockRead(*resp1, 1),
12358 CreateMockRead(*body1, 2),
12359 MockRead(ASYNC, OK, 3) // EOF
12360 };
12361
12362 scoped_ptr<DeterministicSocketData> data1(
12363 new DeterministicSocketData(reads1, arraysize(reads1),
12364 writes1, arraysize(writes1)));
12365 IPAddressNumber ip;
12366 ASSERT_TRUE(ParseIPLiteralToNumber(ip_addr, &ip));
12367 IPEndPoint peer_addr = IPEndPoint(ip, 443);
12368 MockConnect connect_data1(ASYNC, OK, peer_addr);
12369 data1->set_connect_data(connect_data1);
12370
12371 // SPDY GET for HTTPS URL (direct)
[email protected]cdf8f7e72013-05-23 10:56:4612372 scoped_ptr<SpdyFrame> req2(
12373 spdy_util_.ConstructSpdyGet(url2.c_str(), false, 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1712374
12375 MockWrite writes2[] = {
12376 CreateMockWrite(*req2, 0),
12377 };
12378
[email protected]23e482282013-06-14 16:08:0212379 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12380 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1712381 MockRead reads2[] = {
12382 CreateMockRead(*resp2, 1),
12383 CreateMockRead(*body2, 2),
12384 MockRead(ASYNC, OK, 3) // EOF
12385 };
12386
12387 scoped_ptr<DeterministicSocketData> data2(
12388 new DeterministicSocketData(reads2, arraysize(reads2),
12389 writes2, arraysize(writes2)));
12390 MockConnect connect_data2(ASYNC, OK);
12391 data2->set_connect_data(connect_data2);
12392
12393 // Set up a proxy config that sends HTTP requests to a proxy, and
12394 // all others direct.
12395 ProxyConfig proxy_config;
12396 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
[email protected]bb88e1d32013-05-03 23:11:0712397 session_deps_.proxy_service.reset(new ProxyService(
sammc5dd160c2015-04-02 02:43:1312398 new ProxyConfigServiceFixed(proxy_config), nullptr, NULL));
[email protected]2d88e7d2012-07-19 17:55:1712399
bncce36dca22015-04-21 22:11:2312400 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
12401 ssl1.SetNextProto(GetParam());
[email protected]2d88e7d2012-07-19 17:55:1712402 // Load a valid cert. Note, that this does not need to
12403 // be valid for proxy because the MockSSLClientSocket does
12404 // not actually verify it. But SpdySession will use this
12405 // to see if it is valid for the new origin
bncce36dca22015-04-21 22:11:2312406 ssl1.cert = ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
12407 ASSERT_TRUE(ssl1.cert.get());
[email protected]bb88e1d32013-05-03 23:11:0712408 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
12409 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
12410 data1.get());
[email protected]2d88e7d2012-07-19 17:55:1712411
12412 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
[email protected]23e482282013-06-14 16:08:0212413 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0712414 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
12415 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
12416 data2.get());
[email protected]2d88e7d2012-07-19 17:55:1712417
[email protected]bb88e1d32013-05-03 23:11:0712418 session_deps_.host_resolver.reset(new MockCachingHostResolver());
bncce36dca22015-04-21 22:11:2312419 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0712420 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1712421
12422 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0712423 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]2d88e7d2012-07-19 17:55:1712424
12425 // Start the first transaction to set up the SpdySession
12426 HttpRequestInfo request1;
12427 request1.method = "GET";
12428 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1712429 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012430 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1712431 TestCompletionCallback callback1;
12432 ASSERT_EQ(ERR_IO_PENDING,
12433 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
12434 data1->RunFor(3);
12435
12436 ASSERT_TRUE(callback1.have_result());
12437 EXPECT_EQ(OK, callback1.WaitForResult());
12438 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
12439
12440 // Now, start the HTTP request
12441 HttpRequestInfo request2;
12442 request2.method = "GET";
12443 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1712444 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012445 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1712446 TestCompletionCallback callback2;
12447 EXPECT_EQ(ERR_IO_PENDING,
12448 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412449 base::MessageLoop::current()->RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1712450 data2->RunFor(3);
12451
12452 ASSERT_TRUE(callback2.have_result());
12453 EXPECT_EQ(OK, callback2.WaitForResult());
12454 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
12455}
12456
[email protected]85f97342013-04-17 06:12:2412457// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
12458// error) in SPDY session, removes the socket from pool and closes the SPDY
12459// session. Verify that new url's from the same HttpNetworkSession (and a new
12460// SpdySession) do work. http://crbug.com/224701
[email protected]23e482282013-06-14 16:08:0212461TEST_P(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2312462 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2412463
12464 MockRead reads1[] = {
12465 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
12466 };
12467
12468 scoped_ptr<DeterministicSocketData> data1(
12469 new DeterministicSocketData(reads1, arraysize(reads1), NULL, 0));
12470 data1->SetStop(1);
12471
[email protected]cdf8f7e72013-05-23 10:56:4612472 scoped_ptr<SpdyFrame> req2(
12473 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2412474 MockWrite writes2[] = {
12475 CreateMockWrite(*req2, 0),
12476 };
12477
[email protected]23e482282013-06-14 16:08:0212478 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12479 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]85f97342013-04-17 06:12:2412480 MockRead reads2[] = {
12481 CreateMockRead(*resp2, 1),
12482 CreateMockRead(*body2, 2),
12483 MockRead(ASYNC, OK, 3) // EOF
12484 };
12485
12486 scoped_ptr<DeterministicSocketData> data2(
12487 new DeterministicSocketData(reads2, arraysize(reads2),
12488 writes2, arraysize(writes2)));
12489
[email protected]85f97342013-04-17 06:12:2412490 SSLSocketDataProvider ssl1(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212491 ssl1.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0712492 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
12493 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
12494 data1.get());
[email protected]85f97342013-04-17 06:12:2412495
12496 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212497 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0712498 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
12499 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
12500 data2.get());
[email protected]85f97342013-04-17 06:12:2412501
12502 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0712503 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]85f97342013-04-17 06:12:2412504
12505 // Start the first transaction to set up the SpdySession and verify that
12506 // connection was closed.
12507 HttpRequestInfo request1;
12508 request1.method = "GET";
12509 request1.url = GURL(https_url);
12510 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012511 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2412512 TestCompletionCallback callback1;
12513 EXPECT_EQ(ERR_IO_PENDING,
12514 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412515 base::MessageLoop::current()->RunUntilIdle();
[email protected]85f97342013-04-17 06:12:2412516 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback1.WaitForResult());
12517
12518 // Now, start the second request and make sure it succeeds.
12519 HttpRequestInfo request2;
12520 request2.method = "GET";
12521 request2.url = GURL(https_url);
12522 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012523 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2412524 TestCompletionCallback callback2;
12525 EXPECT_EQ(ERR_IO_PENDING,
12526 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412527 base::MessageLoop::current()->RunUntilIdle();
[email protected]85f97342013-04-17 06:12:2412528 data2->RunFor(3);
12529
12530 ASSERT_TRUE(callback2.have_result());
12531 EXPECT_EQ(OK, callback2.WaitForResult());
12532 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
12533}
12534
[email protected]23e482282013-06-14 16:08:0212535TEST_P(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]d7599122014-05-24 03:37:2312536 session_deps_.next_protos = SpdyNextProtos();
[email protected]483fa202013-05-14 01:07:0312537 ClientSocketPoolManager::set_max_sockets_per_group(
12538 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12539 ClientSocketPoolManager::set_max_sockets_per_pool(
12540 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12541
12542 // Use two different hosts with different IPs so they don't get pooled.
12543 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
12544 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
12545 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12546
12547 SSLSocketDataProvider ssl1(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212548 ssl1.SetNextProto(GetParam());
[email protected]483fa202013-05-14 01:07:0312549 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212550 ssl2.SetNextProto(GetParam());
[email protected]483fa202013-05-14 01:07:0312551 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
12552 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
12553
[email protected]cdf8f7e72013-05-23 10:56:4612554 scoped_ptr<SpdyFrame> host1_req(spdy_util_.ConstructSpdyGet(
[email protected]483fa202013-05-14 01:07:0312555 "https://www.a.com", false, 1, DEFAULT_PRIORITY));
12556 MockWrite spdy1_writes[] = {
rch8e6c6c42015-05-01 14:05:1312557 CreateMockWrite(*host1_req, 0),
[email protected]483fa202013-05-14 01:07:0312558 };
[email protected]23e482282013-06-14 16:08:0212559 scoped_ptr<SpdyFrame> host1_resp(
12560 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12561 scoped_ptr<SpdyFrame> host1_resp_body(
12562 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0312563 MockRead spdy1_reads[] = {
rch8e6c6c42015-05-01 14:05:1312564 CreateMockRead(*host1_resp, 1),
12565 CreateMockRead(*host1_resp_body, 2),
12566 MockRead(ASYNC, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0312567 };
12568
rch8e6c6c42015-05-01 14:05:1312569 scoped_ptr<SequencedSocketData> spdy1_data(
12570 new SequencedSocketData(spdy1_reads, arraysize(spdy1_reads), spdy1_writes,
12571 arraysize(spdy1_writes)));
[email protected]483fa202013-05-14 01:07:0312572 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
12573
[email protected]cdf8f7e72013-05-23 10:56:4612574 scoped_ptr<SpdyFrame> host2_req(spdy_util_.ConstructSpdyGet(
[email protected]483fa202013-05-14 01:07:0312575 "https://www.b.com", false, 1, DEFAULT_PRIORITY));
12576 MockWrite spdy2_writes[] = {
rch8e6c6c42015-05-01 14:05:1312577 CreateMockWrite(*host2_req, 0),
[email protected]483fa202013-05-14 01:07:0312578 };
[email protected]23e482282013-06-14 16:08:0212579 scoped_ptr<SpdyFrame> host2_resp(
12580 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12581 scoped_ptr<SpdyFrame> host2_resp_body(
12582 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0312583 MockRead spdy2_reads[] = {
rch8e6c6c42015-05-01 14:05:1312584 CreateMockRead(*host2_resp, 1),
12585 CreateMockRead(*host2_resp_body, 2),
12586 MockRead(ASYNC, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0312587 };
12588
rch8e6c6c42015-05-01 14:05:1312589 scoped_ptr<SequencedSocketData> spdy2_data(
12590 new SequencedSocketData(spdy2_reads, arraysize(spdy2_reads), spdy2_writes,
12591 arraysize(spdy2_writes)));
[email protected]483fa202013-05-14 01:07:0312592 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
12593
12594 MockWrite http_write[] = {
12595 MockWrite("GET / HTTP/1.1\r\n"
12596 "Host: www.a.com\r\n"
12597 "Connection: keep-alive\r\n\r\n"),
12598 };
12599
12600 MockRead http_read[] = {
12601 MockRead("HTTP/1.1 200 OK\r\n"),
12602 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12603 MockRead("Content-Length: 6\r\n\r\n"),
12604 MockRead("hello!"),
12605 };
12606 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
12607 http_write, arraysize(http_write));
12608 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12609
12610 HostPortPair host_port_pair_a("www.a.com", 443);
[email protected]e6d017652013-05-17 18:01:4012611 SpdySessionKey spdy_session_key_a(
[email protected]314b03992014-04-01 01:28:5312612 host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0312613 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2612614 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0312615
12616 TestCompletionCallback callback;
12617 HttpRequestInfo request1;
12618 request1.method = "GET";
12619 request1.url = GURL("https://www.a.com/");
12620 request1.load_flags = 0;
12621 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5012622 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0312623
12624 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
12625 EXPECT_EQ(ERR_IO_PENDING, rv);
12626 EXPECT_EQ(OK, callback.WaitForResult());
12627
12628 const HttpResponseInfo* response = trans->GetResponseInfo();
12629 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5012630 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0312631 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12632 EXPECT_TRUE(response->was_fetched_via_spdy);
12633 EXPECT_TRUE(response->was_npn_negotiated);
12634
12635 std::string response_data;
12636 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
12637 EXPECT_EQ("hello!", response_data);
12638 trans.reset();
12639 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2612640 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0312641
12642 HostPortPair host_port_pair_b("www.b.com", 443);
[email protected]e6d017652013-05-17 18:01:4012643 SpdySessionKey spdy_session_key_b(
[email protected]314b03992014-04-01 01:28:5312644 host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0312645 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2612646 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0312647 HttpRequestInfo request2;
12648 request2.method = "GET";
12649 request2.url = GURL("https://www.b.com/");
12650 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012651 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0312652
12653 rv = trans->Start(&request2, callback.callback(), BoundNetLog());
12654 EXPECT_EQ(ERR_IO_PENDING, rv);
12655 EXPECT_EQ(OK, callback.WaitForResult());
12656
12657 response = trans->GetResponseInfo();
12658 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5012659 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0312660 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12661 EXPECT_TRUE(response->was_fetched_via_spdy);
12662 EXPECT_TRUE(response->was_npn_negotiated);
12663 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
12664 EXPECT_EQ("hello!", response_data);
12665 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2612666 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0312667 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2612668 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0312669
12670 HostPortPair host_port_pair_a1("www.a.com", 80);
[email protected]e6d017652013-05-17 18:01:4012671 SpdySessionKey spdy_session_key_a1(
[email protected]314b03992014-04-01 01:28:5312672 host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0312673 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2612674 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0312675 HttpRequestInfo request3;
12676 request3.method = "GET";
12677 request3.url = GURL("http://www.a.com/");
12678 request3.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012679 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0312680
12681 rv = trans->Start(&request3, callback.callback(), BoundNetLog());
12682 EXPECT_EQ(ERR_IO_PENDING, rv);
12683 EXPECT_EQ(OK, callback.WaitForResult());
12684
12685 response = trans->GetResponseInfo();
12686 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5012687 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0312688 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12689 EXPECT_FALSE(response->was_fetched_via_spdy);
12690 EXPECT_FALSE(response->was_npn_negotiated);
12691 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
12692 EXPECT_EQ("hello!", response_data);
12693 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2612694 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0312695 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2612696 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0312697}
12698
[email protected]79e1fd62013-06-20 06:50:0412699TEST_P(HttpNetworkTransactionTest, HttpSyncConnectError) {
12700 HttpRequestInfo request;
12701 request.method = "GET";
bncce36dca22015-04-21 22:11:2312702 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0412703 request.load_flags = 0;
12704
[email protected]3fe8d2f82013-10-17 08:56:0712705 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412706 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112707 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412708
12709 MockConnect mock_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
12710 StaticSocketDataProvider data;
12711 data.set_connect_data(mock_connect);
12712 session_deps_.socket_factory->AddSocketDataProvider(&data);
12713
12714 TestCompletionCallback callback;
12715
12716 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12717 EXPECT_EQ(ERR_IO_PENDING, rv);
12718
12719 rv = callback.WaitForResult();
12720 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
12721
[email protected]79e1fd62013-06-20 06:50:0412722 // We don't care whether this succeeds or fails, but it shouldn't crash.
12723 HttpRequestHeaders request_headers;
12724 trans->GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4712725
12726 ConnectionAttempts attempts;
12727 trans->GetConnectionAttempts(&attempts);
12728 ASSERT_EQ(1u, attempts.size());
12729 EXPECT_EQ(ERR_CONNECTION_REFUSED, attempts[0].result);
[email protected]79e1fd62013-06-20 06:50:0412730}
12731
12732TEST_P(HttpNetworkTransactionTest, HttpAsyncConnectError) {
12733 HttpRequestInfo request;
12734 request.method = "GET";
bncce36dca22015-04-21 22:11:2312735 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0412736 request.load_flags = 0;
12737
[email protected]3fe8d2f82013-10-17 08:56:0712738 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412739 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112740 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412741
12742 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
12743 StaticSocketDataProvider data;
12744 data.set_connect_data(mock_connect);
12745 session_deps_.socket_factory->AddSocketDataProvider(&data);
12746
12747 TestCompletionCallback callback;
12748
12749 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12750 EXPECT_EQ(ERR_IO_PENDING, rv);
12751
12752 rv = callback.WaitForResult();
12753 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
12754
[email protected]79e1fd62013-06-20 06:50:0412755 // We don't care whether this succeeds or fails, but it shouldn't crash.
12756 HttpRequestHeaders request_headers;
12757 trans->GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4712758
12759 ConnectionAttempts attempts;
12760 trans->GetConnectionAttempts(&attempts);
12761 ASSERT_EQ(1u, attempts.size());
12762 EXPECT_EQ(ERR_CONNECTION_REFUSED, attempts[0].result);
[email protected]79e1fd62013-06-20 06:50:0412763}
12764
12765TEST_P(HttpNetworkTransactionTest, HttpSyncWriteError) {
12766 HttpRequestInfo request;
12767 request.method = "GET";
bncce36dca22015-04-21 22:11:2312768 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0412769 request.load_flags = 0;
12770
[email protected]3fe8d2f82013-10-17 08:56:0712771 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412772 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112773 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412774
12775 MockWrite data_writes[] = {
12776 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
12777 };
12778 MockRead data_reads[] = {
12779 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
12780 };
12781
12782 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12783 data_writes, arraysize(data_writes));
12784 session_deps_.socket_factory->AddSocketDataProvider(&data);
12785
12786 TestCompletionCallback callback;
12787
12788 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12789 EXPECT_EQ(ERR_IO_PENDING, rv);
12790
12791 rv = callback.WaitForResult();
12792 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12793
[email protected]79e1fd62013-06-20 06:50:0412794 HttpRequestHeaders request_headers;
12795 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12796 EXPECT_TRUE(request_headers.HasHeader("Host"));
12797}
12798
12799TEST_P(HttpNetworkTransactionTest, HttpAsyncWriteError) {
12800 HttpRequestInfo request;
12801 request.method = "GET";
bncce36dca22015-04-21 22:11:2312802 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0412803 request.load_flags = 0;
12804
[email protected]3fe8d2f82013-10-17 08:56:0712805 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412806 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112807 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412808
12809 MockWrite data_writes[] = {
12810 MockWrite(ASYNC, ERR_CONNECTION_RESET),
12811 };
12812 MockRead data_reads[] = {
12813 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
12814 };
12815
12816 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12817 data_writes, arraysize(data_writes));
12818 session_deps_.socket_factory->AddSocketDataProvider(&data);
12819
12820 TestCompletionCallback callback;
12821
12822 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12823 EXPECT_EQ(ERR_IO_PENDING, rv);
12824
12825 rv = callback.WaitForResult();
12826 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12827
[email protected]79e1fd62013-06-20 06:50:0412828 HttpRequestHeaders request_headers;
12829 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12830 EXPECT_TRUE(request_headers.HasHeader("Host"));
12831}
12832
12833TEST_P(HttpNetworkTransactionTest, HttpSyncReadError) {
12834 HttpRequestInfo request;
12835 request.method = "GET";
bncce36dca22015-04-21 22:11:2312836 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0412837 request.load_flags = 0;
12838
[email protected]3fe8d2f82013-10-17 08:56:0712839 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412840 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112841 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412842
12843 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2312844 MockWrite(
12845 "GET / HTTP/1.1\r\n"
12846 "Host: www.example.org\r\n"
12847 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0412848 };
12849 MockRead data_reads[] = {
12850 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
12851 };
12852
12853 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12854 data_writes, arraysize(data_writes));
12855 session_deps_.socket_factory->AddSocketDataProvider(&data);
12856
12857 TestCompletionCallback callback;
12858
12859 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12860 EXPECT_EQ(ERR_IO_PENDING, rv);
12861
12862 rv = callback.WaitForResult();
12863 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12864
[email protected]79e1fd62013-06-20 06:50:0412865 HttpRequestHeaders request_headers;
12866 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12867 EXPECT_TRUE(request_headers.HasHeader("Host"));
12868}
12869
12870TEST_P(HttpNetworkTransactionTest, HttpAsyncReadError) {
12871 HttpRequestInfo request;
12872 request.method = "GET";
bncce36dca22015-04-21 22:11:2312873 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0412874 request.load_flags = 0;
12875
[email protected]3fe8d2f82013-10-17 08:56:0712876 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412877 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112878 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412879
12880 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2312881 MockWrite(
12882 "GET / HTTP/1.1\r\n"
12883 "Host: www.example.org\r\n"
12884 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0412885 };
12886 MockRead data_reads[] = {
12887 MockRead(ASYNC, ERR_CONNECTION_RESET),
12888 };
12889
12890 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12891 data_writes, arraysize(data_writes));
12892 session_deps_.socket_factory->AddSocketDataProvider(&data);
12893
12894 TestCompletionCallback callback;
12895
12896 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12897 EXPECT_EQ(ERR_IO_PENDING, rv);
12898
12899 rv = callback.WaitForResult();
12900 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12901
[email protected]79e1fd62013-06-20 06:50:0412902 HttpRequestHeaders request_headers;
12903 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12904 EXPECT_TRUE(request_headers.HasHeader("Host"));
12905}
12906
12907TEST_P(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
12908 HttpRequestInfo request;
12909 request.method = "GET";
bncce36dca22015-04-21 22:11:2312910 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0412911 request.load_flags = 0;
12912 request.extra_headers.SetHeader("X-Foo", "bar");
12913
[email protected]3fe8d2f82013-10-17 08:56:0712914 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412915 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112916 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412917
12918 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2312919 MockWrite(
12920 "GET / HTTP/1.1\r\n"
12921 "Host: www.example.org\r\n"
12922 "Connection: keep-alive\r\n"
12923 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0412924 };
12925 MockRead data_reads[] = {
12926 MockRead("HTTP/1.1 200 OK\r\n"
12927 "Content-Length: 5\r\n\r\n"
12928 "hello"),
12929 MockRead(ASYNC, ERR_UNEXPECTED),
12930 };
12931
12932 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12933 data_writes, arraysize(data_writes));
12934 session_deps_.socket_factory->AddSocketDataProvider(&data);
12935
12936 TestCompletionCallback callback;
12937
12938 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12939 EXPECT_EQ(ERR_IO_PENDING, rv);
12940
12941 rv = callback.WaitForResult();
12942 EXPECT_EQ(OK, rv);
12943
12944 HttpRequestHeaders request_headers;
12945 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12946 std::string foo;
12947 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
12948 EXPECT_EQ("bar", foo);
12949}
12950
[email protected]bf828982013-08-14 18:01:4712951namespace {
12952
yhiranoa7e05bb2014-11-06 05:40:3912953// Fake HttpStream that simply records calls to SetPriority().
12954class FakeStream : public HttpStream,
[email protected]e86839fd2013-08-14 18:29:0312955 public base::SupportsWeakPtr<FakeStream> {
12956 public:
12957 explicit FakeStream(RequestPriority priority) : priority_(priority) {}
dchengb03027d2014-10-21 12:00:2012958 ~FakeStream() override {}
[email protected]e86839fd2013-08-14 18:29:0312959
12960 RequestPriority priority() const { return priority_; }
12961
dchengb03027d2014-10-21 12:00:2012962 int InitializeStream(const HttpRequestInfo* request_info,
12963 RequestPriority priority,
12964 const BoundNetLog& net_log,
12965 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0312966 return ERR_IO_PENDING;
12967 }
12968
dchengb03027d2014-10-21 12:00:2012969 int SendRequest(const HttpRequestHeaders& request_headers,
12970 HttpResponseInfo* response,
12971 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0312972 ADD_FAILURE();
12973 return ERR_UNEXPECTED;
12974 }
12975
dchengb03027d2014-10-21 12:00:2012976 int ReadResponseHeaders(const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0312977 ADD_FAILURE();
12978 return ERR_UNEXPECTED;
12979 }
12980
dchengb03027d2014-10-21 12:00:2012981 int ReadResponseBody(IOBuffer* buf,
12982 int buf_len,
12983 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0312984 ADD_FAILURE();
12985 return ERR_UNEXPECTED;
12986 }
12987
dchengb03027d2014-10-21 12:00:2012988 void Close(bool not_reusable) override {}
[email protected]e86839fd2013-08-14 18:29:0312989
dchengb03027d2014-10-21 12:00:2012990 bool IsResponseBodyComplete() const override {
[email protected]e86839fd2013-08-14 18:29:0312991 ADD_FAILURE();
12992 return false;
12993 }
12994
dchengb03027d2014-10-21 12:00:2012995 bool CanFindEndOfResponse() const override { return false; }
[email protected]e86839fd2013-08-14 18:29:0312996
dchengb03027d2014-10-21 12:00:2012997 bool IsConnectionReused() const override {
[email protected]e86839fd2013-08-14 18:29:0312998 ADD_FAILURE();
12999 return false;
13000 }
13001
dchengb03027d2014-10-21 12:00:2013002 void SetConnectionReused() override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0313003
dchengb03027d2014-10-21 12:00:2013004 bool IsConnectionReusable() const override {
[email protected]e86839fd2013-08-14 18:29:0313005 ADD_FAILURE();
13006 return false;
13007 }
13008
dchengb03027d2014-10-21 12:00:2013009 int64 GetTotalReceivedBytes() const override {
[email protected]bc92bc972013-12-13 08:32:5913010 ADD_FAILURE();
13011 return 0;
13012 }
13013
dchengb03027d2014-10-21 12:00:2013014 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
[email protected]e86839fd2013-08-14 18:29:0313015 ADD_FAILURE();
13016 return false;
13017 }
13018
dchengb03027d2014-10-21 12:00:2013019 void GetSSLInfo(SSLInfo* ssl_info) override { ADD_FAILURE(); }
13020
13021 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
[email protected]e86839fd2013-08-14 18:29:0313022 ADD_FAILURE();
13023 }
13024
dchengb03027d2014-10-21 12:00:2013025 bool IsSpdyHttpStream() const override {
[email protected]e86839fd2013-08-14 18:29:0313026 ADD_FAILURE();
13027 return false;
13028 }
13029
dchengb03027d2014-10-21 12:00:2013030 void Drain(HttpNetworkSession* session) override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0313031
dchengb03027d2014-10-21 12:00:2013032 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]e86839fd2013-08-14 18:29:0313033
yhiranoa7e05bb2014-11-06 05:40:3913034 UploadProgress GetUploadProgress() const override { return UploadProgress(); }
13035
13036 HttpStream* RenewStreamForAuth() override { return NULL; }
13037
[email protected]e86839fd2013-08-14 18:29:0313038 private:
13039 RequestPriority priority_;
13040
13041 DISALLOW_COPY_AND_ASSIGN(FakeStream);
13042};
13043
13044// Fake HttpStreamRequest that simply records calls to SetPriority()
13045// and vends FakeStreams with its current priority.
[email protected]bf828982013-08-14 18:01:4713046class FakeStreamRequest : public HttpStreamRequest,
13047 public base::SupportsWeakPtr<FakeStreamRequest> {
13048 public:
[email protected]e86839fd2013-08-14 18:29:0313049 FakeStreamRequest(RequestPriority priority,
13050 HttpStreamRequest::Delegate* delegate)
13051 : priority_(priority),
[email protected]831e4a32013-11-14 02:14:4413052 delegate_(delegate),
13053 websocket_stream_create_helper_(NULL) {}
13054
13055 FakeStreamRequest(RequestPriority priority,
13056 HttpStreamRequest::Delegate* delegate,
13057 WebSocketHandshakeStreamBase::CreateHelper* create_helper)
13058 : priority_(priority),
13059 delegate_(delegate),
13060 websocket_stream_create_helper_(create_helper) {}
[email protected]e86839fd2013-08-14 18:29:0313061
dchengb03027d2014-10-21 12:00:2013062 ~FakeStreamRequest() override {}
[email protected]bf828982013-08-14 18:01:4713063
13064 RequestPriority priority() const { return priority_; }
13065
[email protected]831e4a32013-11-14 02:14:4413066 const WebSocketHandshakeStreamBase::CreateHelper*
13067 websocket_stream_create_helper() const {
13068 return websocket_stream_create_helper_;
13069 }
13070
[email protected]e86839fd2013-08-14 18:29:0313071 // Create a new FakeStream and pass it to the request's
13072 // delegate. Returns a weak pointer to the FakeStream.
13073 base::WeakPtr<FakeStream> FinishStreamRequest() {
13074 FakeStream* fake_stream = new FakeStream(priority_);
13075 // Do this before calling OnStreamReady() as OnStreamReady() may
13076 // immediately delete |fake_stream|.
13077 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
13078 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), fake_stream);
13079 return weak_stream;
13080 }
13081
dchengb03027d2014-10-21 12:00:2013082 int RestartTunnelWithProxyAuth(const AuthCredentials& credentials) override {
[email protected]bf828982013-08-14 18:01:4713083 ADD_FAILURE();
13084 return ERR_UNEXPECTED;
13085 }
13086
dchengb03027d2014-10-21 12:00:2013087 LoadState GetLoadState() const override {
[email protected]bf828982013-08-14 18:01:4713088 ADD_FAILURE();
13089 return LoadState();
13090 }
13091
dchengb03027d2014-10-21 12:00:2013092 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]bf828982013-08-14 18:01:4713093
dchengb03027d2014-10-21 12:00:2013094 bool was_npn_negotiated() const override { return false; }
[email protected]bf828982013-08-14 18:01:4713095
dchengb03027d2014-10-21 12:00:2013096 NextProto protocol_negotiated() const override { return kProtoUnknown; }
[email protected]bf828982013-08-14 18:01:4713097
dchengb03027d2014-10-21 12:00:2013098 bool using_spdy() const override { return false; }
[email protected]bf828982013-08-14 18:01:4713099
ttuttle1f2d7e92015-04-28 16:17:4713100 const ConnectionAttempts& connection_attempts() const override {
13101 static ConnectionAttempts no_attempts;
13102 return no_attempts;
13103 }
13104
[email protected]bf828982013-08-14 18:01:4713105 private:
13106 RequestPriority priority_;
[email protected]e86839fd2013-08-14 18:29:0313107 HttpStreamRequest::Delegate* const delegate_;
[email protected]831e4a32013-11-14 02:14:4413108 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
[email protected]bf828982013-08-14 18:01:4713109
13110 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
13111};
13112
13113// Fake HttpStreamFactory that vends FakeStreamRequests.
13114class FakeStreamFactory : public HttpStreamFactory {
13115 public:
13116 FakeStreamFactory() {}
dchengb03027d2014-10-21 12:00:2013117 ~FakeStreamFactory() override {}
[email protected]bf828982013-08-14 18:01:4713118
13119 // Returns a WeakPtr<> to the last HttpStreamRequest returned by
13120 // RequestStream() (which may be NULL if it was destroyed already).
13121 base::WeakPtr<FakeStreamRequest> last_stream_request() {
13122 return last_stream_request_;
13123 }
13124
dchengb03027d2014-10-21 12:00:2013125 HttpStreamRequest* RequestStream(const HttpRequestInfo& info,
13126 RequestPriority priority,
13127 const SSLConfig& server_ssl_config,
13128 const SSLConfig& proxy_ssl_config,
13129 HttpStreamRequest::Delegate* delegate,
13130 const BoundNetLog& net_log) override {
[email protected]e86839fd2013-08-14 18:29:0313131 FakeStreamRequest* fake_request = new FakeStreamRequest(priority, delegate);
[email protected]bf828982013-08-14 18:01:4713132 last_stream_request_ = fake_request->AsWeakPtr();
13133 return fake_request;
13134 }
13135
dchengb03027d2014-10-21 12:00:2013136 HttpStreamRequest* RequestWebSocketHandshakeStream(
[email protected]bf828982013-08-14 18:01:4713137 const HttpRequestInfo& info,
13138 RequestPriority priority,
13139 const SSLConfig& server_ssl_config,
13140 const SSLConfig& proxy_ssl_config,
13141 HttpStreamRequest::Delegate* delegate,
[email protected]467086b2013-11-12 08:19:4613142 WebSocketHandshakeStreamBase::CreateHelper* create_helper,
mostynbba063d6032014-10-09 11:01:1313143 const BoundNetLog& net_log) override {
[email protected]831e4a32013-11-14 02:14:4413144 FakeStreamRequest* fake_request =
13145 new FakeStreamRequest(priority, delegate, create_helper);
13146 last_stream_request_ = fake_request->AsWeakPtr();
13147 return fake_request;
[email protected]bf828982013-08-14 18:01:4713148 }
13149
dchengb03027d2014-10-21 12:00:2013150 void PreconnectStreams(int num_streams,
13151 const HttpRequestInfo& info,
13152 RequestPriority priority,
13153 const SSLConfig& server_ssl_config,
13154 const SSLConfig& proxy_ssl_config) override {
[email protected]bf828982013-08-14 18:01:4713155 ADD_FAILURE();
13156 }
13157
dchengb03027d2014-10-21 12:00:2013158 const HostMappingRules* GetHostMappingRules() const override {
[email protected]bf828982013-08-14 18:01:4713159 ADD_FAILURE();
13160 return NULL;
13161 }
13162
13163 private:
13164 base::WeakPtr<FakeStreamRequest> last_stream_request_;
13165
13166 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
13167};
13168
Adam Rice425cf122015-01-19 06:18:2413169// TODO(ricea): Maybe unify this with the one in
13170// url_request_http_job_unittest.cc ?
13171class FakeWebSocketBasicHandshakeStream : public WebSocketHandshakeStreamBase {
13172 public:
13173 FakeWebSocketBasicHandshakeStream(scoped_ptr<ClientSocketHandle> connection,
13174 bool using_proxy)
13175 : state_(connection.release(), using_proxy) {}
13176
13177 // Fake implementation of HttpStreamBase methods.
13178 // This ends up being quite "real" because this object has to really send data
13179 // on the mock socket. It might be easier to use the real implementation, but
13180 // the fact that the WebSocket code is not compiled on iOS makes that
13181 // difficult.
13182 int InitializeStream(const HttpRequestInfo* request_info,
13183 RequestPriority priority,
13184 const BoundNetLog& net_log,
13185 const CompletionCallback& callback) override {
13186 state_.Initialize(request_info, priority, net_log, callback);
13187 return OK;
13188 }
13189
13190 int SendRequest(const HttpRequestHeaders& request_headers,
13191 HttpResponseInfo* response,
13192 const CompletionCallback& callback) override {
13193 return parser()->SendRequest(state_.GenerateRequestLine(), request_headers,
13194 response, callback);
13195 }
13196
13197 int ReadResponseHeaders(const CompletionCallback& callback) override {
13198 return parser()->ReadResponseHeaders(callback);
13199 }
13200
13201 int ReadResponseBody(IOBuffer* buf,
13202 int buf_len,
13203 const CompletionCallback& callback) override {
13204 NOTREACHED();
13205 return ERR_IO_PENDING;
13206 }
13207
13208 void Close(bool not_reusable) override {
13209 if (parser())
13210 parser()->Close(true);
13211 }
13212
13213 bool IsResponseBodyComplete() const override {
13214 NOTREACHED();
13215 return false;
13216 }
13217
13218 bool CanFindEndOfResponse() const override {
13219 return parser()->CanFindEndOfResponse();
13220 }
13221
13222 bool IsConnectionReused() const override {
13223 NOTREACHED();
13224 return false;
13225 }
13226 void SetConnectionReused() override { NOTREACHED(); }
13227
13228 bool IsConnectionReusable() const override {
13229 NOTREACHED();
13230 return false;
13231 }
13232
13233 int64 GetTotalReceivedBytes() const override {
13234 NOTREACHED();
13235 return 0;
13236 }
13237
13238 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
13239 NOTREACHED();
13240 return false;
13241 }
13242
Adam Ricecb76ac62015-02-20 05:33:2513243 void GetSSLInfo(SSLInfo* ssl_info) override {}
Adam Rice425cf122015-01-19 06:18:2413244
13245 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
13246 NOTREACHED();
13247 }
13248
13249 bool IsSpdyHttpStream() const override {
13250 NOTREACHED();
13251 return false;
13252 }
13253
13254 void Drain(HttpNetworkSession* session) override { NOTREACHED(); }
13255
13256 void SetPriority(RequestPriority priority) override { NOTREACHED(); }
13257
13258 UploadProgress GetUploadProgress() const override {
13259 NOTREACHED();
13260 return UploadProgress();
13261 }
13262
13263 HttpStream* RenewStreamForAuth() override {
13264 NOTREACHED();
13265 return nullptr;
13266 }
13267
13268 // Fake implementation of WebSocketHandshakeStreamBase method(s)
13269 scoped_ptr<WebSocketStream> Upgrade() override {
13270 NOTREACHED();
13271 return scoped_ptr<WebSocketStream>();
13272 }
13273
13274 private:
13275 HttpStreamParser* parser() const { return state_.parser(); }
13276 HttpBasicState state_;
13277
13278 DISALLOW_COPY_AND_ASSIGN(FakeWebSocketBasicHandshakeStream);
13279};
13280
[email protected]831e4a32013-11-14 02:14:4413281// TODO(yhirano): Split this class out into a net/websockets file, if it is
13282// worth doing.
13283class FakeWebSocketStreamCreateHelper :
13284 public WebSocketHandshakeStreamBase::CreateHelper {
13285 public:
dchengb03027d2014-10-21 12:00:2013286 WebSocketHandshakeStreamBase* CreateBasicStream(
[email protected]7e841a52013-11-22 09:04:2113287 scoped_ptr<ClientSocketHandle> connection,
mostynbba063d6032014-10-09 11:01:1313288 bool using_proxy) override {
Adam Rice425cf122015-01-19 06:18:2413289 return new FakeWebSocketBasicHandshakeStream(connection.Pass(),
13290 using_proxy);
[email protected]831e4a32013-11-14 02:14:4413291 }
13292
dchengb03027d2014-10-21 12:00:2013293 WebSocketHandshakeStreamBase* CreateSpdyStream(
[email protected]831e4a32013-11-14 02:14:4413294 const base::WeakPtr<SpdySession>& session,
mostynbba063d6032014-10-09 11:01:1313295 bool use_relative_url) override {
[email protected]831e4a32013-11-14 02:14:4413296 NOTREACHED();
13297 return NULL;
13298 };
13299
dchengb03027d2014-10-21 12:00:2013300 ~FakeWebSocketStreamCreateHelper() override {}
[email protected]831e4a32013-11-14 02:14:4413301
13302 virtual scoped_ptr<WebSocketStream> Upgrade() {
13303 NOTREACHED();
13304 return scoped_ptr<WebSocketStream>();
13305 }
13306};
13307
[email protected]bf828982013-08-14 18:01:4713308} // namespace
13309
13310// Make sure that HttpNetworkTransaction passes on its priority to its
13311// stream request on start.
13312TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
13313 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13314 HttpNetworkSessionPeer peer(session);
13315 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4413316 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4713317
dcheng48459ac22014-08-26 00:46:4113318 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4713319
13320 ASSERT_TRUE(fake_factory->last_stream_request() == NULL);
13321
13322 HttpRequestInfo request;
13323 TestCompletionCallback callback;
13324 EXPECT_EQ(ERR_IO_PENDING,
13325 trans.Start(&request, callback.callback(), BoundNetLog()));
13326
13327 base::WeakPtr<FakeStreamRequest> fake_request =
13328 fake_factory->last_stream_request();
13329 ASSERT_TRUE(fake_request != NULL);
13330 EXPECT_EQ(LOW, fake_request->priority());
13331}
13332
13333// Make sure that HttpNetworkTransaction passes on its priority
13334// updates to its stream request.
13335TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriority) {
13336 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13337 HttpNetworkSessionPeer peer(session);
13338 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4413339 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4713340
dcheng48459ac22014-08-26 00:46:4113341 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4713342
13343 HttpRequestInfo request;
13344 TestCompletionCallback callback;
13345 EXPECT_EQ(ERR_IO_PENDING,
13346 trans.Start(&request, callback.callback(), BoundNetLog()));
13347
13348 base::WeakPtr<FakeStreamRequest> fake_request =
13349 fake_factory->last_stream_request();
13350 ASSERT_TRUE(fake_request != NULL);
13351 EXPECT_EQ(LOW, fake_request->priority());
13352
13353 trans.SetPriority(LOWEST);
13354 ASSERT_TRUE(fake_request != NULL);
13355 EXPECT_EQ(LOWEST, fake_request->priority());
13356}
13357
[email protected]e86839fd2013-08-14 18:29:0313358// Make sure that HttpNetworkTransaction passes on its priority
13359// updates to its stream.
13360TEST_P(HttpNetworkTransactionTest, SetStreamPriority) {
13361 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13362 HttpNetworkSessionPeer peer(session);
13363 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4413364 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]e86839fd2013-08-14 18:29:0313365
dcheng48459ac22014-08-26 00:46:4113366 HttpNetworkTransaction trans(LOW, session.get());
[email protected]e86839fd2013-08-14 18:29:0313367
13368 HttpRequestInfo request;
13369 TestCompletionCallback callback;
13370 EXPECT_EQ(ERR_IO_PENDING,
13371 trans.Start(&request, callback.callback(), BoundNetLog()));
13372
13373 base::WeakPtr<FakeStreamRequest> fake_request =
13374 fake_factory->last_stream_request();
13375 ASSERT_TRUE(fake_request != NULL);
13376 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
13377 ASSERT_TRUE(fake_stream != NULL);
13378 EXPECT_EQ(LOW, fake_stream->priority());
13379
13380 trans.SetPriority(LOWEST);
13381 EXPECT_EQ(LOWEST, fake_stream->priority());
13382}
13383
[email protected]831e4a32013-11-14 02:14:4413384TEST_P(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
13385 // The same logic needs to be tested for both ws: and wss: schemes, but this
13386 // test is already parameterised on NextProto, so it uses a loop to verify
13387 // that the different schemes work.
bncce36dca22015-04-21 22:11:2313388 std::string test_cases[] = {"ws://www.example.org/",
13389 "wss://www.example.org/"};
[email protected]831e4a32013-11-14 02:14:4413390 for (size_t i = 0; i < arraysize(test_cases); ++i) {
13391 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13392 HttpNetworkSessionPeer peer(session);
13393 FakeStreamFactory* fake_factory = new FakeStreamFactory();
13394 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
[email protected]0191b51c2013-11-18 10:55:2313395 peer.SetHttpStreamFactoryForWebSocket(
[email protected]831e4a32013-11-14 02:14:4413396 scoped_ptr<HttpStreamFactory>(fake_factory));
13397
dcheng48459ac22014-08-26 00:46:4113398 HttpNetworkTransaction trans(LOW, session.get());
[email protected]831e4a32013-11-14 02:14:4413399 trans.SetWebSocketHandshakeStreamCreateHelper(
13400 &websocket_stream_create_helper);
13401
13402 HttpRequestInfo request;
13403 TestCompletionCallback callback;
13404 request.method = "GET";
13405 request.url = GURL(test_cases[i]);
13406
13407 EXPECT_EQ(ERR_IO_PENDING,
13408 trans.Start(&request, callback.callback(), BoundNetLog()));
13409
13410 base::WeakPtr<FakeStreamRequest> fake_request =
13411 fake_factory->last_stream_request();
13412 ASSERT_TRUE(fake_request != NULL);
13413 EXPECT_EQ(&websocket_stream_create_helper,
13414 fake_request->websocket_stream_create_helper());
13415 }
13416}
13417
[email protected]043b68c82013-08-22 23:41:5213418// Tests that when a used socket is returned to the SSL socket pool, it's closed
13419// if the transport socket pool is stalled on the global socket limit.
13420TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
13421 ClientSocketPoolManager::set_max_sockets_per_group(
13422 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13423 ClientSocketPoolManager::set_max_sockets_per_pool(
13424 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13425
13426 // Set up SSL request.
13427
13428 HttpRequestInfo ssl_request;
13429 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2313430 ssl_request.url = GURL("https://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5213431
13432 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2313433 MockWrite(
13434 "GET / HTTP/1.1\r\n"
13435 "Host: www.example.org\r\n"
13436 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5213437 };
13438 MockRead ssl_reads[] = {
13439 MockRead("HTTP/1.1 200 OK\r\n"),
13440 MockRead("Content-Length: 11\r\n\r\n"),
13441 MockRead("hello world"),
13442 MockRead(SYNCHRONOUS, OK),
13443 };
13444 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
13445 ssl_writes, arraysize(ssl_writes));
13446 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
13447
13448 SSLSocketDataProvider ssl(ASYNC, OK);
13449 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13450
13451 // Set up HTTP request.
13452
13453 HttpRequestInfo http_request;
13454 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2313455 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5213456
13457 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2313458 MockWrite(
13459 "GET / HTTP/1.1\r\n"
13460 "Host: www.example.org\r\n"
13461 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5213462 };
13463 MockRead http_reads[] = {
13464 MockRead("HTTP/1.1 200 OK\r\n"),
13465 MockRead("Content-Length: 7\r\n\r\n"),
13466 MockRead("falafel"),
13467 MockRead(SYNCHRONOUS, OK),
13468 };
13469 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
13470 http_writes, arraysize(http_writes));
13471 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13472
13473 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13474
13475 // Start the SSL request.
13476 TestCompletionCallback ssl_callback;
13477 scoped_ptr<HttpTransaction> ssl_trans(
13478 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13479 ASSERT_EQ(ERR_IO_PENDING,
13480 ssl_trans->Start(&ssl_request, ssl_callback.callback(),
13481 BoundNetLog()));
13482
13483 // Start the HTTP request. Pool should stall.
13484 TestCompletionCallback http_callback;
13485 scoped_ptr<HttpTransaction> http_trans(
13486 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13487 ASSERT_EQ(ERR_IO_PENDING,
13488 http_trans->Start(&http_request, http_callback.callback(),
13489 BoundNetLog()));
dcheng48459ac22014-08-26 00:46:4113490 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5213491
13492 // Wait for response from SSL request.
13493 ASSERT_EQ(OK, ssl_callback.WaitForResult());
13494 std::string response_data;
13495 ASSERT_EQ(OK, ReadTransaction(ssl_trans.get(), &response_data));
13496 EXPECT_EQ("hello world", response_data);
13497
13498 // The SSL socket should automatically be closed, so the HTTP request can
13499 // start.
dcheng48459ac22014-08-26 00:46:4113500 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
13501 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5213502
13503 // The HTTP request can now complete.
13504 ASSERT_EQ(OK, http_callback.WaitForResult());
13505 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
13506 EXPECT_EQ("falafel", response_data);
13507
dcheng48459ac22014-08-26 00:46:4113508 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5213509}
13510
13511// Tests that when a SSL connection is established but there's no corresponding
13512// request that needs it, the new socket is closed if the transport socket pool
13513// is stalled on the global socket limit.
13514TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
13515 ClientSocketPoolManager::set_max_sockets_per_group(
13516 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13517 ClientSocketPoolManager::set_max_sockets_per_pool(
13518 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13519
13520 // Set up an ssl request.
13521
13522 HttpRequestInfo ssl_request;
13523 ssl_request.method = "GET";
13524 ssl_request.url = GURL("https://www.foopy.com/");
13525
13526 // No data will be sent on the SSL socket.
13527 StaticSocketDataProvider ssl_data;
13528 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
13529
13530 SSLSocketDataProvider ssl(ASYNC, OK);
13531 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13532
13533 // Set up HTTP request.
13534
13535 HttpRequestInfo http_request;
13536 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2313537 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5213538
13539 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2313540 MockWrite(
13541 "GET / HTTP/1.1\r\n"
13542 "Host: www.example.org\r\n"
13543 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5213544 };
13545 MockRead http_reads[] = {
13546 MockRead("HTTP/1.1 200 OK\r\n"),
13547 MockRead("Content-Length: 7\r\n\r\n"),
13548 MockRead("falafel"),
13549 MockRead(SYNCHRONOUS, OK),
13550 };
13551 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
13552 http_writes, arraysize(http_writes));
13553 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13554
13555 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13556
13557 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
13558 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2913559 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
13560 SSLConfig ssl_config;
[email protected]043b68c82013-08-22 23:41:5213561 session->ssl_config_service()->GetSSLConfig(&ssl_config);
13562 http_stream_factory->PreconnectStreams(1, ssl_request, DEFAULT_PRIORITY,
13563 ssl_config, ssl_config);
dcheng48459ac22014-08-26 00:46:4113564 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5213565
13566 // Start the HTTP request. Pool should stall.
13567 TestCompletionCallback http_callback;
13568 scoped_ptr<HttpTransaction> http_trans(
13569 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13570 ASSERT_EQ(ERR_IO_PENDING,
13571 http_trans->Start(&http_request, http_callback.callback(),
13572 BoundNetLog()));
dcheng48459ac22014-08-26 00:46:4113573 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5213574
13575 // The SSL connection will automatically be closed once the connection is
13576 // established, to let the HTTP request start.
13577 ASSERT_EQ(OK, http_callback.WaitForResult());
13578 std::string response_data;
13579 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
13580 EXPECT_EQ("falafel", response_data);
13581
dcheng48459ac22014-08-26 00:46:4113582 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5213583}
13584
[email protected]02d74a02014-04-23 18:10:5413585TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
13586 ScopedVector<UploadElementReader> element_readers;
13587 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713588 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413589
13590 HttpRequestInfo request;
13591 request.method = "POST";
13592 request.url = GURL("http://www.foo.com/");
13593 request.upload_data_stream = &upload_data_stream;
13594 request.load_flags = 0;
13595
13596 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13597 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113598 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413599 // Send headers successfully, but get an error while sending the body.
13600 MockWrite data_writes[] = {
13601 MockWrite("POST / HTTP/1.1\r\n"
13602 "Host: www.foo.com\r\n"
13603 "Connection: keep-alive\r\n"
13604 "Content-Length: 3\r\n\r\n"),
13605 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13606 };
13607
13608 MockRead data_reads[] = {
13609 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
13610 MockRead("hello world"),
13611 MockRead(SYNCHRONOUS, OK),
13612 };
13613 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13614 arraysize(data_writes));
13615 session_deps_.socket_factory->AddSocketDataProvider(&data);
13616
13617 TestCompletionCallback callback;
13618
13619 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13620 EXPECT_EQ(ERR_IO_PENDING, rv);
13621
13622 rv = callback.WaitForResult();
13623 EXPECT_EQ(OK, rv);
13624
13625 const HttpResponseInfo* response = trans->GetResponseInfo();
13626 ASSERT_TRUE(response != NULL);
13627
13628 EXPECT_TRUE(response->headers.get() != NULL);
13629 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
13630
13631 std::string response_data;
13632 rv = ReadTransaction(trans.get(), &response_data);
13633 EXPECT_EQ(OK, rv);
13634 EXPECT_EQ("hello world", response_data);
13635}
13636
13637// This test makes sure the retry logic doesn't trigger when reading an error
13638// response from a server that rejected a POST with a CONNECTION_RESET.
13639TEST_P(HttpNetworkTransactionTest,
13640 PostReadsErrorResponseAfterResetOnReusedSocket) {
13641 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13642 MockWrite data_writes[] = {
13643 MockWrite("GET / HTTP/1.1\r\n"
13644 "Host: www.foo.com\r\n"
13645 "Connection: keep-alive\r\n\r\n"),
13646 MockWrite("POST / HTTP/1.1\r\n"
13647 "Host: www.foo.com\r\n"
13648 "Connection: keep-alive\r\n"
13649 "Content-Length: 3\r\n\r\n"),
13650 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13651 };
13652
13653 MockRead data_reads[] = {
13654 MockRead("HTTP/1.1 200 Peachy\r\n"
13655 "Content-Length: 14\r\n\r\n"),
13656 MockRead("first response"),
13657 MockRead("HTTP/1.1 400 Not OK\r\n"
13658 "Content-Length: 15\r\n\r\n"),
13659 MockRead("second response"),
13660 MockRead(SYNCHRONOUS, OK),
13661 };
13662 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13663 arraysize(data_writes));
13664 session_deps_.socket_factory->AddSocketDataProvider(&data);
13665
13666 TestCompletionCallback callback;
13667 HttpRequestInfo request1;
13668 request1.method = "GET";
13669 request1.url = GURL("http://www.foo.com/");
13670 request1.load_flags = 0;
13671
13672 scoped_ptr<HttpTransaction> trans1(
dcheng48459ac22014-08-26 00:46:4113673 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413674 int rv = trans1->Start(&request1, callback.callback(), BoundNetLog());
13675 EXPECT_EQ(ERR_IO_PENDING, rv);
13676
13677 rv = callback.WaitForResult();
13678 EXPECT_EQ(OK, rv);
13679
13680 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
13681 ASSERT_TRUE(response1 != NULL);
13682
13683 EXPECT_TRUE(response1->headers.get() != NULL);
13684 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
13685
13686 std::string response_data1;
13687 rv = ReadTransaction(trans1.get(), &response_data1);
13688 EXPECT_EQ(OK, rv);
13689 EXPECT_EQ("first response", response_data1);
13690 // Delete the transaction to release the socket back into the socket pool.
13691 trans1.reset();
13692
13693 ScopedVector<UploadElementReader> element_readers;
13694 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713695 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413696
13697 HttpRequestInfo request2;
13698 request2.method = "POST";
13699 request2.url = GURL("http://www.foo.com/");
13700 request2.upload_data_stream = &upload_data_stream;
13701 request2.load_flags = 0;
13702
13703 scoped_ptr<HttpTransaction> trans2(
dcheng48459ac22014-08-26 00:46:4113704 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413705 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
13706 EXPECT_EQ(ERR_IO_PENDING, rv);
13707
13708 rv = callback.WaitForResult();
13709 EXPECT_EQ(OK, rv);
13710
13711 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
13712 ASSERT_TRUE(response2 != NULL);
13713
13714 EXPECT_TRUE(response2->headers.get() != NULL);
13715 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
13716
13717 std::string response_data2;
13718 rv = ReadTransaction(trans2.get(), &response_data2);
13719 EXPECT_EQ(OK, rv);
13720 EXPECT_EQ("second response", response_data2);
13721}
13722
13723TEST_P(HttpNetworkTransactionTest,
13724 PostReadsErrorResponseAfterResetPartialBodySent) {
13725 ScopedVector<UploadElementReader> element_readers;
13726 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713727 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413728
13729 HttpRequestInfo request;
13730 request.method = "POST";
13731 request.url = GURL("http://www.foo.com/");
13732 request.upload_data_stream = &upload_data_stream;
13733 request.load_flags = 0;
13734
13735 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13736 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113737 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413738 // Send headers successfully, but get an error while sending the body.
13739 MockWrite data_writes[] = {
13740 MockWrite("POST / HTTP/1.1\r\n"
13741 "Host: www.foo.com\r\n"
13742 "Connection: keep-alive\r\n"
13743 "Content-Length: 3\r\n\r\n"
13744 "fo"),
13745 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13746 };
13747
13748 MockRead data_reads[] = {
13749 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
13750 MockRead("hello world"),
13751 MockRead(SYNCHRONOUS, OK),
13752 };
13753 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13754 arraysize(data_writes));
13755 session_deps_.socket_factory->AddSocketDataProvider(&data);
13756
13757 TestCompletionCallback callback;
13758
13759 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13760 EXPECT_EQ(ERR_IO_PENDING, rv);
13761
13762 rv = callback.WaitForResult();
13763 EXPECT_EQ(OK, rv);
13764
13765 const HttpResponseInfo* response = trans->GetResponseInfo();
13766 ASSERT_TRUE(response != NULL);
13767
13768 EXPECT_TRUE(response->headers.get() != NULL);
13769 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
13770
13771 std::string response_data;
13772 rv = ReadTransaction(trans.get(), &response_data);
13773 EXPECT_EQ(OK, rv);
13774 EXPECT_EQ("hello world", response_data);
13775}
13776
13777// This tests the more common case than the previous test, where headers and
13778// body are not merged into a single request.
13779TEST_P(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
13780 ScopedVector<UploadElementReader> element_readers;
13781 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713782 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5413783
13784 HttpRequestInfo request;
13785 request.method = "POST";
13786 request.url = GURL("http://www.foo.com/");
13787 request.upload_data_stream = &upload_data_stream;
13788 request.load_flags = 0;
13789
13790 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13791 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113792 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413793 // Send headers successfully, but get an error while sending the body.
13794 MockWrite data_writes[] = {
13795 MockWrite("POST / HTTP/1.1\r\n"
13796 "Host: www.foo.com\r\n"
13797 "Connection: keep-alive\r\n"
13798 "Transfer-Encoding: chunked\r\n\r\n"),
13799 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13800 };
13801
13802 MockRead data_reads[] = {
13803 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
13804 MockRead("hello world"),
13805 MockRead(SYNCHRONOUS, OK),
13806 };
13807 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13808 arraysize(data_writes));
13809 session_deps_.socket_factory->AddSocketDataProvider(&data);
13810
13811 TestCompletionCallback callback;
13812
13813 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13814 EXPECT_EQ(ERR_IO_PENDING, rv);
13815 // Make sure the headers are sent before adding a chunk. This ensures that
13816 // they can't be merged with the body in a single send. Not currently
13817 // necessary since a chunked body is never merged with headers, but this makes
13818 // the test more future proof.
13819 base::RunLoop().RunUntilIdle();
13820
mmenkecbc2b712014-10-09 20:29:0713821 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5413822
13823 rv = callback.WaitForResult();
13824 EXPECT_EQ(OK, rv);
13825
13826 const HttpResponseInfo* response = trans->GetResponseInfo();
13827 ASSERT_TRUE(response != NULL);
13828
13829 EXPECT_TRUE(response->headers.get() != NULL);
13830 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
13831
13832 std::string response_data;
13833 rv = ReadTransaction(trans.get(), &response_data);
13834 EXPECT_EQ(OK, rv);
13835 EXPECT_EQ("hello world", response_data);
13836}
13837
13838TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
13839 ScopedVector<UploadElementReader> element_readers;
13840 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713841 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413842
13843 HttpRequestInfo request;
13844 request.method = "POST";
13845 request.url = GURL("http://www.foo.com/");
13846 request.upload_data_stream = &upload_data_stream;
13847 request.load_flags = 0;
13848
13849 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13850 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113851 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413852
13853 MockWrite data_writes[] = {
13854 MockWrite("POST / HTTP/1.1\r\n"
13855 "Host: www.foo.com\r\n"
13856 "Connection: keep-alive\r\n"
13857 "Content-Length: 3\r\n\r\n"),
13858 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13859 };
13860
13861 MockRead data_reads[] = {
13862 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
13863 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
13864 MockRead("hello world"),
13865 MockRead(SYNCHRONOUS, OK),
13866 };
13867 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13868 arraysize(data_writes));
13869 session_deps_.socket_factory->AddSocketDataProvider(&data);
13870
13871 TestCompletionCallback callback;
13872
13873 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13874 EXPECT_EQ(ERR_IO_PENDING, rv);
13875
13876 rv = callback.WaitForResult();
13877 EXPECT_EQ(OK, rv);
13878
13879 const HttpResponseInfo* response = trans->GetResponseInfo();
13880 ASSERT_TRUE(response != NULL);
13881
13882 EXPECT_TRUE(response->headers.get() != NULL);
13883 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
13884
13885 std::string response_data;
13886 rv = ReadTransaction(trans.get(), &response_data);
13887 EXPECT_EQ(OK, rv);
13888 EXPECT_EQ("hello world", response_data);
13889}
13890
13891TEST_P(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
13892 ScopedVector<UploadElementReader> element_readers;
13893 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713894 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413895
13896 HttpRequestInfo request;
13897 request.method = "POST";
13898 request.url = GURL("http://www.foo.com/");
13899 request.upload_data_stream = &upload_data_stream;
13900 request.load_flags = 0;
13901
13902 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13903 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113904 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413905 // Send headers successfully, but get an error while sending the body.
13906 MockWrite data_writes[] = {
13907 MockWrite("POST / HTTP/1.1\r\n"
13908 "Host: www.foo.com\r\n"
13909 "Connection: keep-alive\r\n"
13910 "Content-Length: 3\r\n\r\n"),
13911 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13912 };
13913
13914 MockRead data_reads[] = {
13915 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
13916 MockRead("hello world"),
13917 MockRead(SYNCHRONOUS, OK),
13918 };
13919 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13920 arraysize(data_writes));
13921 session_deps_.socket_factory->AddSocketDataProvider(&data);
13922
13923 TestCompletionCallback callback;
13924
13925 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13926 EXPECT_EQ(ERR_IO_PENDING, rv);
13927
13928 rv = callback.WaitForResult();
13929 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5413930}
13931
13932TEST_P(HttpNetworkTransactionTest,
13933 PostIgnoresNonErrorResponseAfterResetAnd100) {
13934 ScopedVector<UploadElementReader> element_readers;
13935 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713936 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413937
13938 HttpRequestInfo request;
13939 request.method = "POST";
13940 request.url = GURL("http://www.foo.com/");
13941 request.upload_data_stream = &upload_data_stream;
13942 request.load_flags = 0;
13943
13944 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13945 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113946 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413947 // Send headers successfully, but get an error while sending the body.
13948 MockWrite data_writes[] = {
13949 MockWrite("POST / HTTP/1.1\r\n"
13950 "Host: www.foo.com\r\n"
13951 "Connection: keep-alive\r\n"
13952 "Content-Length: 3\r\n\r\n"),
13953 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13954 };
13955
13956 MockRead data_reads[] = {
13957 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
13958 MockRead("HTTP/1.0 302 Redirect\r\n"),
13959 MockRead("Location: http://somewhere-else.com/\r\n"),
13960 MockRead("Content-Length: 0\r\n\r\n"),
13961 MockRead(SYNCHRONOUS, OK),
13962 };
13963 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13964 arraysize(data_writes));
13965 session_deps_.socket_factory->AddSocketDataProvider(&data);
13966
13967 TestCompletionCallback callback;
13968
13969 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13970 EXPECT_EQ(ERR_IO_PENDING, rv);
13971
13972 rv = callback.WaitForResult();
13973 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5413974}
13975
13976TEST_P(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
13977 ScopedVector<UploadElementReader> element_readers;
13978 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713979 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413980
13981 HttpRequestInfo request;
13982 request.method = "POST";
13983 request.url = GURL("http://www.foo.com/");
13984 request.upload_data_stream = &upload_data_stream;
13985 request.load_flags = 0;
13986
13987 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13988 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113989 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413990 // Send headers successfully, but get an error while sending the body.
13991 MockWrite data_writes[] = {
13992 MockWrite("POST / HTTP/1.1\r\n"
13993 "Host: www.foo.com\r\n"
13994 "Connection: keep-alive\r\n"
13995 "Content-Length: 3\r\n\r\n"),
13996 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13997 };
13998
13999 MockRead data_reads[] = {
14000 MockRead("HTTP 0.9 rocks!"),
14001 MockRead(SYNCHRONOUS, OK),
14002 };
14003 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14004 arraysize(data_writes));
14005 session_deps_.socket_factory->AddSocketDataProvider(&data);
14006
14007 TestCompletionCallback callback;
14008
14009 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14010 EXPECT_EQ(ERR_IO_PENDING, rv);
14011
14012 rv = callback.WaitForResult();
14013 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5414014}
14015
14016TEST_P(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
14017 ScopedVector<UploadElementReader> element_readers;
14018 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714019 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5414020
14021 HttpRequestInfo request;
14022 request.method = "POST";
14023 request.url = GURL("http://www.foo.com/");
14024 request.upload_data_stream = &upload_data_stream;
14025 request.load_flags = 0;
14026
14027 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14028 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114029 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414030 // Send headers successfully, but get an error while sending the body.
14031 MockWrite data_writes[] = {
14032 MockWrite("POST / HTTP/1.1\r\n"
14033 "Host: www.foo.com\r\n"
14034 "Connection: keep-alive\r\n"
14035 "Content-Length: 3\r\n\r\n"),
14036 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14037 };
14038
14039 MockRead data_reads[] = {
14040 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
14041 MockRead(SYNCHRONOUS, OK),
14042 };
14043 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14044 arraysize(data_writes));
14045 session_deps_.socket_factory->AddSocketDataProvider(&data);
14046
14047 TestCompletionCallback callback;
14048
14049 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14050 EXPECT_EQ(ERR_IO_PENDING, rv);
14051
14052 rv = callback.WaitForResult();
14053 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5414054}
14055
Adam Rice425cf122015-01-19 06:18:2414056// Verify that proxy headers are not sent to the destination server when
14057// establishing a tunnel for a secure WebSocket connection.
14058TEST_P(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
14059 HttpRequestInfo request;
14060 request.method = "GET";
bncce36dca22015-04-21 22:11:2314061 request.url = GURL("wss://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2414062 AddWebSocketHeaders(&request.extra_headers);
14063
14064 // Configure against proxy server "myproxy:70".
14065 session_deps_.proxy_service.reset(
14066 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
14067
14068 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14069
14070 // Since a proxy is configured, try to establish a tunnel.
14071 MockWrite data_writes[] = {
14072 MockWrite(
bncce36dca22015-04-21 22:11:2314073 "CONNECT www.example.org:443 HTTP/1.1\r\n"
14074 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414075 "Proxy-Connection: keep-alive\r\n\r\n"),
14076
14077 // After calling trans->RestartWithAuth(), this is the request we should
14078 // be issuing -- the final header line contains the credentials.
14079 MockWrite(
bncce36dca22015-04-21 22:11:2314080 "CONNECT www.example.org:443 HTTP/1.1\r\n"
14081 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414082 "Proxy-Connection: keep-alive\r\n"
14083 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
14084
14085 MockWrite(
14086 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2314087 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414088 "Connection: Upgrade\r\n"
14089 "Upgrade: websocket\r\n"
bncce36dca22015-04-21 22:11:2314090 "Origin: http://www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414091 "Sec-WebSocket-Version: 13\r\n"
14092 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
14093 };
14094
14095 // The proxy responds to the connect with a 407, using a persistent
14096 // connection.
14097 MockRead data_reads[] = {
14098 // No credentials.
14099 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
14100 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
14101 MockRead("Proxy-Connection: close\r\n\r\n"),
14102
14103 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
14104
14105 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
14106 MockRead("Upgrade: websocket\r\n"),
14107 MockRead("Connection: Upgrade\r\n"),
14108 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
14109 };
14110
14111 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14112 arraysize(data_writes));
14113 session_deps_.socket_factory->AddSocketDataProvider(&data);
14114 SSLSocketDataProvider ssl(ASYNC, OK);
14115 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14116
14117 scoped_ptr<HttpTransaction> trans(
14118 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
14119 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
14120 trans->SetWebSocketHandshakeStreamCreateHelper(
14121 &websocket_stream_create_helper);
14122
14123 {
14124 TestCompletionCallback callback;
14125
14126 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14127 EXPECT_EQ(ERR_IO_PENDING, rv);
14128
14129 rv = callback.WaitForResult();
14130 EXPECT_EQ(OK, rv);
14131 }
14132
14133 const HttpResponseInfo* response = trans->GetResponseInfo();
14134 ASSERT_TRUE(response);
14135 ASSERT_TRUE(response->headers.get());
14136 EXPECT_EQ(407, response->headers->response_code());
14137
14138 {
14139 TestCompletionCallback callback;
14140
14141 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
14142 callback.callback());
14143 EXPECT_EQ(ERR_IO_PENDING, rv);
14144
14145 rv = callback.WaitForResult();
14146 EXPECT_EQ(OK, rv);
14147 }
14148
14149 response = trans->GetResponseInfo();
14150 ASSERT_TRUE(response);
14151 ASSERT_TRUE(response->headers.get());
14152
14153 EXPECT_EQ(101, response->headers->response_code());
14154
14155 trans.reset();
14156 session->CloseAllConnections();
14157}
14158
14159// Verify that proxy headers are not sent to the destination server when
14160// establishing a tunnel for an insecure WebSocket connection.
14161// This requires the authentication info to be injected into the auth cache
14162// due to crbug.com/395064
14163// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
14164TEST_P(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
14165 HttpRequestInfo request;
14166 request.method = "GET";
bncce36dca22015-04-21 22:11:2314167 request.url = GURL("ws://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2414168 AddWebSocketHeaders(&request.extra_headers);
14169
14170 // Configure against proxy server "myproxy:70".
14171 session_deps_.proxy_service.reset(
14172 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
14173
14174 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14175
14176 MockWrite data_writes[] = {
14177 // Try to establish a tunnel for the WebSocket connection, with
14178 // credentials. Because WebSockets have a separate set of socket pools,
14179 // they cannot and will not use the same TCP/IP connection as the
14180 // preflight HTTP request.
14181 MockWrite(
bncce36dca22015-04-21 22:11:2314182 "CONNECT www.example.org:80 HTTP/1.1\r\n"
14183 "Host: www.example.org:80\r\n"
Adam Rice425cf122015-01-19 06:18:2414184 "Proxy-Connection: keep-alive\r\n"
14185 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
14186
14187 MockWrite(
14188 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2314189 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414190 "Connection: Upgrade\r\n"
14191 "Upgrade: websocket\r\n"
bncce36dca22015-04-21 22:11:2314192 "Origin: http://www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414193 "Sec-WebSocket-Version: 13\r\n"
14194 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
14195 };
14196
14197 MockRead data_reads[] = {
14198 // HTTP CONNECT with credentials.
14199 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
14200
14201 // WebSocket connection established inside tunnel.
14202 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
14203 MockRead("Upgrade: websocket\r\n"),
14204 MockRead("Connection: Upgrade\r\n"),
14205 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
14206 };
14207
14208 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14209 arraysize(data_writes));
14210 session_deps_.socket_factory->AddSocketDataProvider(&data);
14211
14212 session->http_auth_cache()->Add(
14213 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
14214 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
14215
14216 scoped_ptr<HttpTransaction> trans(
14217 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
14218 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
14219 trans->SetWebSocketHandshakeStreamCreateHelper(
14220 &websocket_stream_create_helper);
14221
14222 TestCompletionCallback callback;
14223
14224 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14225 EXPECT_EQ(ERR_IO_PENDING, rv);
14226
14227 rv = callback.WaitForResult();
14228 EXPECT_EQ(OK, rv);
14229
14230 const HttpResponseInfo* response = trans->GetResponseInfo();
14231 ASSERT_TRUE(response);
14232 ASSERT_TRUE(response->headers.get());
14233
14234 EXPECT_EQ(101, response->headers->response_code());
14235
14236 trans.reset();
14237 session->CloseAllConnections();
14238}
14239
[email protected]89ceba9a2009-03-21 03:46:0614240} // namespace net