blob: 25af22fabeebddd8ece2587a2d6518192ed6179f [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>
sclittlebe1ccf62015-09-02 19:40:369#include <stdint.h>
10
[email protected]5285d972011-10-18 18:56:3411#include <string>
[email protected]95d88ffe2010-02-04 21:25:3312#include <vector>
[email protected]77848d12008-11-14 00:00:2213
[email protected]2d731a32010-04-29 01:04:0614#include "base/basictypes.h"
[email protected]68bf9152008-09-25 19:47:3015#include "base/compiler_specific.h"
[email protected]57999812013-02-24 05:40:5216#include "base/files/file_path.h"
thestigd8df0332014-09-04 06:33:2917#include "base/files/file_util.h"
[email protected]f3da152d2012-06-02 01:00:5718#include "base/json/json_writer.h"
Adam Rice425cf122015-01-19 06:18:2419#include "base/logging.h"
[email protected]3b63f8f42011-03-28 01:54:1520#include "base/memory/scoped_ptr.h"
[email protected]bf828982013-08-14 18:01:4721#include "base/memory/weak_ptr.h"
[email protected]a34f61ee2014-03-18 20:59:4922#include "base/run_loop.h"
bnc1b0e36852015-04-28 15:32:5923#include "base/stl_util.h"
[email protected]125ef482013-06-11 18:32:4724#include "base/strings/string_util.h"
[email protected]750b2f3c2013-06-07 18:41:0525#include "base/strings/utf_string_conversions.h"
[email protected]f36a8132011-09-02 18:36:3326#include "base/test/test_file_util.h"
skyostil4891b25b2015-06-11 11:43:4527#include "base/thread_task_runner_handle.h"
[email protected]277d5942010-08-11 21:02:3528#include "net/base/auth.h"
mmenkecbc2b712014-10-09 20:29:0729#include "net/base/chunked_upload_data_stream.h"
[email protected]bacff652009-03-31 17:50:3330#include "net/base/completion_callback.h"
mmenkecbc2b712014-10-09 20:29:0731#include "net/base/elements_upload_data_stream.h"
[email protected]58e32bb2013-01-21 18:23:2532#include "net/base/load_timing_info.h"
33#include "net/base/load_timing_info_test_util.h"
Adam Rice425cf122015-01-19 06:18:2434#include "net/base/net_errors.h"
[email protected]ac790b42009-12-02 04:31:3135#include "net/base/request_priority.h"
initial.commit586acc5fe2008-07-26 22:42:5236#include "net/base/test_completion_callback.h"
[email protected]42fdb452012-11-01 12:44:4037#include "net/base/test_data_directory.h"
[email protected]b2d26cfd2012-12-11 10:36:0638#include "net/base/upload_bytes_element_reader.h"
[email protected]d98961652012-09-11 20:27:2139#include "net/base/upload_file_element_reader.h"
[email protected]6e7845ae2013-03-29 21:48:1140#include "net/cert/mock_cert_verifier.h"
[email protected]bc71b8772013-04-10 20:55:1641#include "net/dns/host_cache.h"
[email protected]f2cb3cf2013-03-21 01:40:5342#include "net/dns/mock_host_resolver.h"
[email protected]df41d0d82014-03-13 00:43:2443#include "net/http/http_auth_challenge_tokenizer.h"
[email protected]3c32c5f2010-05-18 15:18:1244#include "net/http/http_auth_handler_digest.h"
[email protected]3fd9dae2010-06-21 11:39:0045#include "net/http/http_auth_handler_mock.h"
[email protected]385a4672009-03-11 22:21:2946#include "net/http/http_auth_handler_ntlm.h"
Adam Rice425cf122015-01-19 06:18:2447#include "net/http/http_basic_state.h"
[email protected]0877e3d2009-10-17 22:29:5748#include "net/http/http_basic_stream.h"
initial.commit586acc5fe2008-07-26 22:42:5249#include "net/http/http_network_session.h"
[email protected]87bfa3f2010-09-30 14:54:5650#include "net/http/http_network_session_peer.h"
Adam Rice425cf122015-01-19 06:18:2451#include "net/http/http_request_headers.h"
[email protected]17291a022011-10-10 07:32:5352#include "net/http/http_server_properties_impl.h"
[email protected]0877e3d2009-10-17 22:29:5753#include "net/http/http_stream.h"
[email protected]8e6441ca2010-08-19 05:56:3854#include "net/http/http_stream_factory.h"
Adam Rice425cf122015-01-19 06:18:2455#include "net/http/http_stream_parser.h"
[email protected]c41737d2014-05-14 07:47:1956#include "net/http/http_transaction_test_util.h"
eroman87c53d62015-04-02 06:51:0757#include "net/log/net_log.h"
vishal.b62985ca92015-04-17 08:45:5158#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4659#include "net/log/test_net_log_entry.h"
60#include "net/log/test_net_log_util.h"
sammc5dd160c2015-04-02 02:43:1361#include "net/proxy/mock_proxy_resolver.h"
[email protected]51fff29d2008-12-19 22:17:5362#include "net/proxy/proxy_config_service_fixed.h"
[email protected]e86839fd2013-08-14 18:29:0363#include "net/proxy/proxy_info.h"
[email protected]631f1322010-04-30 17:59:1164#include "net/proxy/proxy_resolver.h"
65#include "net/proxy/proxy_service.h"
[email protected]f7984fc62009-06-22 23:26:4466#include "net/socket/client_socket_factory.h"
[email protected]483fa202013-05-14 01:07:0367#include "net/socket/client_socket_pool_manager.h"
ttuttle1f2d7e92015-04-28 16:17:4768#include "net/socket/connection_attempts.h"
[email protected]a42dbd142011-11-17 16:42:0269#include "net/socket/mock_client_socket_pool_manager.h"
[email protected]bb88e1d32013-05-03 23:11:0770#include "net/socket/next_proto.h"
[email protected]f7984fc62009-06-22 23:26:4471#include "net/socket/socket_test_util.h"
72#include "net/socket/ssl_client_socket.h"
[email protected]2ff8b312010-04-26 22:20:5473#include "net/spdy/spdy_framer.h"
74#include "net/spdy/spdy_session.h"
75#include "net/spdy/spdy_session_pool.h"
[email protected]23e482282013-06-14 16:08:0276#include "net/spdy/spdy_test_util_common.h"
[email protected]536fd0b2013-03-14 17:41:5777#include "net/ssl/ssl_cert_request_info.h"
[email protected]e86839fd2013-08-14 18:29:0378#include "net/ssl/ssl_config_service.h"
[email protected]536fd0b2013-03-14 17:41:5779#include "net/ssl/ssl_config_service_defaults.h"
80#include "net/ssl/ssl_info.h"
[email protected]6e7845ae2013-03-29 21:48:1181#include "net/test/cert_test_util.h"
[email protected]831e4a32013-11-14 02:14:4482#include "net/websockets/websocket_handshake_stream_base.h"
initial.commit586acc5fe2008-07-26 22:42:5283#include "testing/gtest/include/gtest/gtest.h"
[email protected]23887f04f2008-12-02 19:20:1584#include "testing/platform_test.h"
[email protected]795cbf82013-07-22 09:37:2785#include "url/gurl.h"
initial.commit586acc5fe2008-07-26 22:42:5286
[email protected]ad65a3e2013-12-25 18:18:0187using base::ASCIIToUTF16;
88
initial.commit586acc5fe2008-07-26 22:42:5289//-----------------------------------------------------------------------------
90
ttuttle859dc7a2015-04-23 19:42:2991namespace net {
92
[email protected]13c8a092010-07-29 06:15:4493namespace {
94
[email protected]42cba2fb2013-03-29 19:58:5795const base::string16 kBar(ASCIIToUTF16("bar"));
96const base::string16 kBar2(ASCIIToUTF16("bar2"));
97const base::string16 kBar3(ASCIIToUTF16("bar3"));
98const base::string16 kBaz(ASCIIToUTF16("baz"));
99const base::string16 kFirst(ASCIIToUTF16("first"));
100const base::string16 kFoo(ASCIIToUTF16("foo"));
101const base::string16 kFoo2(ASCIIToUTF16("foo2"));
102const base::string16 kFoo3(ASCIIToUTF16("foo3"));
103const base::string16 kFou(ASCIIToUTF16("fou"));
104const base::string16 kSecond(ASCIIToUTF16("second"));
105const base::string16 kTestingNTLM(ASCIIToUTF16("testing-ntlm"));
106const base::string16 kWrongPassword(ASCIIToUTF16("wrongpassword"));
[email protected]13c8a092010-07-29 06:15:44107
ttuttle859dc7a2015-04-23 19:42:29108int GetIdleSocketCountInTransportSocketPool(HttpNetworkSession* session) {
109 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
110 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02111}
112
ttuttle859dc7a2015-04-23 19:42:29113int GetIdleSocketCountInSSLSocketPool(HttpNetworkSession* session) {
114 return session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
115 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02116}
117
ttuttle859dc7a2015-04-23 19:42:29118bool IsTransportSocketPoolStalled(HttpNetworkSession* session) {
119 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
120 ->IsStalled();
[email protected]043b68c82013-08-22 23:41:52121}
122
[email protected]f3da152d2012-06-02 01:00:57123// Takes in a Value created from a NetLogHttpResponseParameter, and returns
124// a JSONified list of headers as a single string. Uses single quotes instead
125// of double quotes for easier comparison. Returns false on failure.
[email protected]ea5ef4c2013-06-13 22:50:27126bool GetHeaders(base::DictionaryValue* params, std::string* headers) {
[email protected]f3da152d2012-06-02 01:00:57127 if (!params)
128 return false;
[email protected]ea5ef4c2013-06-13 22:50:27129 base::ListValue* header_list;
[email protected]f3da152d2012-06-02 01:00:57130 if (!params->GetList("headers", &header_list))
131 return false;
132 std::string double_quote_headers;
estade8d046462015-05-16 01:02:34133 base::JSONWriter::Write(*header_list, &double_quote_headers);
[email protected]466c9862013-12-03 22:05:28134 base::ReplaceChars(double_quote_headers, "\"", "'", headers);
[email protected]f3da152d2012-06-02 01:00:57135 return true;
136}
137
[email protected]029c83b62013-01-24 05:28:20138// Tests LoadTimingInfo in the case a socket is reused and no PAC script is
139// used.
ttuttle859dc7a2015-04-23 19:42:29140void TestLoadTimingReused(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20141 EXPECT_TRUE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:29142 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]58e32bb2013-01-21 18:23:25143
[email protected]029c83b62013-01-24 05:28:20144 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
145 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
146
ttuttle859dc7a2015-04-23 19:42:29147 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20148 EXPECT_FALSE(load_timing_info.send_start.is_null());
[email protected]58e32bb2013-01-21 18:23:25149
150 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]58e32bb2013-01-21 18:23:25151
[email protected]3b23a222013-05-15 21:33:25152 // Set at a higher level.
[email protected]58e32bb2013-01-21 18:23:25153 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
154 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25155 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25156}
157
[email protected]029c83b62013-01-24 05:28:20158// Tests LoadTimingInfo in the case a new socket is used and no PAC script is
159// used.
ttuttle859dc7a2015-04-23 19:42:29160void TestLoadTimingNotReused(const LoadTimingInfo& load_timing_info,
[email protected]58e32bb2013-01-21 18:23:25161 int connect_timing_flags) {
[email protected]029c83b62013-01-24 05:28:20162 EXPECT_FALSE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:29163 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20164
165 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
166 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
167
ttuttle859dc7a2015-04-23 19:42:29168 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
169 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20170 EXPECT_LE(load_timing_info.connect_timing.connect_end,
171 load_timing_info.send_start);
172
173 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20174
[email protected]3b23a222013-05-15 21:33:25175 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20176 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
177 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25178 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20179}
180
181// Tests LoadTimingInfo in the case a socket is reused and a PAC script is
182// used.
ttuttle859dc7a2015-04-23 19:42:29183void TestLoadTimingReusedWithPac(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20184 EXPECT_TRUE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:29185 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20186
ttuttle859dc7a2015-04-23 19:42:29187 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20188
189 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
190 EXPECT_LE(load_timing_info.proxy_resolve_start,
191 load_timing_info.proxy_resolve_end);
192 EXPECT_LE(load_timing_info.proxy_resolve_end,
193 load_timing_info.send_start);
194 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20195
[email protected]3b23a222013-05-15 21:33:25196 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20197 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
198 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25199 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20200}
201
202// Tests LoadTimingInfo in the case a new socket is used and a PAC script is
203// used.
ttuttle859dc7a2015-04-23 19:42:29204void TestLoadTimingNotReusedWithPac(const LoadTimingInfo& load_timing_info,
[email protected]029c83b62013-01-24 05:28:20205 int connect_timing_flags) {
206 EXPECT_FALSE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:29207 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20208
209 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
210 EXPECT_LE(load_timing_info.proxy_resolve_start,
211 load_timing_info.proxy_resolve_end);
212 EXPECT_LE(load_timing_info.proxy_resolve_end,
213 load_timing_info.connect_timing.connect_start);
ttuttle859dc7a2015-04-23 19:42:29214 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
215 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20216 EXPECT_LE(load_timing_info.connect_timing.connect_end,
217 load_timing_info.send_start);
218
219 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20220
[email protected]3b23a222013-05-15 21:33:25221 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20222 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
223 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25224 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25225}
226
ttuttle859dc7a2015-04-23 19:42:29227void AddWebSocketHeaders(HttpRequestHeaders* headers) {
Adam Rice425cf122015-01-19 06:18:24228 headers->SetHeader("Connection", "Upgrade");
229 headers->SetHeader("Upgrade", "websocket");
bncce36dca22015-04-21 22:11:23230 headers->SetHeader("Origin", "http://www.example.org");
Adam Rice425cf122015-01-19 06:18:24231 headers->SetHeader("Sec-WebSocket-Version", "13");
232 headers->SetHeader("Sec-WebSocket-Key", "dGhlIHNhbXBsZSBub25jZQ==");
233}
234
mmenke6b3af6e2015-09-12 02:06:06235HttpNetworkSession* CreateSession(SpdySessionDependencies* session_deps) {
[email protected]c6bf8152012-12-02 07:43:34236 return SpdySessionDependencies::SpdyCreateSession(session_deps);
[email protected]e8d536192008-10-17 22:21:14237}
238
[email protected]448d4ca52012-03-04 04:12:23239} // namespace
240
[email protected]23e482282013-06-14 16:08:02241class HttpNetworkTransactionTest
242 : public PlatformTest,
243 public ::testing::WithParamInterface<NextProto> {
[email protected]483fa202013-05-14 01:07:03244 public:
[email protected]23e482282013-06-14 16:08:02245 virtual ~HttpNetworkTransactionTest() {
[email protected]483fa202013-05-14 01:07:03246 // Important to restore the per-pool limit first, since the pool limit must
247 // always be greater than group limit, and the tests reduce both limits.
248 ClientSocketPoolManager::set_max_sockets_per_pool(
249 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
250 ClientSocketPoolManager::set_max_sockets_per_group(
251 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
252 }
253
[email protected]e3ceb682011-06-28 23:55:46254 protected:
[email protected]23e482282013-06-14 16:08:02255 HttpNetworkTransactionTest()
256 : spdy_util_(GetParam()),
257 session_deps_(GetParam()),
[email protected]483fa202013-05-14 01:07:03258 old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
259 HttpNetworkSession::NORMAL_SOCKET_POOL)),
260 old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
261 HttpNetworkSession::NORMAL_SOCKET_POOL)) {
262 }
[email protected]bb88e1d32013-05-03 23:11:07263
[email protected]e3ceb682011-06-28 23:55:46264 struct SimpleGetHelperResult {
265 int rv;
266 std::string status_line;
267 std::string response_data;
sclittlefb249892015-09-10 21:33:22268 int64_t total_received_bytes;
269 int64_t total_sent_bytes;
[email protected]58e32bb2013-01-21 18:23:25270 LoadTimingInfo load_timing_info;
ttuttle1f2d7e92015-04-28 16:17:47271 ConnectionAttempts connection_attempts;
[email protected]e3ceb682011-06-28 23:55:46272 };
273
dcheng67be2b1f2014-10-27 21:47:29274 void SetUp() override {
[email protected]0b0bf032010-09-21 18:08:50275 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:34276 base::MessageLoop::current()->RunUntilIdle();
[email protected]2ff8b312010-04-26 22:20:54277 }
278
dcheng67be2b1f2014-10-27 21:47:29279 void TearDown() override {
[email protected]0b0bf032010-09-21 18:08:50280 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:34281 base::MessageLoop::current()->RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09282 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:34283 base::MessageLoop::current()->RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09284 PlatformTest::TearDown();
[email protected]0b0bf032010-09-21 18:08:50285 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:34286 base::MessageLoop::current()->RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09287 }
288
bnc33b8cef42014-11-19 17:30:38289 const char* GetAlternateProtocolFromParam() {
290 return
291 AlternateProtocolToString(AlternateProtocolFromNextProto(GetParam()));
292 }
293
bncc958faa2015-07-31 18:14:52294 std::string GetAlternativeServiceHttpHeader() {
295 return std::string("Alt-Svc: ") + GetAlternateProtocolFromParam() +
296 "=\"www.example.com:443\"\r\n";
297 }
298
[email protected]8a0fc822013-06-27 20:52:43299 std::string GetAlternateProtocolHttpHeader() {
bnc33b8cef42014-11-19 17:30:38300 return std::string("Alternate-Protocol: 443:") +
bncc958faa2015-07-31 18:14:52301 GetAlternateProtocolFromParam() + "\r\n";
[email protected]8a0fc822013-06-27 20:52:43302 }
303
[email protected]202965992011-12-07 23:04:51304 // Either |write_failure| specifies a write failure or |read_failure|
305 // specifies a read failure when using a reused socket. In either case, the
306 // failure should cause the network transaction to resend the request, and the
307 // other argument should be NULL.
308 void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
309 const MockRead* read_failure);
initial.commit586acc5fe2008-07-26 22:42:52310
[email protected]a34f61ee2014-03-18 20:59:49311 // Either |write_failure| specifies a write failure or |read_failure|
312 // specifies a read failure when using a reused socket. In either case, the
313 // failure should cause the network transaction to resend the request, and the
314 // other argument should be NULL.
315 void PreconnectErrorResendRequestTest(const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:10316 const MockRead* read_failure,
317 bool use_spdy);
[email protected]a34f61ee2014-03-18 20:59:49318
[email protected]5a60c8b2011-10-19 20:14:29319 SimpleGetHelperResult SimpleGetHelperForData(StaticSocketDataProvider* data[],
320 size_t data_count) {
[email protected]ff007e162009-05-23 09:13:15321 SimpleGetHelperResult out;
initial.commit586acc5fe2008-07-26 22:42:52322
[email protected]ff007e162009-05-23 09:13:15323 HttpRequestInfo request;
324 request.method = "GET";
bncce36dca22015-04-21 22:11:23325 request.url = GURL("http://www.example.org/");
[email protected]ff007e162009-05-23 09:13:15326 request.load_flags = 0;
initial.commit586acc5fe2008-07-26 22:42:52327
vishal.b62985ca92015-04-17 08:45:51328 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:07329 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:06330 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:27331 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:41332 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:27333
[email protected]5a60c8b2011-10-19 20:14:29334 for (size_t i = 0; i < data_count; ++i) {
[email protected]bb88e1d32013-05-03 23:11:07335 session_deps_.socket_factory->AddSocketDataProvider(data[i]);
[email protected]5a60c8b2011-10-19 20:14:29336 }
initial.commit586acc5fe2008-07-26 22:42:52337
[email protected]49639fa2011-12-20 23:22:41338 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52339
eroman24bc6a12015-05-06 19:55:48340 EXPECT_TRUE(log.bound().IsCapturing());
[email protected]49639fa2011-12-20 23:22:41341 int rv = trans->Start(&request, callback.callback(), log.bound());
[email protected]ff007e162009-05-23 09:13:15342 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:52343
[email protected]ff007e162009-05-23 09:13:15344 out.rv = callback.WaitForResult();
sclittlefb249892015-09-10 21:33:22345 out.total_received_bytes = trans->GetTotalReceivedBytes();
346 out.total_sent_bytes = trans->GetTotalSentBytes();
[email protected]58e32bb2013-01-21 18:23:25347
348 // Even in the failure cases that use this function, connections are always
349 // successfully established before the error.
350 EXPECT_TRUE(trans->GetLoadTimingInfo(&out.load_timing_info));
351 TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
352
[email protected]ff007e162009-05-23 09:13:15353 if (out.rv != OK)
354 return out;
355
356 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50357 // Can't use ASSERT_* inside helper functions like this, so
358 // return an error.
[email protected]90499482013-06-01 00:39:50359 if (response == NULL || response->headers.get() == NULL) {
[email protected]fe2255a2011-09-20 19:37:50360 out.rv = ERR_UNEXPECTED;
361 return out;
362 }
[email protected]ff007e162009-05-23 09:13:15363 out.status_line = response->headers->GetStatusLine();
364
[email protected]80a09a82012-11-16 17:40:06365 EXPECT_EQ("127.0.0.1", response->socket_address.host());
366 EXPECT_EQ(80, response->socket_address.port());
[email protected]6d81b482011-02-22 19:47:19367
[email protected]ff007e162009-05-23 09:13:15368 rv = ReadTransaction(trans.get(), &out.response_data);
369 EXPECT_EQ(OK, rv);
[email protected]b2fcd0e2010-12-01 15:19:40370
mmenke43758e62015-05-04 21:09:46371 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40372 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:39373 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:40374 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
[email protected]169d0012010-05-10 23:20:12375 NetLog::PHASE_NONE);
[email protected]dbb83db2010-05-11 18:13:39376 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:40377 entries, pos,
[email protected]dbb83db2010-05-11 18:13:39378 NetLog::TYPE_HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
379 NetLog::PHASE_NONE);
[email protected]ff007e162009-05-23 09:13:15380
[email protected]f3da152d2012-06-02 01:00:57381 std::string line;
382 EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
383 EXPECT_EQ("GET / HTTP/1.1\r\n", line);
384
[email protected]79e1fd62013-06-20 06:50:04385 HttpRequestHeaders request_headers;
386 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
387 std::string value;
388 EXPECT_TRUE(request_headers.GetHeader("Host", &value));
bncce36dca22015-04-21 22:11:23389 EXPECT_EQ("www.example.org", value);
[email protected]79e1fd62013-06-20 06:50:04390 EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
391 EXPECT_EQ("keep-alive", value);
392
393 std::string response_headers;
394 EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
bncce36dca22015-04-21 22:11:23395 EXPECT_EQ("['Host: www.example.org','Connection: keep-alive']",
[email protected]79e1fd62013-06-20 06:50:04396 response_headers);
[email protected]3deb9a52010-11-11 00:24:40397
sclittlefb249892015-09-10 21:33:22398 out.total_received_bytes = trans->GetTotalReceivedBytes();
399 // The total number of sent bytes should not have changed.
400 EXPECT_EQ(out.total_sent_bytes, trans->GetTotalSentBytes());
401
ttuttle1f2d7e92015-04-28 16:17:47402 trans->GetConnectionAttempts(&out.connection_attempts);
[email protected]aecfbf22008-10-16 02:02:47403 return out;
[email protected]ff007e162009-05-23 09:13:15404 }
initial.commit586acc5fe2008-07-26 22:42:52405
[email protected]5a60c8b2011-10-19 20:14:29406 SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[],
407 size_t reads_count) {
sclittlefb249892015-09-10 21:33:22408 MockWrite data_writes[] = {
409 MockWrite("GET / HTTP/1.1\r\n"
410 "Host: www.example.org\r\n"
411 "Connection: keep-alive\r\n\r\n"),
412 };
[email protected]5a60c8b2011-10-19 20:14:29413
sclittlefb249892015-09-10 21:33:22414 StaticSocketDataProvider reads(data_reads, reads_count, data_writes,
415 arraysize(data_writes));
416 StaticSocketDataProvider* data[] = {&reads};
417 SimpleGetHelperResult out = SimpleGetHelperForData(data, 1);
418
419 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
420 out.total_sent_bytes);
421 return out;
[email protected]b8015c42013-12-24 15:18:19422 }
423
[email protected]ff007e162009-05-23 09:13:15424 void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
425 int expected_status);
initial.commit586acc5fe2008-07-26 22:42:52426
[email protected]ff007e162009-05-23 09:13:15427 void ConnectStatusHelper(const MockRead& status);
[email protected]bb88e1d32013-05-03 23:11:07428
429 void BypassHostCacheOnRefreshHelper(int load_flags);
430
431 void CheckErrorIsPassedBack(int error, IoMode mode);
432
[email protected]4bd46222013-05-14 19:32:23433 SpdyTestUtil spdy_util_;
[email protected]bb88e1d32013-05-03 23:11:07434 SpdySessionDependencies session_deps_;
[email protected]483fa202013-05-14 01:07:03435
436 // Original socket limits. Some tests set these. Safest to always restore
437 // them once each test has been run.
438 int old_max_group_sockets_;
439 int old_max_pool_sockets_;
[email protected]ff007e162009-05-23 09:13:15440};
[email protected]231d5a32008-09-13 00:45:27441
bnc57685ae62015-03-10 21:27:20442INSTANTIATE_TEST_CASE_P(NextProto,
443 HttpNetworkTransactionTest,
444 testing::Values(kProtoSPDY31,
bnc06d22432015-06-29 12:39:43445 kProtoHTTP2));
[email protected]23e482282013-06-14 16:08:02446
[email protected]448d4ca52012-03-04 04:12:23447namespace {
448
[email protected]1826a402014-01-08 15:40:48449class BeforeNetworkStartHandler {
450 public:
451 explicit BeforeNetworkStartHandler(bool defer)
452 : defer_on_before_network_start_(defer),
453 observed_before_network_start_(false) {}
454
455 void OnBeforeNetworkStart(bool* defer) {
456 *defer = defer_on_before_network_start_;
457 observed_before_network_start_ = true;
458 }
459
460 bool observed_before_network_start() const {
461 return observed_before_network_start_;
462 }
463
464 private:
465 const bool defer_on_before_network_start_;
466 bool observed_before_network_start_;
467
468 DISALLOW_COPY_AND_ASSIGN(BeforeNetworkStartHandler);
469};
470
[email protected]597a1ab2014-06-26 08:12:27471class BeforeProxyHeadersSentHandler {
472 public:
473 BeforeProxyHeadersSentHandler()
474 : observed_before_proxy_headers_sent_(false) {}
475
[email protected]1252d42f2014-07-01 21:20:20476 void OnBeforeProxyHeadersSent(const ProxyInfo& proxy_info,
477 HttpRequestHeaders* request_headers) {
[email protected]597a1ab2014-06-26 08:12:27478 observed_before_proxy_headers_sent_ = true;
479 observed_proxy_server_uri_ = proxy_info.proxy_server().ToURI();
480 }
481
482 bool observed_before_proxy_headers_sent() const {
483 return observed_before_proxy_headers_sent_;
484 }
485
486 std::string observed_proxy_server_uri() const {
487 return observed_proxy_server_uri_;
488 }
489
490 private:
491 bool observed_before_proxy_headers_sent_;
492 std::string observed_proxy_server_uri_;
493
494 DISALLOW_COPY_AND_ASSIGN(BeforeProxyHeadersSentHandler);
495};
496
[email protected]15a5ccf82008-10-23 19:57:43497// Fill |str| with a long header list that consumes >= |size| bytes.
498void FillLargeHeadersString(std::string* str, int size) {
thestig9d3bb0c2015-01-24 00:49:51499 const char row[] =
[email protected]4ddaf2502008-10-23 18:26:19500 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
501 const int sizeof_row = strlen(row);
502 const int num_rows = static_cast<int>(
503 ceil(static_cast<float>(size) / sizeof_row));
504 const int sizeof_data = num_rows * sizeof_row;
505 DCHECK(sizeof_data >= size);
[email protected]15a5ccf82008-10-23 19:57:43506 str->reserve(sizeof_data);
[email protected]372d34a2008-11-05 21:30:51507
[email protected]4ddaf2502008-10-23 18:26:19508 for (int i = 0; i < num_rows; ++i)
[email protected]15a5ccf82008-10-23 19:57:43509 str->append(row, sizeof_row);
[email protected]4ddaf2502008-10-23 18:26:19510}
511
thakis84dff942015-07-28 20:47:38512#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29513// Alternative functions that eliminate randomness and dependency on the local
514// host name so that the generated NTLM messages are reproducible.
[email protected]fe2bc6a2009-03-23 16:52:20515void MockGenerateRandom1(uint8* output, size_t n) {
[email protected]385a4672009-03-11 22:21:29516 static const uint8 bytes[] = {
517 0x55, 0x29, 0x66, 0x26, 0x6b, 0x9c, 0x73, 0x54
518 };
519 static size_t current_byte = 0;
520 for (size_t i = 0; i < n; ++i) {
521 output[i] = bytes[current_byte++];
522 current_byte %= arraysize(bytes);
523 }
524}
525
[email protected]fe2bc6a2009-03-23 16:52:20526void MockGenerateRandom2(uint8* output, size_t n) {
[email protected]385a4672009-03-11 22:21:29527 static const uint8 bytes[] = {
528 0x96, 0x79, 0x85, 0xe7, 0x49, 0x93, 0x70, 0xa1,
529 0x4e, 0xe7, 0x87, 0x45, 0x31, 0x5b, 0xd3, 0x1f
530 };
531 static size_t current_byte = 0;
532 for (size_t i = 0; i < n; ++i) {
533 output[i] = bytes[current_byte++];
534 current_byte %= arraysize(bytes);
535 }
536}
537
[email protected]fe2bc6a2009-03-23 16:52:20538std::string MockGetHostName() {
539 return "WTC-WIN7";
[email protected]385a4672009-03-11 22:21:29540}
thakis84dff942015-07-28 20:47:38541#endif // defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29542
[email protected]e60e47a2010-07-14 03:37:18543template<typename ParentPool>
544class CaptureGroupNameSocketPool : public ParentPool {
[email protected]04e5be32009-06-26 20:00:31545 public:
[email protected]9e1bdd32011-02-03 21:48:34546 CaptureGroupNameSocketPool(HostResolver* host_resolver,
547 CertVerifier* cert_verifier);
[email protected]e60e47a2010-07-14 03:37:18548
[email protected]d80a4322009-08-14 07:07:49549 const std::string last_group_name_received() const {
550 return last_group_name_;
551 }
552
dmichaeld6e570d2014-12-18 22:30:57553 int RequestSocket(const std::string& group_name,
554 const void* socket_params,
555 RequestPriority priority,
556 ClientSocketHandle* handle,
557 const CompletionCallback& callback,
558 const BoundNetLog& net_log) override {
[email protected]04e5be32009-06-26 20:00:31559 last_group_name_ = group_name;
560 return ERR_IO_PENDING;
561 }
dmichaeld6e570d2014-12-18 22:30:57562 void CancelRequest(const std::string& group_name,
563 ClientSocketHandle* handle) override {}
564 void ReleaseSocket(const std::string& group_name,
565 scoped_ptr<StreamSocket> socket,
566 int id) override {}
567 void CloseIdleSockets() override {}
568 int IdleSocketCount() const override { return 0; }
569 int IdleSocketCountInGroup(const std::string& group_name) const override {
[email protected]04e5be32009-06-26 20:00:31570 return 0;
571 }
dmichaeld6e570d2014-12-18 22:30:57572 LoadState GetLoadState(const std::string& group_name,
573 const ClientSocketHandle* handle) const override {
[email protected]04e5be32009-06-26 20:00:31574 return LOAD_STATE_IDLE;
575 }
dmichaeld6e570d2014-12-18 22:30:57576 base::TimeDelta ConnectionTimeout() const override {
[email protected]a796bcec2010-03-22 17:17:26577 return base::TimeDelta();
578 }
[email protected]d80a4322009-08-14 07:07:49579
580 private:
[email protected]04e5be32009-06-26 20:00:31581 std::string last_group_name_;
582};
583
[email protected]ab739042011-04-07 15:22:28584typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
585CaptureGroupNameTransportSocketPool;
[email protected]e772db3f2010-07-12 18:11:13586typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
587CaptureGroupNameHttpProxySocketPool;
[email protected]2d731a32010-04-29 01:04:06588typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
[email protected]2227c692010-05-04 15:36:11589CaptureGroupNameSOCKSSocketPool;
[email protected]e60e47a2010-07-14 03:37:18590typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
591CaptureGroupNameSSLSocketPool;
592
rkaplowd90695c2015-03-25 22:12:41593template <typename ParentPool>
[email protected]e60e47a2010-07-14 03:37:18594CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34595 HostResolver* host_resolver,
596 CertVerifier* /* cert_verifier */)
rkaplowd90695c2015-03-25 22:12:41597 : ParentPool(0, 0, host_resolver, NULL, NULL) {
598}
[email protected]e60e47a2010-07-14 03:37:18599
hashimoto0d3e4fb2015-01-09 05:02:50600template <>
[email protected]2df19bb2010-08-25 20:13:46601CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21602 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34603 CertVerifier* /* cert_verifier */)
rkaplowd90695c2015-03-25 22:12:41604 : HttpProxyClientSocketPool(0, 0, NULL, NULL, NULL) {
hashimoto0d3e4fb2015-01-09 05:02:50605}
[email protected]2df19bb2010-08-25 20:13:46606
[email protected]007b3f82013-04-09 08:46:45607template <>
[email protected]e60e47a2010-07-14 03:37:18608CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21609 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34610 CertVerifier* cert_verifier)
[email protected]007b3f82013-04-09 08:46:45611 : SSLClientSocketPool(0,
612 0,
[email protected]007b3f82013-04-09 08:46:45613 cert_verifier,
614 NULL,
615 NULL,
[email protected]284303b62013-11-28 15:11:54616 NULL,
eranm6571b2b2014-12-03 15:53:23617 NULL,
[email protected]007b3f82013-04-09 08:46:45618 std::string(),
619 NULL,
620 NULL,
621 NULL,
622 NULL,
623 NULL,
[email protected]8e458552014-08-05 00:02:15624 NULL) {
625}
[email protected]2227c692010-05-04 15:36:11626
[email protected]231d5a32008-09-13 00:45:27627//-----------------------------------------------------------------------------
628
[email protected]79cb5c12011-09-12 13:12:04629// Helper functions for validating that AuthChallengeInfo's are correctly
630// configured for common cases.
631bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
632 if (!auth_challenge)
633 return false;
634 EXPECT_FALSE(auth_challenge->is_proxy);
bncce36dca22015-04-21 22:11:23635 EXPECT_EQ("www.example.org:80", auth_challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:04636 EXPECT_EQ("MyRealm1", auth_challenge->realm);
637 EXPECT_EQ("basic", auth_challenge->scheme);
638 return true;
639}
640
641bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
642 if (!auth_challenge)
643 return false;
644 EXPECT_TRUE(auth_challenge->is_proxy);
645 EXPECT_EQ("myproxy:70", auth_challenge->challenger.ToString());
646 EXPECT_EQ("MyRealm1", auth_challenge->realm);
647 EXPECT_EQ("basic", auth_challenge->scheme);
648 return true;
649}
650
651bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
652 if (!auth_challenge)
653 return false;
654 EXPECT_FALSE(auth_challenge->is_proxy);
bncce36dca22015-04-21 22:11:23655 EXPECT_EQ("www.example.org:80", auth_challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:04656 EXPECT_EQ("digestive", auth_challenge->realm);
657 EXPECT_EQ("digest", auth_challenge->scheme);
658 return true;
659}
660
thakis84dff942015-07-28 20:47:38661#if defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04662bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
663 if (!auth_challenge)
664 return false;
665 EXPECT_FALSE(auth_challenge->is_proxy);
666 EXPECT_EQ("172.22.68.17:80", auth_challenge->challenger.ToString());
667 EXPECT_EQ(std::string(), auth_challenge->realm);
668 EXPECT_EQ("ntlm", auth_challenge->scheme);
669 return true;
670}
thakis84dff942015-07-28 20:47:38671#endif // defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04672
[email protected]448d4ca52012-03-04 04:12:23673} // namespace
674
[email protected]23e482282013-06-14 16:08:02675TEST_P(HttpNetworkTransactionTest, Basic) {
mmenke6b3af6e2015-09-12 02:06:06676 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:40677 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:41678 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]231d5a32008-09-13 00:45:27679}
680
[email protected]23e482282013-06-14 16:08:02681TEST_P(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27682 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35683 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
684 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06685 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27686 };
[email protected]31a2bfe2010-02-09 08:03:39687 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
688 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42689 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27690 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
691 EXPECT_EQ("hello world", out.response_data);
sclittlefb249892015-09-10 21:33:22692 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
693 EXPECT_EQ(reads_size, out.total_received_bytes);
ttuttle1f2d7e92015-04-28 16:17:47694 EXPECT_EQ(0u, out.connection_attempts.size());
[email protected]231d5a32008-09-13 00:45:27695}
696
697// Response with no status line.
[email protected]23e482282013-06-14 16:08:02698TEST_P(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27699 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35700 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06701 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27702 };
[email protected]31a2bfe2010-02-09 08:03:39703 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
704 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42705 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27706 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
707 EXPECT_EQ("hello world", out.response_data);
sclittlefb249892015-09-10 21:33:22708 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
709 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27710}
711
712// Allow up to 4 bytes of junk to precede status line.
[email protected]23e482282013-06-14 16:08:02713TEST_P(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27714 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35715 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06716 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27717 };
[email protected]31a2bfe2010-02-09 08:03:39718 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
719 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42720 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27721 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
722 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22723 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
724 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27725}
726
727// Allow up to 4 bytes of junk to precede status line.
[email protected]23e482282013-06-14 16:08:02728TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27729 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35730 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06731 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27732 };
[email protected]31a2bfe2010-02-09 08:03:39733 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
734 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42735 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27736 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
737 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22738 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
739 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27740}
741
742// Beyond 4 bytes of slop and it should fail to find a status line.
[email protected]23e482282013-06-14 16:08:02743TEST_P(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27744 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35745 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06746 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27747 };
[email protected]31a2bfe2010-02-09 08:03:39748 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
749 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42750 EXPECT_EQ(OK, out.rv);
[email protected]3d2a59b2008-09-26 19:44:25751 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
752 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
sclittlefb249892015-09-10 21:33:22753 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
754 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27755}
756
757// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
[email protected]23e482282013-06-14 16:08:02758TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27759 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35760 MockRead("\n"),
761 MockRead("\n"),
762 MockRead("Q"),
763 MockRead("J"),
764 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06765 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27766 };
[email protected]31a2bfe2010-02-09 08:03:39767 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
768 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42769 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27770 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
771 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22772 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
773 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27774}
775
776// Close the connection before enough bytes to have a status line.
[email protected]23e482282013-06-14 16:08:02777TEST_P(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:27778 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35779 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:06780 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27781 };
[email protected]31a2bfe2010-02-09 08:03:39782 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
783 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42784 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27785 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
786 EXPECT_EQ("HTT", out.response_data);
sclittlefb249892015-09-10 21:33:22787 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
788 EXPECT_EQ(reads_size, out.total_received_bytes);
initial.commit586acc5fe2008-07-26 22:42:52789}
790
[email protected]f9d44aa2008-09-23 23:57:17791// Simulate a 204 response, lacking a Content-Length header, sent over a
792// persistent connection. The response should still terminate since a 204
793// cannot have a response body.
[email protected]23e482282013-06-14 16:08:02794TEST_P(HttpNetworkTransactionTest, StopsReading204) {
[email protected]b8015c42013-12-24 15:18:19795 char junk[] = "junk";
[email protected]f9d44aa2008-09-23 23:57:17796 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35797 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
[email protected]b8015c42013-12-24 15:18:19798 MockRead(junk), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:06799 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:17800 };
[email protected]31a2bfe2010-02-09 08:03:39801 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
802 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42803 EXPECT_EQ(OK, out.rv);
[email protected]f9d44aa2008-09-23 23:57:17804 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
805 EXPECT_EQ("", out.response_data);
sclittlefb249892015-09-10 21:33:22806 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
807 int64_t response_size = reads_size - strlen(junk);
808 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]f9d44aa2008-09-23 23:57:17809}
810
[email protected]0877e3d2009-10-17 22:29:57811// A simple request using chunked encoding with some extra data after.
[email protected]23e482282013-06-14 16:08:02812TEST_P(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]b8015c42013-12-24 15:18:19813 std::string final_chunk = "0\r\n\r\n";
814 std::string extra_data = "HTTP/1.1 200 OK\r\n";
815 std::string last_read = final_chunk + extra_data;
[email protected]0877e3d2009-10-17 22:29:57816 MockRead data_reads[] = {
817 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
818 MockRead("5\r\nHello\r\n"),
819 MockRead("1\r\n"),
820 MockRead(" \r\n"),
821 MockRead("5\r\nworld\r\n"),
[email protected]b8015c42013-12-24 15:18:19822 MockRead(last_read.data()),
[email protected]8ddf8322012-02-23 18:08:06823 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:57824 };
[email protected]31a2bfe2010-02-09 08:03:39825 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
826 arraysize(data_reads));
[email protected]0877e3d2009-10-17 22:29:57827 EXPECT_EQ(OK, out.rv);
828 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
829 EXPECT_EQ("Hello world", out.response_data);
sclittlefb249892015-09-10 21:33:22830 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
831 int64_t response_size = reads_size - extra_data.size();
832 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]0877e3d2009-10-17 22:29:57833}
834
[email protected]9fe44f52010-09-23 18:36:00835// Next tests deal with http://crbug.com/56344.
836
[email protected]23e482282013-06-14 16:08:02837TEST_P(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00838 MultipleContentLengthHeadersNoTransferEncoding) {
839 MockRead data_reads[] = {
840 MockRead("HTTP/1.1 200 OK\r\n"),
841 MockRead("Content-Length: 10\r\n"),
842 MockRead("Content-Length: 5\r\n\r\n"),
843 };
844 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
845 arraysize(data_reads));
846 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
847}
848
[email protected]23e482282013-06-14 16:08:02849TEST_P(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04850 DuplicateContentLengthHeadersNoTransferEncoding) {
851 MockRead data_reads[] = {
852 MockRead("HTTP/1.1 200 OK\r\n"),
853 MockRead("Content-Length: 5\r\n"),
854 MockRead("Content-Length: 5\r\n\r\n"),
855 MockRead("Hello"),
856 };
857 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
858 arraysize(data_reads));
859 EXPECT_EQ(OK, out.rv);
860 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
861 EXPECT_EQ("Hello", out.response_data);
862}
863
[email protected]23e482282013-06-14 16:08:02864TEST_P(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04865 ComplexContentLengthHeadersNoTransferEncoding) {
866 // More than 2 dupes.
867 {
868 MockRead data_reads[] = {
869 MockRead("HTTP/1.1 200 OK\r\n"),
870 MockRead("Content-Length: 5\r\n"),
871 MockRead("Content-Length: 5\r\n"),
872 MockRead("Content-Length: 5\r\n\r\n"),
873 MockRead("Hello"),
874 };
875 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
876 arraysize(data_reads));
877 EXPECT_EQ(OK, out.rv);
878 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
879 EXPECT_EQ("Hello", out.response_data);
880 }
881 // HTTP/1.0
882 {
883 MockRead data_reads[] = {
884 MockRead("HTTP/1.0 200 OK\r\n"),
885 MockRead("Content-Length: 5\r\n"),
886 MockRead("Content-Length: 5\r\n"),
887 MockRead("Content-Length: 5\r\n\r\n"),
888 MockRead("Hello"),
889 };
890 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
891 arraysize(data_reads));
892 EXPECT_EQ(OK, out.rv);
893 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
894 EXPECT_EQ("Hello", out.response_data);
895 }
896 // 2 dupes and one mismatched.
897 {
898 MockRead data_reads[] = {
899 MockRead("HTTP/1.1 200 OK\r\n"),
900 MockRead("Content-Length: 10\r\n"),
901 MockRead("Content-Length: 10\r\n"),
902 MockRead("Content-Length: 5\r\n\r\n"),
903 };
904 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
905 arraysize(data_reads));
906 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
907 }
908}
909
[email protected]23e482282013-06-14 16:08:02910TEST_P(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00911 MultipleContentLengthHeadersTransferEncoding) {
912 MockRead data_reads[] = {
913 MockRead("HTTP/1.1 200 OK\r\n"),
914 MockRead("Content-Length: 666\r\n"),
915 MockRead("Content-Length: 1337\r\n"),
916 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
917 MockRead("5\r\nHello\r\n"),
918 MockRead("1\r\n"),
919 MockRead(" \r\n"),
920 MockRead("5\r\nworld\r\n"),
921 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:06922 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:00923 };
924 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
925 arraysize(data_reads));
926 EXPECT_EQ(OK, out.rv);
927 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
928 EXPECT_EQ("Hello world", out.response_data);
929}
930
[email protected]1628fe92011-10-04 23:04:55931// Next tests deal with http://crbug.com/98895.
932
933// Checks that a single Content-Disposition header results in no error.
[email protected]23e482282013-06-14 16:08:02934TEST_P(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:55935 MockRead data_reads[] = {
936 MockRead("HTTP/1.1 200 OK\r\n"),
937 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
938 MockRead("Content-Length: 5\r\n\r\n"),
939 MockRead("Hello"),
940 };
941 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
942 arraysize(data_reads));
943 EXPECT_EQ(OK, out.rv);
944 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
945 EXPECT_EQ("Hello", out.response_data);
946}
947
[email protected]54a9c6e52012-03-21 20:10:59948// Checks that two identical Content-Disposition headers result in no error.
[email protected]23e482282013-06-14 16:08:02949TEST_P(HttpNetworkTransactionTest,
[email protected]54a9c6e52012-03-21 20:10:59950 TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:55951 MockRead data_reads[] = {
952 MockRead("HTTP/1.1 200 OK\r\n"),
953 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
954 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
955 MockRead("Content-Length: 5\r\n\r\n"),
956 MockRead("Hello"),
957 };
958 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
959 arraysize(data_reads));
[email protected]54a9c6e52012-03-21 20:10:59960 EXPECT_EQ(OK, out.rv);
961 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
962 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:55963}
964
965// Checks that two distinct Content-Disposition headers result in an error.
[email protected]23e482282013-06-14 16:08:02966TEST_P(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:55967 MockRead data_reads[] = {
968 MockRead("HTTP/1.1 200 OK\r\n"),
969 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
970 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
971 MockRead("Content-Length: 5\r\n\r\n"),
972 MockRead("Hello"),
973 };
974 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
975 arraysize(data_reads));
976 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION, out.rv);
977}
978
[email protected]54a9c6e52012-03-21 20:10:59979// Checks that two identical Location headers result in no error.
980// Also tests Location header behavior.
[email protected]23e482282013-06-14 16:08:02981TEST_P(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:55982 MockRead data_reads[] = {
983 MockRead("HTTP/1.1 302 Redirect\r\n"),
984 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:59985 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:55986 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:06987 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:55988 };
989
990 HttpRequestInfo request;
991 request.method = "GET";
992 request.url = GURL("http://redirect.com/");
993 request.load_flags = 0;
994
mmenke6b3af6e2015-09-12 02:06:06995 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1628fe92011-10-04 23:04:55996 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:41997 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]1628fe92011-10-04 23:04:55998
999 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071000 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:551001
[email protected]49639fa2011-12-20 23:22:411002 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:551003
[email protected]49639fa2011-12-20 23:22:411004 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1628fe92011-10-04 23:04:551005 EXPECT_EQ(ERR_IO_PENDING, rv);
1006
1007 EXPECT_EQ(OK, callback.WaitForResult());
1008
1009 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]90499482013-06-01 00:39:501010 ASSERT_TRUE(response != NULL && response->headers.get() != NULL);
[email protected]1628fe92011-10-04 23:04:551011 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
1012 std::string url;
1013 EXPECT_TRUE(response->headers->IsRedirect(&url));
1014 EXPECT_EQ("http://good.com/", url);
[email protected]d8fc4722014-06-13 13:17:151015 EXPECT_TRUE(response->proxy_server.IsEmpty());
[email protected]1628fe92011-10-04 23:04:551016}
1017
[email protected]1628fe92011-10-04 23:04:551018// Checks that two distinct Location headers result in an error.
[email protected]23e482282013-06-14 16:08:021019TEST_P(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551020 MockRead data_reads[] = {
1021 MockRead("HTTP/1.1 302 Redirect\r\n"),
1022 MockRead("Location: http://good.com/\r\n"),
1023 MockRead("Location: http://evil.com/\r\n"),
1024 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061025 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551026 };
1027 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1028 arraysize(data_reads));
1029 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION, out.rv);
1030}
1031
[email protected]ef0faf2e72009-03-05 23:27:231032// Do a request using the HEAD method. Verify that we don't try to read the
1033// message body (since HEAD has none).
[email protected]23e482282013-06-14 16:08:021034TEST_P(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:421035 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:231036 request.method = "HEAD";
bncce36dca22015-04-21 22:11:231037 request.url = GURL("http://www.example.org/");
[email protected]ef0faf2e72009-03-05 23:27:231038 request.load_flags = 0;
1039
mmenke6b3af6e2015-09-12 02:06:061040 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271041 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411042 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]597a1ab2014-06-26 08:12:271043 BeforeProxyHeadersSentHandler proxy_headers_handler;
1044 trans->SetBeforeProxyHeadersSentCallback(
1045 base::Bind(&BeforeProxyHeadersSentHandler::OnBeforeProxyHeadersSent,
1046 base::Unretained(&proxy_headers_handler)));
[email protected]cb9bf6ca2011-01-28 13:15:271047
[email protected]ef0faf2e72009-03-05 23:27:231048 MockWrite data_writes1[] = {
csharrisonf473dd192015-08-18 13:54:131049 MockWrite("HEAD / HTTP/1.1\r\n"
1050 "Host: www.example.org\r\n"
1051 "Connection: keep-alive\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231052 };
1053 MockRead data_reads1[] = {
1054 MockRead("HTTP/1.1 404 Not Found\r\n"),
1055 MockRead("Server: Blah\r\n"),
1056 MockRead("Content-Length: 1234\r\n\r\n"),
1057
1058 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:061059 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]ef0faf2e72009-03-05 23:27:231060 };
1061
[email protected]31a2bfe2010-02-09 08:03:391062 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1063 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:071064 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:231065
[email protected]49639fa2011-12-20 23:22:411066 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:231067
[email protected]49639fa2011-12-20 23:22:411068 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421069 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]ef0faf2e72009-03-05 23:27:231070
1071 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421072 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:231073
[email protected]1c773ea12009-04-28 19:58:421074 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501075 ASSERT_TRUE(response != NULL);
[email protected]ef0faf2e72009-03-05 23:27:231076
1077 // Check that the headers got parsed.
[email protected]90499482013-06-01 00:39:501078 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]ef0faf2e72009-03-05 23:27:231079 EXPECT_EQ(1234, response->headers->GetContentLength());
1080 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
[email protected]d8fc4722014-06-13 13:17:151081 EXPECT_TRUE(response->proxy_server.IsEmpty());
[email protected]597a1ab2014-06-26 08:12:271082 EXPECT_FALSE(proxy_headers_handler.observed_before_proxy_headers_sent());
[email protected]ef0faf2e72009-03-05 23:27:231083
1084 std::string server_header;
1085 void* iter = NULL;
1086 bool has_server_header = response->headers->EnumerateHeader(
1087 &iter, "Server", &server_header);
1088 EXPECT_TRUE(has_server_header);
1089 EXPECT_EQ("Blah", server_header);
1090
1091 // Reading should give EOF right away, since there is no message body
1092 // (despite non-zero content-length).
1093 std::string response_data;
1094 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421095 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:231096 EXPECT_EQ("", response_data);
1097}
1098
[email protected]23e482282013-06-14 16:08:021099TEST_P(HttpNetworkTransactionTest, ReuseConnection) {
mmenke6b3af6e2015-09-12 02:06:061100 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:521101
1102 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351103 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1104 MockRead("hello"),
1105 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1106 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061107 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521108 };
[email protected]31a2bfe2010-02-09 08:03:391109 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071110 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521111
[email protected]0b0bf032010-09-21 18:08:501112 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521113 "hello", "world"
1114 };
1115
1116 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:421117 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521118 request.method = "GET";
bncce36dca22015-04-21 22:11:231119 request.url = GURL("http://www.example.org/");
initial.commit586acc5fe2008-07-26 22:42:521120 request.load_flags = 0;
1121
[email protected]262eec82013-03-19 21:01:361122 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501123 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271124
[email protected]49639fa2011-12-20 23:22:411125 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521126
[email protected]49639fa2011-12-20 23:22:411127 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421128 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521129
1130 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421131 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521132
[email protected]1c773ea12009-04-28 19:58:421133 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501134 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521135
[email protected]90499482013-06-01 00:39:501136 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251137 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]d8fc4722014-06-13 13:17:151138 EXPECT_TRUE(response->proxy_server.IsEmpty());
initial.commit586acc5fe2008-07-26 22:42:521139
1140 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571141 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421142 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251143 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521144 }
1145}
1146
[email protected]23e482282013-06-14 16:08:021147TEST_P(HttpNetworkTransactionTest, Ignores100) {
[email protected]b2d26cfd2012-12-11 10:36:061148 ScopedVector<UploadElementReader> element_readers;
1149 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:071150 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:271151
[email protected]1c773ea12009-04-28 19:58:421152 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521153 request.method = "POST";
1154 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271155 request.upload_data_stream = &upload_data_stream;
initial.commit586acc5fe2008-07-26 22:42:521156 request.load_flags = 0;
1157
mmenke6b3af6e2015-09-12 02:06:061158 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271159 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411160 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271161
initial.commit586acc5fe2008-07-26 22:42:521162 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351163 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1164 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1165 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061166 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521167 };
[email protected]31a2bfe2010-02-09 08:03:391168 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071169 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521170
[email protected]49639fa2011-12-20 23:22:411171 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521172
[email protected]49639fa2011-12-20 23:22:411173 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421174 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521175
1176 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421177 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521178
[email protected]1c773ea12009-04-28 19:58:421179 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501180 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521181
[email protected]90499482013-06-01 00:39:501182 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251183 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521184
1185 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571186 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421187 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251188 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521189}
1190
[email protected]3a2d3662009-03-27 03:49:141191// This test is almost the same as Ignores100 above, but the response contains
1192// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571193// HTTP/1.1 and the two status headers are read in one read.
[email protected]23e482282013-06-14 16:08:021194TEST_P(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421195 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141196 request.method = "GET";
1197 request.url = GURL("http://www.foo.com/");
1198 request.load_flags = 0;
1199
mmenke6b3af6e2015-09-12 02:06:061200 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271201 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411202 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271203
[email protected]3a2d3662009-03-27 03:49:141204 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571205 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1206 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141207 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061208 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141209 };
[email protected]31a2bfe2010-02-09 08:03:391210 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071211 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141212
[email protected]49639fa2011-12-20 23:22:411213 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141214
[email protected]49639fa2011-12-20 23:22:411215 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421216 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3a2d3662009-03-27 03:49:141217
1218 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421219 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:141220
[email protected]1c773ea12009-04-28 19:58:421221 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501222 ASSERT_TRUE(response != NULL);
[email protected]3a2d3662009-03-27 03:49:141223
[email protected]90499482013-06-01 00:39:501224 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3a2d3662009-03-27 03:49:141225 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1226
1227 std::string response_data;
1228 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421229 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:141230 EXPECT_EQ("hello world", response_data);
1231}
1232
[email protected]23e482282013-06-14 16:08:021233TEST_P(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
zmo9528c9f42015-08-04 22:12:081234 HttpRequestInfo request;
1235 request.method = "POST";
1236 request.url = GURL("http://www.foo.com/");
1237 request.load_flags = 0;
1238
mmenke6b3af6e2015-09-12 02:06:061239 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
zmo9528c9f42015-08-04 22:12:081240 scoped_ptr<HttpTransaction> trans(
1241 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1242
1243 MockRead data_reads[] = {
1244 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1245 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381246 };
zmo9528c9f42015-08-04 22:12:081247 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1248 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381249
zmo9528c9f42015-08-04 22:12:081250 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381251
zmo9528c9f42015-08-04 22:12:081252 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1253 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]ee9410e72010-01-07 01:42:381254
zmo9528c9f42015-08-04 22:12:081255 rv = callback.WaitForResult();
1256 EXPECT_EQ(OK, rv);
[email protected]ee9410e72010-01-07 01:42:381257
zmo9528c9f42015-08-04 22:12:081258 std::string response_data;
1259 rv = ReadTransaction(trans.get(), &response_data);
1260 EXPECT_EQ(OK, rv);
1261 EXPECT_EQ("", response_data);
[email protected]ee9410e72010-01-07 01:42:381262}
1263
[email protected]23e482282013-06-14 16:08:021264TEST_P(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381265 HttpRequestInfo request;
1266 request.method = "POST";
1267 request.url = GURL("http://www.foo.com/");
1268 request.load_flags = 0;
1269
mmenke6b3af6e2015-09-12 02:06:061270 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271271 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411272 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271273
[email protected]ee9410e72010-01-07 01:42:381274 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061275 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381276 };
[email protected]31a2bfe2010-02-09 08:03:391277 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071278 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381279
[email protected]49639fa2011-12-20 23:22:411280 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381281
[email protected]49639fa2011-12-20 23:22:411282 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]ee9410e72010-01-07 01:42:381283 EXPECT_EQ(ERR_IO_PENDING, rv);
1284
1285 rv = callback.WaitForResult();
1286 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
1287}
1288
[email protected]23e482282013-06-14 16:08:021289void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511290 const MockWrite* write_failure,
1291 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421292 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521293 request.method = "GET";
1294 request.url = GURL("http://www.foo.com/");
1295 request.load_flags = 0;
1296
vishal.b62985ca92015-04-17 08:45:511297 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071298 session_deps_.net_log = &net_log;
mmenke6b3af6e2015-09-12 02:06:061299 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271300
[email protected]202965992011-12-07 23:04:511301 // Written data for successfully sending both requests.
1302 MockWrite data1_writes[] = {
1303 MockWrite("GET / HTTP/1.1\r\n"
1304 "Host: www.foo.com\r\n"
1305 "Connection: keep-alive\r\n\r\n"),
1306 MockWrite("GET / HTTP/1.1\r\n"
1307 "Host: www.foo.com\r\n"
1308 "Connection: keep-alive\r\n\r\n")
1309 };
1310
1311 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521312 MockRead data1_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("hello"),
[email protected]8ddf8322012-02-23 18:08:061315 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521316 };
[email protected]202965992011-12-07 23:04:511317
1318 if (write_failure) {
[email protected]a34f61ee2014-03-18 20:59:491319 ASSERT_FALSE(read_failure);
[email protected]202965992011-12-07 23:04:511320 data1_writes[1] = *write_failure;
1321 } else {
1322 ASSERT_TRUE(read_failure);
1323 data1_reads[2] = *read_failure;
1324 }
1325
1326 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
1327 data1_writes, arraysize(data1_writes));
[email protected]bb88e1d32013-05-03 23:11:071328 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521329
1330 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351331 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1332 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061333 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521334 };
[email protected]31a2bfe2010-02-09 08:03:391335 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071336 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521337
thestig9d3bb0c2015-01-24 00:49:511338 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521339 "hello", "world"
1340 };
1341
[email protected]58e32bb2013-01-21 18:23:251342 uint32 first_socket_log_id = NetLog::Source::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521343 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411344 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521345
[email protected]262eec82013-03-19 21:01:361346 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501347 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
initial.commit586acc5fe2008-07-26 22:42:521348
[email protected]49639fa2011-12-20 23:22:411349 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421350 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521351
1352 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421353 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521354
[email protected]58e32bb2013-01-21 18:23:251355 LoadTimingInfo load_timing_info;
1356 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1357 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1358 if (i == 0) {
1359 first_socket_log_id = load_timing_info.socket_log_id;
1360 } else {
1361 // The second request should be using a new socket.
1362 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1363 }
1364
[email protected]1c773ea12009-04-28 19:58:421365 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501366 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521367
[email protected]90499482013-06-01 00:39:501368 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251369 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521370
1371 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571372 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421373 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251374 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521375 }
1376}
[email protected]3d2a59b2008-09-26 19:44:251377
[email protected]a34f61ee2014-03-18 20:59:491378void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1379 const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:101380 const MockRead* read_failure,
1381 bool use_spdy) {
[email protected]a34f61ee2014-03-18 20:59:491382 HttpRequestInfo request;
1383 request.method = "GET";
[email protected]09356c652014-03-25 15:36:101384 request.url = GURL("https://www.foo.com/");
[email protected]a34f61ee2014-03-18 20:59:491385 request.load_flags = 0;
1386
vishal.b62985ca92015-04-17 08:45:511387 TestNetLog net_log;
[email protected]a34f61ee2014-03-18 20:59:491388 session_deps_.net_log = &net_log;
mmenke6b3af6e2015-09-12 02:06:061389 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a34f61ee2014-03-18 20:59:491390
[email protected]09356c652014-03-25 15:36:101391 SSLSocketDataProvider ssl1(ASYNC, OK);
1392 SSLSocketDataProvider ssl2(ASYNC, OK);
1393 if (use_spdy) {
1394 ssl1.SetNextProto(GetParam());
1395 ssl2.SetNextProto(GetParam());
1396 }
1397 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1398 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]a34f61ee2014-03-18 20:59:491399
[email protected]09356c652014-03-25 15:36:101400 // SPDY versions of the request and response.
1401 scoped_ptr<SpdyFrame> spdy_request(spdy_util_.ConstructSpdyGet(
1402 request.url.spec().c_str(), false, 1, DEFAULT_PRIORITY));
1403 scoped_ptr<SpdyFrame> spdy_response(
1404 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
1405 scoped_ptr<SpdyFrame> spdy_data(
1406 spdy_util_.ConstructSpdyBodyFrame(1, "hello", 5, true));
[email protected]a34f61ee2014-03-18 20:59:491407
[email protected]09356c652014-03-25 15:36:101408 // HTTP/1.1 versions of the request and response.
1409 const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1410 "Host: www.foo.com\r\n"
1411 "Connection: keep-alive\r\n\r\n";
1412 const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1413 const char kHttpData[] = "hello";
1414
1415 std::vector<MockRead> data1_reads;
1416 std::vector<MockWrite> data1_writes;
[email protected]a34f61ee2014-03-18 20:59:491417 if (write_failure) {
1418 ASSERT_FALSE(read_failure);
[email protected]09356c652014-03-25 15:36:101419 data1_writes.push_back(*write_failure);
1420 data1_reads.push_back(MockRead(ASYNC, OK));
[email protected]a34f61ee2014-03-18 20:59:491421 } else {
1422 ASSERT_TRUE(read_failure);
[email protected]09356c652014-03-25 15:36:101423 if (use_spdy) {
1424 data1_writes.push_back(CreateMockWrite(*spdy_request));
1425 } else {
1426 data1_writes.push_back(MockWrite(kHttpRequest));
1427 }
1428 data1_reads.push_back(*read_failure);
[email protected]a34f61ee2014-03-18 20:59:491429 }
1430
[email protected]09356c652014-03-25 15:36:101431 StaticSocketDataProvider data1(&data1_reads[0], data1_reads.size(),
1432 &data1_writes[0], data1_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491433 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1434
[email protected]09356c652014-03-25 15:36:101435 std::vector<MockRead> data2_reads;
1436 std::vector<MockWrite> data2_writes;
1437
1438 if (use_spdy) {
1439 data2_writes.push_back(CreateMockWrite(*spdy_request, 0, ASYNC));
1440
1441 data2_reads.push_back(CreateMockRead(*spdy_response, 1, ASYNC));
1442 data2_reads.push_back(CreateMockRead(*spdy_data, 2, ASYNC));
1443 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1444 } else {
1445 data2_writes.push_back(
1446 MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1447
1448 data2_reads.push_back(
1449 MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1450 data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1451 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1452 }
rch8e6c6c42015-05-01 14:05:131453 SequencedSocketData data2(&data2_reads[0], data2_reads.size(),
1454 &data2_writes[0], data2_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491455 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1456
1457 // Preconnect a socket.
ttuttle859dc7a2015-04-23 19:42:291458 SSLConfig ssl_config;
[email protected]a34f61ee2014-03-18 20:59:491459 session->ssl_config_service()->GetSSLConfig(&ssl_config);
[email protected]d7599122014-05-24 03:37:231460 session->GetNextProtos(&ssl_config.next_protos);
mmenked1205bd2015-07-15 22:26:351461 session->http_stream_factory()->PreconnectStreams(1, request, ssl_config,
1462 ssl_config);
[email protected]a34f61ee2014-03-18 20:59:491463 // Wait for the preconnect to complete.
1464 // TODO(davidben): Some way to wait for an idle socket count might be handy.
1465 base::RunLoop().RunUntilIdle();
[email protected]09356c652014-03-25 15:36:101466 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]a34f61ee2014-03-18 20:59:491467
1468 // Make the request.
1469 TestCompletionCallback callback;
1470
1471 scoped_ptr<HttpTransaction> trans(
1472 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1473
1474 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1475 EXPECT_EQ(ERR_IO_PENDING, rv);
1476
1477 rv = callback.WaitForResult();
1478 EXPECT_EQ(OK, rv);
1479
1480 LoadTimingInfo load_timing_info;
1481 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
[email protected]09356c652014-03-25 15:36:101482 TestLoadTimingNotReused(
1483 load_timing_info,
1484 CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]a34f61ee2014-03-18 20:59:491485
1486 const HttpResponseInfo* response = trans->GetResponseInfo();
1487 ASSERT_TRUE(response != NULL);
1488
1489 EXPECT_TRUE(response->headers.get() != NULL);
1490 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1491
1492 std::string response_data;
1493 rv = ReadTransaction(trans.get(), &response_data);
1494 EXPECT_EQ(OK, rv);
[email protected]09356c652014-03-25 15:36:101495 EXPECT_EQ(kHttpData, response_data);
[email protected]a34f61ee2014-03-18 20:59:491496}
1497
[email protected]23e482282013-06-14 16:08:021498TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:231499 KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061500 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]202965992011-12-07 23:04:511501 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1502}
1503
[email protected]23e482282013-06-14 16:08:021504TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061505 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]202965992011-12-07 23:04:511506 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251507}
1508
[email protected]23e482282013-06-14 16:08:021509TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061510 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]202965992011-12-07 23:04:511511 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251512}
1513
[email protected]d58ceea82014-06-04 10:55:541514// Make sure that on a 408 response (Request Timeout), the request is retried,
1515// if the socket was a reused keep alive socket.
1516TEST_P(HttpNetworkTransactionTest, KeepAlive408) {
1517 MockRead read_failure(SYNCHRONOUS,
1518 "HTTP/1.1 408 Request Timeout\r\n"
1519 "Connection: Keep-Alive\r\n"
1520 "Content-Length: 6\r\n\r\n"
1521 "Pickle");
1522 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1523}
1524
[email protected]a34f61ee2014-03-18 20:59:491525TEST_P(HttpNetworkTransactionTest,
1526 PreconnectErrorNotConnectedOnWrite) {
1527 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]09356c652014-03-25 15:36:101528 PreconnectErrorResendRequestTest(&write_failure, NULL, false);
[email protected]a34f61ee2014-03-18 20:59:491529}
1530
1531TEST_P(HttpNetworkTransactionTest, PreconnectErrorReset) {
1532 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]09356c652014-03-25 15:36:101533 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
[email protected]a34f61ee2014-03-18 20:59:491534}
1535
1536TEST_P(HttpNetworkTransactionTest, PreconnectErrorEOF) {
1537 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]09356c652014-03-25 15:36:101538 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1539}
1540
1541TEST_P(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
1542 MockRead read_failure(ASYNC, OK); // EOF
1543 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1544}
1545
[email protected]d58ceea82014-06-04 10:55:541546// Make sure that on a 408 response (Request Timeout), the request is retried,
1547// if the socket was a preconnected (UNUSED_IDLE) socket.
1548TEST_P(HttpNetworkTransactionTest, RetryOnIdle408) {
1549 MockRead read_failure(SYNCHRONOUS,
1550 "HTTP/1.1 408 Request Timeout\r\n"
1551 "Connection: Keep-Alive\r\n"
1552 "Content-Length: 6\r\n\r\n"
1553 "Pickle");
1554 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1555 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1556}
1557
[email protected]09356c652014-03-25 15:36:101558TEST_P(HttpNetworkTransactionTest,
1559 SpdyPreconnectErrorNotConnectedOnWrite) {
1560 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1561 PreconnectErrorResendRequestTest(&write_failure, NULL, true);
1562}
1563
1564TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
1565 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1566 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1567}
1568
1569TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
1570 MockRead read_failure(SYNCHRONOUS, OK); // EOF
1571 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1572}
1573
1574TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
1575 MockRead read_failure(ASYNC, OK); // EOF
1576 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
[email protected]a34f61ee2014-03-18 20:59:491577}
1578
[email protected]23e482282013-06-14 16:08:021579TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:421580 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:251581 request.method = "GET";
bncce36dca22015-04-21 22:11:231582 request.url = GURL("http://www.example.org/");
[email protected]3d2a59b2008-09-26 19:44:251583 request.load_flags = 0;
1584
mmenke6b3af6e2015-09-12 02:06:061585 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271586 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411587 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271588
[email protected]3d2a59b2008-09-26 19:44:251589 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061590 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:351591 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1592 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061593 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251594 };
[email protected]31a2bfe2010-02-09 08:03:391595 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071596 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:251597
[email protected]49639fa2011-12-20 23:22:411598 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:251599
[email protected]49639fa2011-12-20 23:22:411600 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421601 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3d2a59b2008-09-26 19:44:251602
1603 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421604 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]3d2a59b2008-09-26 19:44:251605}
1606
1607// What do various browsers do when the server closes a non-keepalive
1608// connection without sending any response header or body?
1609//
1610// IE7: error page
1611// Safari 3.1.2 (Windows): error page
1612// Firefox 3.0.1: blank page
1613// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:421614// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1615// Us: error page (EMPTY_RESPONSE)
[email protected]23e482282013-06-14 16:08:021616TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:251617 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061618 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:351619 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1620 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061621 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251622 };
[email protected]31a2bfe2010-02-09 08:03:391623 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1624 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:421625 EXPECT_EQ(ERR_EMPTY_RESPONSE, out.rv);
[email protected]3d2a59b2008-09-26 19:44:251626}
[email protected]038e9a32008-10-08 22:40:161627
[email protected]1826a402014-01-08 15:40:481628// Test that network access can be deferred and resumed.
1629TEST_P(HttpNetworkTransactionTest, ThrottleBeforeNetworkStart) {
1630 HttpRequestInfo request;
1631 request.method = "GET";
bncce36dca22015-04-21 22:11:231632 request.url = GURL("http://www.example.org/");
[email protected]1826a402014-01-08 15:40:481633 request.load_flags = 0;
1634
mmenke6b3af6e2015-09-12 02:06:061635 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1826a402014-01-08 15:40:481636 scoped_ptr<HttpTransaction> trans(
1637 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1638
1639 // Defer on OnBeforeNetworkStart.
1640 BeforeNetworkStartHandler net_start_handler(true); // defer
1641 trans->SetBeforeNetworkStartCallback(
1642 base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
1643 base::Unretained(&net_start_handler)));
1644
1645 MockRead data_reads[] = {
1646 MockRead("HTTP/1.0 200 OK\r\n"),
1647 MockRead("Content-Length: 5\r\n\r\n"),
1648 MockRead("hello"),
1649 MockRead(SYNCHRONOUS, 0),
1650 };
1651 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1652 session_deps_.socket_factory->AddSocketDataProvider(&data);
1653
1654 TestCompletionCallback callback;
1655
1656 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1657 EXPECT_EQ(ERR_IO_PENDING, rv);
1658 base::MessageLoop::current()->RunUntilIdle();
1659
1660 // Should have deferred for network start.
1661 EXPECT_TRUE(net_start_handler.observed_before_network_start());
1662 EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
[email protected]1826a402014-01-08 15:40:481663
1664 trans->ResumeNetworkStart();
1665 rv = callback.WaitForResult();
1666 EXPECT_EQ(OK, rv);
1667 EXPECT_TRUE(trans->GetResponseInfo() != NULL);
1668
1669 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
1670 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
1671 if (rv == ERR_IO_PENDING)
1672 rv = callback.WaitForResult();
1673 EXPECT_EQ(5, rv);
1674 trans.reset();
1675}
1676
1677// Test that network use can be deferred and canceled.
1678TEST_P(HttpNetworkTransactionTest, ThrottleAndCancelBeforeNetworkStart) {
1679 HttpRequestInfo request;
1680 request.method = "GET";
bncce36dca22015-04-21 22:11:231681 request.url = GURL("http://www.example.org/");
[email protected]1826a402014-01-08 15:40:481682 request.load_flags = 0;
1683
mmenke6b3af6e2015-09-12 02:06:061684 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1826a402014-01-08 15:40:481685 scoped_ptr<HttpTransaction> trans(
1686 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1687
1688 // Defer on OnBeforeNetworkStart.
1689 BeforeNetworkStartHandler net_start_handler(true); // defer
1690 trans->SetBeforeNetworkStartCallback(
1691 base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
1692 base::Unretained(&net_start_handler)));
1693
1694 TestCompletionCallback callback;
1695
1696 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1697 EXPECT_EQ(ERR_IO_PENDING, rv);
1698 base::MessageLoop::current()->RunUntilIdle();
1699
1700 // Should have deferred for network start.
1701 EXPECT_TRUE(net_start_handler.observed_before_network_start());
1702 EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
[email protected]1826a402014-01-08 15:40:481703}
1704
[email protected]7a5378b2012-11-04 03:25:171705// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
1706// tests. There was a bug causing HttpNetworkTransaction to hang in the
1707// destructor in such situations.
1708// See http://crbug.com/154712 and http://crbug.com/156609.
[email protected]23e482282013-06-14 16:08:021709TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:171710 HttpRequestInfo request;
1711 request.method = "GET";
bncce36dca22015-04-21 22:11:231712 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171713 request.load_flags = 0;
1714
mmenke6b3af6e2015-09-12 02:06:061715 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:361716 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501717 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171718
1719 MockRead data_reads[] = {
1720 MockRead("HTTP/1.0 200 OK\r\n"),
1721 MockRead("Connection: keep-alive\r\n"),
1722 MockRead("Content-Length: 100\r\n\r\n"),
1723 MockRead("hello"),
1724 MockRead(SYNCHRONOUS, 0),
1725 };
1726 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071727 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171728
1729 TestCompletionCallback callback;
1730
1731 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1732 EXPECT_EQ(ERR_IO_PENDING, rv);
1733
1734 rv = callback.WaitForResult();
1735 EXPECT_EQ(OK, rv);
1736
1737 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501738 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171739 if (rv == ERR_IO_PENDING)
1740 rv = callback.WaitForResult();
1741 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:501742 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171743 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1744
1745 trans.reset();
[email protected]2da659e2013-05-23 20:51:341746 base::MessageLoop::current()->RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171747 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1748}
1749
[email protected]23e482282013-06-14 16:08:021750TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:171751 HttpRequestInfo request;
1752 request.method = "GET";
bncce36dca22015-04-21 22:11:231753 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171754 request.load_flags = 0;
1755
mmenke6b3af6e2015-09-12 02:06:061756 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:361757 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501758 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171759
1760 MockRead data_reads[] = {
1761 MockRead("HTTP/1.0 200 OK\r\n"),
1762 MockRead("Connection: keep-alive\r\n"),
1763 MockRead("Content-Length: 100\r\n\r\n"),
1764 MockRead(SYNCHRONOUS, 0),
1765 };
1766 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071767 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171768
1769 TestCompletionCallback callback;
1770
1771 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1772 EXPECT_EQ(ERR_IO_PENDING, rv);
1773
1774 rv = callback.WaitForResult();
1775 EXPECT_EQ(OK, rv);
1776
1777 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501778 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171779 if (rv == ERR_IO_PENDING)
1780 rv = callback.WaitForResult();
1781 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1782
1783 trans.reset();
[email protected]2da659e2013-05-23 20:51:341784 base::MessageLoop::current()->RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171785 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1786}
1787
[email protected]0b0bf032010-09-21 18:08:501788// Test that we correctly reuse a keep-alive connection after not explicitly
1789// reading the body.
[email protected]23e482282013-06-14 16:08:021790TEST_P(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:131791 HttpRequestInfo request;
1792 request.method = "GET";
1793 request.url = GURL("http://www.foo.com/");
1794 request.load_flags = 0;
1795
vishal.b62985ca92015-04-17 08:45:511796 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071797 session_deps_.net_log = &net_log;
mmenke6b3af6e2015-09-12 02:06:061798 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271799
[email protected]0b0bf032010-09-21 18:08:501800 // Note that because all these reads happen in the same
1801 // StaticSocketDataProvider, it shows that the same socket is being reused for
1802 // all transactions.
[email protected]fc31d6a42010-06-24 18:05:131803 MockRead data1_reads[] = {
[email protected]0b0bf032010-09-21 18:08:501804 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
1805 MockRead("HTTP/1.1 205 Reset Content\r\n\r\n"),
[email protected]fc31d6a42010-06-24 18:05:131806 MockRead("HTTP/1.1 304 Not Modified\r\n\r\n"),
[email protected]0b0bf032010-09-21 18:08:501807 MockRead("HTTP/1.1 302 Found\r\n"
1808 "Content-Length: 0\r\n\r\n"),
1809 MockRead("HTTP/1.1 302 Found\r\n"
1810 "Content-Length: 5\r\n\r\n"
1811 "hello"),
1812 MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1813 "Content-Length: 0\r\n\r\n"),
1814 MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1815 "Content-Length: 5\r\n\r\n"
1816 "hello"),
[email protected]fc31d6a42010-06-24 18:05:131817 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1818 MockRead("hello"),
1819 };
1820 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071821 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]fc31d6a42010-06-24 18:05:131822
1823 MockRead data2_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061824 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]fc31d6a42010-06-24 18:05:131825 };
1826 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071827 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]fc31d6a42010-06-24 18:05:131828
[email protected]0b0bf032010-09-21 18:08:501829 const int kNumUnreadBodies = arraysize(data1_reads) - 2;
1830 std::string response_lines[kNumUnreadBodies];
1831
[email protected]58e32bb2013-01-21 18:23:251832 uint32 first_socket_log_id = NetLog::Source::kInvalidId;
[email protected]0b0bf032010-09-21 18:08:501833 for (size_t i = 0; i < arraysize(data1_reads) - 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411834 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:131835
[email protected]262eec82013-03-19 21:01:361836 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501837 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]fc31d6a42010-06-24 18:05:131838
[email protected]49639fa2011-12-20 23:22:411839 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]fc31d6a42010-06-24 18:05:131840 EXPECT_EQ(ERR_IO_PENDING, rv);
1841
1842 rv = callback.WaitForResult();
1843 EXPECT_EQ(OK, rv);
1844
[email protected]58e32bb2013-01-21 18:23:251845 LoadTimingInfo load_timing_info;
1846 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1847 if (i == 0) {
1848 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1849 first_socket_log_id = load_timing_info.socket_log_id;
1850 } else {
1851 TestLoadTimingReused(load_timing_info);
1852 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
1853 }
1854
[email protected]fc31d6a42010-06-24 18:05:131855 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]0b0bf032010-09-21 18:08:501856 ASSERT_TRUE(response != NULL);
[email protected]fc31d6a42010-06-24 18:05:131857
[email protected]90499482013-06-01 00:39:501858 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]0b0bf032010-09-21 18:08:501859 response_lines[i] = response->headers->GetStatusLine();
1860
1861 // We intentionally don't read the response bodies.
[email protected]fc31d6a42010-06-24 18:05:131862 }
[email protected]0b0bf032010-09-21 18:08:501863
1864 const char* const kStatusLines[] = {
1865 "HTTP/1.1 204 No Content",
1866 "HTTP/1.1 205 Reset Content",
1867 "HTTP/1.1 304 Not Modified",
1868 "HTTP/1.1 302 Found",
1869 "HTTP/1.1 302 Found",
1870 "HTTP/1.1 301 Moved Permanently",
1871 "HTTP/1.1 301 Moved Permanently",
1872 };
1873
mostynb91e0da982015-01-20 19:17:271874 static_assert(kNumUnreadBodies == arraysize(kStatusLines),
1875 "forgot to update kStatusLines");
[email protected]0b0bf032010-09-21 18:08:501876
1877 for (int i = 0; i < kNumUnreadBodies; ++i)
1878 EXPECT_EQ(kStatusLines[i], response_lines[i]);
1879
[email protected]49639fa2011-12-20 23:22:411880 TestCompletionCallback callback;
[email protected]262eec82013-03-19 21:01:361881 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501882 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:411883 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0b0bf032010-09-21 18:08:501884 EXPECT_EQ(ERR_IO_PENDING, rv);
1885 rv = callback.WaitForResult();
1886 EXPECT_EQ(OK, rv);
1887 const HttpResponseInfo* response = trans->GetResponseInfo();
1888 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:501889 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]0b0bf032010-09-21 18:08:501890 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1891 std::string response_data;
1892 rv = ReadTransaction(trans.get(), &response_data);
1893 EXPECT_EQ(OK, rv);
1894 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:131895}
1896
[email protected]038e9a32008-10-08 22:40:161897// Test the request-challenge-retry sequence for basic auth.
1898// (basic auth is the easiest to mock, because it has no randomness).
[email protected]23e482282013-06-14 16:08:021899TEST_P(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:421900 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:161901 request.method = "GET";
bncce36dca22015-04-21 22:11:231902 request.url = GURL("http://www.example.org/");
[email protected]038e9a32008-10-08 22:40:161903 request.load_flags = 0;
1904
vishal.b62985ca92015-04-17 08:45:511905 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:071906 session_deps_.net_log = &log;
mmenke6b3af6e2015-09-12 02:06:061907 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271908 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411909 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271910
[email protected]f9ee6b52008-11-08 06:46:231911 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:231912 MockWrite(
1913 "GET / HTTP/1.1\r\n"
1914 "Host: www.example.org\r\n"
1915 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:231916 };
1917
[email protected]038e9a32008-10-08 22:40:161918 MockRead data_reads1[] = {
1919 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
1920 // Give a couple authenticate options (only the middle one is actually
1921 // supported).
[email protected]22927ad2009-09-21 19:56:191922 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:161923 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1924 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
1925 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1926 // Large content-length -- won't matter, as connection will be reset.
1927 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061928 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:161929 };
1930
1931 // After calling trans->RestartWithAuth(), this is the request we should
1932 // be issuing -- the final header line contains the credentials.
1933 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:231934 MockWrite(
1935 "GET / HTTP/1.1\r\n"
1936 "Host: www.example.org\r\n"
1937 "Connection: keep-alive\r\n"
1938 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:161939 };
1940
1941 // Lastly, the server responds with the actual content.
1942 MockRead data_reads2[] = {
1943 MockRead("HTTP/1.0 200 OK\r\n"),
1944 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1945 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061946 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:161947 };
1948
[email protected]31a2bfe2010-02-09 08:03:391949 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1950 data_writes1, arraysize(data_writes1));
1951 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1952 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:071953 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1954 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:161955
[email protected]49639fa2011-12-20 23:22:411956 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:161957
[email protected]49639fa2011-12-20 23:22:411958 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421959 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:161960
1961 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421962 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:161963
[email protected]58e32bb2013-01-21 18:23:251964 LoadTimingInfo load_timing_info1;
1965 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
1966 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
1967
sclittlefb249892015-09-10 21:33:221968 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
1969 EXPECT_EQ(writes_size1, trans->GetTotalSentBytes());
1970 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
[email protected]b8015c42013-12-24 15:18:191971 EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
1972
[email protected]1c773ea12009-04-28 19:58:421973 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501974 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:041975 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:161976
[email protected]49639fa2011-12-20 23:22:411977 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:161978
[email protected]49639fa2011-12-20 23:22:411979 rv = trans->RestartWithAuth(
1980 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:421981 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:161982
1983 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421984 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:161985
[email protected]58e32bb2013-01-21 18:23:251986 LoadTimingInfo load_timing_info2;
1987 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
1988 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
1989 // The load timing after restart should have a new socket ID, and times after
1990 // those of the first load timing.
1991 EXPECT_LE(load_timing_info1.receive_headers_end,
1992 load_timing_info2.connect_timing.connect_start);
1993 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
1994
sclittlefb249892015-09-10 21:33:221995 int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
1996 EXPECT_EQ(writes_size1 + writes_size2, trans->GetTotalSentBytes());
1997 int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
[email protected]b8015c42013-12-24 15:18:191998 EXPECT_EQ(reads_size1 + reads_size2, trans->GetTotalReceivedBytes());
1999
[email protected]038e9a32008-10-08 22:40:162000 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502001 ASSERT_TRUE(response != NULL);
[email protected]038e9a32008-10-08 22:40:162002 EXPECT_TRUE(response->auth_challenge.get() == NULL);
2003 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:162004}
2005
[email protected]23e482282013-06-14 16:08:022006TEST_P(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:462007 HttpRequestInfo request;
2008 request.method = "GET";
bncce36dca22015-04-21 22:11:232009 request.url = GURL("http://www.example.org/");
ttuttle859dc7a2015-04-23 19:42:292010 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]861fcd52009-08-26 02:33:462011
mmenke6b3af6e2015-09-12 02:06:062012 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272013 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:412014 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:272015
[email protected]861fcd52009-08-26 02:33:462016 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:232017 MockWrite(
2018 "GET / HTTP/1.1\r\n"
2019 "Host: www.example.org\r\n"
2020 "Connection: keep-alive\r\n\r\n"),
[email protected]861fcd52009-08-26 02:33:462021 };
2022
2023 MockRead data_reads[] = {
2024 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2025 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2026 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2027 // Large content-length -- won't matter, as connection will be reset.
2028 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062029 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:462030 };
2031
[email protected]31a2bfe2010-02-09 08:03:392032 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2033 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072034 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:412035 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:462036
[email protected]49639fa2011-12-20 23:22:412037 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]861fcd52009-08-26 02:33:462038 EXPECT_EQ(ERR_IO_PENDING, rv);
2039
2040 rv = callback.WaitForResult();
2041 EXPECT_EQ(0, rv);
2042
sclittlefb249892015-09-10 21:33:222043 int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
2044 EXPECT_EQ(writes_size, trans->GetTotalSentBytes());
2045 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
[email protected]b8015c42013-12-24 15:18:192046 EXPECT_EQ(reads_size, trans->GetTotalReceivedBytes());
2047
[email protected]861fcd52009-08-26 02:33:462048 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502049 ASSERT_TRUE(response != NULL);
[email protected]861fcd52009-08-26 02:33:462050 EXPECT_TRUE(response->auth_challenge.get() == NULL);
2051}
2052
[email protected]2d2697f92009-02-18 21:00:322053// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2054// connection.
[email protected]23e482282013-06-14 16:08:022055TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
[email protected]1c773ea12009-04-28 19:58:422056 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322057 request.method = "GET";
bncce36dca22015-04-21 22:11:232058 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322059 request.load_flags = 0;
2060
vishal.b62985ca92015-04-17 08:45:512061 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072062 session_deps_.net_log = &log;
mmenke6b3af6e2015-09-12 02:06:062063 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272064
[email protected]2d2697f92009-02-18 21:00:322065 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232066 MockWrite(
2067 "GET / HTTP/1.1\r\n"
2068 "Host: www.example.org\r\n"
2069 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322070
bncce36dca22015-04-21 22:11:232071 // After calling trans->RestartWithAuth(), this is the request we should
2072 // be issuing -- the final header line contains the credentials.
2073 MockWrite(
2074 "GET / HTTP/1.1\r\n"
2075 "Host: www.example.org\r\n"
2076 "Connection: keep-alive\r\n"
2077 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322078 };
2079
2080 MockRead data_reads1[] = {
2081 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2082 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2083 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2084 MockRead("Content-Length: 14\r\n\r\n"),
2085 MockRead("Unauthorized\r\n"),
2086
2087 // Lastly, the server responds with the actual content.
2088 MockRead("HTTP/1.1 200 OK\r\n"),
2089 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502090 MockRead("Content-Length: 5\r\n\r\n"),
2091 MockRead("Hello"),
[email protected]2d2697f92009-02-18 21:00:322092 };
2093
[email protected]2d0a4f92011-05-05 16:38:462094 // If there is a regression where we disconnect a Keep-Alive
2095 // connection during an auth roundtrip, we'll end up reading this.
2096 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062097 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462098 };
2099
[email protected]31a2bfe2010-02-09 08:03:392100 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2101 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462102 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2103 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072104 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2105 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322106
[email protected]49639fa2011-12-20 23:22:412107 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322108
[email protected]262eec82013-03-19 21:01:362109 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502110 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412111 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422112 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322113
2114 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422115 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322116
[email protected]58e32bb2013-01-21 18:23:252117 LoadTimingInfo load_timing_info1;
2118 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
2119 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2120
[email protected]1c773ea12009-04-28 19:58:422121 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502122 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042123 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322124
[email protected]49639fa2011-12-20 23:22:412125 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322126
[email protected]49639fa2011-12-20 23:22:412127 rv = trans->RestartWithAuth(
2128 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422129 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322130
2131 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422132 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322133
[email protected]58e32bb2013-01-21 18:23:252134 LoadTimingInfo load_timing_info2;
2135 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
2136 TestLoadTimingReused(load_timing_info2);
2137 // The load timing after restart should have the same socket ID, and times
2138 // those of the first load timing.
2139 EXPECT_LE(load_timing_info1.receive_headers_end,
2140 load_timing_info2.send_start);
2141 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2142
[email protected]2d2697f92009-02-18 21:00:322143 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502144 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322145 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502146 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]b8015c42013-12-24 15:18:192147
2148 std::string response_data;
2149 rv = ReadTransaction(trans.get(), &response_data);
2150 EXPECT_EQ(OK, rv);
sclittlefb249892015-09-10 21:33:222151
2152 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
2153 EXPECT_EQ(writes_size1, trans->GetTotalSentBytes());
2154 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
[email protected]b8015c42013-12-24 15:18:192155 EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
[email protected]2d2697f92009-02-18 21:00:322156}
2157
2158// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2159// connection and with no response body to drain.
[email protected]23e482282013-06-14 16:08:022160TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:422161 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322162 request.method = "GET";
bncce36dca22015-04-21 22:11:232163 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322164 request.load_flags = 0;
2165
mmenke6b3af6e2015-09-12 02:06:062166 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272167
[email protected]2d2697f92009-02-18 21:00:322168 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232169 MockWrite(
2170 "GET / HTTP/1.1\r\n"
2171 "Host: www.example.org\r\n"
2172 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322173
bncce36dca22015-04-21 22:11:232174 // After calling trans->RestartWithAuth(), this is the request we should
2175 // be issuing -- the final header line contains the credentials.
2176 MockWrite(
2177 "GET / HTTP/1.1\r\n"
2178 "Host: www.example.org\r\n"
2179 "Connection: keep-alive\r\n"
2180 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322181 };
2182
[email protected]2d2697f92009-02-18 21:00:322183 MockRead data_reads1[] = {
2184 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2185 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:312186 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:322187
2188 // Lastly, the server responds with the actual content.
2189 MockRead("HTTP/1.1 200 OK\r\n"),
2190 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502191 MockRead("Content-Length: 5\r\n\r\n"),
2192 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322193 };
2194
[email protected]2d0a4f92011-05-05 16:38:462195 // An incorrect reconnect would cause this to be read.
2196 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062197 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462198 };
2199
[email protected]31a2bfe2010-02-09 08:03:392200 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2201 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462202 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2203 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072204 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2205 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322206
[email protected]49639fa2011-12-20 23:22:412207 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322208
[email protected]262eec82013-03-19 21:01:362209 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502210 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412211 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422212 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322213
2214 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422215 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322216
[email protected]1c773ea12009-04-28 19:58:422217 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502218 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042219 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322220
[email protected]49639fa2011-12-20 23:22:412221 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322222
[email protected]49639fa2011-12-20 23:22:412223 rv = trans->RestartWithAuth(
2224 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422225 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322226
2227 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422228 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322229
2230 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502231 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322232 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502233 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322234}
2235
2236// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2237// connection and with a large response body to drain.
[email protected]23e482282013-06-14 16:08:022238TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:422239 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322240 request.method = "GET";
bncce36dca22015-04-21 22:11:232241 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322242 request.load_flags = 0;
2243
mmenke6b3af6e2015-09-12 02:06:062244 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272245
[email protected]2d2697f92009-02-18 21:00:322246 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232247 MockWrite(
2248 "GET / HTTP/1.1\r\n"
2249 "Host: www.example.org\r\n"
2250 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322251
bncce36dca22015-04-21 22:11:232252 // After calling trans->RestartWithAuth(), this is the request we should
2253 // be issuing -- the final header line contains the credentials.
2254 MockWrite(
2255 "GET / HTTP/1.1\r\n"
2256 "Host: www.example.org\r\n"
2257 "Connection: keep-alive\r\n"
2258 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322259 };
2260
2261 // Respond with 5 kb of response body.
2262 std::string large_body_string("Unauthorized");
2263 large_body_string.append(5 * 1024, ' ');
2264 large_body_string.append("\r\n");
2265
2266 MockRead data_reads1[] = {
2267 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2268 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2269 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2270 // 5134 = 12 + 5 * 1024 + 2
2271 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062272 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:322273
2274 // Lastly, the server responds with the actual content.
2275 MockRead("HTTP/1.1 200 OK\r\n"),
2276 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502277 MockRead("Content-Length: 5\r\n\r\n"),
2278 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322279 };
2280
[email protected]2d0a4f92011-05-05 16:38:462281 // An incorrect reconnect would cause this to be read.
2282 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062283 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462284 };
2285
[email protected]31a2bfe2010-02-09 08:03:392286 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2287 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462288 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2289 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072290 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2291 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322292
[email protected]49639fa2011-12-20 23:22:412293 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322294
[email protected]262eec82013-03-19 21:01:362295 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502296 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412297 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422298 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322299
2300 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422301 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322302
[email protected]1c773ea12009-04-28 19:58:422303 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502304 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042305 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322306
[email protected]49639fa2011-12-20 23:22:412307 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322308
[email protected]49639fa2011-12-20 23:22:412309 rv = trans->RestartWithAuth(
2310 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422311 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322312
2313 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422314 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322315
2316 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502317 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322318 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502319 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322320}
2321
2322// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:312323// connection, but the server gets impatient and closes the connection.
[email protected]23e482282013-06-14 16:08:022324TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:312325 HttpRequestInfo request;
2326 request.method = "GET";
bncce36dca22015-04-21 22:11:232327 request.url = GURL("http://www.example.org/");
[email protected]11203f012009-11-12 23:02:312328 request.load_flags = 0;
2329
mmenke6b3af6e2015-09-12 02:06:062330 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272331
[email protected]11203f012009-11-12 23:02:312332 MockWrite data_writes1[] = {
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\r\n"),
2337 // This simulates the seemingly successful write to a closed connection
2338 // if the bug is not fixed.
2339 MockWrite(
2340 "GET / HTTP/1.1\r\n"
2341 "Host: www.example.org\r\n"
2342 "Connection: keep-alive\r\n"
2343 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312344 };
2345
2346 MockRead data_reads1[] = {
2347 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2348 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2349 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2350 MockRead("Content-Length: 14\r\n\r\n"),
2351 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:062352 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:312353 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:062354 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:312355 };
2356
2357 // After calling trans->RestartWithAuth(), this is the request we should
2358 // be issuing -- the final header line contains the credentials.
2359 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232360 MockWrite(
2361 "GET / HTTP/1.1\r\n"
2362 "Host: www.example.org\r\n"
2363 "Connection: keep-alive\r\n"
2364 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312365 };
2366
2367 // Lastly, the server responds with the actual content.
2368 MockRead data_reads2[] = {
2369 MockRead("HTTP/1.1 200 OK\r\n"),
2370 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502371 MockRead("Content-Length: 5\r\n\r\n"),
2372 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:312373 };
2374
[email protected]31a2bfe2010-02-09 08:03:392375 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2376 data_writes1, arraysize(data_writes1));
2377 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2378 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072379 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2380 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:312381
[email protected]49639fa2011-12-20 23:22:412382 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:312383
[email protected]262eec82013-03-19 21:01:362384 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502385 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412386 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]11203f012009-11-12 23:02:312387 EXPECT_EQ(ERR_IO_PENDING, rv);
2388
2389 rv = callback1.WaitForResult();
2390 EXPECT_EQ(OK, rv);
2391
2392 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502393 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042394 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:312395
[email protected]49639fa2011-12-20 23:22:412396 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:312397
[email protected]49639fa2011-12-20 23:22:412398 rv = trans->RestartWithAuth(
2399 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]11203f012009-11-12 23:02:312400 EXPECT_EQ(ERR_IO_PENDING, rv);
2401
2402 rv = callback2.WaitForResult();
2403 EXPECT_EQ(OK, rv);
2404
2405 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502406 ASSERT_TRUE(response != NULL);
[email protected]11203f012009-11-12 23:02:312407 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502408 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:312409}
2410
[email protected]394816e92010-08-03 07:38:592411// Test the request-challenge-retry sequence for basic auth, over a connection
2412// that requires a restart when setting up an SSL tunnel.
ttuttle34f63b52015-03-05 04:33:012413TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
2414 HttpRequestInfo request;
2415 request.method = "GET";
bncce36dca22015-04-21 22:11:232416 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:012417 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292418 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:012419
2420 // Configure against proxy server "myproxy:70".
2421 session_deps_.proxy_service.reset(
2422 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
vishal.b62985ca92015-04-17 08:45:512423 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:012424 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:062425 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:012426
2427 // Since we have proxy, should try to establish tunnel.
2428 MockWrite data_writes1[] = {
mmenkee0b5c882015-08-26 20:29:112429 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
2430 "Host: www.example.org\r\n"
2431 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:012432 };
2433
mmenkee0b5c882015-08-26 20:29:112434 // The proxy responds to the connect with a 407, using a non-persistent
ttuttle34f63b52015-03-05 04:33:012435 // connection.
2436 MockRead data_reads1[] = {
2437 // No credentials.
2438 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
2439 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
mmenkee0b5c882015-08-26 20:29:112440 };
ttuttle34f63b52015-03-05 04:33:012441
mmenkee0b5c882015-08-26 20:29:112442 // Since the first connection couldn't be reused, need to establish another
2443 // once given credentials.
2444 MockWrite data_writes2[] = {
2445 // After calling trans->RestartWithAuth(), this is the request we should
2446 // be issuing -- the final header line contains the credentials.
2447 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
2448 "Host: www.example.org\r\n"
2449 "Proxy-Connection: keep-alive\r\n"
2450 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2451
2452 MockWrite("GET / HTTP/1.1\r\n"
2453 "Host: www.example.org\r\n"
2454 "Connection: keep-alive\r\n\r\n"),
2455 };
2456
2457 MockRead data_reads2[] = {
ttuttle34f63b52015-03-05 04:33:012458 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
2459
2460 MockRead("HTTP/1.1 200 OK\r\n"),
2461 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2462 MockRead("Content-Length: 5\r\n\r\n"),
2463 MockRead(SYNCHRONOUS, "hello"),
2464 };
2465
2466 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2467 data_writes1, arraysize(data_writes1));
2468 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee0b5c882015-08-26 20:29:112469 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2470 data_writes2, arraysize(data_writes2));
2471 session_deps_.socket_factory->AddSocketDataProvider(&data2);
ttuttle34f63b52015-03-05 04:33:012472 SSLSocketDataProvider ssl(ASYNC, OK);
2473 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
2474
2475 TestCompletionCallback callback1;
2476
2477 scoped_ptr<HttpTransaction> trans(
2478 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2479
2480 int rv = trans->Start(&request, callback1.callback(), log.bound());
2481 EXPECT_EQ(ERR_IO_PENDING, rv);
2482
2483 rv = callback1.WaitForResult();
2484 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:462485 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:012486 log.GetEntries(&entries);
2487 size_t pos = ExpectLogContainsSomewhere(
2488 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
2489 NetLog::PHASE_NONE);
2490 ExpectLogContainsSomewhere(
2491 entries, pos, NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2492 NetLog::PHASE_NONE);
2493
2494 const HttpResponseInfo* response = trans->GetResponseInfo();
2495 ASSERT_TRUE(response != NULL);
2496 EXPECT_FALSE(response->headers->IsKeepAlive());
2497 ASSERT_FALSE(response->headers.get() == NULL);
2498 EXPECT_EQ(407, response->headers->response_code());
2499 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
2500 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2501
2502 LoadTimingInfo load_timing_info;
2503 // CONNECT requests and responses are handled at the connect job level, so
2504 // the transaction does not yet have a connection.
2505 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
2506
2507 TestCompletionCallback callback2;
2508
2509 rv =
2510 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
2511 EXPECT_EQ(ERR_IO_PENDING, rv);
2512
2513 rv = callback2.WaitForResult();
2514 EXPECT_EQ(OK, rv);
2515
2516 response = trans->GetResponseInfo();
2517 ASSERT_TRUE(response != NULL);
2518
2519 EXPECT_TRUE(response->headers->IsKeepAlive());
2520 EXPECT_EQ(200, response->headers->response_code());
2521 EXPECT_EQ(5, response->headers->GetContentLength());
2522 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2523
2524 // The password prompt info should not be set.
2525 EXPECT_TRUE(response->auth_challenge.get() == NULL);
2526
2527 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2528 TestLoadTimingNotReusedWithPac(load_timing_info,
2529 CONNECT_TIMING_HAS_SSL_TIMES);
2530
2531 trans.reset();
2532 session->CloseAllConnections();
2533}
2534
2535// Test the request-challenge-retry sequence for basic auth, over a connection
2536// that requires a restart when setting up an SSL tunnel.
2537TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) {
[email protected]394816e92010-08-03 07:38:592538 HttpRequestInfo request;
2539 request.method = "GET";
bncce36dca22015-04-21 22:11:232540 request.url = GURL("https://www.example.org/");
[email protected]394816e92010-08-03 07:38:592541 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292542 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]394816e92010-08-03 07:38:592543
[email protected]cb9bf6ca2011-01-28 13:15:272544 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072545 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:202546 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
vishal.b62985ca92015-04-17 08:45:512547 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072548 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:062549 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272550
[email protected]394816e92010-08-03 07:38:592551 // Since we have proxy, should try to establish tunnel.
2552 MockWrite data_writes1[] = {
mmenkee0b5c882015-08-26 20:29:112553 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
2554 "Host: www.example.org\r\n"
2555 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]394816e92010-08-03 07:38:592556 };
2557
mmenkee0b5c882015-08-26 20:29:112558 // The proxy responds to the connect with a 407, using a non-persistent
[email protected]394816e92010-08-03 07:38:592559 // connection.
2560 MockRead data_reads1[] = {
mmenkee0b5c882015-08-26 20:29:112561 // No credentials.
2562 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2563 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2564 MockRead("Proxy-Connection: close\r\n\r\n"),
2565 };
[email protected]394816e92010-08-03 07:38:592566
mmenkee0b5c882015-08-26 20:29:112567 MockWrite data_writes2[] = {
2568 // After calling trans->RestartWithAuth(), this is the request we should
2569 // be issuing -- the final header line contains the credentials.
2570 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
2571 "Host: www.example.org\r\n"
2572 "Proxy-Connection: keep-alive\r\n"
2573 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]394816e92010-08-03 07:38:592574
mmenkee0b5c882015-08-26 20:29:112575 MockWrite("GET / HTTP/1.1\r\n"
2576 "Host: www.example.org\r\n"
2577 "Connection: keep-alive\r\n\r\n"),
2578 };
2579
2580 MockRead data_reads2[] = {
2581 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2582
2583 MockRead("HTTP/1.1 200 OK\r\n"),
2584 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2585 MockRead("Content-Length: 5\r\n\r\n"),
2586 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:592587 };
2588
2589 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2590 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072591 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee0b5c882015-08-26 20:29:112592 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2593 data_writes2, arraysize(data_writes2));
2594 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8ddf8322012-02-23 18:08:062595 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072596 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:592597
[email protected]49639fa2011-12-20 23:22:412598 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:592599
[email protected]262eec82013-03-19 21:01:362600 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502601 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:502602
[email protected]49639fa2011-12-20 23:22:412603 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]394816e92010-08-03 07:38:592604 EXPECT_EQ(ERR_IO_PENDING, rv);
2605
2606 rv = callback1.WaitForResult();
2607 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:462608 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:402609 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:592610 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402611 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]394816e92010-08-03 07:38:592612 NetLog::PHASE_NONE);
2613 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402614 entries, pos,
[email protected]394816e92010-08-03 07:38:592615 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2616 NetLog::PHASE_NONE);
2617
2618 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502619 ASSERT_TRUE(response != NULL);
ttuttle34f63b52015-03-05 04:33:012620 EXPECT_FALSE(response->headers->IsKeepAlive());
[email protected]90499482013-06-01 00:39:502621 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]394816e92010-08-03 07:38:592622 EXPECT_EQ(407, response->headers->response_code());
2623 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042624 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:592625
[email protected]029c83b62013-01-24 05:28:202626 LoadTimingInfo load_timing_info;
2627 // CONNECT requests and responses are handled at the connect job level, so
2628 // the transaction does not yet have a connection.
2629 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
2630
[email protected]49639fa2011-12-20 23:22:412631 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:592632
[email protected]49639fa2011-12-20 23:22:412633 rv = trans->RestartWithAuth(
2634 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]394816e92010-08-03 07:38:592635 EXPECT_EQ(ERR_IO_PENDING, rv);
2636
2637 rv = callback2.WaitForResult();
2638 EXPECT_EQ(OK, rv);
2639
2640 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502641 ASSERT_TRUE(response != NULL);
[email protected]394816e92010-08-03 07:38:592642
2643 EXPECT_TRUE(response->headers->IsKeepAlive());
2644 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:502645 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:592646 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2647
2648 // The password prompt info should not be set.
2649 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502650
[email protected]029c83b62013-01-24 05:28:202651 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2652 TestLoadTimingNotReusedWithPac(load_timing_info,
2653 CONNECT_TIMING_HAS_SSL_TIMES);
2654
[email protected]0b0bf032010-09-21 18:08:502655 trans.reset();
[email protected]102e27c2011-02-23 01:01:312656 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:592657}
2658
[email protected]11203f012009-11-12 23:02:312659// Test the request-challenge-retry sequence for basic auth, over a keep-alive
ttuttle34f63b52015-03-05 04:33:012660// proxy connection with HTTP/1.0 responses, when setting up an SSL tunnel.
2661TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
2662 HttpRequestInfo request;
2663 request.method = "GET";
bncce36dca22015-04-21 22:11:232664 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:012665 // Ensure that proxy authentication is attempted even
2666 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292667 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:012668
2669 // Configure against proxy server "myproxy:70".
2670 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
vishal.b62985ca92015-04-17 08:45:512671 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:012672 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:062673 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:012674
2675 scoped_ptr<HttpTransaction> trans(
2676 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2677
2678 // Since we have proxy, should try to establish tunnel.
2679 MockWrite data_writes1[] = {
2680 MockWrite(
bncce36dca22015-04-21 22:11:232681 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2682 "Host: www.example.org\r\n"
ttuttle34f63b52015-03-05 04:33:012683 "Proxy-Connection: keep-alive\r\n\r\n"),
2684
2685 // After calling trans->RestartWithAuth(), this is the request we should
2686 // be issuing -- the final header line contains the credentials.
2687 MockWrite(
bncce36dca22015-04-21 22:11:232688 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2689 "Host: www.example.org\r\n"
ttuttle34f63b52015-03-05 04:33:012690 "Proxy-Connection: keep-alive\r\n"
2691 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
2692 };
2693
2694 // The proxy responds to the connect with a 407, using a persistent
2695 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
2696 MockRead data_reads1[] = {
2697 // No credentials.
2698 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
2699 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2700 MockRead("Proxy-Connection: keep-alive\r\n"),
2701 MockRead("Content-Length: 10\r\n\r\n"),
2702 MockRead("0123456789"),
2703
2704 // Wrong credentials (wrong password).
2705 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
2706 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2707 MockRead("Proxy-Connection: keep-alive\r\n"),
2708 MockRead("Content-Length: 10\r\n\r\n"),
2709 // No response body because the test stops reading here.
2710 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
2711 };
2712
2713 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2714 data_writes1, arraysize(data_writes1));
2715 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2716
2717 TestCompletionCallback callback1;
2718
2719 int rv = trans->Start(&request, callback1.callback(), log.bound());
2720 EXPECT_EQ(ERR_IO_PENDING, rv);
2721
2722 rv = callback1.WaitForResult();
2723 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:462724 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:012725 log.GetEntries(&entries);
2726 size_t pos = ExpectLogContainsSomewhere(
2727 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
2728 NetLog::PHASE_NONE);
2729 ExpectLogContainsSomewhere(
2730 entries, pos, NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2731 NetLog::PHASE_NONE);
2732
2733 const HttpResponseInfo* response = trans->GetResponseInfo();
2734 ASSERT_TRUE(response);
2735 ASSERT_TRUE(response->headers);
2736 EXPECT_TRUE(response->headers->IsKeepAlive());
2737 EXPECT_EQ(407, response->headers->response_code());
2738 EXPECT_EQ(10, response->headers->GetContentLength());
2739 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
2740 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2741
2742 TestCompletionCallback callback2;
2743
2744 // Wrong password (should be "bar").
2745 rv =
2746 trans->RestartWithAuth(AuthCredentials(kFoo, kBaz), callback2.callback());
2747 EXPECT_EQ(ERR_IO_PENDING, rv);
2748
2749 rv = callback2.WaitForResult();
2750 EXPECT_EQ(OK, rv);
2751
2752 response = trans->GetResponseInfo();
2753 ASSERT_TRUE(response);
2754 ASSERT_TRUE(response->headers);
2755 EXPECT_TRUE(response->headers->IsKeepAlive());
2756 EXPECT_EQ(407, response->headers->response_code());
2757 EXPECT_EQ(10, response->headers->GetContentLength());
2758 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
2759 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2760
2761 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
2762 // out of scope.
2763 session->CloseAllConnections();
2764}
2765
2766// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2767// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel.
2768TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
[email protected]cb9bf6ca2011-01-28 13:15:272769 HttpRequestInfo request;
2770 request.method = "GET";
bncce36dca22015-04-21 22:11:232771 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:272772 // Ensure that proxy authentication is attempted even
2773 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292774 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]cb9bf6ca2011-01-28 13:15:272775
[email protected]2d2697f92009-02-18 21:00:322776 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072777 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
vishal.b62985ca92015-04-17 08:45:512778 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072779 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:062780 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:322781
[email protected]262eec82013-03-19 21:01:362782 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502783 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d2697f92009-02-18 21:00:322784
[email protected]2d2697f92009-02-18 21:00:322785 // Since we have proxy, should try to establish tunnel.
2786 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232787 MockWrite(
2788 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2789 "Host: www.example.org\r\n"
2790 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322791
bncce36dca22015-04-21 22:11:232792 // After calling trans->RestartWithAuth(), this is the request we should
2793 // be issuing -- the final header line contains the credentials.
2794 MockWrite(
2795 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2796 "Host: www.example.org\r\n"
2797 "Proxy-Connection: keep-alive\r\n"
2798 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322799 };
2800
2801 // The proxy responds to the connect with a 407, using a persistent
2802 // connection.
2803 MockRead data_reads1[] = {
2804 // No credentials.
2805 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2806 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2807 MockRead("Content-Length: 10\r\n\r\n"),
2808 MockRead("0123456789"),
2809
2810 // Wrong credentials (wrong password).
2811 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2812 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2813 MockRead("Content-Length: 10\r\n\r\n"),
2814 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:062815 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]2d2697f92009-02-18 21:00:322816 };
2817
[email protected]31a2bfe2010-02-09 08:03:392818 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2819 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072820 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d2697f92009-02-18 21:00:322821
[email protected]49639fa2011-12-20 23:22:412822 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322823
[email protected]49639fa2011-12-20 23:22:412824 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]1c773ea12009-04-28 19:58:422825 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322826
2827 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422828 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:462829 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:402830 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:392831 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402832 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]dbb83db2010-05-11 18:13:392833 NetLog::PHASE_NONE);
2834 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402835 entries, pos,
[email protected]dbb83db2010-05-11 18:13:392836 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2837 NetLog::PHASE_NONE);
[email protected]2d2697f92009-02-18 21:00:322838
[email protected]1c773ea12009-04-28 19:58:422839 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:242840 ASSERT_TRUE(response);
2841 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:322842 EXPECT_TRUE(response->headers->IsKeepAlive());
2843 EXPECT_EQ(407, response->headers->response_code());
ttuttle34f63b52015-03-05 04:33:012844 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422845 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042846 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322847
[email protected]49639fa2011-12-20 23:22:412848 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322849
2850 // Wrong password (should be "bar").
[email protected]49639fa2011-12-20 23:22:412851 rv = trans->RestartWithAuth(
2852 AuthCredentials(kFoo, kBaz), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422853 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322854
2855 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422856 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322857
2858 response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:242859 ASSERT_TRUE(response);
2860 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:322861 EXPECT_TRUE(response->headers->IsKeepAlive());
2862 EXPECT_EQ(407, response->headers->response_code());
ttuttle34f63b52015-03-05 04:33:012863 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422864 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042865 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]e772db3f2010-07-12 18:11:132866
[email protected]e60e47a2010-07-14 03:37:182867 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
2868 // out of scope.
[email protected]102e27c2011-02-23 01:01:312869 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:322870}
2871
mmenkee0b5c882015-08-26 20:29:112872// Test the case a proxy closes a socket while the challenge body is being
2873// drained.
2874TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHangupDuringBody) {
2875 HttpRequestInfo request;
2876 request.method = "GET";
2877 request.url = GURL("https://www.example.org/");
2878 // Ensure that proxy authentication is attempted even
2879 // when the no authentication data flag is set.
2880 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
2881
2882 // Configure against proxy server "myproxy:70".
2883 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
mmenke6b3af6e2015-09-12 02:06:062884 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee0b5c882015-08-26 20:29:112885
2886 scoped_ptr<HttpTransaction> trans(
2887 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2888
2889 // Since we have proxy, should try to establish tunnel.
2890 MockWrite data_writes1[] = {
2891 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
2892 "Host: www.example.org\r\n"
2893 "Proxy-Connection: keep-alive\r\n\r\n"),
2894 };
2895
2896 // The proxy responds to the connect with a 407, using a persistent
2897 // connection.
2898 MockRead data_reads1[] = {
2899 // No credentials.
2900 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2901 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2902 MockRead("Content-Length: 10\r\n\r\n"), MockRead("spam!"),
2903 // Server hands up in the middle of the body.
2904 MockRead(ASYNC, ERR_CONNECTION_CLOSED),
2905 };
2906
2907 MockWrite data_writes2[] = {
2908 // After calling trans->RestartWithAuth(), this is the request we should
2909 // be issuing -- the final header line contains the credentials.
2910 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
2911 "Host: www.example.org\r\n"
2912 "Proxy-Connection: keep-alive\r\n"
2913 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2914
2915 MockWrite("GET / HTTP/1.1\r\n"
2916 "Host: www.example.org\r\n"
2917 "Connection: keep-alive\r\n\r\n"),
2918 };
2919
2920 MockRead data_reads2[] = {
2921 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2922
2923 MockRead("HTTP/1.1 200 OK\r\n"),
2924 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2925 MockRead("Content-Length: 5\r\n\r\n"),
2926 MockRead(SYNCHRONOUS, "hello"),
2927 };
2928
2929 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2930 data_writes1, arraysize(data_writes1));
2931 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2932 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2933 data_writes2, arraysize(data_writes2));
2934 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2935 SSLSocketDataProvider ssl(ASYNC, OK);
2936 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
2937
2938 TestCompletionCallback callback;
2939
2940 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
2941 EXPECT_EQ(OK, callback.GetResult(rv));
2942
2943 const HttpResponseInfo* response = trans->GetResponseInfo();
2944 ASSERT_TRUE(response);
2945 ASSERT_TRUE(response->headers);
2946 EXPECT_TRUE(response->headers->IsKeepAlive());
2947 EXPECT_EQ(407, response->headers->response_code());
2948 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2949
2950 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
2951 EXPECT_EQ(OK, callback.GetResult(rv));
2952
2953 response = trans->GetResponseInfo();
2954 ASSERT_TRUE(response);
2955 ASSERT_TRUE(response->headers);
2956 EXPECT_TRUE(response->headers->IsKeepAlive());
2957 EXPECT_EQ(200, response->headers->response_code());
2958 std::string body;
2959 EXPECT_EQ(OK, ReadTransaction(trans.get(), &body));
2960 EXPECT_EQ("hello", body);
2961}
2962
[email protected]a8e9b162009-03-12 00:06:442963// Test that we don't read the response body when we fail to establish a tunnel,
2964// even if the user cancels the proxy's auth attempt.
[email protected]23e482282013-06-14 16:08:022965TEST_P(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:272966 HttpRequestInfo request;
2967 request.method = "GET";
bncce36dca22015-04-21 22:11:232968 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:272969 request.load_flags = 0;
2970
[email protected]a8e9b162009-03-12 00:06:442971 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072972 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]a8e9b162009-03-12 00:06:442973
mmenke6b3af6e2015-09-12 02:06:062974 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:442975
[email protected]262eec82013-03-19 21:01:362976 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502977 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]a8e9b162009-03-12 00:06:442978
[email protected]a8e9b162009-03-12 00:06:442979 // Since we have proxy, should try to establish tunnel.
2980 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:232981 MockWrite(
2982 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2983 "Host: www.example.org\r\n"
2984 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:442985 };
2986
2987 // The proxy responds to the connect with a 407.
2988 MockRead data_reads[] = {
ttuttle7933c112015-01-06 00:55:242989 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2990 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2991 MockRead("Content-Length: 10\r\n\r\n"),
2992 MockRead("0123456789"), // Should not be reached.
2993 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]a8e9b162009-03-12 00:06:442994 };
2995
[email protected]31a2bfe2010-02-09 08:03:392996 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2997 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072998 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:442999
[email protected]49639fa2011-12-20 23:22:413000 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:443001
[email protected]49639fa2011-12-20 23:22:413002 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:423003 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a8e9b162009-03-12 00:06:443004
3005 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:423006 EXPECT_EQ(OK, rv);
[email protected]a8e9b162009-03-12 00:06:443007
[email protected]1c773ea12009-04-28 19:58:423008 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243009 ASSERT_TRUE(response);
3010 ASSERT_TRUE(response->headers);
[email protected]a8e9b162009-03-12 00:06:443011 EXPECT_TRUE(response->headers->IsKeepAlive());
3012 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423013 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:443014
3015 std::string response_data;
3016 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:423017 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]e60e47a2010-07-14 03:37:183018
3019 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:313020 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:443021}
3022
ttuttle7933c112015-01-06 00:55:243023// Test that we don't pass extraneous headers from the proxy's response to the
3024// caller when the proxy responds to CONNECT with 407.
3025TEST_P(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
3026 HttpRequestInfo request;
3027 request.method = "GET";
bncce36dca22015-04-21 22:11:233028 request.url = GURL("https://www.example.org/");
ttuttle7933c112015-01-06 00:55:243029 request.load_flags = 0;
3030
3031 // Configure against proxy server "myproxy:70".
3032 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
3033
mmenke6b3af6e2015-09-12 02:06:063034 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle7933c112015-01-06 00:55:243035
3036 scoped_ptr<HttpTransaction> trans(
3037 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3038
3039 // Since we have proxy, should try to establish tunnel.
3040 MockWrite data_writes[] = {
3041 MockWrite(
bncce36dca22015-04-21 22:11:233042 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3043 "Host: www.example.org\r\n"
ttuttle7933c112015-01-06 00:55:243044 "Proxy-Connection: keep-alive\r\n\r\n"),
3045 };
3046
3047 // The proxy responds to the connect with a 407.
3048 MockRead data_reads[] = {
3049 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3050 MockRead("X-Foo: bar\r\n"),
3051 MockRead("Set-Cookie: foo=bar\r\n"),
3052 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3053 MockRead("Content-Length: 10\r\n\r\n"),
3054 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
3055 };
3056
3057 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
3058 arraysize(data_writes));
3059 session_deps_.socket_factory->AddSocketDataProvider(&data);
3060
3061 TestCompletionCallback callback;
3062
3063 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
3064 EXPECT_EQ(ERR_IO_PENDING, rv);
3065
3066 rv = callback.WaitForResult();
3067 EXPECT_EQ(OK, rv);
3068
3069 const HttpResponseInfo* response = trans->GetResponseInfo();
3070 ASSERT_TRUE(response);
3071 ASSERT_TRUE(response->headers);
3072 EXPECT_TRUE(response->headers->IsKeepAlive());
3073 EXPECT_EQ(407, response->headers->response_code());
3074 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3075 EXPECT_FALSE(response->headers->HasHeader("X-Foo"));
3076 EXPECT_FALSE(response->headers->HasHeader("Set-Cookie"));
3077
3078 std::string response_data;
3079 rv = ReadTransaction(trans.get(), &response_data);
3080 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
3081
3082 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
3083 session->CloseAllConnections();
3084}
3085
[email protected]8fdbcd22010-05-05 02:54:523086// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
3087// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
[email protected]23e482282013-06-14 16:08:023088TEST_P(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:523089 HttpRequestInfo request;
3090 request.method = "GET";
bncce36dca22015-04-21 22:11:233091 request.url = GURL("http://www.example.org/");
[email protected]8fdbcd22010-05-05 02:54:523092 request.load_flags = 0;
3093
[email protected]cb9bf6ca2011-01-28 13:15:273094 // We are using a DIRECT connection (i.e. no proxy) for this session.
mmenke6b3af6e2015-09-12 02:06:063095 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273096 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:413097 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:273098
[email protected]8fdbcd22010-05-05 02:54:523099 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233100 MockWrite(
3101 "GET / HTTP/1.1\r\n"
3102 "Host: www.example.org\r\n"
3103 "Connection: keep-alive\r\n\r\n"),
[email protected]8fdbcd22010-05-05 02:54:523104 };
3105
3106 MockRead data_reads1[] = {
3107 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
3108 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3109 // Large content-length -- won't matter, as connection will be reset.
3110 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063111 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:523112 };
3113
3114 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3115 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073116 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:523117
[email protected]49639fa2011-12-20 23:22:413118 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:523119
[email protected]49639fa2011-12-20 23:22:413120 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]8fdbcd22010-05-05 02:54:523121 EXPECT_EQ(ERR_IO_PENDING, rv);
3122
3123 rv = callback.WaitForResult();
3124 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
3125}
3126
[email protected]7a67a8152010-11-05 18:31:103127// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
3128// through a non-authenticating proxy. The request should fail with
3129// ERR_UNEXPECTED_PROXY_AUTH.
3130// Note that it is impossible to detect if an HTTP server returns a 407 through
3131// a non-authenticating proxy - there is nothing to indicate whether the
3132// response came from the proxy or the server, so it is treated as if the proxy
3133// issued the challenge.
[email protected]23e482282013-06-14 16:08:023134TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:233135 HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:273136 HttpRequestInfo request;
3137 request.method = "GET";
bncce36dca22015-04-21 22:11:233138 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273139
[email protected]bb88e1d32013-05-03 23:11:073140 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
vishal.b62985ca92015-04-17 08:45:513141 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073142 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:063143 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:103144
[email protected]7a67a8152010-11-05 18:31:103145 // Since we have proxy, should try to establish tunnel.
3146 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233147 MockWrite(
3148 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3149 "Host: www.example.org\r\n"
3150 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103151
bncce36dca22015-04-21 22:11:233152 MockWrite(
3153 "GET / HTTP/1.1\r\n"
3154 "Host: www.example.org\r\n"
3155 "Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103156 };
3157
3158 MockRead data_reads1[] = {
3159 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3160
3161 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
3162 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3163 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:063164 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:103165 };
3166
3167 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3168 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073169 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063170 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073171 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:103172
[email protected]49639fa2011-12-20 23:22:413173 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:103174
[email protected]262eec82013-03-19 21:01:363175 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503176 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a67a8152010-11-05 18:31:103177
[email protected]49639fa2011-12-20 23:22:413178 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7a67a8152010-11-05 18:31:103179 EXPECT_EQ(ERR_IO_PENDING, rv);
3180
3181 rv = callback1.WaitForResult();
3182 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
mmenke43758e62015-05-04 21:09:463183 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403184 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:103185 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403186 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]7a67a8152010-11-05 18:31:103187 NetLog::PHASE_NONE);
3188 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403189 entries, pos,
[email protected]7a67a8152010-11-05 18:31:103190 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3191 NetLog::PHASE_NONE);
3192}
[email protected]2df19bb2010-08-25 20:13:463193
[email protected]029c83b62013-01-24 05:28:203194// Test the load timing for HTTPS requests with an HTTP proxy.
[email protected]23e482282013-06-14 16:08:023195TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:203196 HttpRequestInfo request1;
3197 request1.method = "GET";
bncce36dca22015-04-21 22:11:233198 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:203199
3200 HttpRequestInfo request2;
3201 request2.method = "GET";
bncce36dca22015-04-21 22:11:233202 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:203203
3204 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073205 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:203206 ProxyService::CreateFixed("PROXY myproxy:70"));
vishal.b62985ca92015-04-17 08:45:513207 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073208 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:063209 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:203210
3211 // Since we have proxy, should try to establish tunnel.
3212 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233213 MockWrite(
3214 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3215 "Host: www.example.org\r\n"
3216 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203217
bncce36dca22015-04-21 22:11:233218 MockWrite(
3219 "GET /1 HTTP/1.1\r\n"
3220 "Host: www.example.org\r\n"
3221 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203222
bncce36dca22015-04-21 22:11:233223 MockWrite(
3224 "GET /2 HTTP/1.1\r\n"
3225 "Host: www.example.org\r\n"
3226 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203227 };
3228
3229 // The proxy responds to the connect with a 407, using a persistent
3230 // connection.
3231 MockRead data_reads1[] = {
3232 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3233
3234 MockRead("HTTP/1.1 200 OK\r\n"),
3235 MockRead("Content-Length: 1\r\n\r\n"),
3236 MockRead(SYNCHRONOUS, "1"),
3237
3238 MockRead("HTTP/1.1 200 OK\r\n"),
3239 MockRead("Content-Length: 2\r\n\r\n"),
3240 MockRead(SYNCHRONOUS, "22"),
3241 };
3242
3243 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3244 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073245 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:203246 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073247 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:203248
3249 TestCompletionCallback callback1;
[email protected]262eec82013-03-19 21:01:363250 scoped_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:503251 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:203252
3253 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
3254 EXPECT_EQ(ERR_IO_PENDING, rv);
3255
3256 rv = callback1.WaitForResult();
3257 EXPECT_EQ(OK, rv);
3258
3259 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
3260 ASSERT_TRUE(response1 != NULL);
[email protected]90499482013-06-01 00:39:503261 ASSERT_TRUE(response1->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:203262 EXPECT_EQ(1, response1->headers->GetContentLength());
3263
3264 LoadTimingInfo load_timing_info1;
3265 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
3266 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
3267
3268 trans1.reset();
3269
3270 TestCompletionCallback callback2;
[email protected]262eec82013-03-19 21:01:363271 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503272 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:203273
3274 rv = trans2->Start(&request2, callback2.callback(), log.bound());
3275 EXPECT_EQ(ERR_IO_PENDING, rv);
3276
3277 rv = callback2.WaitForResult();
3278 EXPECT_EQ(OK, rv);
3279
3280 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
3281 ASSERT_TRUE(response2 != NULL);
[email protected]90499482013-06-01 00:39:503282 ASSERT_TRUE(response2->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:203283 EXPECT_EQ(2, response2->headers->GetContentLength());
3284
3285 LoadTimingInfo load_timing_info2;
3286 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3287 TestLoadTimingReused(load_timing_info2);
3288
3289 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
3290
3291 trans2.reset();
3292 session->CloseAllConnections();
3293}
3294
3295// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
[email protected]23e482282013-06-14 16:08:023296TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:203297 HttpRequestInfo request1;
3298 request1.method = "GET";
bncce36dca22015-04-21 22:11:233299 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:203300
3301 HttpRequestInfo request2;
3302 request2.method = "GET";
bncce36dca22015-04-21 22:11:233303 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:203304
3305 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073306 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:203307 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
vishal.b62985ca92015-04-17 08:45:513308 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073309 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:063310 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:203311
3312 // Since we have proxy, should try to establish tunnel.
3313 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233314 MockWrite(
3315 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3316 "Host: www.example.org\r\n"
3317 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203318
bncce36dca22015-04-21 22:11:233319 MockWrite(
3320 "GET /1 HTTP/1.1\r\n"
3321 "Host: www.example.org\r\n"
3322 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203323
bncce36dca22015-04-21 22:11:233324 MockWrite(
3325 "GET /2 HTTP/1.1\r\n"
3326 "Host: www.example.org\r\n"
3327 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203328 };
3329
3330 // The proxy responds to the connect with a 407, using a persistent
3331 // connection.
3332 MockRead data_reads1[] = {
3333 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3334
3335 MockRead("HTTP/1.1 200 OK\r\n"),
3336 MockRead("Content-Length: 1\r\n\r\n"),
3337 MockRead(SYNCHRONOUS, "1"),
3338
3339 MockRead("HTTP/1.1 200 OK\r\n"),
3340 MockRead("Content-Length: 2\r\n\r\n"),
3341 MockRead(SYNCHRONOUS, "22"),
3342 };
3343
3344 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3345 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073346 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:203347 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073348 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:203349
3350 TestCompletionCallback callback1;
[email protected]262eec82013-03-19 21:01:363351 scoped_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:503352 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:203353
3354 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
3355 EXPECT_EQ(ERR_IO_PENDING, rv);
3356
3357 rv = callback1.WaitForResult();
3358 EXPECT_EQ(OK, rv);
3359
3360 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
3361 ASSERT_TRUE(response1 != NULL);
[email protected]90499482013-06-01 00:39:503362 ASSERT_TRUE(response1->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:203363 EXPECT_EQ(1, response1->headers->GetContentLength());
3364
3365 LoadTimingInfo load_timing_info1;
3366 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
3367 TestLoadTimingNotReusedWithPac(load_timing_info1,
3368 CONNECT_TIMING_HAS_SSL_TIMES);
3369
3370 trans1.reset();
3371
3372 TestCompletionCallback callback2;
[email protected]262eec82013-03-19 21:01:363373 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503374 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:203375
3376 rv = trans2->Start(&request2, callback2.callback(), log.bound());
3377 EXPECT_EQ(ERR_IO_PENDING, rv);
3378
3379 rv = callback2.WaitForResult();
3380 EXPECT_EQ(OK, rv);
3381
3382 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
3383 ASSERT_TRUE(response2 != NULL);
[email protected]90499482013-06-01 00:39:503384 ASSERT_TRUE(response2->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:203385 EXPECT_EQ(2, response2->headers->GetContentLength());
3386
3387 LoadTimingInfo load_timing_info2;
3388 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3389 TestLoadTimingReusedWithPac(load_timing_info2);
3390
3391 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
3392
3393 trans2.reset();
3394 session->CloseAllConnections();
3395}
3396
[email protected]2df19bb2010-08-25 20:13:463397// Test a simple get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023398TEST_P(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:273399 HttpRequestInfo request;
3400 request.method = "GET";
bncce36dca22015-04-21 22:11:233401 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273402
[email protected]2df19bb2010-08-25 20:13:463403 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073404 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113405 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513406 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073407 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:063408 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:463409
[email protected]2df19bb2010-08-25 20:13:463410 // Since we have proxy, should use full url
3411 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233412 MockWrite(
3413 "GET http://www.example.org/ HTTP/1.1\r\n"
3414 "Host: www.example.org\r\n"
3415 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:463416 };
3417
3418 MockRead data_reads1[] = {
3419 MockRead("HTTP/1.1 200 OK\r\n"),
3420 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3421 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063422 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:463423 };
3424
3425 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3426 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073427 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063428 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073429 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:463430
[email protected]49639fa2011-12-20 23:22:413431 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:463432
[email protected]262eec82013-03-19 21:01:363433 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503434 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503435
[email protected]49639fa2011-12-20 23:22:413436 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:463437 EXPECT_EQ(ERR_IO_PENDING, rv);
3438
3439 rv = callback1.WaitForResult();
3440 EXPECT_EQ(OK, rv);
3441
[email protected]58e32bb2013-01-21 18:23:253442 LoadTimingInfo load_timing_info;
3443 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3444 TestLoadTimingNotReused(load_timing_info,
3445 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3446
[email protected]2df19bb2010-08-25 20:13:463447 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503448 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:463449
3450 EXPECT_TRUE(response->headers->IsKeepAlive());
3451 EXPECT_EQ(200, response->headers->response_code());
3452 EXPECT_EQ(100, response->headers->GetContentLength());
3453 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3454
3455 // The password prompt info should not be set.
3456 EXPECT_TRUE(response->auth_challenge.get() == NULL);
3457}
3458
[email protected]7642b5ae2010-09-01 20:55:173459// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023460TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:273461 HttpRequestInfo request;
3462 request.method = "GET";
bncce36dca22015-04-21 22:11:233463 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273464 request.load_flags = 0;
3465
[email protected]7642b5ae2010-09-01 20:55:173466 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073467 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113468 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513469 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073470 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:063471 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:173472
bncce36dca22015-04-21 22:11:233473 // fetch http://www.example.org/ via SPDY
[email protected]cdf8f7e72013-05-23 10:56:463474 scoped_ptr<SpdyFrame> req(
3475 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
rch8e6c6c42015-05-01 14:05:133476 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]7642b5ae2010-09-01 20:55:173477
[email protected]23e482282013-06-14 16:08:023478 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3479 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:173480 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:133481 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]7642b5ae2010-09-01 20:55:173482 };
3483
rch8e6c6c42015-05-01 14:05:133484 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3485 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073486 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:173487
[email protected]8ddf8322012-02-23 18:08:063488 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023489 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073490 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:173491
[email protected]49639fa2011-12-20 23:22:413492 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:173493
[email protected]262eec82013-03-19 21:01:363494 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503495 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503496
[email protected]49639fa2011-12-20 23:22:413497 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7642b5ae2010-09-01 20:55:173498 EXPECT_EQ(ERR_IO_PENDING, rv);
3499
3500 rv = callback1.WaitForResult();
3501 EXPECT_EQ(OK, rv);
3502
[email protected]58e32bb2013-01-21 18:23:253503 LoadTimingInfo load_timing_info;
3504 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3505 TestLoadTimingNotReused(load_timing_info,
3506 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3507
[email protected]7642b5ae2010-09-01 20:55:173508 const HttpResponseInfo* response = trans->GetResponseInfo();
3509 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503510 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]7642b5ae2010-09-01 20:55:173511 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3512
3513 std::string response_data;
3514 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:233515 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:173516}
3517
[email protected]1c173852014-06-19 12:51:503518// Verifies that a session which races and wins against the owning transaction
3519// (completing prior to host resolution), doesn't fail the transaction.
3520// Regression test for crbug.com/334413.
3521TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
3522 HttpRequestInfo request;
3523 request.method = "GET";
bncce36dca22015-04-21 22:11:233524 request.url = GURL("http://www.example.org/");
[email protected]1c173852014-06-19 12:51:503525 request.load_flags = 0;
3526
3527 // Configure SPDY proxy server "proxy:70".
3528 session_deps_.proxy_service.reset(
3529 ProxyService::CreateFixed("https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513530 BoundTestNetLog log;
[email protected]1c173852014-06-19 12:51:503531 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:063532 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1c173852014-06-19 12:51:503533
bncce36dca22015-04-21 22:11:233534 // Fetch http://www.example.org/ through the SPDY proxy.
[email protected]1c173852014-06-19 12:51:503535 scoped_ptr<SpdyFrame> req(
3536 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
rch8e6c6c42015-05-01 14:05:133537 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]1c173852014-06-19 12:51:503538
3539 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3540 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
3541 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:133542 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]1c173852014-06-19 12:51:503543 };
3544
rch8e6c6c42015-05-01 14:05:133545 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3546 arraysize(spdy_writes));
[email protected]1c173852014-06-19 12:51:503547 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
3548
3549 SSLSocketDataProvider ssl(ASYNC, OK);
3550 ssl.SetNextProto(GetParam());
3551 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3552
3553 TestCompletionCallback callback1;
3554
3555 scoped_ptr<HttpTransaction> trans(
3556 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3557
3558 // Stall the hostname resolution begun by the transaction.
3559 session_deps_.host_resolver->set_synchronous_mode(false);
3560 session_deps_.host_resolver->set_ondemand_mode(true);
3561
3562 int rv = trans->Start(&request, callback1.callback(), log.bound());
3563 EXPECT_EQ(ERR_IO_PENDING, rv);
3564
3565 // Race a session to the proxy, which completes first.
3566 session_deps_.host_resolver->set_ondemand_mode(false);
3567 SpdySessionKey key(
3568 HostPortPair("proxy", 70), ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
3569 base::WeakPtr<SpdySession> spdy_session =
mmenke6b3af6e2015-09-12 02:06:063570 CreateSecureSpdySession(session, key, log.bound());
[email protected]1c173852014-06-19 12:51:503571
3572 // Unstall the resolution begun by the transaction.
3573 session_deps_.host_resolver->set_ondemand_mode(true);
3574 session_deps_.host_resolver->ResolveAllPending();
3575
3576 EXPECT_FALSE(callback1.have_result());
3577 rv = callback1.WaitForResult();
3578 EXPECT_EQ(OK, rv);
3579
3580 const HttpResponseInfo* response = trans->GetResponseInfo();
3581 ASSERT_TRUE(response != NULL);
3582 ASSERT_TRUE(response->headers.get() != NULL);
3583 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3584
3585 std::string response_data;
3586 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
3587 EXPECT_EQ(kUploadData, response_data);
3588}
3589
[email protected]dc7bd1c52010-11-12 00:01:133590// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023591TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:273592 HttpRequestInfo request;
3593 request.method = "GET";
bncce36dca22015-04-21 22:11:233594 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273595 request.load_flags = 0;
3596
[email protected]79cb5c12011-09-12 13:12:043597 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073598 session_deps_.proxy_service.reset(
[email protected]79cb5c12011-09-12 13:12:043599 ProxyService::CreateFixed("https://myproxy:70"));
vishal.b62985ca92015-04-17 08:45:513600 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073601 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:063602 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:133603
[email protected]dc7bd1c52010-11-12 00:01:133604 // The first request will be a bare GET, the second request will be a
3605 // GET with a Proxy-Authorization header.
[email protected]ff98d7f02012-03-22 21:44:193606 scoped_ptr<SpdyFrame> req_get(
[email protected]cdf8f7e72013-05-23 10:56:463607 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]dc7bd1c52010-11-12 00:01:133608 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:463609 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:133610 };
[email protected]ff98d7f02012-03-22 21:44:193611 scoped_ptr<SpdyFrame> req_get_authorization(
[email protected]cdf8f7e72013-05-23 10:56:463612 spdy_util_.ConstructSpdyGet(kExtraAuthorizationHeaders,
3613 arraysize(kExtraAuthorizationHeaders) / 2,
3614 false,
3615 3,
3616 LOWEST,
3617 false));
[email protected]dc7bd1c52010-11-12 00:01:133618 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:133619 CreateMockWrite(*req_get, 0), CreateMockWrite(*req_get_authorization, 3),
[email protected]dc7bd1c52010-11-12 00:01:133620 };
3621
3622 // The first response is a 407 proxy authentication challenge, and the second
3623 // response will be a 200 response since the second request includes a valid
3624 // Authorization header.
3625 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:463626 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:133627 };
[email protected]ff98d7f02012-03-22 21:44:193628 scoped_ptr<SpdyFrame> resp_authentication(
[email protected]23e482282013-06-14 16:08:023629 spdy_util_.ConstructSpdySynReplyError(
[email protected]dc7bd1c52010-11-12 00:01:133630 "407 Proxy Authentication Required",
3631 kExtraAuthenticationHeaders, arraysize(kExtraAuthenticationHeaders)/2,
3632 1));
[email protected]ff98d7f02012-03-22 21:44:193633 scoped_ptr<SpdyFrame> body_authentication(
[email protected]23e482282013-06-14 16:08:023634 spdy_util_.ConstructSpdyBodyFrame(1, true));
3635 scoped_ptr<SpdyFrame> resp_data(
3636 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
3637 scoped_ptr<SpdyFrame> body_data(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:133638 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:133639 CreateMockRead(*resp_authentication, 1),
3640 CreateMockRead(*body_authentication, 2),
3641 CreateMockRead(*resp_data, 4),
3642 CreateMockRead(*body_data, 5),
3643 MockRead(ASYNC, 0, 6),
[email protected]dc7bd1c52010-11-12 00:01:133644 };
3645
rch8e6c6c42015-05-01 14:05:133646 SequencedSocketData data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3647 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073648 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:133649
[email protected]8ddf8322012-02-23 18:08:063650 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023651 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073652 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:133653
[email protected]49639fa2011-12-20 23:22:413654 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:133655
[email protected]262eec82013-03-19 21:01:363656 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503657 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]dc7bd1c52010-11-12 00:01:133658
[email protected]49639fa2011-12-20 23:22:413659 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]dc7bd1c52010-11-12 00:01:133660 EXPECT_EQ(ERR_IO_PENDING, rv);
3661
3662 rv = callback1.WaitForResult();
3663 EXPECT_EQ(OK, rv);
3664
3665 const HttpResponseInfo* const response = trans->GetResponseInfo();
3666
3667 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503668 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]dc7bd1c52010-11-12 00:01:133669 EXPECT_EQ(407, response->headers->response_code());
3670 EXPECT_TRUE(response->was_fetched_via_spdy);
[email protected]79cb5c12011-09-12 13:12:043671 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:133672
[email protected]49639fa2011-12-20 23:22:413673 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:133674
[email protected]49639fa2011-12-20 23:22:413675 rv = trans->RestartWithAuth(
3676 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]dc7bd1c52010-11-12 00:01:133677 EXPECT_EQ(ERR_IO_PENDING, rv);
3678
3679 rv = callback2.WaitForResult();
3680 EXPECT_EQ(OK, rv);
3681
3682 const HttpResponseInfo* const response_restart = trans->GetResponseInfo();
3683
3684 ASSERT_TRUE(response_restart != NULL);
[email protected]90499482013-06-01 00:39:503685 ASSERT_TRUE(response_restart->headers.get() != NULL);
[email protected]dc7bd1c52010-11-12 00:01:133686 EXPECT_EQ(200, response_restart->headers->response_code());
3687 // The password prompt info should not be set.
3688 EXPECT_TRUE(response_restart->auth_challenge.get() == NULL);
3689}
3690
[email protected]d9da5fe2010-10-13 22:37:163691// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
[email protected]23e482282013-06-14 16:08:023692TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:273693 HttpRequestInfo request;
3694 request.method = "GET";
bncce36dca22015-04-21 22:11:233695 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273696 request.load_flags = 0;
3697
[email protected]d9da5fe2010-10-13 22:37:163698 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073699 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113700 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513701 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073702 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:063703 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:163704
[email protected]262eec82013-03-19 21:01:363705 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503706 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:163707
bncce36dca22015-04-21 22:11:233708 // CONNECT to www.example.org:443 via SPDY
lgarrona91df87f2014-12-05 00:51:343709 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:233710 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
3711 // fetch https://www.example.org/ via HTTP
[email protected]d9da5fe2010-10-13 22:37:163712
bncce36dca22015-04-21 22:11:233713 const char get[] =
3714 "GET / HTTP/1.1\r\n"
3715 "Host: www.example.org\r\n"
3716 "Connection: keep-alive\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:193717 scoped_ptr<SpdyFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:023718 spdy_util_.ConstructSpdyBodyFrame(1, get, strlen(get), false));
3719 scoped_ptr<SpdyFrame> conn_resp(
3720 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:163721 const char resp[] = "HTTP/1.1 200 OK\r\n"
3722 "Content-Length: 10\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:193723 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:023724 spdy_util_.ConstructSpdyBodyFrame(1, resp, strlen(resp), false));
[email protected]ff98d7f02012-03-22 21:44:193725 scoped_ptr<SpdyFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:023726 spdy_util_.ConstructSpdyBodyFrame(1, "1234567890", 10, false));
[email protected]ff98d7f02012-03-22 21:44:193727 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203728 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
[email protected]8d2f7012012-02-16 00:08:043729
3730 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:133731 CreateMockWrite(*connect, 0),
3732 CreateMockWrite(*wrapped_get, 2),
3733 CreateMockWrite(*window_update, 6),
[email protected]8d2f7012012-02-16 00:08:043734 };
3735
[email protected]d9da5fe2010-10-13 22:37:163736 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:133737 CreateMockRead(*conn_resp, 1, ASYNC),
3738 CreateMockRead(*wrapped_get_resp, 3, ASYNC),
3739 CreateMockRead(*wrapped_body, 4, ASYNC),
3740 CreateMockRead(*wrapped_body, 5, ASYNC),
3741 MockRead(ASYNC, 0, 7),
[email protected]d9da5fe2010-10-13 22:37:163742 };
3743
rch8e6c6c42015-05-01 14:05:133744 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3745 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073746 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163747
[email protected]8ddf8322012-02-23 18:08:063748 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023749 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073750 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063751 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073752 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163753
[email protected]49639fa2011-12-20 23:22:413754 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163755
[email protected]49639fa2011-12-20 23:22:413756 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163757 EXPECT_EQ(ERR_IO_PENDING, rv);
3758
3759 rv = callback1.WaitForResult();
rch8e6c6c42015-05-01 14:05:133760 ASSERT_EQ(OK, rv);
[email protected]d9da5fe2010-10-13 22:37:163761
[email protected]58e32bb2013-01-21 18:23:253762 LoadTimingInfo load_timing_info;
3763 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3764 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3765
[email protected]d9da5fe2010-10-13 22:37:163766 const HttpResponseInfo* response = trans->GetResponseInfo();
3767 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503768 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d9da5fe2010-10-13 22:37:163769 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3770
3771 std::string response_data;
3772 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
3773 EXPECT_EQ("1234567890", response_data);
3774}
3775
3776// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
[email protected]23e482282013-06-14 16:08:023777TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
[email protected]cb9bf6ca2011-01-28 13:15:273778 HttpRequestInfo request;
3779 request.method = "GET";
bncce36dca22015-04-21 22:11:233780 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273781 request.load_flags = 0;
3782
[email protected]d9da5fe2010-10-13 22:37:163783 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073784 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113785 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513786 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073787 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:063788 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:163789
[email protected]262eec82013-03-19 21:01:363790 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503791 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:163792
bncce36dca22015-04-21 22:11:233793 // CONNECT to www.example.org:443 via SPDY
lgarrona91df87f2014-12-05 00:51:343794 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:233795 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
3796 // fetch https://www.example.org/ via SPDY
3797 const char kMyUrl[] = "https://www.example.org/";
[email protected]cdf8f7e72013-05-23 10:56:463798 scoped_ptr<SpdyFrame> get(
3799 spdy_util_.ConstructSpdyGet(kMyUrl, false, 1, LOWEST));
[email protected]23e482282013-06-14 16:08:023800 scoped_ptr<SpdyFrame> wrapped_get(
3801 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
3802 scoped_ptr<SpdyFrame> conn_resp(
3803 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3804 scoped_ptr<SpdyFrame> get_resp(
3805 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]ff98d7f02012-03-22 21:44:193806 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:023807 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
3808 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
3809 scoped_ptr<SpdyFrame> wrapped_body(
3810 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
[email protected]ff98d7f02012-03-22 21:44:193811 scoped_ptr<SpdyFrame> window_update_get_resp(
[email protected]c10b20852013-05-15 21:29:203812 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
[email protected]ff98d7f02012-03-22 21:44:193813 scoped_ptr<SpdyFrame> window_update_body(
[email protected]c10b20852013-05-15 21:29:203814 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body->size()));
[email protected]8d2f7012012-02-16 00:08:043815
3816 MockWrite spdy_writes[] = {
rch32320842015-05-16 15:57:093817 CreateMockWrite(*connect, 0),
3818 CreateMockWrite(*wrapped_get, 2),
3819 CreateMockWrite(*window_update_get_resp, 6),
[email protected]8d2f7012012-02-16 00:08:043820 CreateMockWrite(*window_update_body, 7),
3821 };
3822
[email protected]d9da5fe2010-10-13 22:37:163823 MockRead spdy_reads[] = {
rch32320842015-05-16 15:57:093824 CreateMockRead(*conn_resp, 1, ASYNC),
3825 MockRead(ASYNC, ERR_IO_PENDING, 3),
rch8e6c6c42015-05-01 14:05:133826 CreateMockRead(*wrapped_get_resp, 4, ASYNC),
rch32320842015-05-16 15:57:093827 CreateMockRead(*wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:133828 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:163829 };
3830
rch32320842015-05-16 15:57:093831 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3832 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073833 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163834
[email protected]8ddf8322012-02-23 18:08:063835 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023836 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073837 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063838 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023839 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073840 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163841
[email protected]49639fa2011-12-20 23:22:413842 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163843
[email protected]49639fa2011-12-20 23:22:413844 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163845 EXPECT_EQ(ERR_IO_PENDING, rv);
3846
rch32320842015-05-16 15:57:093847 // Allow the SpdyProxyClientSocket's write callback to complete.
3848 base::MessageLoop::current()->RunUntilIdle();
3849 // Now allow the read of the response to complete.
3850 spdy_data.CompleteRead();
[email protected]d9da5fe2010-10-13 22:37:163851 rv = callback1.WaitForResult();
3852 EXPECT_EQ(OK, rv);
3853
[email protected]58e32bb2013-01-21 18:23:253854 LoadTimingInfo load_timing_info;
3855 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3856 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3857
[email protected]d9da5fe2010-10-13 22:37:163858 const HttpResponseInfo* response = trans->GetResponseInfo();
3859 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503860 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d9da5fe2010-10-13 22:37:163861 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3862
3863 std::string response_data;
3864 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:233865 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:163866}
3867
3868// Test a SPDY CONNECT failure through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023869TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:273870 HttpRequestInfo request;
3871 request.method = "GET";
bncce36dca22015-04-21 22:11:233872 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273873 request.load_flags = 0;
3874
[email protected]d9da5fe2010-10-13 22:37:163875 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073876 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113877 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513878 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073879 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:063880 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:163881
[email protected]262eec82013-03-19 21:01:363882 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503883 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:163884
bncce36dca22015-04-21 22:11:233885 // CONNECT to www.example.org:443 via SPDY
lgarrona91df87f2014-12-05 00:51:343886 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:233887 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]c10b20852013-05-15 21:29:203888 scoped_ptr<SpdyFrame> get(
3889 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:163890
3891 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:133892 CreateMockWrite(*connect, 0), CreateMockWrite(*get, 2),
[email protected]d9da5fe2010-10-13 22:37:163893 };
3894
[email protected]23e482282013-06-14 16:08:023895 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdySynReplyError(1));
3896 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:163897 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:133898 CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 3),
[email protected]d9da5fe2010-10-13 22:37:163899 };
3900
rch8e6c6c42015-05-01 14:05:133901 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3902 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073903 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163904
[email protected]8ddf8322012-02-23 18:08:063905 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023906 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073907 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063908 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023909 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073910 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163911
[email protected]49639fa2011-12-20 23:22:413912 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163913
[email protected]49639fa2011-12-20 23:22:413914 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163915 EXPECT_EQ(ERR_IO_PENDING, rv);
3916
3917 rv = callback1.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:173918 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]d9da5fe2010-10-13 22:37:163919
[email protected]4eddbc732012-08-09 05:40:173920 // TODO(ttuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:163921}
3922
[email protected]f6c63db52013-02-02 00:35:223923// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
3924// HTTPS Proxy to different servers.
[email protected]23e482282013-06-14 16:08:023925TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:223926 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
3927 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073928 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:223929 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513930 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073931 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:063932 scoped_refptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:503933 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:223934
3935 HttpRequestInfo request1;
3936 request1.method = "GET";
bncce36dca22015-04-21 22:11:233937 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:223938 request1.load_flags = 0;
3939
3940 HttpRequestInfo request2;
3941 request2.method = "GET";
bncce36dca22015-04-21 22:11:233942 request2.url = GURL("https://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:223943 request2.load_flags = 0;
3944
bncce36dca22015-04-21 22:11:233945 // CONNECT to www.example.org:443 via SPDY.
lgarrona91df87f2014-12-05 00:51:343946 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:233947 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]23e482282013-06-14 16:08:023948 scoped_ptr<SpdyFrame> conn_resp1(
3949 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:223950
bncce36dca22015-04-21 22:11:233951 // Fetch https://www.example.org/ via HTTP.
3952 const char get1[] =
3953 "GET / HTTP/1.1\r\n"
3954 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:223955 "Connection: keep-alive\r\n\r\n";
3956 scoped_ptr<SpdyFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:023957 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:223958 const char resp1[] = "HTTP/1.1 200 OK\r\n"
3959 "Content-Length: 1\r\n\r\n";
3960 scoped_ptr<SpdyFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:023961 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
3962 scoped_ptr<SpdyFrame> wrapped_body1(
3963 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
[email protected]f6c63db52013-02-02 00:35:223964 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203965 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:223966
bncce36dca22015-04-21 22:11:233967 // CONNECT to mail.example.org:443 via SPDY.
[email protected]745aa9c2014-06-27 02:21:293968 SpdyHeaderBlock connect2_block;
3969 connect2_block[spdy_util_.GetMethodKey()] = "CONNECT";
bnc9b79a572015-09-02 12:25:033970 if (GetParam() == kProtoHTTP2) {
bnc6b996d532015-07-29 10:51:323971 connect2_block[spdy_util_.GetHostKey()] = "mail.example.org:443";
3972 } else {
3973 connect2_block[spdy_util_.GetPathKey()] = "mail.example.org:443";
3974 connect2_block[spdy_util_.GetHostKey()] = "mail.example.org";
3975 }
[email protected]745aa9c2014-06-27 02:21:293976 spdy_util_.MaybeAddVersionHeader(&connect2_block);
[email protected]f6c63db52013-02-02 00:35:223977 scoped_ptr<SpdyFrame> connect2(
[email protected]745aa9c2014-06-27 02:21:293978 spdy_util_.ConstructSpdySyn(3, connect2_block, LOWEST, false, false));
[email protected]601e03f12014-04-06 16:26:393979
[email protected]23e482282013-06-14 16:08:023980 scoped_ptr<SpdyFrame> conn_resp2(
3981 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:223982
bncce36dca22015-04-21 22:11:233983 // Fetch https://mail.example.org/ via HTTP.
3984 const char get2[] =
3985 "GET / HTTP/1.1\r\n"
3986 "Host: mail.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(3, 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(3, 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(3, "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(*connect2, 5),
4001 CreateMockWrite(*wrapped_get2, 7),
4002 };
4003
4004 MockRead spdy_reads[] = {
4005 CreateMockRead(*conn_resp1, 1, ASYNC),
4006 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
4007 CreateMockRead(*wrapped_body1, 4, ASYNC),
4008 CreateMockRead(*conn_resp2, 6, ASYNC),
4009 CreateMockRead(*wrapped_get_resp2, 8, ASYNC),
4010 CreateMockRead(*wrapped_body2, 9, ASYNC),
4011 MockRead(ASYNC, 0, 10),
4012 };
4013
mmenke11eb5152015-06-09 14:50:504014 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4015 arraysize(spdy_writes));
4016 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:224017
4018 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:024019 ssl.SetNextProto(GetParam());
mmenke11eb5152015-06-09 14:50:504020 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:224021 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:504022 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:224023 SSLSocketDataProvider ssl3(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:504024 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:224025
4026 TestCompletionCallback callback;
4027
[email protected]262eec82013-03-19 21:01:364028 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504029 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224030 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:504031 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224032
4033 LoadTimingInfo load_timing_info;
4034 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4035 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
4036
4037 const HttpResponseInfo* response = trans->GetResponseInfo();
4038 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504039 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:224040 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4041
4042 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:294043 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
mmenke11eb5152015-06-09 14:50:504044 rv = trans->Read(buf.get(), 256, callback.callback());
4045 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224046
[email protected]262eec82013-03-19 21:01:364047 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:504048 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224049 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:504050 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224051
4052 LoadTimingInfo load_timing_info2;
4053 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4054 // Even though the SPDY connection is reused, a new tunnelled connection has
4055 // to be created, so the socket's load timing looks like a fresh connection.
4056 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
4057
4058 // The requests should have different IDs, since they each are using their own
4059 // separate stream.
4060 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
4061
mmenke11eb5152015-06-09 14:50:504062 rv = trans2->Read(buf.get(), 256, callback.callback());
4063 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224064}
4065
4066// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
4067// HTTPS Proxy to the same server.
[email protected]23e482282013-06-14 16:08:024068TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:224069 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
4070 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:074071 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:224072 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:514073 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074074 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:064075 scoped_refptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:504076 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:224077
4078 HttpRequestInfo request1;
4079 request1.method = "GET";
bncce36dca22015-04-21 22:11:234080 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:224081 request1.load_flags = 0;
4082
4083 HttpRequestInfo request2;
4084 request2.method = "GET";
bncce36dca22015-04-21 22:11:234085 request2.url = GURL("https://www.example.org/2");
[email protected]f6c63db52013-02-02 00:35:224086 request2.load_flags = 0;
4087
bncce36dca22015-04-21 22:11:234088 // CONNECT to www.example.org:443 via SPDY.
lgarrona91df87f2014-12-05 00:51:344089 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234090 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]23e482282013-06-14 16:08:024091 scoped_ptr<SpdyFrame> conn_resp1(
4092 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:224093
bncce36dca22015-04-21 22:11:234094 // Fetch https://www.example.org/ via HTTP.
4095 const char get1[] =
4096 "GET / HTTP/1.1\r\n"
4097 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:224098 "Connection: keep-alive\r\n\r\n";
4099 scoped_ptr<SpdyFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:024100 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:224101 const char resp1[] = "HTTP/1.1 200 OK\r\n"
4102 "Content-Length: 1\r\n\r\n";
4103 scoped_ptr<SpdyFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:024104 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
4105 scoped_ptr<SpdyFrame> wrapped_body1(
4106 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
[email protected]f6c63db52013-02-02 00:35:224107 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:204108 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:224109
bncce36dca22015-04-21 22:11:234110 // Fetch https://www.example.org/2 via HTTP.
4111 const char get2[] =
4112 "GET /2 HTTP/1.1\r\n"
4113 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:224114 "Connection: keep-alive\r\n\r\n";
4115 scoped_ptr<SpdyFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:024116 spdy_util_.ConstructSpdyBodyFrame(1, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:224117 const char resp2[] = "HTTP/1.1 200 OK\r\n"
4118 "Content-Length: 2\r\n\r\n";
4119 scoped_ptr<SpdyFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:024120 spdy_util_.ConstructSpdyBodyFrame(1, resp2, strlen(resp2), false));
[email protected]f6c63db52013-02-02 00:35:224121 scoped_ptr<SpdyFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:024122 spdy_util_.ConstructSpdyBodyFrame(1, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:224123
4124 MockWrite spdy_writes[] = {
4125 CreateMockWrite(*connect1, 0),
4126 CreateMockWrite(*wrapped_get1, 2),
4127 CreateMockWrite(*wrapped_get2, 5),
4128 };
4129
4130 MockRead spdy_reads[] = {
4131 CreateMockRead(*conn_resp1, 1, ASYNC),
4132 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
4133 CreateMockRead(*wrapped_body1, 4, ASYNC),
4134 CreateMockRead(*wrapped_get_resp2, 6, ASYNC),
4135 CreateMockRead(*wrapped_body2, 7, ASYNC),
4136 MockRead(ASYNC, 0, 8),
4137 };
4138
mmenke11eb5152015-06-09 14:50:504139 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4140 arraysize(spdy_writes));
4141 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:224142
4143 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:024144 ssl.SetNextProto(GetParam());
mmenke11eb5152015-06-09 14:50:504145 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:224146 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:504147 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:224148
4149 TestCompletionCallback callback;
4150
[email protected]262eec82013-03-19 21:01:364151 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504152 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224153 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
4154 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f6c63db52013-02-02 00:35:224155
4156 rv = callback.WaitForResult();
4157 EXPECT_EQ(OK, rv);
4158
4159 LoadTimingInfo load_timing_info;
4160 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4161 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
4162
4163 const HttpResponseInfo* response = trans->GetResponseInfo();
4164 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504165 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:224166 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4167
4168 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:294169 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]90499482013-06-01 00:39:504170 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:224171 trans.reset();
4172
[email protected]262eec82013-03-19 21:01:364173 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:504174 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224175 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
4176 EXPECT_EQ(ERR_IO_PENDING, rv);
4177
[email protected]f6c63db52013-02-02 00:35:224178 rv = callback.WaitForResult();
4179 EXPECT_EQ(OK, rv);
4180
4181 LoadTimingInfo load_timing_info2;
4182 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4183 TestLoadTimingReused(load_timing_info2);
4184
4185 // The requests should have the same ID.
4186 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
4187
[email protected]90499482013-06-01 00:39:504188 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:224189}
4190
4191// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
4192// Proxy to different servers.
mmenke11eb5152015-06-09 14:50:504193TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) {
[email protected]f6c63db52013-02-02 00:35:224194 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:074195 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:224196 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:514197 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074198 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:064199 scoped_refptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:504200 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:224201
4202 HttpRequestInfo request1;
4203 request1.method = "GET";
bncce36dca22015-04-21 22:11:234204 request1.url = GURL("http://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:224205 request1.load_flags = 0;
4206
4207 HttpRequestInfo request2;
4208 request2.method = "GET";
bncce36dca22015-04-21 22:11:234209 request2.url = GURL("http://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:224210 request2.load_flags = 0;
4211
bncce36dca22015-04-21 22:11:234212 // http://www.example.org/
[email protected]23e482282013-06-14 16:08:024213 scoped_ptr<SpdyHeaderBlock> headers(
bncce36dca22015-04-21 22:11:234214 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
[email protected]745aa9c2014-06-27 02:21:294215 scoped_ptr<SpdyFrame> get1(
4216 spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, false, true));
[email protected]23e482282013-06-14 16:08:024217 scoped_ptr<SpdyFrame> get_resp1(
4218 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
4219 scoped_ptr<SpdyFrame> body1(
4220 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, true));
[email protected]f6c63db52013-02-02 00:35:224221
bncce36dca22015-04-21 22:11:234222 // http://mail.example.org/
[email protected]23e482282013-06-14 16:08:024223 scoped_ptr<SpdyHeaderBlock> headers2(
bncce36dca22015-04-21 22:11:234224 spdy_util_.ConstructGetHeaderBlockForProxy("http://mail.example.org/"));
[email protected]745aa9c2014-06-27 02:21:294225 scoped_ptr<SpdyFrame> get2(
4226 spdy_util_.ConstructSpdySyn(3, *headers2, LOWEST, false, true));
[email protected]23e482282013-06-14 16:08:024227 scoped_ptr<SpdyFrame> get_resp2(
4228 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
4229 scoped_ptr<SpdyFrame> body2(
4230 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, true));
[email protected]f6c63db52013-02-02 00:35:224231
4232 MockWrite spdy_writes[] = {
4233 CreateMockWrite(*get1, 0),
4234 CreateMockWrite(*get2, 3),
4235 };
4236
4237 MockRead spdy_reads[] = {
4238 CreateMockRead(*get_resp1, 1, ASYNC),
4239 CreateMockRead(*body1, 2, ASYNC),
4240 CreateMockRead(*get_resp2, 4, ASYNC),
4241 CreateMockRead(*body2, 5, ASYNC),
4242 MockRead(ASYNC, 0, 6),
4243 };
4244
mmenke11eb5152015-06-09 14:50:504245 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4246 arraysize(spdy_writes));
4247 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:224248
4249 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:024250 ssl.SetNextProto(GetParam());
mmenke11eb5152015-06-09 14:50:504251 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:224252
4253 TestCompletionCallback callback;
4254
[email protected]262eec82013-03-19 21:01:364255 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504256 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224257 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:504258 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224259
4260 LoadTimingInfo load_timing_info;
4261 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4262 TestLoadTimingNotReused(load_timing_info,
4263 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4264
4265 const HttpResponseInfo* response = trans->GetResponseInfo();
4266 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504267 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:224268 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4269
4270 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:294271 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
mmenke11eb5152015-06-09 14:50:504272 rv = trans->Read(buf.get(), 256, callback.callback());
4273 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224274 // Delete the first request, so the second one can reuse the socket.
4275 trans.reset();
4276
[email protected]262eec82013-03-19 21:01:364277 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:504278 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224279 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:504280 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224281
4282 LoadTimingInfo load_timing_info2;
4283 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4284 TestLoadTimingReused(load_timing_info2);
4285
4286 // The requests should have the same ID.
4287 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
4288
mmenke11eb5152015-06-09 14:50:504289 rv = trans2->Read(buf.get(), 256, callback.callback());
4290 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224291}
4292
[email protected]2df19bb2010-08-25 20:13:464293// Test the challenge-response-retry sequence through an HTTPS Proxy
[email protected]23e482282013-06-14 16:08:024294TEST_P(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:464295 HttpRequestInfo request;
4296 request.method = "GET";
bncce36dca22015-04-21 22:11:234297 request.url = GURL("http://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:464298 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:294299 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]2df19bb2010-08-25 20:13:464300
[email protected]79cb5c12011-09-12 13:12:044301 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:074302 session_deps_.proxy_service.reset(
[email protected]79cb5c12011-09-12 13:12:044303 ProxyService::CreateFixed("https://myproxy:70"));
vishal.b62985ca92015-04-17 08:45:514304 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074305 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:064306 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274307
[email protected]2df19bb2010-08-25 20:13:464308 // Since we have proxy, should use full url
4309 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:234310 MockWrite(
4311 "GET http://www.example.org/ HTTP/1.1\r\n"
4312 "Host: www.example.org\r\n"
4313 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:464314
bncce36dca22015-04-21 22:11:234315 // After calling trans->RestartWithAuth(), this is the request we should
4316 // be issuing -- the final header line contains the credentials.
4317 MockWrite(
4318 "GET http://www.example.org/ HTTP/1.1\r\n"
4319 "Host: www.example.org\r\n"
4320 "Proxy-Connection: keep-alive\r\n"
4321 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:464322 };
4323
4324 // The proxy responds to the GET with a 407, using a persistent
4325 // connection.
4326 MockRead data_reads1[] = {
4327 // No credentials.
4328 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4329 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4330 MockRead("Proxy-Connection: keep-alive\r\n"),
4331 MockRead("Content-Length: 0\r\n\r\n"),
4332
4333 MockRead("HTTP/1.1 200 OK\r\n"),
4334 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4335 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064336 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:464337 };
4338
4339 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4340 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074341 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:064342 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074343 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:464344
[email protected]49639fa2011-12-20 23:22:414345 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:464346
[email protected]262eec82013-03-19 21:01:364347 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504348 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504349
[email protected]49639fa2011-12-20 23:22:414350 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:464351 EXPECT_EQ(ERR_IO_PENDING, rv);
4352
4353 rv = callback1.WaitForResult();
4354 EXPECT_EQ(OK, rv);
4355
[email protected]58e32bb2013-01-21 18:23:254356 LoadTimingInfo load_timing_info;
4357 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4358 TestLoadTimingNotReused(load_timing_info,
4359 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4360
[email protected]2df19bb2010-08-25 20:13:464361 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504362 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504363 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]2df19bb2010-08-25 20:13:464364 EXPECT_EQ(407, response->headers->response_code());
4365 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:044366 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:464367
[email protected]49639fa2011-12-20 23:22:414368 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:464369
[email protected]49639fa2011-12-20 23:22:414370 rv = trans->RestartWithAuth(
4371 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]2df19bb2010-08-25 20:13:464372 EXPECT_EQ(ERR_IO_PENDING, rv);
4373
4374 rv = callback2.WaitForResult();
4375 EXPECT_EQ(OK, rv);
4376
[email protected]58e32bb2013-01-21 18:23:254377 load_timing_info = LoadTimingInfo();
4378 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4379 // Retrying with HTTP AUTH is considered to be reusing a socket.
4380 TestLoadTimingReused(load_timing_info);
4381
[email protected]2df19bb2010-08-25 20:13:464382 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504383 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:464384
4385 EXPECT_TRUE(response->headers->IsKeepAlive());
4386 EXPECT_EQ(200, response->headers->response_code());
4387 EXPECT_EQ(100, response->headers->GetContentLength());
4388 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4389
4390 // The password prompt info should not be set.
4391 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4392}
4393
[email protected]23e482282013-06-14 16:08:024394void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:084395 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:424396 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:084397 request.method = "GET";
bncce36dca22015-04-21 22:11:234398 request.url = GURL("https://www.example.org/");
[email protected]c744cf22009-02-27 07:28:084399 request.load_flags = 0;
4400
[email protected]cb9bf6ca2011-01-28 13:15:274401 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:074402 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
mmenke6b3af6e2015-09-12 02:06:064403 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274404
[email protected]c744cf22009-02-27 07:28:084405 // Since we have proxy, should try to establish tunnel.
4406 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:234407 MockWrite(
4408 "CONNECT www.example.org:443 HTTP/1.1\r\n"
4409 "Host: www.example.org\r\n"
4410 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:084411 };
4412
4413 MockRead data_reads[] = {
4414 status,
4415 MockRead("Content-Length: 10\r\n\r\n"),
4416 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:064417 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]c744cf22009-02-27 07:28:084418 };
4419
[email protected]31a2bfe2010-02-09 08:03:394420 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
4421 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:074422 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:084423
[email protected]49639fa2011-12-20 23:22:414424 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:084425
[email protected]262eec82013-03-19 21:01:364426 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504427 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504428
[email protected]49639fa2011-12-20 23:22:414429 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424430 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]c744cf22009-02-27 07:28:084431
4432 rv = callback.WaitForResult();
4433 EXPECT_EQ(expected_status, rv);
4434}
4435
[email protected]23e482282013-06-14 16:08:024436void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:234437 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:084438 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:424439 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:084440}
4441
[email protected]23e482282013-06-14 16:08:024442TEST_P(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:084443 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
4444}
4445
[email protected]23e482282013-06-14 16:08:024446TEST_P(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:084447 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
4448}
4449
[email protected]23e482282013-06-14 16:08:024450TEST_P(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:084451 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
4452}
4453
[email protected]23e482282013-06-14 16:08:024454TEST_P(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:084455 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
4456}
4457
[email protected]23e482282013-06-14 16:08:024458TEST_P(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:084459 ConnectStatusHelper(
4460 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
4461}
4462
[email protected]23e482282013-06-14 16:08:024463TEST_P(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:084464 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
4465}
4466
[email protected]23e482282013-06-14 16:08:024467TEST_P(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:084468 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
4469}
4470
[email protected]23e482282013-06-14 16:08:024471TEST_P(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:084472 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
4473}
4474
[email protected]23e482282013-06-14 16:08:024475TEST_P(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:084476 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
4477}
4478
[email protected]23e482282013-06-14 16:08:024479TEST_P(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:084480 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
4481}
4482
[email protected]23e482282013-06-14 16:08:024483TEST_P(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:084484 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
4485}
4486
[email protected]23e482282013-06-14 16:08:024487TEST_P(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:084488 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
4489}
4490
[email protected]23e482282013-06-14 16:08:024491TEST_P(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:084492 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
4493}
4494
[email protected]23e482282013-06-14 16:08:024495TEST_P(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:084496 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
4497}
4498
[email protected]23e482282013-06-14 16:08:024499TEST_P(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:084500 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
4501}
4502
[email protected]23e482282013-06-14 16:08:024503TEST_P(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:084504 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
4505}
4506
[email protected]0a17aab32014-04-24 03:32:374507TEST_P(HttpNetworkTransactionTest, ConnectStatus308) {
4508 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
4509}
4510
[email protected]23e482282013-06-14 16:08:024511TEST_P(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:084512 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
4513}
4514
[email protected]23e482282013-06-14 16:08:024515TEST_P(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:084516 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
4517}
4518
[email protected]23e482282013-06-14 16:08:024519TEST_P(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:084520 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
4521}
4522
[email protected]23e482282013-06-14 16:08:024523TEST_P(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:084524 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
4525}
4526
[email protected]23e482282013-06-14 16:08:024527TEST_P(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:084528 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
4529}
4530
[email protected]23e482282013-06-14 16:08:024531TEST_P(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:084532 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
4533}
4534
[email protected]23e482282013-06-14 16:08:024535TEST_P(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:084536 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
4537}
4538
[email protected]23e482282013-06-14 16:08:024539TEST_P(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:084540 ConnectStatusHelperWithExpectedStatus(
4541 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:544542 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:084543}
4544
[email protected]23e482282013-06-14 16:08:024545TEST_P(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:084546 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
4547}
4548
[email protected]23e482282013-06-14 16:08:024549TEST_P(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:084550 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
4551}
4552
[email protected]23e482282013-06-14 16:08:024553TEST_P(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:084554 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
4555}
4556
[email protected]23e482282013-06-14 16:08:024557TEST_P(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:084558 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
4559}
4560
[email protected]23e482282013-06-14 16:08:024561TEST_P(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:084562 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
4563}
4564
[email protected]23e482282013-06-14 16:08:024565TEST_P(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:084566 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
4567}
4568
[email protected]23e482282013-06-14 16:08:024569TEST_P(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:084570 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
4571}
4572
[email protected]23e482282013-06-14 16:08:024573TEST_P(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:084574 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
4575}
4576
[email protected]23e482282013-06-14 16:08:024577TEST_P(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:084578 ConnectStatusHelper(
4579 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
4580}
4581
[email protected]23e482282013-06-14 16:08:024582TEST_P(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:084583 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
4584}
4585
[email protected]23e482282013-06-14 16:08:024586TEST_P(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:084587 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
4588}
4589
[email protected]23e482282013-06-14 16:08:024590TEST_P(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:084591 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
4592}
4593
[email protected]23e482282013-06-14 16:08:024594TEST_P(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:084595 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
4596}
4597
[email protected]23e482282013-06-14 16:08:024598TEST_P(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:084599 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
4600}
4601
[email protected]23e482282013-06-14 16:08:024602TEST_P(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:084603 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
4604}
4605
[email protected]23e482282013-06-14 16:08:024606TEST_P(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:084607 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
4608}
4609
[email protected]038e9a32008-10-08 22:40:164610// Test the flow when both the proxy server AND origin server require
4611// authentication. Again, this uses basic auth for both since that is
4612// the simplest to mock.
[email protected]23e482282013-06-14 16:08:024613TEST_P(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:274614 HttpRequestInfo request;
4615 request.method = "GET";
bncce36dca22015-04-21 22:11:234616 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274617 request.load_flags = 0;
4618
[email protected]038e9a32008-10-08 22:40:164619 // Configure against proxy server "myproxy:70".
[email protected]3fe8d2f82013-10-17 08:56:074620 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
mmenke6b3af6e2015-09-12 02:06:064621 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:074622
4623 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:414624 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]038e9a32008-10-08 22:40:164625
[email protected]f9ee6b52008-11-08 06:46:234626 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:234627 MockWrite(
4628 "GET http://www.example.org/ HTTP/1.1\r\n"
4629 "Host: www.example.org\r\n"
4630 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:234631 };
4632
[email protected]038e9a32008-10-08 22:40:164633 MockRead data_reads1[] = {
4634 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
4635 // Give a couple authenticate options (only the middle one is actually
4636 // supported).
[email protected]22927ad2009-09-21 19:56:194637 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:164638 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4639 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
4640 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4641 // Large content-length -- won't matter, as connection will be reset.
4642 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064643 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:164644 };
4645
4646 // After calling trans->RestartWithAuth() the first time, this is the
4647 // request we should be issuing -- the final header line contains the
4648 // proxy's credentials.
4649 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:234650 MockWrite(
4651 "GET http://www.example.org/ HTTP/1.1\r\n"
4652 "Host: www.example.org\r\n"
4653 "Proxy-Connection: keep-alive\r\n"
4654 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:164655 };
4656
4657 // Now the proxy server lets the request pass through to origin server.
4658 // The origin server responds with a 401.
4659 MockRead data_reads2[] = {
4660 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4661 // Note: We are using the same realm-name as the proxy server. This is
4662 // completely valid, as realms are unique across hosts.
4663 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4664 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4665 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064666 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:164667 };
4668
4669 // After calling trans->RestartWithAuth() the second time, we should send
4670 // the credentials for both the proxy and origin server.
4671 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:234672 MockWrite(
4673 "GET http://www.example.org/ HTTP/1.1\r\n"
4674 "Host: www.example.org\r\n"
4675 "Proxy-Connection: keep-alive\r\n"
4676 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
4677 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:164678 };
4679
4680 // Lastly we get the desired content.
4681 MockRead data_reads3[] = {
4682 MockRead("HTTP/1.0 200 OK\r\n"),
4683 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4684 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064685 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:164686 };
4687
[email protected]31a2bfe2010-02-09 08:03:394688 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4689 data_writes1, arraysize(data_writes1));
4690 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4691 data_writes2, arraysize(data_writes2));
4692 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4693 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:074694 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4695 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4696 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:164697
[email protected]49639fa2011-12-20 23:22:414698 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:164699
[email protected]49639fa2011-12-20 23:22:414700 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424701 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:164702
4703 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424704 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:164705
[email protected]1c773ea12009-04-28 19:58:424706 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504707 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044708 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:164709
[email protected]49639fa2011-12-20 23:22:414710 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:164711
[email protected]49639fa2011-12-20 23:22:414712 rv = trans->RestartWithAuth(
4713 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:424714 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:164715
4716 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424717 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:164718
4719 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504720 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044721 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:164722
[email protected]49639fa2011-12-20 23:22:414723 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:164724
[email protected]49639fa2011-12-20 23:22:414725 rv = trans->RestartWithAuth(
4726 AuthCredentials(kFoo2, kBar2), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424727 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:164728
4729 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424730 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:164731
4732 response = trans->GetResponseInfo();
4733 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4734 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:164735}
[email protected]4ddaf2502008-10-23 18:26:194736
[email protected]ea9dc9a2009-09-05 00:43:324737// For the NTLM implementation using SSPI, we skip the NTLM tests since we
4738// can't hook into its internals to cause it to generate predictable NTLM
4739// authorization headers.
4740#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:294741// The NTLM authentication unit tests were generated by capturing the HTTP
4742// requests and responses using Fiddler 2 and inspecting the generated random
4743// bytes in the debugger.
4744
4745// Enter the correct password and authenticate successfully.
[email protected]23e482282013-06-14 16:08:024746TEST_P(HttpNetworkTransactionTest, NTLMAuth1) {
[email protected]1c773ea12009-04-28 19:58:424747 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:244748 request.method = "GET";
4749 request.url = GURL("http://172.22.68.17/kids/login.aspx");
[email protected]2217aa22013-10-11 03:03:544750
4751 // Ensure load is not disrupted by flags which suppress behaviour specific
4752 // to other auth schemes.
4753 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:244754
[email protected]cb9bf6ca2011-01-28 13:15:274755 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
4756 MockGetHostName);
mmenke6b3af6e2015-09-12 02:06:064757 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274758
[email protected]3f918782009-02-28 01:29:244759 MockWrite data_writes1[] = {
4760 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4761 "Host: 172.22.68.17\r\n"
4762 "Connection: keep-alive\r\n\r\n"),
4763 };
4764
4765 MockRead data_reads1[] = {
4766 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:044767 // Negotiate and NTLM are often requested together. However, we only want
4768 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
4769 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:244770 MockRead("WWW-Authenticate: NTLM\r\n"),
4771 MockRead("Connection: close\r\n"),
4772 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364773 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:244774 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064775 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]3f918782009-02-28 01:29:244776 };
4777
4778 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:224779 // After restarting with a null identity, this is the
[email protected]3f918782009-02-28 01:29:244780 // request we should be issuing -- the final header line contains a Type
4781 // 1 message.
4782 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4783 "Host: 172.22.68.17\r\n"
4784 "Connection: keep-alive\r\n"
4785 "Authorization: NTLM "
4786 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4787
4788 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4789 // (the credentials for the origin server). The second request continues
4790 // on the same connection.
4791 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4792 "Host: 172.22.68.17\r\n"
4793 "Connection: keep-alive\r\n"
[email protected]385a4672009-03-11 22:21:294794 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4795 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4796 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
4797 "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
4798 "ahlhx5I=\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:244799 };
4800
4801 MockRead data_reads2[] = {
4802 // The origin server responds with a Type 2 message.
4803 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4804 MockRead("WWW-Authenticate: NTLM "
[email protected]385a4672009-03-11 22:21:294805 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
[email protected]3f918782009-02-28 01:29:244806 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4807 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4808 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4809 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4810 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4811 "BtAAAAAAA=\r\n"),
4812 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364813 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:244814 MockRead("You are not authorized to view this page\r\n"),
4815
4816 // Lastly we get the desired content.
4817 MockRead("HTTP/1.1 200 OK\r\n"),
4818 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
4819 MockRead("Content-Length: 13\r\n\r\n"),
4820 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:064821 MockRead(SYNCHRONOUS, OK),
[email protected]3f918782009-02-28 01:29:244822 };
4823
[email protected]31a2bfe2010-02-09 08:03:394824 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4825 data_writes1, arraysize(data_writes1));
4826 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4827 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:074828 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4829 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:244830
[email protected]49639fa2011-12-20 23:22:414831 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:244832
[email protected]262eec82013-03-19 21:01:364833 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504834 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504835
[email protected]49639fa2011-12-20 23:22:414836 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424837 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:244838
4839 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424840 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:244841
[email protected]0757e7702009-03-27 04:00:224842 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4843
[email protected]1c773ea12009-04-28 19:58:424844 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:044845 ASSERT_FALSE(response == NULL);
4846 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:244847
[email protected]49639fa2011-12-20 23:22:414848 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:254849
[email protected]f3cf9802011-10-28 18:44:584850 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:414851 callback2.callback());
[email protected]10af5fe72011-01-31 16:17:254852 EXPECT_EQ(ERR_IO_PENDING, rv);
4853
4854 rv = callback2.WaitForResult();
4855 EXPECT_EQ(OK, rv);
4856
4857 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4858
4859 response = trans->GetResponseInfo();
4860 ASSERT_TRUE(response != NULL);
[email protected]10af5fe72011-01-31 16:17:254861 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4862
[email protected]49639fa2011-12-20 23:22:414863 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:244864
[email protected]49639fa2011-12-20 23:22:414865 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424866 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:244867
[email protected]0757e7702009-03-27 04:00:224868 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424869 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:244870
4871 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504872 ASSERT_TRUE(response != NULL);
[email protected]3f918782009-02-28 01:29:244873 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4874 EXPECT_EQ(13, response->headers->GetContentLength());
4875}
4876
[email protected]385a4672009-03-11 22:21:294877// Enter a wrong password, and then the correct one.
[email protected]23e482282013-06-14 16:08:024878TEST_P(HttpNetworkTransactionTest, NTLMAuth2) {
[email protected]1c773ea12009-04-28 19:58:424879 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:294880 request.method = "GET";
4881 request.url = GURL("http://172.22.68.17/kids/login.aspx");
4882 request.load_flags = 0;
4883
[email protected]cb9bf6ca2011-01-28 13:15:274884 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
4885 MockGetHostName);
mmenke6b3af6e2015-09-12 02:06:064886 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274887
[email protected]385a4672009-03-11 22:21:294888 MockWrite data_writes1[] = {
4889 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4890 "Host: 172.22.68.17\r\n"
4891 "Connection: keep-alive\r\n\r\n"),
4892 };
4893
4894 MockRead data_reads1[] = {
4895 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:044896 // Negotiate and NTLM are often requested together. However, we only want
4897 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
4898 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:294899 MockRead("WWW-Authenticate: NTLM\r\n"),
4900 MockRead("Connection: close\r\n"),
4901 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364902 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294903 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064904 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:294905 };
4906
4907 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:224908 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:294909 // request we should be issuing -- the final header line contains a Type
4910 // 1 message.
4911 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4912 "Host: 172.22.68.17\r\n"
4913 "Connection: keep-alive\r\n"
4914 "Authorization: NTLM "
4915 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4916
4917 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4918 // (the credentials for the origin server). The second request continues
4919 // on the same connection.
4920 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4921 "Host: 172.22.68.17\r\n"
4922 "Connection: keep-alive\r\n"
4923 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4924 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4925 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
4926 "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
4927 "4Ww7b7E=\r\n\r\n"),
4928 };
4929
4930 MockRead data_reads2[] = {
4931 // The origin server responds with a Type 2 message.
4932 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4933 MockRead("WWW-Authenticate: NTLM "
4934 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
4935 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4936 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4937 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4938 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4939 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4940 "BtAAAAAAA=\r\n"),
4941 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364942 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294943 MockRead("You are not authorized to view this page\r\n"),
4944
4945 // Wrong password.
4946 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]385a4672009-03-11 22:21:294947 MockRead("WWW-Authenticate: NTLM\r\n"),
4948 MockRead("Connection: close\r\n"),
4949 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364950 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294951 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064952 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:294953 };
4954
4955 MockWrite data_writes3[] = {
[email protected]0757e7702009-03-27 04:00:224956 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:294957 // request we should be issuing -- the final header line contains a Type
4958 // 1 message.
4959 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4960 "Host: 172.22.68.17\r\n"
4961 "Connection: keep-alive\r\n"
4962 "Authorization: NTLM "
4963 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4964
4965 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4966 // (the credentials for the origin server). The second request continues
4967 // on the same connection.
4968 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4969 "Host: 172.22.68.17\r\n"
4970 "Connection: keep-alive\r\n"
4971 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4972 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4973 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
4974 "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
4975 "+4MUm7c=\r\n\r\n"),
4976 };
4977
4978 MockRead data_reads3[] = {
4979 // The origin server responds with a Type 2 message.
4980 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4981 MockRead("WWW-Authenticate: NTLM "
4982 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
4983 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4984 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4985 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4986 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4987 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4988 "BtAAAAAAA=\r\n"),
4989 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364990 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294991 MockRead("You are not authorized to view this page\r\n"),
4992
4993 // Lastly we get the desired content.
4994 MockRead("HTTP/1.1 200 OK\r\n"),
4995 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
4996 MockRead("Content-Length: 13\r\n\r\n"),
4997 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:064998 MockRead(SYNCHRONOUS, OK),
[email protected]385a4672009-03-11 22:21:294999 };
5000
[email protected]31a2bfe2010-02-09 08:03:395001 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5002 data_writes1, arraysize(data_writes1));
5003 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5004 data_writes2, arraysize(data_writes2));
5005 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5006 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075007 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5008 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5009 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:295010
[email protected]49639fa2011-12-20 23:22:415011 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:295012
[email protected]262eec82013-03-19 21:01:365013 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505014 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:505015
[email protected]49639fa2011-12-20 23:22:415016 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425017 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:295018
5019 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425020 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:295021
[email protected]0757e7702009-03-27 04:00:225022 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:295023
[email protected]1c773ea12009-04-28 19:58:425024 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505025 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045026 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:295027
[email protected]49639fa2011-12-20 23:22:415028 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:295029
[email protected]0757e7702009-03-27 04:00:225030 // Enter the wrong password.
[email protected]f3cf9802011-10-28 18:44:585031 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword),
[email protected]49639fa2011-12-20 23:22:415032 callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425033 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:295034
[email protected]10af5fe72011-01-31 16:17:255035 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425036 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:295037
[email protected]0757e7702009-03-27 04:00:225038 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:415039 TestCompletionCallback callback3;
5040 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:425041 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]10af5fe72011-01-31 16:17:255042 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425043 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225044 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5045
5046 response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:045047 ASSERT_FALSE(response == NULL);
5048 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:225049
[email protected]49639fa2011-12-20 23:22:415050 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:225051
5052 // Now enter the right password.
[email protected]f3cf9802011-10-28 18:44:585053 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:415054 callback4.callback());
[email protected]10af5fe72011-01-31 16:17:255055 EXPECT_EQ(ERR_IO_PENDING, rv);
5056
5057 rv = callback4.WaitForResult();
5058 EXPECT_EQ(OK, rv);
5059
5060 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5061
[email protected]49639fa2011-12-20 23:22:415062 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:255063
5064 // One more roundtrip
[email protected]49639fa2011-12-20 23:22:415065 rv = trans->RestartWithAuth(AuthCredentials(), callback5.callback());
[email protected]1c773ea12009-04-28 19:58:425066 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:225067
5068 rv = callback5.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425069 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225070
[email protected]385a4672009-03-11 22:21:295071 response = trans->GetResponseInfo();
5072 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5073 EXPECT_EQ(13, response->headers->GetContentLength());
5074}
[email protected]ea9dc9a2009-09-05 00:43:325075#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:295076
[email protected]4ddaf2502008-10-23 18:26:195077// Test reading a server response which has only headers, and no body.
5078// After some maximum number of bytes is consumed, the transaction should
5079// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
[email protected]23e482282013-06-14 16:08:025080TEST_P(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:425081 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:195082 request.method = "GET";
bncce36dca22015-04-21 22:11:235083 request.url = GURL("http://www.example.org/");
[email protected]4ddaf2502008-10-23 18:26:195084 request.load_flags = 0;
5085
mmenke6b3af6e2015-09-12 02:06:065086 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275087 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415088 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275089
[email protected]b75b7b2f2009-10-06 00:54:535090 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:435091 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:535092 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:195093
5094 MockRead data_reads[] = {
5095 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:065096 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:195097 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:065098 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:195099 };
[email protected]31a2bfe2010-02-09 08:03:395100 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:075101 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:195102
[email protected]49639fa2011-12-20 23:22:415103 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:195104
[email protected]49639fa2011-12-20 23:22:415105 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425106 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]4ddaf2502008-10-23 18:26:195107
5108 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425109 EXPECT_EQ(ERR_RESPONSE_HEADERS_TOO_BIG, rv);
[email protected]4ddaf2502008-10-23 18:26:195110}
[email protected]f4e426b2008-11-05 00:24:495111
5112// Make sure that we don't try to reuse a TCPClientSocket when failing to
5113// establish tunnel.
5114// http://code.google.com/p/chromium/issues/detail?id=3772
[email protected]23e482282013-06-14 16:08:025115TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:235116 DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:275117 HttpRequestInfo request;
5118 request.method = "GET";
bncce36dca22015-04-21 22:11:235119 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275120 request.load_flags = 0;
5121
[email protected]f4e426b2008-11-05 00:24:495122 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:075123 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]db8f44c2008-12-13 04:52:015124
mmenke6b3af6e2015-09-12 02:06:065125 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:495126
[email protected]262eec82013-03-19 21:01:365127 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505128 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f4e426b2008-11-05 00:24:495129
[email protected]f4e426b2008-11-05 00:24:495130 // Since we have proxy, should try to establish tunnel.
5131 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235132 MockWrite(
5133 "CONNECT www.example.org:443 HTTP/1.1\r\n"
5134 "Host: www.example.org\r\n"
5135 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:495136 };
5137
[email protected]77848d12008-11-14 00:00:225138 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:495139 // connection. Usually a proxy would return 501 (not implemented),
5140 // or 200 (tunnel established).
5141 MockRead data_reads1[] = {
5142 MockRead("HTTP/1.1 404 Not Found\r\n"),
5143 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065144 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]f4e426b2008-11-05 00:24:495145 };
5146
[email protected]31a2bfe2010-02-09 08:03:395147 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5148 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075149 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:495150
[email protected]49639fa2011-12-20 23:22:415151 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:495152
[email protected]49639fa2011-12-20 23:22:415153 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425154 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f4e426b2008-11-05 00:24:495155
5156 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425157 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]f4e426b2008-11-05 00:24:495158
[email protected]b4404c02009-04-10 16:38:525159 // Empty the current queue. This is necessary because idle sockets are
5160 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345161 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:525162
[email protected]f4e426b2008-11-05 00:24:495163 // We now check to make sure the TCPClientSocket was not added back to
5164 // the pool.
[email protected]90499482013-06-01 00:39:505165 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:495166 trans.reset();
[email protected]2da659e2013-05-23 20:51:345167 base::MessageLoop::current()->RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:495168 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:505169 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:495170}
[email protected]372d34a2008-11-05 21:30:515171
[email protected]1b157c02009-04-21 01:55:405172// Make sure that we recycle a socket after reading all of the response body.
[email protected]23e482282013-06-14 16:08:025173TEST_P(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:425174 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:405175 request.method = "GET";
bncce36dca22015-04-21 22:11:235176 request.url = GURL("http://www.example.org/");
[email protected]1b157c02009-04-21 01:55:405177 request.load_flags = 0;
5178
mmenke6b3af6e2015-09-12 02:06:065179 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275180
[email protected]262eec82013-03-19 21:01:365181 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505182 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275183
[email protected]1b157c02009-04-21 01:55:405184 MockRead data_reads[] = {
5185 // A part of the response body is received with the response headers.
5186 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
5187 // The rest of the response body is received in two parts.
5188 MockRead("lo"),
5189 MockRead(" world"),
5190 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:065191 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:405192 };
5193
[email protected]31a2bfe2010-02-09 08:03:395194 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:075195 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:405196
[email protected]49639fa2011-12-20 23:22:415197 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:405198
[email protected]49639fa2011-12-20 23:22:415199 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425200 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]1b157c02009-04-21 01:55:405201
5202 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425203 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:405204
[email protected]1c773ea12009-04-28 19:58:425205 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505206 ASSERT_TRUE(response != NULL);
[email protected]1b157c02009-04-21 01:55:405207
[email protected]90499482013-06-01 00:39:505208 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]1b157c02009-04-21 01:55:405209 std::string status_line = response->headers->GetStatusLine();
5210 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
5211
[email protected]90499482013-06-01 00:39:505212 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:405213
5214 std::string response_data;
5215 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:425216 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:405217 EXPECT_EQ("hello world", response_data);
5218
5219 // Empty the current queue. This is necessary because idle sockets are
5220 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345221 base::MessageLoop::current()->RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:405222
5223 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505224 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:405225}
5226
[email protected]76a505b2010-08-25 06:23:005227// Make sure that we recycle a SSL socket after reading all of the response
5228// body.
[email protected]23e482282013-06-14 16:08:025229TEST_P(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:005230 HttpRequestInfo request;
5231 request.method = "GET";
bncce36dca22015-04-21 22:11:235232 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:005233 request.load_flags = 0;
5234
5235 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:235236 MockWrite(
5237 "GET / HTTP/1.1\r\n"
5238 "Host: www.example.org\r\n"
5239 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:005240 };
5241
5242 MockRead data_reads[] = {
5243 MockRead("HTTP/1.1 200 OK\r\n"),
5244 MockRead("Content-Length: 11\r\n\r\n"),
5245 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:065246 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:005247 };
5248
[email protected]8ddf8322012-02-23 18:08:065249 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075250 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:005251
5252 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5253 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:075254 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:005255
[email protected]49639fa2011-12-20 23:22:415256 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:005257
mmenke6b3af6e2015-09-12 02:06:065258 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:365259 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505260 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:005261
[email protected]49639fa2011-12-20 23:22:415262 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:005263
5264 EXPECT_EQ(ERR_IO_PENDING, rv);
5265 EXPECT_EQ(OK, callback.WaitForResult());
5266
5267 const HttpResponseInfo* response = trans->GetResponseInfo();
5268 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:505269 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:005270 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5271
[email protected]90499482013-06-01 00:39:505272 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005273
5274 std::string response_data;
5275 rv = ReadTransaction(trans.get(), &response_data);
5276 EXPECT_EQ(OK, rv);
5277 EXPECT_EQ("hello world", response_data);
5278
5279 // Empty the current queue. This is necessary because idle sockets are
5280 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345281 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:005282
5283 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505284 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005285}
5286
5287// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
5288// from the pool and make sure that we recover okay.
[email protected]23e482282013-06-14 16:08:025289TEST_P(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:005290 HttpRequestInfo request;
5291 request.method = "GET";
bncce36dca22015-04-21 22:11:235292 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:005293 request.load_flags = 0;
5294
5295 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:235296 MockWrite(
5297 "GET / HTTP/1.1\r\n"
5298 "Host: www.example.org\r\n"
5299 "Connection: keep-alive\r\n\r\n"),
5300 MockWrite(
5301 "GET / HTTP/1.1\r\n"
5302 "Host: www.example.org\r\n"
5303 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:005304 };
5305
5306 MockRead data_reads[] = {
5307 MockRead("HTTP/1.1 200 OK\r\n"),
5308 MockRead("Content-Length: 11\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065309 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:005310 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:065311 MockRead(ASYNC, 0, 0) // EOF
[email protected]76a505b2010-08-25 06:23:005312 };
5313
[email protected]8ddf8322012-02-23 18:08:065314 SSLSocketDataProvider ssl(ASYNC, OK);
5315 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075316 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5317 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:005318
5319 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5320 data_writes, arraysize(data_writes));
5321 StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
5322 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:075323 session_deps_.socket_factory->AddSocketDataProvider(&data);
5324 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:005325
[email protected]49639fa2011-12-20 23:22:415326 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:005327
mmenke6b3af6e2015-09-12 02:06:065328 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:365329 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505330 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:005331
[email protected]49639fa2011-12-20 23:22:415332 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:005333
5334 EXPECT_EQ(ERR_IO_PENDING, rv);
5335 EXPECT_EQ(OK, callback.WaitForResult());
5336
5337 const HttpResponseInfo* response = trans->GetResponseInfo();
5338 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:505339 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:005340 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5341
[email protected]90499482013-06-01 00:39:505342 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005343
5344 std::string response_data;
5345 rv = ReadTransaction(trans.get(), &response_data);
5346 EXPECT_EQ(OK, rv);
5347 EXPECT_EQ("hello world", response_data);
5348
5349 // Empty the current queue. This is necessary because idle sockets are
5350 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345351 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:005352
5353 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505354 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005355
5356 // Now start the second transaction, which should reuse the previous socket.
5357
[email protected]90499482013-06-01 00:39:505358 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:005359
[email protected]49639fa2011-12-20 23:22:415360 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:005361
5362 EXPECT_EQ(ERR_IO_PENDING, rv);
5363 EXPECT_EQ(OK, callback.WaitForResult());
5364
5365 response = trans->GetResponseInfo();
5366 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:505367 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:005368 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5369
[email protected]90499482013-06-01 00:39:505370 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005371
5372 rv = ReadTransaction(trans.get(), &response_data);
5373 EXPECT_EQ(OK, rv);
5374 EXPECT_EQ("hello world", response_data);
5375
5376 // Empty the current queue. This is necessary because idle sockets are
5377 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345378 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:005379
5380 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505381 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005382}
5383
[email protected]b4404c02009-04-10 16:38:525384// Make sure that we recycle a socket after a zero-length response.
5385// http://crbug.com/9880
[email protected]23e482282013-06-14 16:08:025386TEST_P(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:425387 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:525388 request.method = "GET";
bncce36dca22015-04-21 22:11:235389 request.url = GURL(
5390 "http://www.example.org/csi?v=3&s=web&action=&"
5391 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
5392 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
5393 "rt=prt.2642,ol.2649,xjs.2951");
[email protected]b4404c02009-04-10 16:38:525394 request.load_flags = 0;
5395
mmenke6b3af6e2015-09-12 02:06:065396 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275397
[email protected]262eec82013-03-19 21:01:365398 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505399 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275400
[email protected]b4404c02009-04-10 16:38:525401 MockRead data_reads[] = {
5402 MockRead("HTTP/1.1 204 No Content\r\n"
5403 "Content-Length: 0\r\n"
5404 "Content-Type: text/html\r\n\r\n"),
5405 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:065406 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:525407 };
5408
[email protected]31a2bfe2010-02-09 08:03:395409 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:075410 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:525411
[email protected]49639fa2011-12-20 23:22:415412 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:525413
[email protected]49639fa2011-12-20 23:22:415414 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425415 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]b4404c02009-04-10 16:38:525416
5417 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425418 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:525419
[email protected]1c773ea12009-04-28 19:58:425420 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505421 ASSERT_TRUE(response != NULL);
[email protected]b4404c02009-04-10 16:38:525422
[email protected]90499482013-06-01 00:39:505423 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]b4404c02009-04-10 16:38:525424 std::string status_line = response->headers->GetStatusLine();
5425 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
5426
[email protected]90499482013-06-01 00:39:505427 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:525428
5429 std::string response_data;
5430 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:425431 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:525432 EXPECT_EQ("", response_data);
5433
5434 // Empty the current queue. This is necessary because idle sockets are
5435 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345436 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:525437
5438 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505439 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:525440}
5441
[email protected]23e482282013-06-14 16:08:025442TEST_P(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
[email protected]b2d26cfd2012-12-11 10:36:065443 ScopedVector<UploadElementReader> element_readers;
5444 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:075445 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:275446
[email protected]1c773ea12009-04-28 19:58:425447 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:515448 // Transaction 1: a GET request that succeeds. The socket is recycled
5449 // after use.
5450 request[0].method = "GET";
5451 request[0].url = GURL("http://www.google.com/");
5452 request[0].load_flags = 0;
5453 // Transaction 2: a POST request. Reuses the socket kept alive from
5454 // transaction 1. The first attempts fails when writing the POST data.
5455 // This causes the transaction to retry with a new socket. The second
5456 // attempt succeeds.
5457 request[1].method = "POST";
5458 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:275459 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:515460 request[1].load_flags = 0;
5461
mmenke6b3af6e2015-09-12 02:06:065462 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:515463
5464 // The first socket is used for transaction 1 and the first attempt of
5465 // transaction 2.
5466
5467 // The response of transaction 1.
5468 MockRead data_reads1[] = {
5469 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
5470 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:065471 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:515472 };
5473 // The mock write results of transaction 1 and the first attempt of
5474 // transaction 2.
5475 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:065476 MockWrite(SYNCHRONOUS, 64), // GET
5477 MockWrite(SYNCHRONOUS, 93), // POST
5478 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:515479 };
[email protected]31a2bfe2010-02-09 08:03:395480 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5481 data_writes1, arraysize(data_writes1));
[email protected]372d34a2008-11-05 21:30:515482
5483 // The second socket is used for the second attempt of transaction 2.
5484
5485 // The response of transaction 2.
5486 MockRead data_reads2[] = {
5487 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
5488 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:065489 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:515490 };
5491 // The mock write results of the second attempt of transaction 2.
5492 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:065493 MockWrite(SYNCHRONOUS, 93), // POST
5494 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:515495 };
[email protected]31a2bfe2010-02-09 08:03:395496 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5497 data_writes2, arraysize(data_writes2));
[email protected]372d34a2008-11-05 21:30:515498
[email protected]bb88e1d32013-05-03 23:11:075499 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5500 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:515501
thestig9d3bb0c2015-01-24 00:49:515502 const char* const kExpectedResponseData[] = {
[email protected]372d34a2008-11-05 21:30:515503 "hello world", "welcome"
5504 };
5505
5506 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:425507 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505508 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]372d34a2008-11-05 21:30:515509
[email protected]49639fa2011-12-20 23:22:415510 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:515511
[email protected]49639fa2011-12-20 23:22:415512 int rv = trans->Start(&request[i], callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425513 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]372d34a2008-11-05 21:30:515514
5515 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425516 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:515517
[email protected]1c773ea12009-04-28 19:58:425518 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505519 ASSERT_TRUE(response != NULL);
[email protected]372d34a2008-11-05 21:30:515520
[email protected]90499482013-06-01 00:39:505521 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]372d34a2008-11-05 21:30:515522 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5523
5524 std::string response_data;
5525 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:425526 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:515527 EXPECT_EQ(kExpectedResponseData[i], response_data);
5528 }
5529}
[email protected]f9ee6b52008-11-08 06:46:235530
5531// Test the request-challenge-retry sequence for basic auth when there is
5532// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:165533// it fails the identity from the URL is used to answer the challenge.
[email protected]23e482282013-06-14 16:08:025534TEST_P(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:425535 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235536 request.method = "GET";
bncce36dca22015-04-21 22:11:235537 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:415538 request.load_flags = LOAD_NORMAL;
[email protected]a97cca42009-08-14 01:00:295539
mmenke6b3af6e2015-09-12 02:06:065540 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275541 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415542 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275543
[email protected]a97cca42009-08-14 01:00:295544 // The password contains an escaped character -- for this test to pass it
5545 // will need to be unescaped by HttpNetworkTransaction.
5546 EXPECT_EQ("b%40r", request.url.password());
5547
[email protected]f9ee6b52008-11-08 06:46:235548 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235549 MockWrite(
5550 "GET / HTTP/1.1\r\n"
5551 "Host: www.example.org\r\n"
5552 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235553 };
5554
5555 MockRead data_reads1[] = {
5556 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5557 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5558 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065559 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235560 };
5561
[email protected]2262e3a2012-05-22 16:08:165562 // After the challenge above, the transaction will be restarted using the
5563 // identity from the url (foo, b@r) to answer the challenge.
5564 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235565 MockWrite(
5566 "GET / HTTP/1.1\r\n"
5567 "Host: www.example.org\r\n"
5568 "Connection: keep-alive\r\n"
5569 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:165570 };
5571
5572 MockRead data_reads2[] = {
5573 MockRead("HTTP/1.0 200 OK\r\n"),
5574 MockRead("Content-Length: 100\r\n\r\n"),
5575 MockRead(SYNCHRONOUS, OK),
5576 };
5577
[email protected]31a2bfe2010-02-09 08:03:395578 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5579 data_writes1, arraysize(data_writes1));
[email protected]2262e3a2012-05-22 16:08:165580 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5581 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075582 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5583 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235584
[email protected]49639fa2011-12-20 23:22:415585 TestCompletionCallback callback1;
[email protected]49639fa2011-12-20 23:22:415586 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425587 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235588 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425589 EXPECT_EQ(OK, rv);
[email protected]2262e3a2012-05-22 16:08:165590 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5591
5592 TestCompletionCallback callback2;
5593 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
5594 EXPECT_EQ(ERR_IO_PENDING, rv);
5595 rv = callback2.WaitForResult();
5596 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225597 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5598
[email protected]2262e3a2012-05-22 16:08:165599 const HttpResponseInfo* response = trans->GetResponseInfo();
5600 ASSERT_TRUE(response != NULL);
5601
5602 // There is no challenge info, since the identity in URL worked.
5603 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5604
5605 EXPECT_EQ(100, response->headers->GetContentLength());
5606
5607 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:345608 base::MessageLoop::current()->RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:165609}
5610
5611// Test the request-challenge-retry sequence for basic auth when there is an
5612// incorrect identity in the URL. The identity from the URL should be used only
5613// once.
[email protected]23e482282013-06-14 16:08:025614TEST_P(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:165615 HttpRequestInfo request;
5616 request.method = "GET";
5617 // Note: the URL has a username:password in it. The password "baz" is
5618 // wrong (should be "bar").
bncce36dca22015-04-21 22:11:235619 request.url = GURL("http://foo:[email protected]/");
[email protected]2262e3a2012-05-22 16:08:165620
5621 request.load_flags = LOAD_NORMAL;
5622
mmenke6b3af6e2015-09-12 02:06:065623 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2262e3a2012-05-22 16:08:165624 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415625 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2262e3a2012-05-22 16:08:165626
5627 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235628 MockWrite(
5629 "GET / HTTP/1.1\r\n"
5630 "Host: www.example.org\r\n"
5631 "Connection: keep-alive\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:165632 };
5633
5634 MockRead data_reads1[] = {
5635 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5636 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5637 MockRead("Content-Length: 10\r\n\r\n"),
5638 MockRead(SYNCHRONOUS, ERR_FAILED),
5639 };
5640
5641 // After the challenge above, the transaction will be restarted using the
5642 // identity from the url (foo, baz) to answer the challenge.
5643 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235644 MockWrite(
5645 "GET / HTTP/1.1\r\n"
5646 "Host: www.example.org\r\n"
5647 "Connection: keep-alive\r\n"
5648 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:165649 };
5650
5651 MockRead data_reads2[] = {
5652 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5653 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5654 MockRead("Content-Length: 10\r\n\r\n"),
5655 MockRead(SYNCHRONOUS, ERR_FAILED),
5656 };
5657
5658 // After the challenge above, the transaction will be restarted using the
5659 // identity supplied by the user (foo, bar) to answer the challenge.
5660 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:235661 MockWrite(
5662 "GET / HTTP/1.1\r\n"
5663 "Host: www.example.org\r\n"
5664 "Connection: keep-alive\r\n"
5665 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:165666 };
5667
5668 MockRead data_reads3[] = {
5669 MockRead("HTTP/1.0 200 OK\r\n"),
5670 MockRead("Content-Length: 100\r\n\r\n"),
5671 MockRead(SYNCHRONOUS, OK),
5672 };
5673
5674 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5675 data_writes1, arraysize(data_writes1));
5676 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5677 data_writes2, arraysize(data_writes2));
5678 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5679 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075680 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5681 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5682 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:165683
5684 TestCompletionCallback callback1;
5685
5686 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5687 EXPECT_EQ(ERR_IO_PENDING, rv);
5688
5689 rv = callback1.WaitForResult();
5690 EXPECT_EQ(OK, rv);
5691
5692 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5693 TestCompletionCallback callback2;
5694 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
5695 EXPECT_EQ(ERR_IO_PENDING, rv);
5696 rv = callback2.WaitForResult();
5697 EXPECT_EQ(OK, rv);
5698 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5699
5700 const HttpResponseInfo* response = trans->GetResponseInfo();
5701 ASSERT_TRUE(response != NULL);
5702 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
5703
5704 TestCompletionCallback callback3;
5705 rv = trans->RestartWithAuth(
5706 AuthCredentials(kFoo, kBar), callback3.callback());
5707 EXPECT_EQ(ERR_IO_PENDING, rv);
5708 rv = callback3.WaitForResult();
5709 EXPECT_EQ(OK, rv);
5710 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5711
5712 response = trans->GetResponseInfo();
5713 ASSERT_TRUE(response != NULL);
5714
5715 // There is no challenge info, since the identity worked.
5716 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5717
5718 EXPECT_EQ(100, response->headers->GetContentLength());
5719
[email protected]ea9dc9a2009-09-05 00:43:325720 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:345721 base::MessageLoop::current()->RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:325722}
5723
[email protected]2217aa22013-10-11 03:03:545724
5725// Test the request-challenge-retry sequence for basic auth when there is a
5726// correct identity in the URL, but its use is being suppressed. The identity
5727// from the URL should never be used.
5728TEST_P(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
5729 HttpRequestInfo request;
5730 request.method = "GET";
bncce36dca22015-04-21 22:11:235731 request.url = GURL("http://foo:[email protected]/");
[email protected]2217aa22013-10-11 03:03:545732 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
5733
mmenke6b3af6e2015-09-12 02:06:065734 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2217aa22013-10-11 03:03:545735 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415736 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2217aa22013-10-11 03:03:545737
5738 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235739 MockWrite(
5740 "GET / HTTP/1.1\r\n"
5741 "Host: www.example.org\r\n"
5742 "Connection: keep-alive\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:545743 };
5744
5745 MockRead data_reads1[] = {
5746 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5747 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5748 MockRead("Content-Length: 10\r\n\r\n"),
5749 MockRead(SYNCHRONOUS, ERR_FAILED),
5750 };
5751
5752 // After the challenge above, the transaction will be restarted using the
5753 // identity supplied by the user, not the one in the URL, to answer the
5754 // challenge.
5755 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:235756 MockWrite(
5757 "GET / HTTP/1.1\r\n"
5758 "Host: www.example.org\r\n"
5759 "Connection: keep-alive\r\n"
5760 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:545761 };
5762
5763 MockRead data_reads3[] = {
5764 MockRead("HTTP/1.0 200 OK\r\n"),
5765 MockRead("Content-Length: 100\r\n\r\n"),
5766 MockRead(SYNCHRONOUS, OK),
5767 };
5768
5769 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5770 data_writes1, arraysize(data_writes1));
5771 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5772 data_writes3, arraysize(data_writes3));
5773 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5774 session_deps_.socket_factory->AddSocketDataProvider(&data3);
5775
5776 TestCompletionCallback callback1;
5777 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5778 EXPECT_EQ(ERR_IO_PENDING, rv);
5779 rv = callback1.WaitForResult();
5780 EXPECT_EQ(OK, rv);
5781 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5782
5783 const HttpResponseInfo* response = trans->GetResponseInfo();
5784 ASSERT_TRUE(response != NULL);
5785 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
5786
5787 TestCompletionCallback callback3;
5788 rv = trans->RestartWithAuth(
5789 AuthCredentials(kFoo, kBar), callback3.callback());
5790 EXPECT_EQ(ERR_IO_PENDING, rv);
5791 rv = callback3.WaitForResult();
5792 EXPECT_EQ(OK, rv);
5793 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5794
5795 response = trans->GetResponseInfo();
5796 ASSERT_TRUE(response != NULL);
5797
5798 // There is no challenge info, since the identity worked.
5799 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5800 EXPECT_EQ(100, response->headers->GetContentLength());
5801
5802 // Empty the current queue.
5803 base::MessageLoop::current()->RunUntilIdle();
5804}
5805
[email protected]f9ee6b52008-11-08 06:46:235806// Test that previously tried username/passwords for a realm get re-used.
[email protected]23e482282013-06-14 16:08:025807TEST_P(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
mmenke6b3af6e2015-09-12 02:06:065808 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:235809
5810 // Transaction 1: authenticate (foo, bar) on MyRealm1
5811 {
[email protected]1c773ea12009-04-28 19:58:425812 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235813 request.method = "GET";
bncce36dca22015-04-21 22:11:235814 request.url = GURL("http://www.example.org/x/y/z");
[email protected]f9ee6b52008-11-08 06:46:235815 request.load_flags = 0;
5816
[email protected]262eec82013-03-19 21:01:365817 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505818 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275819
[email protected]f9ee6b52008-11-08 06:46:235820 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235821 MockWrite(
5822 "GET /x/y/z HTTP/1.1\r\n"
5823 "Host: www.example.org\r\n"
5824 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235825 };
5826
5827 MockRead data_reads1[] = {
5828 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5829 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5830 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065831 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235832 };
5833
5834 // Resend with authorization (username=foo, password=bar)
5835 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235836 MockWrite(
5837 "GET /x/y/z HTTP/1.1\r\n"
5838 "Host: www.example.org\r\n"
5839 "Connection: keep-alive\r\n"
5840 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235841 };
5842
5843 // Sever accepts the authorization.
5844 MockRead data_reads2[] = {
5845 MockRead("HTTP/1.0 200 OK\r\n"),
5846 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065847 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235848 };
5849
[email protected]31a2bfe2010-02-09 08:03:395850 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5851 data_writes1, arraysize(data_writes1));
5852 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5853 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075854 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5855 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235856
[email protected]49639fa2011-12-20 23:22:415857 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235858
[email protected]49639fa2011-12-20 23:22:415859 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425860 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235861
5862 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425863 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235864
[email protected]1c773ea12009-04-28 19:58:425865 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505866 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045867 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:235868
[email protected]49639fa2011-12-20 23:22:415869 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:235870
[email protected]49639fa2011-12-20 23:22:415871 rv = trans->RestartWithAuth(
5872 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425873 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235874
5875 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425876 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235877
5878 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505879 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235880 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5881 EXPECT_EQ(100, response->headers->GetContentLength());
5882 }
5883
5884 // ------------------------------------------------------------------------
5885
5886 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
5887 {
[email protected]1c773ea12009-04-28 19:58:425888 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235889 request.method = "GET";
5890 // Note that Transaction 1 was at /x/y/z, so this is in the same
5891 // protection space as MyRealm1.
bncce36dca22015-04-21 22:11:235892 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]f9ee6b52008-11-08 06:46:235893 request.load_flags = 0;
5894
[email protected]262eec82013-03-19 21:01:365895 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505896 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275897
[email protected]f9ee6b52008-11-08 06:46:235898 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235899 MockWrite(
5900 "GET /x/y/a/b HTTP/1.1\r\n"
5901 "Host: www.example.org\r\n"
5902 "Connection: keep-alive\r\n"
5903 // Send preemptive authorization for MyRealm1
5904 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235905 };
5906
5907 // The server didn't like the preemptive authorization, and
5908 // challenges us for a different realm (MyRealm2).
5909 MockRead data_reads1[] = {
5910 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5911 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
5912 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065913 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235914 };
5915
5916 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
5917 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235918 MockWrite(
5919 "GET /x/y/a/b HTTP/1.1\r\n"
5920 "Host: www.example.org\r\n"
5921 "Connection: keep-alive\r\n"
5922 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235923 };
5924
5925 // Sever accepts the authorization.
5926 MockRead data_reads2[] = {
5927 MockRead("HTTP/1.0 200 OK\r\n"),
5928 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065929 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235930 };
5931
[email protected]31a2bfe2010-02-09 08:03:395932 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5933 data_writes1, arraysize(data_writes1));
5934 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5935 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075936 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5937 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235938
[email protected]49639fa2011-12-20 23:22:415939 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235940
[email protected]49639fa2011-12-20 23:22:415941 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425942 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235943
5944 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425945 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235946
[email protected]1c773ea12009-04-28 19:58:425947 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505948 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045949 ASSERT_TRUE(response->auth_challenge.get());
5950 EXPECT_FALSE(response->auth_challenge->is_proxy);
bncce36dca22015-04-21 22:11:235951 EXPECT_EQ("www.example.org:80",
[email protected]79cb5c12011-09-12 13:12:045952 response->auth_challenge->challenger.ToString());
5953 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
5954 EXPECT_EQ("basic", response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:235955
[email protected]49639fa2011-12-20 23:22:415956 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:235957
[email protected]49639fa2011-12-20 23:22:415958 rv = trans->RestartWithAuth(
5959 AuthCredentials(kFoo2, kBar2), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425960 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235961
5962 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425963 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235964
5965 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505966 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235967 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5968 EXPECT_EQ(100, response->headers->GetContentLength());
5969 }
5970
5971 // ------------------------------------------------------------------------
5972
5973 // Transaction 3: Resend a request in MyRealm's protection space --
5974 // succeed with preemptive authorization.
5975 {
[email protected]1c773ea12009-04-28 19:58:425976 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235977 request.method = "GET";
bncce36dca22015-04-21 22:11:235978 request.url = GURL("http://www.example.org/x/y/z2");
[email protected]f9ee6b52008-11-08 06:46:235979 request.load_flags = 0;
5980
[email protected]262eec82013-03-19 21:01:365981 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505982 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275983
[email protected]f9ee6b52008-11-08 06:46:235984 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235985 MockWrite(
5986 "GET /x/y/z2 HTTP/1.1\r\n"
5987 "Host: www.example.org\r\n"
5988 "Connection: keep-alive\r\n"
5989 // The authorization for MyRealm1 gets sent preemptively
5990 // (since the url is in the same protection space)
5991 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235992 };
5993
5994 // Sever accepts the preemptive authorization
5995 MockRead data_reads1[] = {
5996 MockRead("HTTP/1.0 200 OK\r\n"),
5997 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065998 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235999 };
6000
[email protected]31a2bfe2010-02-09 08:03:396001 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6002 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:076003 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:236004
[email protected]49639fa2011-12-20 23:22:416005 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:236006
[email protected]49639fa2011-12-20 23:22:416007 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426008 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236009
6010 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426011 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236012
[email protected]1c773ea12009-04-28 19:58:426013 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506014 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:236015
6016 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6017 EXPECT_EQ(100, response->headers->GetContentLength());
6018 }
6019
6020 // ------------------------------------------------------------------------
6021
6022 // Transaction 4: request another URL in MyRealm (however the
6023 // url is not known to belong to the protection space, so no pre-auth).
6024 {
[email protected]1c773ea12009-04-28 19:58:426025 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236026 request.method = "GET";
bncce36dca22015-04-21 22:11:236027 request.url = GURL("http://www.example.org/x/1");
[email protected]f9ee6b52008-11-08 06:46:236028 request.load_flags = 0;
6029
[email protected]262eec82013-03-19 21:01:366030 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506031 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276032
[email protected]f9ee6b52008-11-08 06:46:236033 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236034 MockWrite(
6035 "GET /x/1 HTTP/1.1\r\n"
6036 "Host: www.example.org\r\n"
6037 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236038 };
6039
6040 MockRead data_reads1[] = {
6041 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6042 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6043 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066044 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236045 };
6046
6047 // Resend with authorization from MyRealm's cache.
6048 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236049 MockWrite(
6050 "GET /x/1 HTTP/1.1\r\n"
6051 "Host: www.example.org\r\n"
6052 "Connection: keep-alive\r\n"
6053 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236054 };
6055
6056 // Sever accepts the authorization.
6057 MockRead data_reads2[] = {
6058 MockRead("HTTP/1.0 200 OK\r\n"),
6059 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066060 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:236061 };
6062
[email protected]31a2bfe2010-02-09 08:03:396063 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6064 data_writes1, arraysize(data_writes1));
6065 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6066 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076067 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6068 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:236069
[email protected]49639fa2011-12-20 23:22:416070 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:236071
[email protected]49639fa2011-12-20 23:22:416072 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426073 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236074
6075 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426076 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236077
[email protected]0757e7702009-03-27 04:00:226078 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:416079 TestCompletionCallback callback2;
6080 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:426081 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:226082 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426083 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:226084 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6085
[email protected]1c773ea12009-04-28 19:58:426086 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506087 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:236088 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6089 EXPECT_EQ(100, response->headers->GetContentLength());
6090 }
6091
6092 // ------------------------------------------------------------------------
6093
6094 // Transaction 5: request a URL in MyRealm, but the server rejects the
6095 // cached identity. Should invalidate and re-prompt.
6096 {
[email protected]1c773ea12009-04-28 19:58:426097 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236098 request.method = "GET";
bncce36dca22015-04-21 22:11:236099 request.url = GURL("http://www.example.org/p/q/t");
[email protected]f9ee6b52008-11-08 06:46:236100 request.load_flags = 0;
6101
[email protected]262eec82013-03-19 21:01:366102 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506103 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276104
[email protected]f9ee6b52008-11-08 06:46:236105 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236106 MockWrite(
6107 "GET /p/q/t HTTP/1.1\r\n"
6108 "Host: www.example.org\r\n"
6109 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236110 };
6111
6112 MockRead data_reads1[] = {
6113 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6114 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6115 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066116 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236117 };
6118
6119 // Resend with authorization from cache for MyRealm.
6120 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236121 MockWrite(
6122 "GET /p/q/t HTTP/1.1\r\n"
6123 "Host: www.example.org\r\n"
6124 "Connection: keep-alive\r\n"
6125 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236126 };
6127
6128 // Sever rejects the authorization.
6129 MockRead data_reads2[] = {
6130 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6131 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6132 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066133 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236134 };
6135
6136 // At this point we should prompt for new credentials for MyRealm.
6137 // Restart with username=foo3, password=foo4.
6138 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236139 MockWrite(
6140 "GET /p/q/t HTTP/1.1\r\n"
6141 "Host: www.example.org\r\n"
6142 "Connection: keep-alive\r\n"
6143 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236144 };
6145
6146 // Sever accepts the authorization.
6147 MockRead data_reads3[] = {
6148 MockRead("HTTP/1.0 200 OK\r\n"),
6149 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066150 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:236151 };
6152
[email protected]31a2bfe2010-02-09 08:03:396153 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6154 data_writes1, arraysize(data_writes1));
6155 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6156 data_writes2, arraysize(data_writes2));
6157 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6158 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076159 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6160 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6161 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:236162
[email protected]49639fa2011-12-20 23:22:416163 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:236164
[email protected]49639fa2011-12-20 23:22:416165 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426166 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236167
6168 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426169 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236170
[email protected]0757e7702009-03-27 04:00:226171 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:416172 TestCompletionCallback callback2;
6173 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:426174 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:226175 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426176 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:226177 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6178
[email protected]1c773ea12009-04-28 19:58:426179 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506180 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:046181 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:236182
[email protected]49639fa2011-12-20 23:22:416183 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:236184
[email protected]49639fa2011-12-20 23:22:416185 rv = trans->RestartWithAuth(
6186 AuthCredentials(kFoo3, kBar3), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:426187 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236188
[email protected]0757e7702009-03-27 04:00:226189 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426190 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236191
6192 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506193 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:236194 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6195 EXPECT_EQ(100, response->headers->GetContentLength());
6196 }
6197}
[email protected]89ceba9a2009-03-21 03:46:066198
[email protected]3c32c5f2010-05-18 15:18:126199// Tests that nonce count increments when multiple auth attempts
6200// are started with the same nonce.
[email protected]23e482282013-06-14 16:08:026201TEST_P(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:446202 HttpAuthHandlerDigest::Factory* digest_factory =
6203 new HttpAuthHandlerDigest::Factory();
6204 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
6205 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
6206 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:076207 session_deps_.http_auth_handler_factory.reset(digest_factory);
mmenke6b3af6e2015-09-12 02:06:066208 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:126209
6210 // Transaction 1: authenticate (foo, bar) on MyRealm1
6211 {
[email protected]3c32c5f2010-05-18 15:18:126212 HttpRequestInfo request;
6213 request.method = "GET";
bncce36dca22015-04-21 22:11:236214 request.url = GURL("http://www.example.org/x/y/z");
[email protected]3c32c5f2010-05-18 15:18:126215 request.load_flags = 0;
6216
[email protected]262eec82013-03-19 21:01:366217 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506218 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276219
[email protected]3c32c5f2010-05-18 15:18:126220 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236221 MockWrite(
6222 "GET /x/y/z HTTP/1.1\r\n"
6223 "Host: www.example.org\r\n"
6224 "Connection: keep-alive\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:126225 };
6226
6227 MockRead data_reads1[] = {
6228 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6229 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
6230 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066231 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:126232 };
6233
6234 // Resend with authorization (username=foo, password=bar)
6235 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236236 MockWrite(
6237 "GET /x/y/z HTTP/1.1\r\n"
6238 "Host: www.example.org\r\n"
6239 "Connection: keep-alive\r\n"
6240 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
6241 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
6242 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
6243 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:126244 };
6245
6246 // Sever accepts the authorization.
6247 MockRead data_reads2[] = {
zmo9528c9f42015-08-04 22:12:086248 MockRead("HTTP/1.0 200 OK\r\n"),
6249 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:126250 };
6251
6252 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6253 data_writes1, arraysize(data_writes1));
6254 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6255 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076256 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6257 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:126258
[email protected]49639fa2011-12-20 23:22:416259 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:126260
[email protected]49639fa2011-12-20 23:22:416261 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:126262 EXPECT_EQ(ERR_IO_PENDING, rv);
6263
6264 rv = callback1.WaitForResult();
6265 EXPECT_EQ(OK, rv);
6266
6267 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506268 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:046269 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:126270
[email protected]49639fa2011-12-20 23:22:416271 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:126272
[email protected]49639fa2011-12-20 23:22:416273 rv = trans->RestartWithAuth(
6274 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]3c32c5f2010-05-18 15:18:126275 EXPECT_EQ(ERR_IO_PENDING, rv);
6276
6277 rv = callback2.WaitForResult();
6278 EXPECT_EQ(OK, rv);
6279
6280 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506281 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:126282 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6283 }
6284
6285 // ------------------------------------------------------------------------
6286
6287 // Transaction 2: Request another resource in digestive's protection space.
6288 // This will preemptively add an Authorization header which should have an
6289 // "nc" value of 2 (as compared to 1 in the first use.
6290 {
[email protected]3c32c5f2010-05-18 15:18:126291 HttpRequestInfo request;
6292 request.method = "GET";
6293 // Note that Transaction 1 was at /x/y/z, so this is in the same
6294 // protection space as digest.
bncce36dca22015-04-21 22:11:236295 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]3c32c5f2010-05-18 15:18:126296 request.load_flags = 0;
6297
[email protected]262eec82013-03-19 21:01:366298 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506299 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276300
[email protected]3c32c5f2010-05-18 15:18:126301 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236302 MockWrite(
6303 "GET /x/y/a/b HTTP/1.1\r\n"
6304 "Host: www.example.org\r\n"
6305 "Connection: keep-alive\r\n"
6306 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
6307 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
6308 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
6309 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:126310 };
6311
6312 // Sever accepts the authorization.
6313 MockRead data_reads1[] = {
6314 MockRead("HTTP/1.0 200 OK\r\n"),
6315 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066316 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:126317 };
6318
6319 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6320 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:076321 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:126322
[email protected]49639fa2011-12-20 23:22:416323 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:126324
[email protected]49639fa2011-12-20 23:22:416325 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:126326 EXPECT_EQ(ERR_IO_PENDING, rv);
6327
6328 rv = callback1.WaitForResult();
6329 EXPECT_EQ(OK, rv);
6330
6331 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506332 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:126333 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6334 }
6335}
6336
[email protected]89ceba9a2009-03-21 03:46:066337// Test the ResetStateForRestart() private method.
[email protected]23e482282013-06-14 16:08:026338TEST_P(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:066339 // Create a transaction (the dependencies aren't important).
mmenke6b3af6e2015-09-12 02:06:066340 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:406341 scoped_ptr<HttpNetworkTransaction> trans(
dcheng48459ac22014-08-26 00:46:416342 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]89ceba9a2009-03-21 03:46:066343
6344 // Setup some state (which we expect ResetStateForRestart() will clear).
[email protected]89ceba9a2009-03-21 03:46:066345 trans->read_buf_ = new IOBuffer(15);
6346 trans->read_buf_len_ = 15;
[email protected]b94f92d2010-10-27 16:45:206347 trans->request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:066348
6349 // Setup state in response_
[email protected]a7e41312009-12-16 23:18:146350 HttpResponseInfo* response = &trans->response_;
[email protected]0877e3d2009-10-17 22:29:576351 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:086352 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:576353 response->response_time = base::Time::Now();
6354 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:066355
6356 { // Setup state for response_.vary_data
6357 HttpRequestInfo request;
6358 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
6359 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:276360 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:436361 request.extra_headers.SetHeader("Foo", "1");
6362 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:506363 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:066364 }
6365
6366 // Cause the above state to be reset.
6367 trans->ResetStateForRestart();
6368
6369 // Verify that the state that needed to be reset, has been reset.
[email protected]9b6fee12009-09-29 18:13:076370 EXPECT_TRUE(trans->read_buf_.get() == NULL);
[email protected]89ceba9a2009-03-21 03:46:066371 EXPECT_EQ(0, trans->read_buf_len_);
[email protected]b94f92d2010-10-27 16:45:206372 EXPECT_TRUE(trans->request_headers_.IsEmpty());
[email protected]0877e3d2009-10-17 22:29:576373 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6374 EXPECT_TRUE(response->headers.get() == NULL);
[email protected]34f40942010-10-04 00:34:046375 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:086376 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:576377 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:066378}
6379
[email protected]bacff652009-03-31 17:50:336380// Test HTTPS connections to a site with a bad certificate
[email protected]23e482282013-06-14 16:08:026381TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:336382 HttpRequestInfo request;
6383 request.method = "GET";
bncce36dca22015-04-21 22:11:236384 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:336385 request.load_flags = 0;
6386
mmenke6b3af6e2015-09-12 02:06:066387 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276388 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416389 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276390
[email protected]bacff652009-03-31 17:50:336391 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236392 MockWrite(
6393 "GET / HTTP/1.1\r\n"
6394 "Host: www.example.org\r\n"
6395 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:336396 };
6397
6398 MockRead data_reads[] = {
6399 MockRead("HTTP/1.0 200 OK\r\n"),
6400 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6401 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066402 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:336403 };
6404
[email protected]5ecc992a42009-11-11 01:41:596405 StaticSocketDataProvider ssl_bad_certificate;
[email protected]31a2bfe2010-02-09 08:03:396406 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6407 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066408 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
6409 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:336410
[email protected]bb88e1d32013-05-03 23:11:076411 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
6412 session_deps_.socket_factory->AddSocketDataProvider(&data);
6413 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
6414 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:336415
[email protected]49639fa2011-12-20 23:22:416416 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:336417
[email protected]49639fa2011-12-20 23:22:416418 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:336419 EXPECT_EQ(ERR_IO_PENDING, rv);
6420
6421 rv = callback.WaitForResult();
6422 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
6423
[email protected]49639fa2011-12-20 23:22:416424 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:336425 EXPECT_EQ(ERR_IO_PENDING, rv);
6426
6427 rv = callback.WaitForResult();
6428 EXPECT_EQ(OK, rv);
6429
6430 const HttpResponseInfo* response = trans->GetResponseInfo();
6431
[email protected]fe2255a2011-09-20 19:37:506432 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:336433 EXPECT_EQ(100, response->headers->GetContentLength());
6434}
6435
6436// Test HTTPS connections to a site with a bad certificate, going through a
6437// proxy
[email protected]23e482282013-06-14 16:08:026438TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
[email protected]bb88e1d32013-05-03 23:11:076439 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]bacff652009-03-31 17:50:336440
6441 HttpRequestInfo request;
6442 request.method = "GET";
bncce36dca22015-04-21 22:11:236443 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:336444 request.load_flags = 0;
6445
6446 MockWrite proxy_writes[] = {
bncce36dca22015-04-21 22:11:236447 MockWrite(
6448 "CONNECT www.example.org:443 HTTP/1.1\r\n"
6449 "Host: www.example.org\r\n"
6450 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:336451 };
6452
6453 MockRead proxy_reads[] = {
6454 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066455 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:336456 };
6457
6458 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236459 MockWrite(
6460 "CONNECT www.example.org:443 HTTP/1.1\r\n"
6461 "Host: www.example.org\r\n"
6462 "Proxy-Connection: keep-alive\r\n\r\n"),
6463 MockWrite(
6464 "GET / HTTP/1.1\r\n"
6465 "Host: www.example.org\r\n"
6466 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:336467 };
6468
6469 MockRead data_reads[] = {
6470 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
6471 MockRead("HTTP/1.0 200 OK\r\n"),
6472 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6473 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066474 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:336475 };
6476
[email protected]31a2bfe2010-02-09 08:03:396477 StaticSocketDataProvider ssl_bad_certificate(
6478 proxy_reads, arraysize(proxy_reads),
6479 proxy_writes, arraysize(proxy_writes));
6480 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6481 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066482 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
6483 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:336484
[email protected]bb88e1d32013-05-03 23:11:076485 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
6486 session_deps_.socket_factory->AddSocketDataProvider(&data);
6487 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
6488 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:336489
[email protected]49639fa2011-12-20 23:22:416490 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:336491
6492 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:076493 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:336494
mmenke6b3af6e2015-09-12 02:06:066495 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:406496 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416497 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bacff652009-03-31 17:50:336498
[email protected]49639fa2011-12-20 23:22:416499 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:336500 EXPECT_EQ(ERR_IO_PENDING, rv);
6501
6502 rv = callback.WaitForResult();
6503 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
6504
[email protected]49639fa2011-12-20 23:22:416505 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:336506 EXPECT_EQ(ERR_IO_PENDING, rv);
6507
6508 rv = callback.WaitForResult();
6509 EXPECT_EQ(OK, rv);
6510
6511 const HttpResponseInfo* response = trans->GetResponseInfo();
6512
[email protected]fe2255a2011-09-20 19:37:506513 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:336514 EXPECT_EQ(100, response->headers->GetContentLength());
6515 }
6516}
6517
[email protected]2df19bb2010-08-25 20:13:466518
6519// Test HTTPS connections to a site, going through an HTTPS proxy
[email protected]23e482282013-06-14 16:08:026520TEST_P(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076521 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206522 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
vishal.b62985ca92015-04-17 08:45:516523 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076524 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:466525
6526 HttpRequestInfo request;
6527 request.method = "GET";
bncce36dca22015-04-21 22:11:236528 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:466529 request.load_flags = 0;
6530
6531 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236532 MockWrite(
6533 "CONNECT www.example.org:443 HTTP/1.1\r\n"
6534 "Host: www.example.org\r\n"
6535 "Proxy-Connection: keep-alive\r\n\r\n"),
6536 MockWrite(
6537 "GET / HTTP/1.1\r\n"
6538 "Host: www.example.org\r\n"
6539 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:466540 };
6541
6542 MockRead data_reads[] = {
6543 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
6544 MockRead("HTTP/1.1 200 OK\r\n"),
6545 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6546 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066547 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:466548 };
6549
6550 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6551 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066552 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
6553 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:466554
[email protected]bb88e1d32013-05-03 23:11:076555 session_deps_.socket_factory->AddSocketDataProvider(&data);
6556 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
6557 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:466558
[email protected]49639fa2011-12-20 23:22:416559 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:466560
mmenke6b3af6e2015-09-12 02:06:066561 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:466562 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416563 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2df19bb2010-08-25 20:13:466564
[email protected]49639fa2011-12-20 23:22:416565 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:466566 EXPECT_EQ(ERR_IO_PENDING, rv);
6567
6568 rv = callback.WaitForResult();
6569 EXPECT_EQ(OK, rv);
6570 const HttpResponseInfo* response = trans->GetResponseInfo();
6571
[email protected]fe2255a2011-09-20 19:37:506572 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:466573
6574 EXPECT_TRUE(response->headers->IsKeepAlive());
6575 EXPECT_EQ(200, response->headers->response_code());
6576 EXPECT_EQ(100, response->headers->GetContentLength());
6577 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:206578
6579 LoadTimingInfo load_timing_info;
6580 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6581 TestLoadTimingNotReusedWithPac(load_timing_info,
6582 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:466583}
6584
[email protected]511f6f52010-12-17 03:58:296585// Test an HTTPS Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:026586TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076587 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206588 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
vishal.b62985ca92015-04-17 08:45:516589 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076590 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:296591
6592 HttpRequestInfo request;
6593 request.method = "GET";
bncce36dca22015-04-21 22:11:236594 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:296595 request.load_flags = 0;
6596
6597 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236598 MockWrite(
6599 "CONNECT www.example.org:443 HTTP/1.1\r\n"
6600 "Host: www.example.org\r\n"
6601 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:296602 };
6603
6604 MockRead data_reads[] = {
6605 MockRead("HTTP/1.1 302 Redirect\r\n"),
6606 MockRead("Location: http://login.example.com/\r\n"),
6607 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066608 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:296609 };
6610
6611 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6612 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066613 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:296614
[email protected]bb88e1d32013-05-03 23:11:076615 session_deps_.socket_factory->AddSocketDataProvider(&data);
6616 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296617
[email protected]49639fa2011-12-20 23:22:416618 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296619
mmenke6b3af6e2015-09-12 02:06:066620 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296621 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416622 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:296623
[email protected]49639fa2011-12-20 23:22:416624 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296625 EXPECT_EQ(ERR_IO_PENDING, rv);
6626
6627 rv = callback.WaitForResult();
6628 EXPECT_EQ(OK, rv);
6629 const HttpResponseInfo* response = trans->GetResponseInfo();
6630
[email protected]fe2255a2011-09-20 19:37:506631 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:296632
6633 EXPECT_EQ(302, response->headers->response_code());
6634 std::string url;
6635 EXPECT_TRUE(response->headers->IsRedirect(&url));
6636 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:206637
6638 // In the case of redirects from proxies, HttpNetworkTransaction returns
6639 // timing for the proxy connection instead of the connection to the host,
6640 // and no send / receive times.
6641 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
6642 LoadTimingInfo load_timing_info;
6643 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6644
6645 EXPECT_FALSE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:296646 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:206647
6648 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
6649 EXPECT_LE(load_timing_info.proxy_resolve_start,
6650 load_timing_info.proxy_resolve_end);
6651 EXPECT_LE(load_timing_info.proxy_resolve_end,
6652 load_timing_info.connect_timing.connect_start);
6653 ExpectConnectTimingHasTimes(
6654 load_timing_info.connect_timing,
6655 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
6656
6657 EXPECT_TRUE(load_timing_info.send_start.is_null());
6658 EXPECT_TRUE(load_timing_info.send_end.is_null());
6659 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:296660}
6661
6662// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:026663TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
[email protected]bb88e1d32013-05-03 23:11:076664 session_deps_.proxy_service.reset(
[email protected]511f6f52010-12-17 03:58:296665 ProxyService::CreateFixed("https://proxy:70"));
6666
6667 HttpRequestInfo request;
6668 request.method = "GET";
bncce36dca22015-04-21 22:11:236669 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:296670 request.load_flags = 0;
6671
lgarrona91df87f2014-12-05 00:51:346672 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:236673 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]c10b20852013-05-15 21:29:206674 scoped_ptr<SpdyFrame> goaway(
6675 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:296676 MockWrite data_writes[] = {
rch8e6c6c42015-05-01 14:05:136677 CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
6678 CreateMockWrite(*goaway.get(), 2, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:296679 };
6680
6681 static const char* const kExtraHeaders[] = {
6682 "location",
6683 "http://login.example.com/",
6684 };
[email protected]ff98d7f02012-03-22 21:44:196685 scoped_ptr<SpdyFrame> resp(
[email protected]23e482282013-06-14 16:08:026686 spdy_util_.ConstructSpdySynReplyError("302 Redirect", kExtraHeaders,
[email protected]511f6f52010-12-17 03:58:296687 arraysize(kExtraHeaders)/2, 1));
6688 MockRead data_reads[] = {
rch8e6c6c42015-05-01 14:05:136689 CreateMockRead(*resp.get(), 1), MockRead(ASYNC, 0, 3), // EOF
[email protected]511f6f52010-12-17 03:58:296690 };
6691
rch8e6c6c42015-05-01 14:05:136692 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
6693 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066694 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]23e482282013-06-14 16:08:026695 proxy_ssl.SetNextProto(GetParam());
[email protected]511f6f52010-12-17 03:58:296696
[email protected]bb88e1d32013-05-03 23:11:076697 session_deps_.socket_factory->AddSocketDataProvider(&data);
6698 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296699
[email protected]49639fa2011-12-20 23:22:416700 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296701
mmenke6b3af6e2015-09-12 02:06:066702 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296703 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416704 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:296705
[email protected]49639fa2011-12-20 23:22:416706 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296707 EXPECT_EQ(ERR_IO_PENDING, rv);
6708
6709 rv = callback.WaitForResult();
6710 EXPECT_EQ(OK, rv);
6711 const HttpResponseInfo* response = trans->GetResponseInfo();
6712
[email protected]fe2255a2011-09-20 19:37:506713 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:296714
6715 EXPECT_EQ(302, response->headers->response_code());
6716 std::string url;
6717 EXPECT_TRUE(response->headers->IsRedirect(&url));
6718 EXPECT_EQ("http://login.example.com/", url);
6719}
6720
[email protected]4eddbc732012-08-09 05:40:176721// Test that an HTTPS proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:026722TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:176723 ErrorResponseToHttpsConnectViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076724 session_deps_.proxy_service.reset(
[email protected]511f6f52010-12-17 03:58:296725 ProxyService::CreateFixed("https://proxy:70"));
6726
6727 HttpRequestInfo request;
6728 request.method = "GET";
bncce36dca22015-04-21 22:11:236729 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:296730 request.load_flags = 0;
6731
6732 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236733 MockWrite(
6734 "CONNECT www.example.org:443 HTTP/1.1\r\n"
6735 "Host: www.example.org\r\n"
6736 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:296737 };
6738
6739 MockRead data_reads[] = {
6740 MockRead("HTTP/1.1 404 Not Found\r\n"),
6741 MockRead("Content-Length: 23\r\n\r\n"),
6742 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:066743 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:296744 };
6745
6746 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6747 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066748 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:296749
[email protected]bb88e1d32013-05-03 23:11:076750 session_deps_.socket_factory->AddSocketDataProvider(&data);
6751 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296752
[email protected]49639fa2011-12-20 23:22:416753 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296754
mmenke6b3af6e2015-09-12 02:06:066755 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296756 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416757 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:296758
[email protected]49639fa2011-12-20 23:22:416759 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296760 EXPECT_EQ(ERR_IO_PENDING, rv);
6761
6762 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:176763 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:296764
[email protected]4eddbc732012-08-09 05:40:176765 // TODO(ttuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:296766}
6767
[email protected]4eddbc732012-08-09 05:40:176768// Test that a SPDY proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:026769TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:176770 ErrorResponseToHttpsConnectViaSpdyProxy) {
[email protected]bb88e1d32013-05-03 23:11:076771 session_deps_.proxy_service.reset(
6772 ProxyService::CreateFixed("https://proxy:70"));
[email protected]511f6f52010-12-17 03:58:296773
6774 HttpRequestInfo request;
6775 request.method = "GET";
bncce36dca22015-04-21 22:11:236776 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:296777 request.load_flags = 0;
6778
lgarrona91df87f2014-12-05 00:51:346779 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:236780 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]c10b20852013-05-15 21:29:206781 scoped_ptr<SpdyFrame> rst(
6782 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:296783 MockWrite data_writes[] = {
rch8e6c6c42015-05-01 14:05:136784 CreateMockWrite(*conn.get(), 0), CreateMockWrite(*rst.get(), 3),
[email protected]511f6f52010-12-17 03:58:296785 };
6786
6787 static const char* const kExtraHeaders[] = {
6788 "location",
6789 "http://login.example.com/",
6790 };
[email protected]ff98d7f02012-03-22 21:44:196791 scoped_ptr<SpdyFrame> resp(
[email protected]23e482282013-06-14 16:08:026792 spdy_util_.ConstructSpdySynReplyError("404 Not Found", kExtraHeaders,
[email protected]511f6f52010-12-17 03:58:296793 arraysize(kExtraHeaders)/2, 1));
[email protected]ff98d7f02012-03-22 21:44:196794 scoped_ptr<SpdyFrame> body(
[email protected]23e482282013-06-14 16:08:026795 spdy_util_.ConstructSpdyBodyFrame(
6796 1, "The host does not exist", 23, true));
[email protected]511f6f52010-12-17 03:58:296797 MockRead data_reads[] = {
rch8e6c6c42015-05-01 14:05:136798 CreateMockRead(*resp.get(), 1),
6799 CreateMockRead(*body.get(), 2),
6800 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:296801 };
6802
rch8e6c6c42015-05-01 14:05:136803 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
6804 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066805 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]23e482282013-06-14 16:08:026806 proxy_ssl.SetNextProto(GetParam());
[email protected]511f6f52010-12-17 03:58:296807
[email protected]bb88e1d32013-05-03 23:11:076808 session_deps_.socket_factory->AddSocketDataProvider(&data);
6809 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296810
[email protected]49639fa2011-12-20 23:22:416811 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296812
mmenke6b3af6e2015-09-12 02:06:066813 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296814 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416815 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:296816
[email protected]49639fa2011-12-20 23:22:416817 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296818 EXPECT_EQ(ERR_IO_PENDING, rv);
6819
6820 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:176821 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:296822
[email protected]4eddbc732012-08-09 05:40:176823 // TODO(ttuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:296824}
6825
[email protected]0c5fb722012-02-28 11:50:356826// Test the request-challenge-retry sequence for basic auth, through
6827// a SPDY proxy over a single SPDY session.
[email protected]23e482282013-06-14 16:08:026828TEST_P(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:356829 HttpRequestInfo request;
6830 request.method = "GET";
bncce36dca22015-04-21 22:11:236831 request.url = GURL("https://www.example.org/");
[email protected]0c5fb722012-02-28 11:50:356832 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:296833 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]0c5fb722012-02-28 11:50:356834
6835 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076836 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206837 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
vishal.b62985ca92015-04-17 08:45:516838 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076839 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:066840 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:356841
6842 // Since we have proxy, should try to establish tunnel.
lgarrona91df87f2014-12-05 00:51:346843 scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:236844 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]c10b20852013-05-15 21:29:206845 scoped_ptr<SpdyFrame> rst(
6846 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]0c5fb722012-02-28 11:50:356847
6848 // After calling trans->RestartWithAuth(), this is the request we should
6849 // be issuing -- the final header line contains the credentials.
6850 const char* const kAuthCredentials[] = {
6851 "proxy-authorization", "Basic Zm9vOmJhcg==",
6852 };
[email protected]fba2dbde2013-05-24 16:09:016853 scoped_ptr<SpdyFrame> connect2(spdy_util_.ConstructSpdyConnect(
lgarrona91df87f2014-12-05 00:51:346854 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST,
bncce36dca22015-04-21 22:11:236855 HostPortPair("www.example.org", 443)));
6856 // fetch https://www.example.org/ via HTTP
6857 const char get[] =
6858 "GET / HTTP/1.1\r\n"
6859 "Host: www.example.org\r\n"
6860 "Connection: keep-alive\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:196861 scoped_ptr<SpdyFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:026862 spdy_util_.ConstructSpdyBodyFrame(3, get, strlen(get), false));
[email protected]0c5fb722012-02-28 11:50:356863
6864 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:136865 CreateMockWrite(*req, 0, ASYNC),
6866 CreateMockWrite(*rst, 2, ASYNC),
6867 CreateMockWrite(*connect2, 3),
6868 CreateMockWrite(*wrapped_get, 5),
[email protected]0c5fb722012-02-28 11:50:356869 };
6870
6871 // The proxy responds to the connect with a 407, using a persistent
6872 // connection.
thestig9d3bb0c2015-01-24 00:49:516873 const char kAuthStatus[] = "407";
[email protected]0c5fb722012-02-28 11:50:356874 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:356875 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
6876 };
[email protected]745aa9c2014-06-27 02:21:296877 scoped_ptr<SpdyFrame> conn_auth_resp(spdy_util_.ConstructSpdySynReplyError(
6878 kAuthStatus, kAuthChallenge, arraysize(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:356879
[email protected]23e482282013-06-14 16:08:026880 scoped_ptr<SpdyFrame> conn_resp(
6881 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:356882 const char resp[] = "HTTP/1.1 200 OK\r\n"
6883 "Content-Length: 5\r\n\r\n";
6884
[email protected]ff98d7f02012-03-22 21:44:196885 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:026886 spdy_util_.ConstructSpdyBodyFrame(3, resp, strlen(resp), false));
[email protected]ff98d7f02012-03-22 21:44:196887 scoped_ptr<SpdyFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:026888 spdy_util_.ConstructSpdyBodyFrame(3, "hello", 5, false));
[email protected]0c5fb722012-02-28 11:50:356889 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:136890 CreateMockRead(*conn_auth_resp, 1, ASYNC),
6891 CreateMockRead(*conn_resp, 4, ASYNC),
6892 CreateMockRead(*wrapped_get_resp, 6, ASYNC),
6893 CreateMockRead(*wrapped_body, 7, ASYNC),
6894 MockRead(ASYNC, OK, 8), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:356895 };
6896
rch8e6c6c42015-05-01 14:05:136897 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
6898 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:076899 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:356900 // Negotiate SPDY to the proxy
6901 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:026902 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:076903 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:356904 // Vanilla SSL to the server
6905 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076906 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:356907
6908 TestCompletionCallback callback1;
6909
[email protected]262eec82013-03-19 21:01:366910 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506911 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0c5fb722012-02-28 11:50:356912
6913 int rv = trans->Start(&request, callback1.callback(), log.bound());
6914 EXPECT_EQ(ERR_IO_PENDING, rv);
6915
6916 rv = callback1.WaitForResult();
6917 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:466918 TestNetLogEntry::List entries;
[email protected]0c5fb722012-02-28 11:50:356919 log.GetEntries(&entries);
6920 size_t pos = ExpectLogContainsSomewhere(
6921 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
6922 NetLog::PHASE_NONE);
6923 ExpectLogContainsSomewhere(
6924 entries, pos,
6925 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
6926 NetLog::PHASE_NONE);
6927
6928 const HttpResponseInfo* response = trans->GetResponseInfo();
6929 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:506930 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]0c5fb722012-02-28 11:50:356931 EXPECT_EQ(407, response->headers->response_code());
6932 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6933 EXPECT_TRUE(response->auth_challenge.get() != NULL);
6934 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
6935
6936 TestCompletionCallback callback2;
6937
6938 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
6939 callback2.callback());
6940 EXPECT_EQ(ERR_IO_PENDING, rv);
6941
6942 rv = callback2.WaitForResult();
6943 EXPECT_EQ(OK, rv);
6944
6945 response = trans->GetResponseInfo();
6946 ASSERT_TRUE(response != NULL);
6947
6948 EXPECT_TRUE(response->headers->IsKeepAlive());
6949 EXPECT_EQ(200, response->headers->response_code());
6950 EXPECT_EQ(5, response->headers->GetContentLength());
6951 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6952
6953 // The password prompt info should not be set.
6954 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6955
[email protected]029c83b62013-01-24 05:28:206956 LoadTimingInfo load_timing_info;
6957 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6958 TestLoadTimingNotReusedWithPac(load_timing_info,
6959 CONNECT_TIMING_HAS_SSL_TIMES);
6960
[email protected]0c5fb722012-02-28 11:50:356961 trans.reset();
6962 session->CloseAllConnections();
6963}
6964
[email protected]7c6f7ba2012-04-03 04:09:296965// Test that an explicitly trusted SPDY proxy can push a resource from an
6966// origin that is different from that of its associated resource.
[email protected]23e482282013-06-14 16:08:026967TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPush) {
[email protected]7c6f7ba2012-04-03 04:09:296968 HttpRequestInfo request;
6969 HttpRequestInfo push_request;
6970
[email protected]7c6f7ba2012-04-03 04:09:296971 request.method = "GET";
bncce36dca22015-04-21 22:11:236972 request.url = GURL("http://www.example.org/");
[email protected]7c6f7ba2012-04-03 04:09:296973 push_request.method = "GET";
6974 push_request.url = GURL("http://www.another-origin.com/foo.dat");
6975
[email protected]7c6f7ba2012-04-03 04:09:296976 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076977 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206978 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
vishal.b62985ca92015-04-17 08:45:516979 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076980 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:506981
6982 // Enable cross-origin push.
[email protected]bb88e1d32013-05-03 23:11:076983 session_deps_.trusted_spdy_proxy = "myproxy:70";
[email protected]61b4efc2012-04-27 18:12:506984
mmenke6b3af6e2015-09-12 02:06:066985 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:296986
[email protected]cdf8f7e72013-05-23 10:56:466987 scoped_ptr<SpdyFrame> stream1_syn(
6988 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]7c6f7ba2012-04-03 04:09:296989
6990 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:136991 CreateMockWrite(*stream1_syn, 0, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:296992 };
6993
6994 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026995 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:296996
6997 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026998 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:296999
7000 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:027001 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
[email protected]7c6f7ba2012-04-03 04:09:297002 0,
7003 2,
7004 1,
7005 "http://www.another-origin.com/foo.dat"));
[email protected]8a0fc822013-06-27 20:52:437006 const char kPushedData[] = "pushed";
7007 scoped_ptr<SpdyFrame> stream2_body(
7008 spdy_util_.ConstructSpdyBodyFrame(
7009 2, kPushedData, strlen(kPushedData), true));
[email protected]7c6f7ba2012-04-03 04:09:297010
7011 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:137012 CreateMockRead(*stream1_reply, 1, ASYNC),
7013 CreateMockRead(*stream2_syn, 2, ASYNC),
7014 CreateMockRead(*stream1_body, 3, ASYNC),
7015 CreateMockRead(*stream2_body, 4, ASYNC),
7016 MockRead(ASYNC, ERR_IO_PENDING, 5), // Force a pause
[email protected]7c6f7ba2012-04-03 04:09:297017 };
7018
rch8e6c6c42015-05-01 14:05:137019 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
7020 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:077021 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:297022 // Negotiate SPDY to the proxy
7023 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:027024 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:077025 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:297026
[email protected]262eec82013-03-19 21:01:367027 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507028 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7c6f7ba2012-04-03 04:09:297029 TestCompletionCallback callback;
7030 int rv = trans->Start(&request, callback.callback(), log.bound());
7031 EXPECT_EQ(ERR_IO_PENDING, rv);
7032
7033 rv = callback.WaitForResult();
7034 EXPECT_EQ(OK, rv);
7035 const HttpResponseInfo* response = trans->GetResponseInfo();
7036
[email protected]262eec82013-03-19 21:01:367037 scoped_ptr<HttpTransaction> push_trans(
[email protected]90499482013-06-01 00:39:507038 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
7039 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
[email protected]7c6f7ba2012-04-03 04:09:297040 EXPECT_EQ(ERR_IO_PENDING, rv);
7041
7042 rv = callback.WaitForResult();
7043 EXPECT_EQ(OK, rv);
7044 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
7045
7046 ASSERT_TRUE(response != NULL);
7047 EXPECT_TRUE(response->headers->IsKeepAlive());
7048
7049 EXPECT_EQ(200, response->headers->response_code());
7050 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
7051
7052 std::string response_data;
7053 rv = ReadTransaction(trans.get(), &response_data);
7054 EXPECT_EQ(OK, rv);
7055 EXPECT_EQ("hello!", response_data);
7056
[email protected]029c83b62013-01-24 05:28:207057 LoadTimingInfo load_timing_info;
7058 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7059 TestLoadTimingNotReusedWithPac(load_timing_info,
7060 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7061
[email protected]7c6f7ba2012-04-03 04:09:297062 // Verify the pushed stream.
[email protected]90499482013-06-01 00:39:507063 EXPECT_TRUE(push_response->headers.get() != NULL);
[email protected]7c6f7ba2012-04-03 04:09:297064 EXPECT_EQ(200, push_response->headers->response_code());
7065
7066 rv = ReadTransaction(push_trans.get(), &response_data);
7067 EXPECT_EQ(OK, rv);
7068 EXPECT_EQ("pushed", response_data);
7069
[email protected]029c83b62013-01-24 05:28:207070 LoadTimingInfo push_load_timing_info;
7071 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
7072 TestLoadTimingReusedWithPac(push_load_timing_info);
7073 // The transactions should share a socket ID, despite being for different
7074 // origins.
7075 EXPECT_EQ(load_timing_info.socket_log_id,
7076 push_load_timing_info.socket_log_id);
7077
[email protected]7c6f7ba2012-04-03 04:09:297078 trans.reset();
7079 push_trans.reset();
7080 session->CloseAllConnections();
7081}
7082
[email protected]8c843192012-04-05 07:15:007083// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
[email protected]23e482282013-06-14 16:08:027084TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
[email protected]8c843192012-04-05 07:15:007085 HttpRequestInfo request;
7086
7087 request.method = "GET";
bncce36dca22015-04-21 22:11:237088 request.url = GURL("http://www.example.org/");
[email protected]8c843192012-04-05 07:15:007089
[email protected]8c843192012-04-05 07:15:007090 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:077091 session_deps_.proxy_service.reset(
[email protected]8c843192012-04-05 07:15:007092 ProxyService::CreateFixed("https://myproxy:70"));
vishal.b62985ca92015-04-17 08:45:517093 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:077094 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:507095
7096 // Enable cross-origin push.
[email protected]bb88e1d32013-05-03 23:11:077097 session_deps_.trusted_spdy_proxy = "myproxy:70";
[email protected]61b4efc2012-04-27 18:12:507098
mmenke6b3af6e2015-09-12 02:06:067099 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:007100
[email protected]cdf8f7e72013-05-23 10:56:467101 scoped_ptr<SpdyFrame> stream1_syn(
7102 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]8c843192012-04-05 07:15:007103
7104 scoped_ptr<SpdyFrame> push_rst(
[email protected]c10b20852013-05-15 21:29:207105 spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:007106
7107 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:137108 CreateMockWrite(*stream1_syn, 0, ASYNC), CreateMockWrite(*push_rst, 3),
[email protected]8c843192012-04-05 07:15:007109 };
7110
7111 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:027112 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:007113
7114 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:027115 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8c843192012-04-05 07:15:007116
7117 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:027118 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
[email protected]8c843192012-04-05 07:15:007119 0,
7120 2,
7121 1,
7122 "https://www.another-origin.com/foo.dat"));
7123
7124 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:137125 CreateMockRead(*stream1_reply, 1, ASYNC),
7126 CreateMockRead(*stream2_syn, 2, ASYNC),
7127 CreateMockRead(*stream1_body, 4, ASYNC),
7128 MockRead(ASYNC, ERR_IO_PENDING, 5), // Force a pause
[email protected]8c843192012-04-05 07:15:007129 };
7130
rch8e6c6c42015-05-01 14:05:137131 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
7132 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:077133 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:007134 // Negotiate SPDY to the proxy
7135 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:027136 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:077137 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:007138
[email protected]262eec82013-03-19 21:01:367139 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507140 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c843192012-04-05 07:15:007141 TestCompletionCallback callback;
7142 int rv = trans->Start(&request, callback.callback(), log.bound());
7143 EXPECT_EQ(ERR_IO_PENDING, rv);
7144
7145 rv = callback.WaitForResult();
7146 EXPECT_EQ(OK, rv);
7147 const HttpResponseInfo* response = trans->GetResponseInfo();
7148
7149 ASSERT_TRUE(response != NULL);
7150 EXPECT_TRUE(response->headers->IsKeepAlive());
7151
7152 EXPECT_EQ(200, response->headers->response_code());
7153 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
7154
7155 std::string response_data;
7156 rv = ReadTransaction(trans.get(), &response_data);
7157 EXPECT_EQ(OK, rv);
7158 EXPECT_EQ("hello!", response_data);
7159
7160 trans.reset();
7161 session->CloseAllConnections();
7162}
7163
[email protected]2df19bb2010-08-25 20:13:467164// Test HTTPS connections to a site with a bad certificate, going through an
7165// HTTPS proxy
[email protected]23e482282013-06-14 16:08:027166TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:077167 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:117168 "https://proxy:70"));
[email protected]2df19bb2010-08-25 20:13:467169
7170 HttpRequestInfo request;
7171 request.method = "GET";
bncce36dca22015-04-21 22:11:237172 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:467173 request.load_flags = 0;
7174
7175 // Attempt to fetch the URL from a server with a bad cert
7176 MockWrite bad_cert_writes[] = {
bncce36dca22015-04-21 22:11:237177 MockWrite(
7178 "CONNECT www.example.org:443 HTTP/1.1\r\n"
7179 "Host: www.example.org\r\n"
7180 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:467181 };
7182
7183 MockRead bad_cert_reads[] = {
7184 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067185 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:467186 };
7187
7188 // Attempt to fetch the URL with a good cert
7189 MockWrite good_data_writes[] = {
bncce36dca22015-04-21 22:11:237190 MockWrite(
7191 "CONNECT www.example.org:443 HTTP/1.1\r\n"
7192 "Host: www.example.org\r\n"
7193 "Proxy-Connection: keep-alive\r\n\r\n"),
7194 MockWrite(
7195 "GET / HTTP/1.1\r\n"
7196 "Host: www.example.org\r\n"
7197 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:467198 };
7199
7200 MockRead good_cert_reads[] = {
7201 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
7202 MockRead("HTTP/1.0 200 OK\r\n"),
7203 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7204 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067205 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:467206 };
7207
7208 StaticSocketDataProvider ssl_bad_certificate(
7209 bad_cert_reads, arraysize(bad_cert_reads),
7210 bad_cert_writes, arraysize(bad_cert_writes));
7211 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
7212 good_data_writes, arraysize(good_data_writes));
[email protected]8ddf8322012-02-23 18:08:067213 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
7214 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:467215
7216 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:077217 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7218 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
7219 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:467220
7221 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:077222 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7223 session_deps_.socket_factory->AddSocketDataProvider(&data);
7224 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:467225
[email protected]49639fa2011-12-20 23:22:417226 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:467227
mmenke6b3af6e2015-09-12 02:06:067228 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:467229 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417230 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2df19bb2010-08-25 20:13:467231
[email protected]49639fa2011-12-20 23:22:417232 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:467233 EXPECT_EQ(ERR_IO_PENDING, rv);
7234
7235 rv = callback.WaitForResult();
7236 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
7237
[email protected]49639fa2011-12-20 23:22:417238 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]2df19bb2010-08-25 20:13:467239 EXPECT_EQ(ERR_IO_PENDING, rv);
7240
7241 rv = callback.WaitForResult();
7242 EXPECT_EQ(OK, rv);
7243
7244 const HttpResponseInfo* response = trans->GetResponseInfo();
7245
[email protected]fe2255a2011-09-20 19:37:507246 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:467247 EXPECT_EQ(100, response->headers->GetContentLength());
7248}
7249
[email protected]23e482282013-06-14 16:08:027250TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:427251 HttpRequestInfo request;
7252 request.method = "GET";
bncce36dca22015-04-21 22:11:237253 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:437254 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
7255 "Chromium Ultra Awesome X Edition");
[email protected]1c773ea12009-04-28 19:58:427256
mmenke6b3af6e2015-09-12 02:06:067257 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277258 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417259 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277260
[email protected]1c773ea12009-04-28 19:58:427261 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237262 MockWrite(
7263 "GET / HTTP/1.1\r\n"
7264 "Host: www.example.org\r\n"
7265 "Connection: keep-alive\r\n"
7266 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427267 };
7268
7269 // Lastly, the server responds with the actual content.
7270 MockRead data_reads[] = {
7271 MockRead("HTTP/1.0 200 OK\r\n"),
7272 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7273 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067274 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427275 };
7276
[email protected]31a2bfe2010-02-09 08:03:397277 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7278 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077279 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427280
[email protected]49639fa2011-12-20 23:22:417281 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427282
[email protected]49639fa2011-12-20 23:22:417283 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427284 EXPECT_EQ(ERR_IO_PENDING, rv);
7285
7286 rv = callback.WaitForResult();
7287 EXPECT_EQ(OK, rv);
7288}
7289
[email protected]23e482282013-06-14 16:08:027290TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:297291 HttpRequestInfo request;
7292 request.method = "GET";
bncce36dca22015-04-21 22:11:237293 request.url = GURL("https://www.example.org/");
[email protected]da81f132010-08-18 23:39:297294 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
7295 "Chromium Ultra Awesome X Edition");
7296
[email protected]bb88e1d32013-05-03 23:11:077297 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
mmenke6b3af6e2015-09-12 02:06:067298 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277299 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417300 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277301
[email protected]da81f132010-08-18 23:39:297302 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237303 MockWrite(
7304 "CONNECT www.example.org:443 HTTP/1.1\r\n"
7305 "Host: www.example.org\r\n"
7306 "Proxy-Connection: keep-alive\r\n"
7307 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]da81f132010-08-18 23:39:297308 };
7309 MockRead data_reads[] = {
7310 // Return an error, so the transaction stops here (this test isn't
7311 // interested in the rest).
7312 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
7313 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7314 MockRead("Proxy-Connection: close\r\n\r\n"),
7315 };
7316
7317 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7318 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077319 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:297320
[email protected]49639fa2011-12-20 23:22:417321 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:297322
[email protected]49639fa2011-12-20 23:22:417323 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]da81f132010-08-18 23:39:297324 EXPECT_EQ(ERR_IO_PENDING, rv);
7325
7326 rv = callback.WaitForResult();
7327 EXPECT_EQ(OK, rv);
7328}
7329
[email protected]23e482282013-06-14 16:08:027330TEST_P(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:427331 HttpRequestInfo request;
7332 request.method = "GET";
bncce36dca22015-04-21 22:11:237333 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427334 request.load_flags = 0;
[email protected]c10450102011-06-27 09:06:167335 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
7336 "http://the.previous.site.com/");
[email protected]1c773ea12009-04-28 19:58:427337
mmenke6b3af6e2015-09-12 02:06:067338 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277339 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417340 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277341
[email protected]1c773ea12009-04-28 19:58:427342 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237343 MockWrite(
7344 "GET / HTTP/1.1\r\n"
7345 "Host: www.example.org\r\n"
7346 "Connection: keep-alive\r\n"
7347 "Referer: http://the.previous.site.com/\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427348 };
7349
7350 // Lastly, the server responds with the actual content.
7351 MockRead data_reads[] = {
7352 MockRead("HTTP/1.0 200 OK\r\n"),
7353 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7354 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067355 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427356 };
7357
[email protected]31a2bfe2010-02-09 08:03:397358 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7359 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077360 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427361
[email protected]49639fa2011-12-20 23:22:417362 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427363
[email protected]49639fa2011-12-20 23:22:417364 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427365 EXPECT_EQ(ERR_IO_PENDING, rv);
7366
7367 rv = callback.WaitForResult();
7368 EXPECT_EQ(OK, rv);
7369}
7370
[email protected]23e482282013-06-14 16:08:027371TEST_P(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:427372 HttpRequestInfo request;
7373 request.method = "POST";
bncce36dca22015-04-21 22:11:237374 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427375
mmenke6b3af6e2015-09-12 02:06:067376 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277377 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417378 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277379
[email protected]1c773ea12009-04-28 19:58:427380 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237381 MockWrite(
7382 "POST / HTTP/1.1\r\n"
7383 "Host: www.example.org\r\n"
7384 "Connection: keep-alive\r\n"
7385 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427386 };
7387
7388 // Lastly, the server responds with the actual content.
7389 MockRead data_reads[] = {
7390 MockRead("HTTP/1.0 200 OK\r\n"),
7391 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7392 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067393 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427394 };
7395
[email protected]31a2bfe2010-02-09 08:03:397396 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7397 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077398 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427399
[email protected]49639fa2011-12-20 23:22:417400 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427401
[email protected]49639fa2011-12-20 23:22:417402 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427403 EXPECT_EQ(ERR_IO_PENDING, rv);
7404
7405 rv = callback.WaitForResult();
7406 EXPECT_EQ(OK, rv);
7407}
7408
[email protected]23e482282013-06-14 16:08:027409TEST_P(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:427410 HttpRequestInfo request;
7411 request.method = "PUT";
bncce36dca22015-04-21 22:11:237412 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427413
mmenke6b3af6e2015-09-12 02:06:067414 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277415 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417416 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277417
[email protected]1c773ea12009-04-28 19:58:427418 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237419 MockWrite(
7420 "PUT / HTTP/1.1\r\n"
7421 "Host: www.example.org\r\n"
7422 "Connection: keep-alive\r\n"
7423 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427424 };
7425
7426 // Lastly, the server responds with the actual content.
7427 MockRead data_reads[] = {
7428 MockRead("HTTP/1.0 200 OK\r\n"),
7429 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7430 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067431 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427432 };
7433
[email protected]31a2bfe2010-02-09 08:03:397434 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7435 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077436 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427437
[email protected]49639fa2011-12-20 23:22:417438 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427439
[email protected]49639fa2011-12-20 23:22:417440 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427441 EXPECT_EQ(ERR_IO_PENDING, rv);
7442
7443 rv = callback.WaitForResult();
7444 EXPECT_EQ(OK, rv);
7445}
7446
[email protected]23e482282013-06-14 16:08:027447TEST_P(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:427448 HttpRequestInfo request;
7449 request.method = "HEAD";
bncce36dca22015-04-21 22:11:237450 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427451
mmenke6b3af6e2015-09-12 02:06:067452 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277453 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417454 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277455
[email protected]1c773ea12009-04-28 19:58:427456 MockWrite data_writes[] = {
csharrisonf473dd192015-08-18 13:54:137457 MockWrite("HEAD / HTTP/1.1\r\n"
7458 "Host: www.example.org\r\n"
7459 "Connection: keep-alive\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427460 };
7461
7462 // Lastly, the server responds with the actual content.
7463 MockRead data_reads[] = {
7464 MockRead("HTTP/1.0 200 OK\r\n"),
7465 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7466 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067467 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427468 };
7469
[email protected]31a2bfe2010-02-09 08:03:397470 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7471 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077472 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427473
[email protected]49639fa2011-12-20 23:22:417474 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427475
[email protected]49639fa2011-12-20 23:22:417476 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427477 EXPECT_EQ(ERR_IO_PENDING, rv);
7478
7479 rv = callback.WaitForResult();
7480 EXPECT_EQ(OK, rv);
7481}
7482
[email protected]23e482282013-06-14 16:08:027483TEST_P(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:427484 HttpRequestInfo request;
7485 request.method = "GET";
bncce36dca22015-04-21 22:11:237486 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427487 request.load_flags = LOAD_BYPASS_CACHE;
7488
mmenke6b3af6e2015-09-12 02:06:067489 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277490 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417491 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277492
[email protected]1c773ea12009-04-28 19:58:427493 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237494 MockWrite(
7495 "GET / HTTP/1.1\r\n"
7496 "Host: www.example.org\r\n"
7497 "Connection: keep-alive\r\n"
7498 "Pragma: no-cache\r\n"
7499 "Cache-Control: no-cache\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427500 };
7501
7502 // Lastly, the server responds with the actual content.
7503 MockRead data_reads[] = {
7504 MockRead("HTTP/1.0 200 OK\r\n"),
7505 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7506 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067507 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427508 };
7509
[email protected]31a2bfe2010-02-09 08:03:397510 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7511 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077512 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427513
[email protected]49639fa2011-12-20 23:22:417514 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427515
[email protected]49639fa2011-12-20 23:22:417516 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427517 EXPECT_EQ(ERR_IO_PENDING, rv);
7518
7519 rv = callback.WaitForResult();
7520 EXPECT_EQ(OK, rv);
7521}
7522
[email protected]23e482282013-06-14 16:08:027523TEST_P(HttpNetworkTransactionTest,
[email protected]1c773ea12009-04-28 19:58:427524 BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:427525 HttpRequestInfo request;
7526 request.method = "GET";
bncce36dca22015-04-21 22:11:237527 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427528 request.load_flags = LOAD_VALIDATE_CACHE;
7529
mmenke6b3af6e2015-09-12 02:06:067530 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277531 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417532 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277533
[email protected]1c773ea12009-04-28 19:58:427534 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237535 MockWrite(
7536 "GET / HTTP/1.1\r\n"
7537 "Host: www.example.org\r\n"
7538 "Connection: keep-alive\r\n"
7539 "Cache-Control: max-age=0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427540 };
7541
7542 // Lastly, the server responds with the actual content.
7543 MockRead data_reads[] = {
7544 MockRead("HTTP/1.0 200 OK\r\n"),
7545 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7546 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067547 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427548 };
7549
[email protected]31a2bfe2010-02-09 08:03:397550 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7551 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077552 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427553
[email protected]49639fa2011-12-20 23:22:417554 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427555
[email protected]49639fa2011-12-20 23:22:417556 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427557 EXPECT_EQ(ERR_IO_PENDING, rv);
7558
7559 rv = callback.WaitForResult();
7560 EXPECT_EQ(OK, rv);
7561}
7562
[email protected]23e482282013-06-14 16:08:027563TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:427564 HttpRequestInfo request;
7565 request.method = "GET";
bncce36dca22015-04-21 22:11:237566 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:437567 request.extra_headers.SetHeader("FooHeader", "Bar");
[email protected]1c773ea12009-04-28 19:58:427568
mmenke6b3af6e2015-09-12 02:06:067569 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277570 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417571 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277572
[email protected]1c773ea12009-04-28 19:58:427573 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237574 MockWrite(
7575 "GET / HTTP/1.1\r\n"
7576 "Host: www.example.org\r\n"
7577 "Connection: keep-alive\r\n"
7578 "FooHeader: Bar\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427579 };
7580
7581 // Lastly, the server responds with the actual content.
7582 MockRead data_reads[] = {
7583 MockRead("HTTP/1.0 200 OK\r\n"),
7584 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7585 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067586 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427587 };
7588
[email protected]31a2bfe2010-02-09 08:03:397589 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7590 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077591 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427592
[email protected]49639fa2011-12-20 23:22:417593 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427594
[email protected]49639fa2011-12-20 23:22:417595 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427596 EXPECT_EQ(ERR_IO_PENDING, rv);
7597
7598 rv = callback.WaitForResult();
7599 EXPECT_EQ(OK, rv);
7600}
7601
[email protected]23e482282013-06-14 16:08:027602TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:477603 HttpRequestInfo request;
7604 request.method = "GET";
bncce36dca22015-04-21 22:11:237605 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:437606 request.extra_headers.SetHeader("referer", "www.foo.com");
7607 request.extra_headers.SetHeader("hEllo", "Kitty");
7608 request.extra_headers.SetHeader("FoO", "bar");
[email protected]270c6412010-03-29 22:02:477609
mmenke6b3af6e2015-09-12 02:06:067610 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277611 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417612 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277613
[email protected]270c6412010-03-29 22:02:477614 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237615 MockWrite(
7616 "GET / HTTP/1.1\r\n"
7617 "Host: www.example.org\r\n"
7618 "Connection: keep-alive\r\n"
7619 "referer: www.foo.com\r\n"
7620 "hEllo: Kitty\r\n"
7621 "FoO: bar\r\n\r\n"),
[email protected]270c6412010-03-29 22:02:477622 };
7623
7624 // Lastly, the server responds with the actual content.
7625 MockRead data_reads[] = {
7626 MockRead("HTTP/1.0 200 OK\r\n"),
7627 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7628 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067629 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:477630 };
7631
7632 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]270c6412010-03-29 22:02:477635
[email protected]49639fa2011-12-20 23:22:417636 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:477637
[email protected]49639fa2011-12-20 23:22:417638 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]270c6412010-03-29 22:02:477639 EXPECT_EQ(ERR_IO_PENDING, rv);
7640
7641 rv = callback.WaitForResult();
7642 EXPECT_EQ(OK, rv);
7643}
7644
[email protected]23e482282013-06-14 16:08:027645TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277646 HttpRequestInfo request;
7647 request.method = "GET";
bncce36dca22015-04-21 22:11:237648 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:277649 request.load_flags = 0;
7650
[email protected]bb88e1d32013-05-03 23:11:077651 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207652 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
vishal.b62985ca92015-04-17 08:45:517653 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077654 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:027655
mmenke6b3af6e2015-09-12 02:06:067656 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3cd17242009-06-23 02:59:027657 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417658 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3cd17242009-06-23 02:59:027659
[email protected]3cd17242009-06-23 02:59:027660 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
7661 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7662
7663 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237664 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
7665 MockWrite(
7666 "GET / HTTP/1.1\r\n"
7667 "Host: www.example.org\r\n"
7668 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:027669
7670 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:067671 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:027672 MockRead("HTTP/1.0 200 OK\r\n"),
7673 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7674 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067675 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:027676 };
7677
[email protected]31a2bfe2010-02-09 08:03:397678 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7679 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077680 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:027681
[email protected]49639fa2011-12-20 23:22:417682 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:027683
[email protected]49639fa2011-12-20 23:22:417684 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:027685 EXPECT_EQ(ERR_IO_PENDING, rv);
7686
7687 rv = callback.WaitForResult();
7688 EXPECT_EQ(OK, rv);
7689
7690 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507691 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:027692
[email protected]029c83b62013-01-24 05:28:207693 LoadTimingInfo load_timing_info;
7694 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7695 TestLoadTimingNotReusedWithPac(load_timing_info,
7696 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7697
[email protected]3cd17242009-06-23 02:59:027698 std::string response_text;
7699 rv = ReadTransaction(trans.get(), &response_text);
7700 EXPECT_EQ(OK, rv);
7701 EXPECT_EQ("Payload", response_text);
7702}
7703
[email protected]23e482282013-06-14 16:08:027704TEST_P(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277705 HttpRequestInfo request;
7706 request.method = "GET";
bncce36dca22015-04-21 22:11:237707 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:277708 request.load_flags = 0;
7709
[email protected]bb88e1d32013-05-03 23:11:077710 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207711 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
vishal.b62985ca92015-04-17 08:45:517712 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077713 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:027714
mmenke6b3af6e2015-09-12 02:06:067715 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3cd17242009-06-23 02:59:027716 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417717 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3cd17242009-06-23 02:59:027718
[email protected]3cd17242009-06-23 02:59:027719 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
7720 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7721
7722 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237723 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
7724 arraysize(write_buffer)),
7725 MockWrite(
7726 "GET / HTTP/1.1\r\n"
7727 "Host: www.example.org\r\n"
7728 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:027729
7730 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:017731 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
7732 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:357733 MockRead("HTTP/1.0 200 OK\r\n"),
7734 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7735 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067736 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:357737 };
7738
[email protected]31a2bfe2010-02-09 08:03:397739 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7740 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077741 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:357742
[email protected]8ddf8322012-02-23 18:08:067743 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077744 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:357745
[email protected]49639fa2011-12-20 23:22:417746 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:357747
[email protected]49639fa2011-12-20 23:22:417748 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:357749 EXPECT_EQ(ERR_IO_PENDING, rv);
7750
7751 rv = callback.WaitForResult();
7752 EXPECT_EQ(OK, rv);
7753
[email protected]029c83b62013-01-24 05:28:207754 LoadTimingInfo load_timing_info;
7755 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7756 TestLoadTimingNotReusedWithPac(load_timing_info,
7757 CONNECT_TIMING_HAS_SSL_TIMES);
7758
[email protected]e0c27be2009-07-15 13:09:357759 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507760 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:357761
7762 std::string response_text;
7763 rv = ReadTransaction(trans.get(), &response_text);
7764 EXPECT_EQ(OK, rv);
7765 EXPECT_EQ("Payload", response_text);
7766}
7767
[email protected]23e482282013-06-14 16:08:027768TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:207769 HttpRequestInfo request;
7770 request.method = "GET";
bncce36dca22015-04-21 22:11:237771 request.url = GURL("http://www.example.org/");
[email protected]029c83b62013-01-24 05:28:207772 request.load_flags = 0;
7773
[email protected]bb88e1d32013-05-03 23:11:077774 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207775 ProxyService::CreateFixed("socks4://myproxy:1080"));
vishal.b62985ca92015-04-17 08:45:517776 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077777 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:207778
mmenke6b3af6e2015-09-12 02:06:067779 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:207780 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417781 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:207782
7783 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
7784 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7785
7786 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237787 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
7788 MockWrite(
7789 "GET / HTTP/1.1\r\n"
7790 "Host: www.example.org\r\n"
7791 "Connection: keep-alive\r\n\r\n")};
[email protected]029c83b62013-01-24 05:28:207792
7793 MockRead data_reads[] = {
7794 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
7795 MockRead("HTTP/1.0 200 OK\r\n"),
7796 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7797 MockRead("Payload"),
7798 MockRead(SYNCHRONOUS, OK)
7799 };
7800
7801 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7802 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077803 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:207804
7805 TestCompletionCallback callback;
7806
7807 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7808 EXPECT_EQ(ERR_IO_PENDING, rv);
7809
7810 rv = callback.WaitForResult();
7811 EXPECT_EQ(OK, rv);
7812
7813 const HttpResponseInfo* response = trans->GetResponseInfo();
7814 ASSERT_TRUE(response != NULL);
7815
7816 LoadTimingInfo load_timing_info;
7817 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7818 TestLoadTimingNotReused(load_timing_info,
7819 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7820
7821 std::string response_text;
7822 rv = ReadTransaction(trans.get(), &response_text);
7823 EXPECT_EQ(OK, rv);
7824 EXPECT_EQ("Payload", response_text);
7825}
7826
[email protected]23e482282013-06-14 16:08:027827TEST_P(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277828 HttpRequestInfo request;
7829 request.method = "GET";
bncce36dca22015-04-21 22:11:237830 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:277831 request.load_flags = 0;
7832
[email protected]bb88e1d32013-05-03 23:11:077833 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207834 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
vishal.b62985ca92015-04-17 08:45:517835 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077836 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:357837
mmenke6b3af6e2015-09-12 02:06:067838 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e0c27be2009-07-15 13:09:357839 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417840 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]e0c27be2009-07-15 13:09:357841
[email protected]e0c27be2009-07-15 13:09:357842 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
7843 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:377844 const char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:237845 0x05, // Version
7846 0x01, // Command (CONNECT)
7847 0x00, // Reserved.
7848 0x03, // Address type (DOMAINNAME).
7849 0x0F, // Length of domain (15)
7850 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
7851 '.', 'o', 'r', 'g', 0x00, 0x50, // 16-bit port (80)
[email protected]f209dba2009-12-18 00:24:377852 };
[email protected]e0c27be2009-07-15 13:09:357853 const char kSOCKS5OkResponse[] =
7854 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
7855
7856 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237857 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
7858 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
7859 MockWrite(
7860 "GET / HTTP/1.1\r\n"
7861 "Host: www.example.org\r\n"
7862 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:357863
7864 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:017865 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
7866 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:357867 MockRead("HTTP/1.0 200 OK\r\n"),
7868 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7869 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067870 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:357871 };
7872
[email protected]31a2bfe2010-02-09 08:03:397873 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7874 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077875 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:357876
[email protected]49639fa2011-12-20 23:22:417877 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:357878
[email protected]49639fa2011-12-20 23:22:417879 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:357880 EXPECT_EQ(ERR_IO_PENDING, rv);
7881
7882 rv = callback.WaitForResult();
7883 EXPECT_EQ(OK, rv);
7884
7885 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507886 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:357887
[email protected]029c83b62013-01-24 05:28:207888 LoadTimingInfo load_timing_info;
7889 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7890 TestLoadTimingNotReusedWithPac(load_timing_info,
7891 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7892
[email protected]e0c27be2009-07-15 13:09:357893 std::string response_text;
7894 rv = ReadTransaction(trans.get(), &response_text);
7895 EXPECT_EQ(OK, rv);
7896 EXPECT_EQ("Payload", response_text);
7897}
7898
[email protected]23e482282013-06-14 16:08:027899TEST_P(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277900 HttpRequestInfo request;
7901 request.method = "GET";
bncce36dca22015-04-21 22:11:237902 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:277903 request.load_flags = 0;
7904
[email protected]bb88e1d32013-05-03 23:11:077905 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207906 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
vishal.b62985ca92015-04-17 08:45:517907 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077908 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:357909
mmenke6b3af6e2015-09-12 02:06:067910 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e0c27be2009-07-15 13:09:357911 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417912 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]e0c27be2009-07-15 13:09:357913
[email protected]e0c27be2009-07-15 13:09:357914 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
7915 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:377916 const unsigned char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:237917 0x05, // Version
7918 0x01, // Command (CONNECT)
7919 0x00, // Reserved.
7920 0x03, // Address type (DOMAINNAME).
7921 0x0F, // Length of domain (15)
7922 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
7923 '.', 'o', 'r', 'g', 0x01, 0xBB, // 16-bit port (443)
[email protected]f209dba2009-12-18 00:24:377924 };
7925
[email protected]e0c27be2009-07-15 13:09:357926 const char kSOCKS5OkResponse[] =
7927 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
7928
7929 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237930 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
7931 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
7932 arraysize(kSOCKS5OkRequest)),
7933 MockWrite(
7934 "GET / HTTP/1.1\r\n"
7935 "Host: www.example.org\r\n"
7936 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:357937
7938 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:017939 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
7940 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:027941 MockRead("HTTP/1.0 200 OK\r\n"),
7942 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7943 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067944 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:027945 };
7946
[email protected]31a2bfe2010-02-09 08:03:397947 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7948 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077949 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:027950
[email protected]8ddf8322012-02-23 18:08:067951 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077952 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:027953
[email protected]49639fa2011-12-20 23:22:417954 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:027955
[email protected]49639fa2011-12-20 23:22:417956 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:027957 EXPECT_EQ(ERR_IO_PENDING, rv);
7958
7959 rv = callback.WaitForResult();
7960 EXPECT_EQ(OK, rv);
7961
7962 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507963 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:027964
[email protected]029c83b62013-01-24 05:28:207965 LoadTimingInfo load_timing_info;
7966 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7967 TestLoadTimingNotReusedWithPac(load_timing_info,
7968 CONNECT_TIMING_HAS_SSL_TIMES);
7969
[email protected]3cd17242009-06-23 02:59:027970 std::string response_text;
7971 rv = ReadTransaction(trans.get(), &response_text);
7972 EXPECT_EQ(OK, rv);
7973 EXPECT_EQ("Payload", response_text);
7974}
7975
[email protected]448d4ca52012-03-04 04:12:237976namespace {
7977
[email protected]04e5be32009-06-26 20:00:317978// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:067979
7980struct GroupNameTest {
7981 std::string proxy_server;
7982 std::string url;
7983 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:187984 bool ssl;
[email protected]2d731a32010-04-29 01:04:067985};
7986
mmenke6b3af6e2015-09-12 02:06:067987scoped_refptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]8a0fc822013-06-27 20:52:437988 NextProto next_proto,
[email protected]bb88e1d32013-05-03 23:11:077989 SpdySessionDependencies* session_deps_) {
mmenke6b3af6e2015-09-12 02:06:067990 scoped_refptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:067991
[email protected]30d4c022013-07-18 22:58:167992 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:537993 session->http_server_properties();
bnccacc0992015-03-20 20:22:227994 AlternativeService alternative_service(
bnc4988e432015-03-31 03:06:257995 AlternateProtocolFromNextProto(next_proto), "", 443);
bnc7dc7e1b42015-07-28 14:43:127996 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:227997 http_server_properties->SetAlternativeService(
bnc7dc7e1b42015-07-28 14:43:127998 HostPortPair("host.with.alternate", 80), alternative_service, 1.0,
7999 expiration);
[email protected]2d731a32010-04-29 01:04:068000
8001 return session;
8002}
8003
mmenke6b3af6e2015-09-12 02:06:068004int GroupNameTransactionHelper(
8005 const std::string& url,
8006 const scoped_refptr<HttpNetworkSession>& session) {
[email protected]2d731a32010-04-29 01:04:068007 HttpRequestInfo request;
8008 request.method = "GET";
8009 request.url = GURL(url);
8010 request.load_flags = 0;
8011
[email protected]262eec82013-03-19 21:01:368012 scoped_ptr<HttpTransaction> trans(
mmenke6b3af6e2015-09-12 02:06:068013 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278014
[email protected]49639fa2011-12-20 23:22:418015 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:068016
8017 // We do not complete this request, the dtor will clean the transaction up.
[email protected]49639fa2011-12-20 23:22:418018 return trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d731a32010-04-29 01:04:068019}
8020
[email protected]448d4ca52012-03-04 04:12:238021} // namespace
8022
[email protected]23e482282013-06-14 16:08:028023TEST_P(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:068024 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:238025 {
8026 "", // unused
8027 "http://www.example.org/direct",
8028 "www.example.org:80",
8029 false,
8030 },
8031 {
8032 "", // unused
8033 "http://[2001:1418:13:1::25]/direct",
8034 "[2001:1418:13:1::25]:80",
8035 false,
8036 },
[email protected]04e5be32009-06-26 20:00:318037
bncce36dca22015-04-21 22:11:238038 // SSL Tests
8039 {
8040 "", // unused
8041 "https://www.example.org/direct_ssl",
8042 "ssl/www.example.org:443",
8043 true,
8044 },
8045 {
8046 "", // unused
8047 "https://[2001:1418:13:1::25]/direct",
8048 "ssl/[2001:1418:13:1::25]:443",
8049 true,
8050 },
8051 {
8052 "", // unused
8053 "http://host.with.alternate/direct",
8054 "ssl/host.with.alternate:443",
8055 true,
8056 },
[email protected]2d731a32010-04-29 01:04:068057 };
[email protected]2ff8b312010-04-26 22:20:548058
bnc55ff9da2015-08-19 18:42:358059 session_deps_.use_alternative_services = true;
[email protected]2d731a32010-04-29 01:04:068060
viettrungluue4a8b882014-10-16 06:17:388061 for (size_t i = 0; i < arraysize(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:078062 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:028063 ProxyService::CreateFixed(tests[i].proxy_server));
mmenke6b3af6e2015-09-12 02:06:068064 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:438065 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:068066
mmenke6b3af6e2015-09-12 02:06:068067 HttpNetworkSessionPeer peer(session);
[email protected]ab739042011-04-07 15:22:288068 CaptureGroupNameTransportSocketPool* transport_conn_pool =
8069 new CaptureGroupNameTransportSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:138070 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:348071 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]831e4a32013-11-14 02:14:448072 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
8073 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:028074 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
8075 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
dchenge3d1ddc2014-10-15 19:30:518076 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]2d731a32010-04-29 01:04:068077
8078 EXPECT_EQ(ERR_IO_PENDING,
mmenke6b3af6e2015-09-12 02:06:068079 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:188080 if (tests[i].ssl)
8081 EXPECT_EQ(tests[i].expected_group_name,
8082 ssl_conn_pool->last_group_name_received());
8083 else
8084 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:288085 transport_conn_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:068086 }
[email protected]2d731a32010-04-29 01:04:068087}
8088
[email protected]23e482282013-06-14 16:08:028089TEST_P(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:068090 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:238091 {
8092 "http_proxy",
8093 "http://www.example.org/http_proxy_normal",
8094 "www.example.org:80",
8095 false,
8096 },
[email protected]2d731a32010-04-29 01:04:068097
bncce36dca22015-04-21 22:11:238098 // SSL Tests
8099 {
8100 "http_proxy",
8101 "https://www.example.org/http_connect_ssl",
8102 "ssl/www.example.org:443",
8103 true,
8104 },
[email protected]af3490e2010-10-16 21:02:298105
bncce36dca22015-04-21 22:11:238106 {
8107 "http_proxy",
8108 "http://host.with.alternate/direct",
8109 "ssl/host.with.alternate:443",
8110 true,
8111 },
[email protected]45499252013-01-23 17:12:568112
bncce36dca22015-04-21 22:11:238113 {
8114 "http_proxy",
8115 "ftp://ftp.google.com/http_proxy_normal",
8116 "ftp/ftp.google.com:21",
8117 false,
8118 },
[email protected]2d731a32010-04-29 01:04:068119 };
8120
bnc55ff9da2015-08-19 18:42:358121 session_deps_.use_alternative_services = true;
[email protected]2d731a32010-04-29 01:04:068122
viettrungluue4a8b882014-10-16 06:17:388123 for (size_t i = 0; i < arraysize(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:078124 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:028125 ProxyService::CreateFixed(tests[i].proxy_server));
mmenke6b3af6e2015-09-12 02:06:068126 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:438127 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:068128
mmenke6b3af6e2015-09-12 02:06:068129 HttpNetworkSessionPeer peer(session);
[email protected]2d731a32010-04-29 01:04:068130
[email protected]e60e47a2010-07-14 03:37:188131 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:138132 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:348133 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:138134 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:348135 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:028136
[email protected]831e4a32013-11-14 02:14:448137 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
8138 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:028139 mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool);
8140 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
dchenge3d1ddc2014-10-15 19:30:518141 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]2d731a32010-04-29 01:04:068142
8143 EXPECT_EQ(ERR_IO_PENDING,
mmenke6b3af6e2015-09-12 02:06:068144 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:188145 if (tests[i].ssl)
8146 EXPECT_EQ(tests[i].expected_group_name,
8147 ssl_conn_pool->last_group_name_received());
8148 else
8149 EXPECT_EQ(tests[i].expected_group_name,
8150 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:068151 }
[email protected]2d731a32010-04-29 01:04:068152}
8153
[email protected]23e482282013-06-14 16:08:028154TEST_P(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:068155 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:238156 {
8157 "socks4://socks_proxy:1080",
8158 "http://www.example.org/socks4_direct",
8159 "socks4/www.example.org:80",
8160 false,
8161 },
8162 {
8163 "socks5://socks_proxy:1080",
8164 "http://www.example.org/socks5_direct",
8165 "socks5/www.example.org:80",
8166 false,
8167 },
[email protected]2d731a32010-04-29 01:04:068168
bncce36dca22015-04-21 22:11:238169 // SSL Tests
8170 {
8171 "socks4://socks_proxy:1080",
8172 "https://www.example.org/socks4_ssl",
8173 "socks4/ssl/www.example.org:443",
8174 true,
8175 },
8176 {
8177 "socks5://socks_proxy:1080",
8178 "https://www.example.org/socks5_ssl",
8179 "socks5/ssl/www.example.org:443",
8180 true,
8181 },
[email protected]af3490e2010-10-16 21:02:298182
bncce36dca22015-04-21 22:11:238183 {
8184 "socks4://socks_proxy:1080",
8185 "http://host.with.alternate/direct",
8186 "socks4/ssl/host.with.alternate:443",
8187 true,
8188 },
[email protected]04e5be32009-06-26 20:00:318189 };
8190
bnc55ff9da2015-08-19 18:42:358191 session_deps_.use_alternative_services = true;
[email protected]2ff8b312010-04-26 22:20:548192
viettrungluue4a8b882014-10-16 06:17:388193 for (size_t i = 0; i < arraysize(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:078194 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:028195 ProxyService::CreateFixed(tests[i].proxy_server));
mmenke6b3af6e2015-09-12 02:06:068196 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:438197 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]8b114dd72011-03-25 05:33:028198
mmenke6b3af6e2015-09-12 02:06:068199 HttpNetworkSessionPeer peer(session);
[email protected]04e5be32009-06-26 20:00:318200
[email protected]e60e47a2010-07-14 03:37:188201 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:138202 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:348203 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:138204 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:348205 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:028206
[email protected]831e4a32013-11-14 02:14:448207 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
8208 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:028209 mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_conn_pool);
8210 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
dchenge3d1ddc2014-10-15 19:30:518211 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]04e5be32009-06-26 20:00:318212
[email protected]262eec82013-03-19 21:01:368213 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508214 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]04e5be32009-06-26 20:00:318215
[email protected]2d731a32010-04-29 01:04:068216 EXPECT_EQ(ERR_IO_PENDING,
mmenke6b3af6e2015-09-12 02:06:068217 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:188218 if (tests[i].ssl)
8219 EXPECT_EQ(tests[i].expected_group_name,
8220 ssl_conn_pool->last_group_name_received());
8221 else
8222 EXPECT_EQ(tests[i].expected_group_name,
8223 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:318224 }
8225}
8226
[email protected]23e482282013-06-14 16:08:028227TEST_P(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:278228 HttpRequestInfo request;
8229 request.method = "GET";
bncce36dca22015-04-21 22:11:238230 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278231
[email protected]bb88e1d32013-05-03 23:11:078232 session_deps_.proxy_service.reset(
[email protected]81cdfcd2010-10-16 00:49:008233 ProxyService::CreateFixed("myproxy:70;foobar:80"));
[email protected]b59ff372009-07-15 22:04:328234
[email protected]69719062010-01-05 20:09:218235 // This simulates failure resolving all hostnames; that means we will fail
8236 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:078237 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:328238
mmenke6b3af6e2015-09-12 02:06:068239 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]9172a982009-06-06 00:30:258240 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418241 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]9172a982009-06-06 00:30:258242
[email protected]49639fa2011-12-20 23:22:418243 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:258244
[email protected]49639fa2011-12-20 23:22:418245 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9172a982009-06-06 00:30:258246 EXPECT_EQ(ERR_IO_PENDING, rv);
8247
[email protected]9172a982009-06-06 00:30:258248 rv = callback.WaitForResult();
[email protected]f7fccee2010-09-16 20:53:018249 EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
[email protected]9172a982009-06-06 00:30:258250}
8251
[email protected]685af592010-05-11 19:31:248252// Base test to make sure that when the load flags for a request specify to
8253// bypass the cache, the DNS cache is not used.
[email protected]23e482282013-06-14 16:08:028254void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
[email protected]bb88e1d32013-05-03 23:11:078255 int load_flags) {
[email protected]cb9bf6ca2011-01-28 13:15:278256 // Issue a request, asking to bypass the cache(s).
8257 HttpRequestInfo request;
8258 request.method = "GET";
8259 request.load_flags = load_flags;
bncce36dca22015-04-21 22:11:238260 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278261
[email protected]a2c2fb92009-07-18 07:31:048262 // Select a host resolver that does caching.
[email protected]bb88e1d32013-05-03 23:11:078263 session_deps_.host_resolver.reset(new MockCachingHostResolver);
[email protected]b59ff372009-07-15 22:04:328264
mmenke6b3af6e2015-09-12 02:06:068265 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:078266 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418267 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3b9cca42009-06-16 01:08:288268
bncce36dca22015-04-21 22:11:238269 // Warm up the host cache so it has an entry for "www.example.org".
[email protected]3b9cca42009-06-16 01:08:288270 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:298271 TestCompletionCallback callback;
[email protected]bb88e1d32013-05-03 23:11:078272 int rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:238273 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
8274 DEFAULT_PRIORITY, &addrlist, callback.callback(), NULL, BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:478275 EXPECT_EQ(ERR_IO_PENDING, rv);
8276 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:288277 EXPECT_EQ(OK, rv);
8278
8279 // Verify that it was added to host cache, by doing a subsequent async lookup
8280 // and confirming it completes synchronously.
[email protected]bb88e1d32013-05-03 23:11:078281 rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:238282 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
8283 DEFAULT_PRIORITY, &addrlist, callback.callback(), NULL, BoundNetLog());
[email protected]b59ff372009-07-15 22:04:328284 ASSERT_EQ(OK, rv);
[email protected]3b9cca42009-06-16 01:08:288285
bncce36dca22015-04-21 22:11:238286 // Inject a failure the next time that "www.example.org" is resolved. This way
[email protected]3b9cca42009-06-16 01:08:288287 // we can tell if the next lookup hit the cache, or the "network".
8288 // (cache --> success, "network" --> failure).
bncce36dca22015-04-21 22:11:238289 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.example.org");
[email protected]3b9cca42009-06-16 01:08:288290
8291 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
8292 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:068293 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
[email protected]31a2bfe2010-02-09 08:03:398294 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078295 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:288296
[email protected]3b9cca42009-06-16 01:08:288297 // Run the request.
[email protected]49639fa2011-12-20 23:22:418298 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3b9cca42009-06-16 01:08:288299 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:418300 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:288301
8302 // If we bypassed the cache, we would have gotten a failure while resolving
bncce36dca22015-04-21 22:11:238303 // "www.example.org".
[email protected]3b9cca42009-06-16 01:08:288304 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
8305}
8306
[email protected]685af592010-05-11 19:31:248307// There are multiple load flags that should trigger the host cache bypass.
8308// Test each in isolation:
[email protected]23e482282013-06-14 16:08:028309TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
[email protected]685af592010-05-11 19:31:248310 BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
8311}
8312
[email protected]23e482282013-06-14 16:08:028313TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
[email protected]685af592010-05-11 19:31:248314 BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
8315}
8316
[email protected]23e482282013-06-14 16:08:028317TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
[email protected]685af592010-05-11 19:31:248318 BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
8319}
8320
[email protected]0877e3d2009-10-17 22:29:578321// Make sure we can handle an error when writing the request.
[email protected]23e482282013-06-14 16:08:028322TEST_P(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:578323 HttpRequestInfo request;
8324 request.method = "GET";
8325 request.url = GURL("http://www.foo.com/");
8326 request.load_flags = 0;
8327
8328 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:068329 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:578330 };
[email protected]31a2bfe2010-02-09 08:03:398331 StaticSocketDataProvider data(NULL, 0,
8332 write_failure, arraysize(write_failure));
[email protected]bb88e1d32013-05-03 23:11:078333 session_deps_.socket_factory->AddSocketDataProvider(&data);
mmenke6b3af6e2015-09-12 02:06:068334 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578335
[email protected]49639fa2011-12-20 23:22:418336 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:578337
8338 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418339 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:578340
[email protected]49639fa2011-12-20 23:22:418341 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578342 EXPECT_EQ(ERR_IO_PENDING, rv);
8343
8344 rv = callback.WaitForResult();
8345 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
8346}
8347
zmo9528c9f42015-08-04 22:12:088348// Check that a connection closed after the start of the headers finishes ok.
8349TEST_P(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:578350 HttpRequestInfo request;
8351 request.method = "GET";
8352 request.url = GURL("http://www.foo.com/");
8353 request.load_flags = 0;
8354
8355 MockRead data_reads[] = {
8356 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:068357 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:578358 };
8359
[email protected]31a2bfe2010-02-09 08:03:398360 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078361 session_deps_.socket_factory->AddSocketDataProvider(&data);
mmenke6b3af6e2015-09-12 02:06:068362 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578363
[email protected]49639fa2011-12-20 23:22:418364 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:578365
8366 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418367 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:578368
[email protected]49639fa2011-12-20 23:22:418369 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578370 EXPECT_EQ(ERR_IO_PENDING, rv);
8371
8372 rv = callback.WaitForResult();
zmo9528c9f42015-08-04 22:12:088373 EXPECT_EQ(OK, rv);
8374
8375 const HttpResponseInfo* response = trans->GetResponseInfo();
8376 ASSERT_TRUE(response != NULL);
8377
8378 EXPECT_TRUE(response->headers.get() != NULL);
8379 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
8380
8381 std::string response_data;
8382 rv = ReadTransaction(trans.get(), &response_data);
8383 EXPECT_EQ(OK, rv);
8384 EXPECT_EQ("", response_data);
[email protected]0877e3d2009-10-17 22:29:578385}
8386
8387// Make sure that a dropped connection while draining the body for auth
8388// restart does the right thing.
[email protected]23e482282013-06-14 16:08:028389TEST_P(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:578390 HttpRequestInfo request;
8391 request.method = "GET";
bncce36dca22015-04-21 22:11:238392 request.url = GURL("http://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:578393 request.load_flags = 0;
8394
8395 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238396 MockWrite(
8397 "GET / HTTP/1.1\r\n"
8398 "Host: www.example.org\r\n"
8399 "Connection: keep-alive\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:578400 };
8401
8402 MockRead data_reads1[] = {
8403 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
8404 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8405 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8406 MockRead("Content-Length: 14\r\n\r\n"),
8407 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:068408 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:578409 };
8410
[email protected]31a2bfe2010-02-09 08:03:398411 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8412 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:078413 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:578414
8415 // After calling trans->RestartWithAuth(), this is the request we should
8416 // be issuing -- the final header line contains the credentials.
8417 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238418 MockWrite(
8419 "GET / HTTP/1.1\r\n"
8420 "Host: www.example.org\r\n"
8421 "Connection: keep-alive\r\n"
8422 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:578423 };
8424
8425 // Lastly, the server responds with the actual content.
8426 MockRead data_reads2[] = {
8427 MockRead("HTTP/1.1 200 OK\r\n"),
8428 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8429 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068430 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:578431 };
8432
[email protected]31a2bfe2010-02-09 08:03:398433 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8434 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:078435 session_deps_.socket_factory->AddSocketDataProvider(&data2);
mmenke6b3af6e2015-09-12 02:06:068436 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578437
[email protected]49639fa2011-12-20 23:22:418438 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:578439
[email protected]262eec82013-03-19 21:01:368440 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508441 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:508442
[email protected]49639fa2011-12-20 23:22:418443 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578444 EXPECT_EQ(ERR_IO_PENDING, rv);
8445
8446 rv = callback1.WaitForResult();
8447 EXPECT_EQ(OK, rv);
8448
8449 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508450 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048451 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:578452
[email protected]49639fa2011-12-20 23:22:418453 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:578454
[email protected]49639fa2011-12-20 23:22:418455 rv = trans->RestartWithAuth(
8456 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]0877e3d2009-10-17 22:29:578457 EXPECT_EQ(ERR_IO_PENDING, rv);
8458
8459 rv = callback2.WaitForResult();
8460 EXPECT_EQ(OK, rv);
8461
8462 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508463 ASSERT_TRUE(response != NULL);
[email protected]0877e3d2009-10-17 22:29:578464 EXPECT_TRUE(response->auth_challenge.get() == NULL);
8465 EXPECT_EQ(100, response->headers->GetContentLength());
8466}
8467
8468// Test HTTPS connections going through a proxy that sends extra data.
[email protected]23e482282013-06-14 16:08:028469TEST_P(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
[email protected]bb88e1d32013-05-03 23:11:078470 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]0877e3d2009-10-17 22:29:578471
8472 HttpRequestInfo request;
8473 request.method = "GET";
bncce36dca22015-04-21 22:11:238474 request.url = GURL("https://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:578475 request.load_flags = 0;
8476
8477 MockRead proxy_reads[] = {
8478 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:068479 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:578480 };
8481
[email protected]31a2bfe2010-02-09 08:03:398482 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
[email protected]8ddf8322012-02-23 18:08:068483 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:578484
[email protected]bb88e1d32013-05-03 23:11:078485 session_deps_.socket_factory->AddSocketDataProvider(&data);
8486 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:578487
[email protected]49639fa2011-12-20 23:22:418488 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:578489
[email protected]bb88e1d32013-05-03 23:11:078490 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:578491
mmenke6b3af6e2015-09-12 02:06:068492 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578493 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418494 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:578495
[email protected]49639fa2011-12-20 23:22:418496 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578497 EXPECT_EQ(ERR_IO_PENDING, rv);
8498
8499 rv = callback.WaitForResult();
8500 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
8501}
8502
[email protected]23e482282013-06-14 16:08:028503TEST_P(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:468504 HttpRequestInfo request;
8505 request.method = "GET";
bncce36dca22015-04-21 22:11:238506 request.url = GURL("http://www.example.org/");
[email protected]9492e4a2010-02-24 00:58:468507 request.load_flags = 0;
8508
mmenke6b3af6e2015-09-12 02:06:068509 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:278510 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418511 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278512
[email protected]e22e1362009-11-23 21:31:128513 MockRead data_reads[] = {
8514 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068515 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:128516 };
[email protected]9492e4a2010-02-24 00:58:468517
8518 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078519 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:468520
[email protected]49639fa2011-12-20 23:22:418521 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:468522
[email protected]49639fa2011-12-20 23:22:418523 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9492e4a2010-02-24 00:58:468524 EXPECT_EQ(ERR_IO_PENDING, rv);
8525
8526 EXPECT_EQ(OK, callback.WaitForResult());
8527
8528 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508529 ASSERT_TRUE(response != NULL);
[email protected]9492e4a2010-02-24 00:58:468530
[email protected]90499482013-06-01 00:39:508531 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]9492e4a2010-02-24 00:58:468532 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
8533
8534 std::string response_data;
8535 rv = ReadTransaction(trans.get(), &response_data);
[email protected]5543cbb2012-04-20 16:35:238536 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
[email protected]e22e1362009-11-23 21:31:128537}
8538
[email protected]23e482282013-06-14 16:08:028539TEST_P(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:158540 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:528541 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
[email protected]95d88ffe2010-02-04 21:25:338542 const uint64 kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:218543 UploadFileElementReader::ScopedOverridingContentLengthForTests
8544 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:338545
[email protected]b2d26cfd2012-12-11 10:36:068546 ScopedVector<UploadElementReader> element_readers;
8547 element_readers.push_back(
skyostil4891b25b2015-06-11 11:43:458548 new UploadFileElementReader(base::ThreadTaskRunnerHandle::Get().get(),
8549 temp_file_path, 0, kuint64max, base::Time()));
mmenkecbc2b712014-10-09 20:29:078550 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:278551
8552 HttpRequestInfo request;
8553 request.method = "POST";
bncce36dca22015-04-21 22:11:238554 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:278555 request.upload_data_stream = &upload_data_stream;
8556 request.load_flags = 0;
8557
mmenke6b3af6e2015-09-12 02:06:068558 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]329b68b2012-11-14 17:54:278559 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418560 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]95d88ffe2010-02-04 21:25:338561
8562 MockRead data_reads[] = {
8563 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
8564 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068565 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:338566 };
[email protected]31a2bfe2010-02-09 08:03:398567 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078568 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:338569
[email protected]49639fa2011-12-20 23:22:418570 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:338571
[email protected]49639fa2011-12-20 23:22:418572 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]95d88ffe2010-02-04 21:25:338573 EXPECT_EQ(ERR_IO_PENDING, rv);
8574
8575 rv = callback.WaitForResult();
8576 EXPECT_EQ(OK, rv);
8577
8578 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508579 ASSERT_TRUE(response != NULL);
[email protected]95d88ffe2010-02-04 21:25:338580
[email protected]90499482013-06-01 00:39:508581 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]95d88ffe2010-02-04 21:25:338582 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
8583
8584 std::string response_data;
8585 rv = ReadTransaction(trans.get(), &response_data);
8586 EXPECT_EQ(OK, rv);
8587 EXPECT_EQ("hello world", response_data);
8588
[email protected]dd3aa792013-07-16 19:10:238589 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:338590}
8591
[email protected]23e482282013-06-14 16:08:028592TEST_P(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:158593 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:528594 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:368595 std::string temp_file_content("Unreadable file.");
[email protected]e5c2a22e2014-03-06 20:42:308596 ASSERT_TRUE(base::WriteFile(temp_file, temp_file_content.c_str(),
[email protected]6624b4622010-03-29 19:58:368597 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:118598 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:368599
[email protected]b2d26cfd2012-12-11 10:36:068600 ScopedVector<UploadElementReader> element_readers;
8601 element_readers.push_back(
skyostil4891b25b2015-06-11 11:43:458602 new UploadFileElementReader(base::ThreadTaskRunnerHandle::Get().get(),
8603 temp_file, 0, kuint64max, base::Time()));
mmenkecbc2b712014-10-09 20:29:078604 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:278605
8606 HttpRequestInfo request;
8607 request.method = "POST";
bncce36dca22015-04-21 22:11:238608 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:278609 request.upload_data_stream = &upload_data_stream;
8610 request.load_flags = 0;
8611
[email protected]999dd8c2013-11-12 06:45:548612 // If we try to upload an unreadable file, the transaction should fail.
mmenke6b3af6e2015-09-12 02:06:068613 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]329b68b2012-11-14 17:54:278614 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418615 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]6624b4622010-03-29 19:58:368616
[email protected]999dd8c2013-11-12 06:45:548617 StaticSocketDataProvider data(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078618 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:368619
[email protected]49639fa2011-12-20 23:22:418620 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:368621
[email protected]49639fa2011-12-20 23:22:418622 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]6624b4622010-03-29 19:58:368623 EXPECT_EQ(ERR_IO_PENDING, rv);
8624
8625 rv = callback.WaitForResult();
[email protected]999dd8c2013-11-12 06:45:548626 EXPECT_EQ(ERR_ACCESS_DENIED, rv);
[email protected]6624b4622010-03-29 19:58:368627
[email protected]dd3aa792013-07-16 19:10:238628 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:368629}
8630
[email protected]02cad5d2013-10-02 08:14:038631TEST_P(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
8632 class FakeUploadElementReader : public UploadElementReader {
8633 public:
8634 FakeUploadElementReader() {}
dchengb03027d2014-10-21 12:00:208635 ~FakeUploadElementReader() override {}
[email protected]02cad5d2013-10-02 08:14:038636
8637 const CompletionCallback& callback() const { return callback_; }
8638
8639 // UploadElementReader overrides:
dchengb03027d2014-10-21 12:00:208640 int Init(const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:038641 callback_ = callback;
8642 return ERR_IO_PENDING;
8643 }
dchengb03027d2014-10-21 12:00:208644 uint64 GetContentLength() const override { return 0; }
8645 uint64 BytesRemaining() const override { return 0; }
8646 int Read(IOBuffer* buf,
8647 int buf_length,
8648 const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:038649 return ERR_FAILED;
8650 }
8651
8652 private:
8653 CompletionCallback callback_;
8654 };
8655
8656 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
8657 ScopedVector<UploadElementReader> element_readers;
8658 element_readers.push_back(fake_reader);
mmenkecbc2b712014-10-09 20:29:078659 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02cad5d2013-10-02 08:14:038660
8661 HttpRequestInfo request;
8662 request.method = "POST";
bncce36dca22015-04-21 22:11:238663 request.url = GURL("http://www.example.org/upload");
[email protected]02cad5d2013-10-02 08:14:038664 request.upload_data_stream = &upload_data_stream;
8665 request.load_flags = 0;
8666
mmenke6b3af6e2015-09-12 02:06:068667 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02cad5d2013-10-02 08:14:038668 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418669 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02cad5d2013-10-02 08:14:038670
8671 StaticSocketDataProvider data;
8672 session_deps_.socket_factory->AddSocketDataProvider(&data);
8673
8674 TestCompletionCallback callback;
8675 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8676 EXPECT_EQ(ERR_IO_PENDING, rv);
8677 base::MessageLoop::current()->RunUntilIdle();
8678
8679 // Transaction is pending on request body initialization.
8680 ASSERT_FALSE(fake_reader->callback().is_null());
8681
8682 // Return Init()'s result after the transaction gets destroyed.
8683 trans.reset();
8684 fake_reader->callback().Run(OK); // Should not crash.
8685}
8686
[email protected]aeefc9e82010-02-19 16:18:278687// Tests that changes to Auth realms are treated like auth rejections.
[email protected]23e482282013-06-14 16:08:028688TEST_P(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:278689 HttpRequestInfo request;
8690 request.method = "GET";
bncce36dca22015-04-21 22:11:238691 request.url = GURL("http://www.example.org/");
[email protected]aeefc9e82010-02-19 16:18:278692 request.load_flags = 0;
8693
8694 // First transaction will request a resource and receive a Basic challenge
8695 // with realm="first_realm".
8696 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238697 MockWrite(
8698 "GET / HTTP/1.1\r\n"
8699 "Host: www.example.org\r\n"
8700 "Connection: keep-alive\r\n"
8701 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:278702 };
8703 MockRead data_reads1[] = {
8704 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8705 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
8706 "\r\n"),
8707 };
8708
8709 // After calling trans->RestartWithAuth(), provide an Authentication header
8710 // for first_realm. The server will reject and provide a challenge with
8711 // second_realm.
8712 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238713 MockWrite(
8714 "GET / HTTP/1.1\r\n"
8715 "Host: www.example.org\r\n"
8716 "Connection: keep-alive\r\n"
8717 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
8718 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:278719 };
8720 MockRead data_reads2[] = {
8721 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8722 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
8723 "\r\n"),
8724 };
8725
8726 // This again fails, and goes back to first_realm. Make sure that the
8727 // entry is removed from cache.
8728 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:238729 MockWrite(
8730 "GET / HTTP/1.1\r\n"
8731 "Host: www.example.org\r\n"
8732 "Connection: keep-alive\r\n"
8733 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
8734 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:278735 };
8736 MockRead data_reads3[] = {
8737 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8738 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
8739 "\r\n"),
8740 };
8741
8742 // Try one last time (with the correct password) and get the resource.
8743 MockWrite data_writes4[] = {
bncce36dca22015-04-21 22:11:238744 MockWrite(
8745 "GET / HTTP/1.1\r\n"
8746 "Host: www.example.org\r\n"
8747 "Connection: keep-alive\r\n"
8748 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
8749 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:278750 };
8751 MockRead data_reads4[] = {
8752 MockRead("HTTP/1.1 200 OK\r\n"
8753 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:508754 "Content-Length: 5\r\n"
8755 "\r\n"
8756 "hello"),
[email protected]aeefc9e82010-02-19 16:18:278757 };
8758
8759 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8760 data_writes1, arraysize(data_writes1));
8761 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8762 data_writes2, arraysize(data_writes2));
8763 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
8764 data_writes3, arraysize(data_writes3));
8765 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
8766 data_writes4, arraysize(data_writes4));
[email protected]bb88e1d32013-05-03 23:11:078767 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8768 session_deps_.socket_factory->AddSocketDataProvider(&data2);
8769 session_deps_.socket_factory->AddSocketDataProvider(&data3);
8770 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:278771
[email protected]49639fa2011-12-20 23:22:418772 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:278773
mmenke6b3af6e2015-09-12 02:06:068774 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0b0bf032010-09-21 18:08:508775 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418776 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:508777
[email protected]aeefc9e82010-02-19 16:18:278778 // Issue the first request with Authorize headers. There should be a
8779 // password prompt for first_realm waiting to be filled in after the
8780 // transaction completes.
[email protected]49639fa2011-12-20 23:22:418781 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]aeefc9e82010-02-19 16:18:278782 EXPECT_EQ(ERR_IO_PENDING, rv);
8783 rv = callback1.WaitForResult();
8784 EXPECT_EQ(OK, rv);
8785 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508786 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048787 const AuthChallengeInfo* challenge = response->auth_challenge.get();
8788 ASSERT_FALSE(challenge == NULL);
8789 EXPECT_FALSE(challenge->is_proxy);
bncce36dca22015-04-21 22:11:238790 EXPECT_EQ("www.example.org:80", challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:048791 EXPECT_EQ("first_realm", challenge->realm);
8792 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278793
8794 // Issue the second request with an incorrect password. There should be a
8795 // password prompt for second_realm waiting to be filled in after the
8796 // transaction completes.
[email protected]49639fa2011-12-20 23:22:418797 TestCompletionCallback callback2;
8798 rv = trans->RestartWithAuth(
8799 AuthCredentials(kFirst, kBaz), callback2.callback());
[email protected]aeefc9e82010-02-19 16:18:278800 EXPECT_EQ(ERR_IO_PENDING, rv);
8801 rv = callback2.WaitForResult();
8802 EXPECT_EQ(OK, rv);
8803 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508804 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048805 challenge = response->auth_challenge.get();
8806 ASSERT_FALSE(challenge == NULL);
8807 EXPECT_FALSE(challenge->is_proxy);
bncce36dca22015-04-21 22:11:238808 EXPECT_EQ("www.example.org:80", challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:048809 EXPECT_EQ("second_realm", challenge->realm);
8810 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278811
8812 // Issue the third request with another incorrect password. There should be
8813 // a password prompt for first_realm waiting to be filled in. If the password
8814 // prompt is not present, it indicates that the HttpAuthCacheEntry for
8815 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:418816 TestCompletionCallback callback3;
8817 rv = trans->RestartWithAuth(
8818 AuthCredentials(kSecond, kFou), callback3.callback());
[email protected]aeefc9e82010-02-19 16:18:278819 EXPECT_EQ(ERR_IO_PENDING, rv);
8820 rv = callback3.WaitForResult();
8821 EXPECT_EQ(OK, rv);
8822 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508823 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048824 challenge = response->auth_challenge.get();
8825 ASSERT_FALSE(challenge == NULL);
8826 EXPECT_FALSE(challenge->is_proxy);
bncce36dca22015-04-21 22:11:238827 EXPECT_EQ("www.example.org:80", challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:048828 EXPECT_EQ("first_realm", challenge->realm);
8829 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278830
8831 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:418832 TestCompletionCallback callback4;
8833 rv = trans->RestartWithAuth(
8834 AuthCredentials(kFirst, kBar), callback4.callback());
[email protected]aeefc9e82010-02-19 16:18:278835 EXPECT_EQ(ERR_IO_PENDING, rv);
8836 rv = callback4.WaitForResult();
8837 EXPECT_EQ(OK, rv);
8838 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508839 ASSERT_TRUE(response != NULL);
[email protected]aeefc9e82010-02-19 16:18:278840 EXPECT_TRUE(response->auth_challenge.get() == NULL);
8841}
8842
bncc958faa2015-07-31 18:14:528843TEST_P(HttpNetworkTransactionTest, HonorAlternativeServiceHeader) {
8844 session_deps_.next_protos = SpdyNextProtos();
bnc55ff9da2015-08-19 18:42:358845 session_deps_.use_alternative_services = true;
bncc958faa2015-07-31 18:14:528846
8847 std::string alternative_service_http_header =
8848 GetAlternativeServiceHttpHeader();
8849
8850 MockRead data_reads[] = {
8851 MockRead("HTTP/1.1 200 OK\r\n"),
8852 MockRead(alternative_service_http_header.c_str()),
8853 MockRead("\r\n"),
8854 MockRead("hello world"),
8855 MockRead(SYNCHRONOUS, OK),
8856 };
8857
8858 HttpRequestInfo request;
8859 request.method = "GET";
8860 request.url = GURL("http://www.example.org/");
8861 request.load_flags = 0;
8862
8863 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
8864
8865 session_deps_.socket_factory->AddSocketDataProvider(&data);
8866
8867 TestCompletionCallback callback;
8868
mmenke6b3af6e2015-09-12 02:06:068869 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bncc958faa2015-07-31 18:14:528870 scoped_ptr<HttpTransaction> trans(
8871 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8872
8873 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8874 EXPECT_EQ(ERR_IO_PENDING, rv);
8875
8876 HostPortPair http_host_port_pair("www.example.org", 80);
8877 HttpServerProperties& http_server_properties =
8878 *session->http_server_properties();
8879 AlternativeServiceVector alternative_service_vector =
8880 http_server_properties.GetAlternativeServices(http_host_port_pair);
8881 EXPECT_TRUE(alternative_service_vector.empty());
8882
8883 EXPECT_EQ(OK, callback.WaitForResult());
8884
8885 const HttpResponseInfo* response = trans->GetResponseInfo();
8886 ASSERT_TRUE(response != NULL);
8887 ASSERT_TRUE(response->headers.get() != NULL);
8888 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8889 EXPECT_FALSE(response->was_fetched_via_spdy);
8890 EXPECT_FALSE(response->was_npn_negotiated);
8891
8892 std::string response_data;
8893 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8894 EXPECT_EQ("hello world", response_data);
8895
8896 alternative_service_vector =
8897 http_server_properties.GetAlternativeServices(http_host_port_pair);
8898 ASSERT_EQ(1u, alternative_service_vector.size());
8899 EXPECT_EQ(AlternateProtocolFromNextProto(GetParam()),
8900 alternative_service_vector[0].protocol);
8901 EXPECT_EQ("www.example.com", alternative_service_vector[0].host);
8902 EXPECT_EQ(443, alternative_service_vector[0].port);
8903}
8904
bnc54ec34b72015-08-26 19:34:568905// Alternative Service headers must be ignored when |use_alternative_services|
8906// is false.
8907TEST_P(HttpNetworkTransactionTest, DoNotHonorAlternativeServiceHeader) {
8908 session_deps_.next_protos = SpdyNextProtos();
8909 session_deps_.use_alternative_services = false;
8910
8911 std::string alternative_service_http_header =
8912 GetAlternativeServiceHttpHeader();
8913
8914 MockRead data_reads[] = {
8915 MockRead("HTTP/1.1 200 OK\r\n"),
8916 MockRead(alternative_service_http_header.c_str()),
8917 MockRead("\r\n"),
8918 MockRead("hello world"),
8919 MockRead(SYNCHRONOUS, OK),
8920 };
8921
8922 HttpRequestInfo request;
8923 request.method = "GET";
8924 request.url = GURL("http://www.example.org/");
8925 request.load_flags = 0;
8926
8927 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
8928
8929 session_deps_.socket_factory->AddSocketDataProvider(&data);
8930
8931 TestCompletionCallback callback;
8932
mmenke6b3af6e2015-09-12 02:06:068933 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc54ec34b72015-08-26 19:34:568934 scoped_ptr<HttpTransaction> trans(
8935 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8936
8937 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8938 EXPECT_EQ(ERR_IO_PENDING, rv);
8939
8940 HostPortPair http_host_port_pair("www.example.org", 80);
8941 HttpServerProperties& http_server_properties =
8942 *session->http_server_properties();
8943 AlternativeServiceVector alternative_service_vector =
8944 http_server_properties.GetAlternativeServices(http_host_port_pair);
8945 EXPECT_TRUE(alternative_service_vector.empty());
8946
8947 EXPECT_EQ(OK, callback.WaitForResult());
8948
8949 const HttpResponseInfo* response = trans->GetResponseInfo();
8950 ASSERT_TRUE(response != nullptr);
8951 ASSERT_TRUE(response->headers.get() != nullptr);
8952 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8953 EXPECT_FALSE(response->was_fetched_via_spdy);
8954 EXPECT_FALSE(response->was_npn_negotiated);
8955
8956 std::string response_data;
8957 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8958 EXPECT_EQ("hello world", response_data);
8959
8960 alternative_service_vector =
8961 http_server_properties.GetAlternativeServices(http_host_port_pair);
8962 EXPECT_TRUE(alternative_service_vector.empty());
8963}
8964
bncc958faa2015-07-31 18:14:528965TEST_P(HttpNetworkTransactionTest, HonorMultipleAlternativeServiceHeader) {
8966 session_deps_.next_protos = SpdyNextProtos();
bnc55ff9da2015-08-19 18:42:358967 session_deps_.use_alternative_services = true;
bncc958faa2015-07-31 18:14:528968
8969 MockRead data_reads[] = {
8970 MockRead("HTTP/1.1 200 OK\r\n"),
8971 MockRead("Alt-Svc: "),
8972 MockRead(GetAlternateProtocolFromParam()),
8973 MockRead("=\"www.example.com:443\";p=1.0,"),
8974 MockRead("quic=\":1234\"\r\n\r\n"),
8975 MockRead("hello world"),
8976 MockRead(SYNCHRONOUS, OK),
8977 };
8978
8979 HttpRequestInfo request;
8980 request.method = "GET";
8981 request.url = GURL("http://www.example.org/");
8982 request.load_flags = 0;
8983
8984 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
8985
8986 session_deps_.socket_factory->AddSocketDataProvider(&data);
8987
8988 TestCompletionCallback callback;
8989
mmenke6b3af6e2015-09-12 02:06:068990 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bncc958faa2015-07-31 18:14:528991 scoped_ptr<HttpTransaction> trans(
8992 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8993
8994 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8995 EXPECT_EQ(ERR_IO_PENDING, rv);
8996
8997 HostPortPair http_host_port_pair("www.example.org", 80);
8998 HttpServerProperties& http_server_properties =
8999 *session->http_server_properties();
9000 AlternativeServiceVector alternative_service_vector =
9001 http_server_properties.GetAlternativeServices(http_host_port_pair);
9002 EXPECT_TRUE(alternative_service_vector.empty());
9003
9004 EXPECT_EQ(OK, callback.WaitForResult());
9005
9006 const HttpResponseInfo* response = trans->GetResponseInfo();
9007 ASSERT_TRUE(response != NULL);
9008 ASSERT_TRUE(response->headers.get() != NULL);
9009 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9010 EXPECT_FALSE(response->was_fetched_via_spdy);
9011 EXPECT_FALSE(response->was_npn_negotiated);
9012
9013 std::string response_data;
9014 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9015 EXPECT_EQ("hello world", response_data);
9016
9017 alternative_service_vector =
9018 http_server_properties.GetAlternativeServices(http_host_port_pair);
9019 ASSERT_EQ(2u, alternative_service_vector.size());
9020 EXPECT_EQ(AlternateProtocolFromNextProto(GetParam()),
9021 alternative_service_vector[0].protocol);
9022 EXPECT_EQ("www.example.com", alternative_service_vector[0].host);
9023 EXPECT_EQ(443, alternative_service_vector[0].port);
9024 EXPECT_EQ(QUIC, alternative_service_vector[1].protocol);
9025 EXPECT_EQ("www.example.org", alternative_service_vector[1].host);
9026 EXPECT_EQ(1234, alternative_service_vector[1].port);
9027}
9028
bnc54ec34b72015-08-26 19:34:569029// Alternate Protocol headers must be honored even if |use_alternative_services|
9030// is false.
[email protected]23e482282013-06-14 16:08:029031TEST_P(HttpNetworkTransactionTest, HonorAlternateProtocolHeader) {
[email protected]d7599122014-05-24 03:37:239032 session_deps_.next_protos = SpdyNextProtos();
bnc54ec34b72015-08-26 19:34:569033 session_deps_.use_alternative_services = false;
[email protected]a2cb8122010-03-10 17:22:429034
[email protected]8a0fc822013-06-27 20:52:439035 std::string alternate_protocol_http_header =
9036 GetAlternateProtocolHttpHeader();
9037
[email protected]564b4912010-03-09 16:30:429038 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:529039 MockRead("HTTP/1.1 200 OK\r\n"),
9040 MockRead(alternate_protocol_http_header.c_str()),
9041 MockRead("\r\n"),
9042 MockRead("hello world"),
9043 MockRead(SYNCHRONOUS, OK),
[email protected]564b4912010-03-09 16:30:429044 };
9045
9046 HttpRequestInfo request;
9047 request.method = "GET";
bncce36dca22015-04-21 22:11:239048 request.url = GURL("http://www.example.org/");
[email protected]564b4912010-03-09 16:30:429049 request.load_flags = 0;
9050
9051 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
9052
[email protected]bb88e1d32013-05-03 23:11:079053 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]564b4912010-03-09 16:30:429054
[email protected]49639fa2011-12-20 23:22:419055 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:429056
mmenke6b3af6e2015-09-12 02:06:069057 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369058 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509059 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]564b4912010-03-09 16:30:429060
[email protected]49639fa2011-12-20 23:22:419061 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:429062 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]9e743cd2010-03-16 07:03:539063
bncce36dca22015-04-21 22:11:239064 HostPortPair http_host_port_pair("www.example.org", 80);
[email protected]9801e3702014-03-07 09:33:559065 HttpServerProperties& http_server_properties =
[email protected]17291a022011-10-10 07:32:539066 *session->http_server_properties();
bncd9b132e2015-07-08 05:16:109067 AlternativeServiceVector alternative_service_vector =
9068 http_server_properties.GetAlternativeServices(http_host_port_pair);
9069 EXPECT_TRUE(alternative_service_vector.empty());
[email protected]564b4912010-03-09 16:30:429070
9071 EXPECT_EQ(OK, callback.WaitForResult());
9072
9073 const HttpResponseInfo* response = trans->GetResponseInfo();
9074 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509075 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:429076 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539077 EXPECT_FALSE(response->was_fetched_via_spdy);
9078 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]564b4912010-03-09 16:30:429079
9080 std::string response_data;
9081 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9082 EXPECT_EQ("hello world", response_data);
9083
bncd9b132e2015-07-08 05:16:109084 alternative_service_vector =
9085 http_server_properties.GetAlternativeServices(http_host_port_pair);
9086 ASSERT_EQ(1u, alternative_service_vector.size());
9087 EXPECT_EQ(443, alternative_service_vector[0].port);
bnc181b39a2015-03-17 21:36:479088 EXPECT_EQ(AlternateProtocolFromNextProto(GetParam()),
bncd9b132e2015-07-08 05:16:109089 alternative_service_vector[0].protocol);
[email protected]564b4912010-03-09 16:30:429090}
9091
rch89c6e102015-03-18 18:56:529092TEST_P(HttpNetworkTransactionTest, EmptyAlternateProtocolHeader) {
9093 session_deps_.next_protos = SpdyNextProtos();
bnc55ff9da2015-08-19 18:42:359094 session_deps_.use_alternative_services = true;
rch89c6e102015-03-18 18:56:529095
9096 MockRead data_reads[] = {
9097 MockRead("HTTP/1.1 200 OK\r\n"),
9098 MockRead("Alternate-Protocol: \r\n\r\n"),
9099 MockRead("hello world"),
9100 MockRead(SYNCHRONOUS, OK),
9101 };
9102
9103 HttpRequestInfo request;
9104 request.method = "GET";
bncce36dca22015-04-21 22:11:239105 request.url = GURL("http://www.example.org/");
rch89c6e102015-03-18 18:56:529106 request.load_flags = 0;
9107
9108 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
9109
9110 session_deps_.socket_factory->AddSocketDataProvider(&data);
9111
9112 TestCompletionCallback callback;
9113
mmenke6b3af6e2015-09-12 02:06:069114 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
rch89c6e102015-03-18 18:56:529115
bncce36dca22015-04-21 22:11:239116 HostPortPair http_host_port_pair("www.example.org", 80);
rch89c6e102015-03-18 18:56:529117 HttpServerProperties& http_server_properties =
9118 *session->http_server_properties();
bnccacc0992015-03-20 20:22:229119 AlternativeService alternative_service(QUIC, "", 80);
bnc7dc7e1b42015-07-28 14:43:129120 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
9121 http_server_properties.SetAlternativeService(
9122 http_host_port_pair, alternative_service, 1.0, expiration);
bnccacc0992015-03-20 20:22:229123
bncd9b132e2015-07-08 05:16:109124 AlternativeServiceVector alternative_service_vector =
9125 http_server_properties.GetAlternativeServices(http_host_port_pair);
9126 ASSERT_EQ(1u, alternative_service_vector.size());
9127 EXPECT_EQ(QUIC, alternative_service_vector[0].protocol);
rch89c6e102015-03-18 18:56:529128
9129 scoped_ptr<HttpTransaction> trans(
9130 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9131
9132 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9133 EXPECT_EQ(ERR_IO_PENDING, rv);
9134
9135 EXPECT_EQ(OK, callback.WaitForResult());
9136
9137 const HttpResponseInfo* response = trans->GetResponseInfo();
9138 ASSERT_TRUE(response != NULL);
9139 ASSERT_TRUE(response->headers.get() != NULL);
9140 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9141 EXPECT_FALSE(response->was_fetched_via_spdy);
9142 EXPECT_FALSE(response->was_npn_negotiated);
9143
9144 std::string response_data;
9145 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9146 EXPECT_EQ("hello world", response_data);
9147
bncd9b132e2015-07-08 05:16:109148 alternative_service_vector =
9149 http_server_properties.GetAlternativeServices(http_host_port_pair);
9150 EXPECT_TRUE(alternative_service_vector.empty());
rch89c6e102015-03-18 18:56:529151}
9152
bncc958faa2015-07-31 18:14:529153TEST_P(HttpNetworkTransactionTest, AltSvcOverwritesAlternateProtocol) {
9154 session_deps_.next_protos = SpdyNextProtos();
bnc55ff9da2015-08-19 18:42:359155 session_deps_.use_alternative_services = true;
bncc958faa2015-07-31 18:14:529156
9157 std::string alternative_service_http_header =
9158 GetAlternativeServiceHttpHeader();
9159 std::string alternate_protocol_http_header = GetAlternateProtocolHttpHeader();
9160
9161 MockRead data_reads[] = {
9162 MockRead("HTTP/1.1 200 OK\r\n"),
9163 MockRead(alternative_service_http_header.c_str()),
9164 MockRead(alternate_protocol_http_header.c_str()),
9165 MockRead("\r\n"),
9166 MockRead("hello world"),
9167 MockRead(SYNCHRONOUS, OK),
9168 };
9169
9170 HttpRequestInfo request;
9171 request.method = "GET";
9172 request.url = GURL("http://www.example.org/");
9173 request.load_flags = 0;
9174
9175 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
9176
9177 session_deps_.socket_factory->AddSocketDataProvider(&data);
9178
9179 TestCompletionCallback callback;
9180
mmenke6b3af6e2015-09-12 02:06:069181 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bncc958faa2015-07-31 18:14:529182 scoped_ptr<HttpTransaction> trans(
9183 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9184
9185 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9186 EXPECT_EQ(ERR_IO_PENDING, rv);
9187
9188 HostPortPair http_host_port_pair("www.example.org", 80);
9189 HttpServerProperties& http_server_properties =
9190 *session->http_server_properties();
9191 AlternativeServiceVector alternative_service_vector =
9192 http_server_properties.GetAlternativeServices(http_host_port_pair);
9193 EXPECT_TRUE(alternative_service_vector.empty());
9194
9195 EXPECT_EQ(OK, callback.WaitForResult());
9196
9197 const HttpResponseInfo* response = trans->GetResponseInfo();
9198 ASSERT_TRUE(response != NULL);
9199 ASSERT_TRUE(response->headers.get() != NULL);
9200 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9201 EXPECT_FALSE(response->was_fetched_via_spdy);
9202 EXPECT_FALSE(response->was_npn_negotiated);
9203
9204 std::string response_data;
9205 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9206 EXPECT_EQ("hello world", response_data);
9207
9208 alternative_service_vector =
9209 http_server_properties.GetAlternativeServices(http_host_port_pair);
9210 ASSERT_EQ(1u, alternative_service_vector.size());
9211 EXPECT_EQ(AlternateProtocolFromNextProto(GetParam()),
9212 alternative_service_vector[0].protocol);
9213 EXPECT_EQ("www.example.com", alternative_service_vector[0].host);
9214 EXPECT_EQ(443, alternative_service_vector[0].port);
9215}
9216
bnc54ec34b72015-08-26 19:34:569217// When |use_alternative_services| is false, do not observe alternative service
9218// entries that point to a different host.
9219TEST_P(HttpNetworkTransactionTest, DisableAlternativeServiceToDifferentHost) {
9220 session_deps_.use_alternative_services = false;
9221
9222 HttpRequestInfo request;
9223 request.method = "GET";
9224 request.url = GURL("http://www.example.org/");
9225 request.load_flags = 0;
9226
9227 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
9228 StaticSocketDataProvider first_data;
9229 first_data.set_connect_data(mock_connect);
9230 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
9231
9232 MockRead data_reads[] = {
9233 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
9234 MockRead(ASYNC, OK),
9235 };
9236 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads),
9237 nullptr, 0);
9238 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
9239
mmenke6b3af6e2015-09-12 02:06:069240 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc54ec34b72015-08-26 19:34:569241
9242 base::WeakPtr<HttpServerProperties> http_server_properties =
9243 session->http_server_properties();
9244 AlternativeService alternative_service(
9245 AlternateProtocolFromNextProto(GetParam()), "different.example.org", 80);
9246 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
9247 http_server_properties->SetAlternativeService(
9248 HostPortPair::FromURL(request.url), alternative_service, 1.0, expiration);
9249
9250 scoped_ptr<HttpTransaction> trans(
9251 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9252 TestCompletionCallback callback;
9253
9254 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9255 // The connetion to origin was refused, and the alternative service should not
9256 // be used (even though mock data are there), therefore the request should
9257 // fail.
9258 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.GetResult(rv));
9259}
9260
[email protected]23e482282013-06-14 16:08:029261TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239262 MarkBrokenAlternateProtocolAndFallback) {
bnc55ff9da2015-08-19 18:42:359263 session_deps_.use_alternative_services = true;
[email protected]564b4912010-03-09 16:30:429264
9265 HttpRequestInfo request;
9266 request.method = "GET";
bncce36dca22015-04-21 22:11:239267 request.url = GURL("http://www.example.org/");
[email protected]564b4912010-03-09 16:30:429268 request.load_flags = 0;
9269
[email protected]d973e99a2012-02-17 21:02:369270 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:429271 StaticSocketDataProvider first_data;
9272 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079273 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]564b4912010-03-09 16:30:429274
9275 MockRead data_reads[] = {
9276 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9277 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069278 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:429279 };
9280 StaticSocketDataProvider second_data(
9281 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079282 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:429283
mmenke6b3af6e2015-09-12 02:06:069284 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:429285
[email protected]30d4c022013-07-18 22:58:169286 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:539287 session->http_server_properties();
bnc8445b3002015-03-13 01:57:099288 const HostPortPair host_port_pair = HostPortPair::FromURL(request.url);
[email protected]3912662a32011-10-04 00:51:119289 // Port must be < 1024, or the header will be ignored (since initial port was
9290 // port 80 (another restricted port).
bncd9b132e2015-07-08 05:16:109291 const AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239292 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bncd9b132e2015-07-08 05:16:109293 666); // Port is ignored by MockConnect anyway.
bnc7dc7e1b42015-07-28 14:43:129294 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
9295 http_server_properties->SetAlternativeService(
9296 host_port_pair, alternative_service, 1.0, expiration);
[email protected]564b4912010-03-09 16:30:429297
[email protected]262eec82013-03-19 21:01:369298 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509299 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419300 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:429301
[email protected]49639fa2011-12-20 23:22:419302 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:429303 EXPECT_EQ(ERR_IO_PENDING, rv);
9304 EXPECT_EQ(OK, callback.WaitForResult());
9305
9306 const HttpResponseInfo* response = trans->GetResponseInfo();
9307 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509308 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:429309 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9310
9311 std::string response_data;
9312 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9313 EXPECT_EQ("hello world", response_data);
9314
bncd9b132e2015-07-08 05:16:109315 const AlternativeServiceVector alternative_service_vector =
9316 http_server_properties->GetAlternativeServices(host_port_pair);
9317 ASSERT_EQ(1u, alternative_service_vector.size());
9318 EXPECT_EQ(alternative_service, alternative_service_vector[0]);
9319 EXPECT_TRUE(http_server_properties->IsAlternativeServiceBroken(
9320 alternative_service_vector[0]));
[email protected]564b4912010-03-09 16:30:429321}
9322
bnc55ff9da2015-08-19 18:42:359323// Ensure that we are not allowed to redirect traffic via an alternate protocol
9324// to an unrestricted (port >= 1024) when the original traffic was on a
9325// restricted port (port < 1024). Ensure that we can redirect in all other
9326// cases.
[email protected]23e482282013-06-14 16:08:029327TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239328 AlternateProtocolPortRestrictedBlocked) {
bnc55ff9da2015-08-19 18:42:359329 session_deps_.use_alternative_services = true;
[email protected]3912662a32011-10-04 00:51:119330
9331 HttpRequestInfo restricted_port_request;
9332 restricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:239333 restricted_port_request.url = GURL("http://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:119334 restricted_port_request.load_flags = 0;
9335
[email protected]d973e99a2012-02-17 21:02:369336 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:119337 StaticSocketDataProvider first_data;
9338 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079339 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:119340
9341 MockRead data_reads[] = {
9342 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9343 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069344 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:119345 };
9346 StaticSocketDataProvider second_data(
9347 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079348 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:119349
mmenke6b3af6e2015-09-12 02:06:069350 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:119351
[email protected]30d4c022013-07-18 22:58:169352 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:539353 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:119354 const int kUnrestrictedAlternatePort = 1024;
bnccacc0992015-03-20 20:22:229355 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239356 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229357 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:129358 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:229359 http_server_properties->SetAlternativeService(
9360 HostPortPair::FromURL(restricted_port_request.url), alternative_service,
bnc7dc7e1b42015-07-28 14:43:129361 1.0, expiration);
[email protected]3912662a32011-10-04 00:51:119362
[email protected]262eec82013-03-19 21:01:369363 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509364 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419365 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:119366
[email protected]49639fa2011-12-20 23:22:419367 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:369368 &restricted_port_request,
9369 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:119370 EXPECT_EQ(ERR_IO_PENDING, rv);
9371 // Invalid change to unrestricted port should fail.
9372 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.WaitForResult());
[email protected]c54c6962013-02-01 04:53:199373}
[email protected]3912662a32011-10-04 00:51:119374
bnc55ff9da2015-08-19 18:42:359375// Ensure that we are allowed to redirect traffic via an alternate protocol to
9376// an unrestricted (port >= 1024) when the original traffic was on a restricted
9377// port (port < 1024) if we set |enable_user_alternate_protocol_ports|.
[email protected]23e482282013-06-14 16:08:029378TEST_P(HttpNetworkTransactionTest,
[email protected]c54c6962013-02-01 04:53:199379 AlternateProtocolPortRestrictedPermitted) {
bnc55ff9da2015-08-19 18:42:359380 session_deps_.use_alternative_services = true;
[email protected]bb88e1d32013-05-03 23:11:079381 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:199382
9383 HttpRequestInfo restricted_port_request;
9384 restricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:239385 restricted_port_request.url = GURL("http://www.example.org:1023/");
[email protected]c54c6962013-02-01 04:53:199386 restricted_port_request.load_flags = 0;
9387
9388 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
9389 StaticSocketDataProvider first_data;
9390 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079391 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:199392
9393 MockRead data_reads[] = {
9394 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9395 MockRead("hello world"),
9396 MockRead(ASYNC, OK),
9397 };
9398 StaticSocketDataProvider second_data(
9399 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079400 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]c54c6962013-02-01 04:53:199401
mmenke6b3af6e2015-09-12 02:06:069402 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:199403
[email protected]30d4c022013-07-18 22:58:169404 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]c54c6962013-02-01 04:53:199405 session->http_server_properties();
9406 const int kUnrestrictedAlternatePort = 1024;
bnccacc0992015-03-20 20:22:229407 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239408 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229409 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:129410 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:229411 http_server_properties->SetAlternativeService(
9412 HostPortPair::FromURL(restricted_port_request.url), alternative_service,
bnc7dc7e1b42015-07-28 14:43:129413 1.0, expiration);
[email protected]c54c6962013-02-01 04:53:199414
[email protected]262eec82013-03-19 21:01:369415 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509416 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]c54c6962013-02-01 04:53:199417 TestCompletionCallback callback;
9418
9419 EXPECT_EQ(ERR_IO_PENDING, trans->Start(
[email protected]262eec82013-03-19 21:01:369420 &restricted_port_request,
9421 callback.callback(), BoundNetLog()));
[email protected]c54c6962013-02-01 04:53:199422 // Change to unrestricted port should succeed.
9423 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:119424}
9425
bnc55ff9da2015-08-19 18:42:359426// Ensure that we are not allowed to redirect traffic via an alternate protocol
9427// to an unrestricted (port >= 1024) when the original traffic was on a
9428// restricted port (port < 1024). Ensure that we can redirect in all other
9429// cases.
[email protected]23e482282013-06-14 16:08:029430TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239431 AlternateProtocolPortRestrictedAllowed) {
bnc55ff9da2015-08-19 18:42:359432 session_deps_.use_alternative_services = true;
[email protected]3912662a32011-10-04 00:51:119433
9434 HttpRequestInfo restricted_port_request;
9435 restricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:239436 restricted_port_request.url = GURL("http://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:119437 restricted_port_request.load_flags = 0;
9438
[email protected]d973e99a2012-02-17 21:02:369439 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:119440 StaticSocketDataProvider first_data;
9441 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079442 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:119443
9444 MockRead data_reads[] = {
9445 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9446 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069447 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:119448 };
9449 StaticSocketDataProvider second_data(
9450 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079451 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:119452
mmenke6b3af6e2015-09-12 02:06:069453 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:119454
[email protected]30d4c022013-07-18 22:58:169455 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:539456 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:119457 const int kRestrictedAlternatePort = 80;
bnccacc0992015-03-20 20:22:229458 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239459 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229460 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:129461 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:229462 http_server_properties->SetAlternativeService(
9463 HostPortPair::FromURL(restricted_port_request.url), alternative_service,
bnc7dc7e1b42015-07-28 14:43:129464 1.0, expiration);
[email protected]3912662a32011-10-04 00:51:119465
[email protected]262eec82013-03-19 21:01:369466 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509467 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419468 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:119469
[email protected]49639fa2011-12-20 23:22:419470 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:369471 &restricted_port_request,
9472 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:119473 EXPECT_EQ(ERR_IO_PENDING, rv);
9474 // Valid change to restricted port should pass.
9475 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:119476}
9477
bnc55ff9da2015-08-19 18:42:359478// Ensure that we are not allowed to redirect traffic via an alternate protocol
9479// to an unrestricted (port >= 1024) when the original traffic was on a
9480// restricted port (port < 1024). Ensure that we can redirect in all other
9481// cases.
[email protected]23e482282013-06-14 16:08:029482TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239483 AlternateProtocolPortUnrestrictedAllowed1) {
bnc55ff9da2015-08-19 18:42:359484 session_deps_.use_alternative_services = true;
[email protected]3912662a32011-10-04 00:51:119485
9486 HttpRequestInfo unrestricted_port_request;
9487 unrestricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:239488 unrestricted_port_request.url = GURL("http://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:119489 unrestricted_port_request.load_flags = 0;
9490
[email protected]d973e99a2012-02-17 21:02:369491 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:119492 StaticSocketDataProvider first_data;
9493 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079494 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:119495
9496 MockRead data_reads[] = {
9497 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9498 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069499 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:119500 };
9501 StaticSocketDataProvider second_data(
9502 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079503 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:119504
mmenke6b3af6e2015-09-12 02:06:069505 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:119506
[email protected]30d4c022013-07-18 22:58:169507 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:539508 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:119509 const int kRestrictedAlternatePort = 80;
bnccacc0992015-03-20 20:22:229510 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239511 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229512 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:129513 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:229514 http_server_properties->SetAlternativeService(
9515 HostPortPair::FromURL(unrestricted_port_request.url), alternative_service,
bnc7dc7e1b42015-07-28 14:43:129516 1.0, expiration);
[email protected]3912662a32011-10-04 00:51:119517
[email protected]262eec82013-03-19 21:01:369518 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509519 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419520 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:119521
[email protected]49639fa2011-12-20 23:22:419522 int rv = trans->Start(
9523 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:119524 EXPECT_EQ(ERR_IO_PENDING, rv);
9525 // Valid change to restricted port should pass.
9526 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:119527}
9528
bnc55ff9da2015-08-19 18:42:359529// Ensure that we are not allowed to redirect traffic via an alternate protocol
9530// to an unrestricted (port >= 1024) when the original traffic was on a
9531// restricted port (port < 1024). Ensure that we can redirect in all other
9532// cases.
[email protected]23e482282013-06-14 16:08:029533TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239534 AlternateProtocolPortUnrestrictedAllowed2) {
bnc55ff9da2015-08-19 18:42:359535 session_deps_.use_alternative_services = true;
[email protected]3912662a32011-10-04 00:51:119536
9537 HttpRequestInfo unrestricted_port_request;
9538 unrestricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:239539 unrestricted_port_request.url = GURL("http://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:119540 unrestricted_port_request.load_flags = 0;
9541
[email protected]d973e99a2012-02-17 21:02:369542 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:119543 StaticSocketDataProvider first_data;
9544 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079545 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:119546
9547 MockRead data_reads[] = {
9548 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9549 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069550 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:119551 };
9552 StaticSocketDataProvider second_data(
9553 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079554 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:119555
mmenke6b3af6e2015-09-12 02:06:069556 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:119557
[email protected]30d4c022013-07-18 22:58:169558 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:539559 session->http_server_properties();
bnc0bbb02622015-07-23 10:06:229560 const int kUnrestrictedAlternatePort = 1025;
bnccacc0992015-03-20 20:22:229561 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239562 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229563 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:129564 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:229565 http_server_properties->SetAlternativeService(
9566 HostPortPair::FromURL(unrestricted_port_request.url), alternative_service,
bnc7dc7e1b42015-07-28 14:43:129567 1.0, expiration);
[email protected]3912662a32011-10-04 00:51:119568
[email protected]262eec82013-03-19 21:01:369569 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509570 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419571 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:119572
[email protected]49639fa2011-12-20 23:22:419573 int rv = trans->Start(
9574 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:119575 EXPECT_EQ(ERR_IO_PENDING, rv);
9576 // Valid change to an unrestricted port should pass.
9577 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:119578}
9579
bnc55ff9da2015-08-19 18:42:359580// Ensure that we are not allowed to redirect traffic via an alternate protocol
9581// to an unsafe port, and that we resume the second HttpStreamFactoryImpl::Job
9582// once the alternate protocol request fails.
[email protected]d7599122014-05-24 03:37:239583TEST_P(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
bnc55ff9da2015-08-19 18:42:359584 session_deps_.use_alternative_services = true;
[email protected]eb6234e2012-01-19 01:50:029585
9586 HttpRequestInfo request;
9587 request.method = "GET";
bncce36dca22015-04-21 22:11:239588 request.url = GURL("http://www.example.org/");
[email protected]eb6234e2012-01-19 01:50:029589 request.load_flags = 0;
9590
9591 // The alternate protocol request will error out before we attempt to connect,
9592 // so only the standard HTTP request will try to connect.
9593 MockRead data_reads[] = {
9594 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9595 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069596 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:029597 };
9598 StaticSocketDataProvider data(
9599 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079600 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:029601
mmenke6b3af6e2015-09-12 02:06:069602 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:029603
[email protected]30d4c022013-07-18 22:58:169604 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]eb6234e2012-01-19 01:50:029605 session->http_server_properties();
9606 const int kUnsafePort = 7;
bnccacc0992015-03-20 20:22:229607 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239608 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229609 kUnsafePort);
bnc7dc7e1b42015-07-28 14:43:129610 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:229611 http_server_properties->SetAlternativeService(
bnc7dc7e1b42015-07-28 14:43:129612 HostPortPair::FromURL(request.url), alternative_service, 1.0, expiration);
[email protected]eb6234e2012-01-19 01:50:029613
[email protected]262eec82013-03-19 21:01:369614 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509615 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]eb6234e2012-01-19 01:50:029616 TestCompletionCallback callback;
9617
9618 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9619 EXPECT_EQ(ERR_IO_PENDING, rv);
9620 // The HTTP request should succeed.
9621 EXPECT_EQ(OK, callback.WaitForResult());
9622
[email protected]eb6234e2012-01-19 01:50:029623 const HttpResponseInfo* response = trans->GetResponseInfo();
9624 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509625 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]eb6234e2012-01-19 01:50:029626 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9627
9628 std::string response_data;
9629 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9630 EXPECT_EQ("hello world", response_data);
9631}
9632
[email protected]23e482282013-06-14 16:08:029633TEST_P(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
bnc55ff9da2015-08-19 18:42:359634 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:239635 session_deps_.next_protos = SpdyNextProtos();
[email protected]2ff8b312010-04-26 22:20:549636
9637 HttpRequestInfo request;
9638 request.method = "GET";
bncce36dca22015-04-21 22:11:239639 request.url = GURL("http://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:549640 request.load_flags = 0;
9641
[email protected]8a0fc822013-06-27 20:52:439642 std::string alternate_protocol_http_header =
9643 GetAlternateProtocolHttpHeader();
9644
[email protected]2ff8b312010-04-26 22:20:549645 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:529646 MockRead("HTTP/1.1 200 OK\r\n"),
9647 MockRead(alternate_protocol_http_header.c_str()),
9648 MockRead("\r\n"),
9649 MockRead("hello world"),
9650 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
9651 MockRead(ASYNC, OK)};
[email protected]2ff8b312010-04-26 22:20:549652
9653 StaticSocketDataProvider first_transaction(
9654 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079655 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:549656
[email protected]8ddf8322012-02-23 18:08:069657 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029658 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:239659 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
9660 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:079661 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:549662
[email protected]cdf8f7e72013-05-23 10:56:469663 scoped_ptr<SpdyFrame> req(
9664 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
rch8e6c6c42015-05-01 14:05:139665 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]2ff8b312010-04-26 22:20:549666
[email protected]23e482282013-06-14 16:08:029667 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9668 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:549669 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:139670 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:549671 };
9672
rch8e6c6c42015-05-01 14:05:139673 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9674 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079675 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:549676
[email protected]d973e99a2012-02-17 21:02:369677 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559678 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
9679 NULL, 0, NULL, 0);
9680 hanging_non_alternate_protocol_socket.set_connect_data(
9681 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:079682 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:559683 &hanging_non_alternate_protocol_socket);
9684
[email protected]49639fa2011-12-20 23:22:419685 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:549686
mmenke6b3af6e2015-09-12 02:06:069687 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369688 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509689 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:549690
[email protected]49639fa2011-12-20 23:22:419691 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:549692 EXPECT_EQ(ERR_IO_PENDING, rv);
9693 EXPECT_EQ(OK, callback.WaitForResult());
9694
9695 const HttpResponseInfo* response = trans->GetResponseInfo();
9696 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509697 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:549698 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9699
9700 std::string response_data;
9701 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9702 EXPECT_EQ("hello world", response_data);
9703
[email protected]90499482013-06-01 00:39:509704 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:549705
[email protected]49639fa2011-12-20 23:22:419706 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:549707 EXPECT_EQ(ERR_IO_PENDING, rv);
9708 EXPECT_EQ(OK, callback.WaitForResult());
9709
9710 response = trans->GetResponseInfo();
9711 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509712 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:549713 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539714 EXPECT_TRUE(response->was_fetched_via_spdy);
9715 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:549716
9717 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9718 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:549719}
9720
[email protected]23e482282013-06-14 16:08:029721TEST_P(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
bnc55ff9da2015-08-19 18:42:359722 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:239723 session_deps_.next_protos = SpdyNextProtos();
[email protected]2d6728692011-03-12 01:39:559724
9725 HttpRequestInfo request;
9726 request.method = "GET";
bncce36dca22015-04-21 22:11:239727 request.url = GURL("http://www.example.org/");
[email protected]2d6728692011-03-12 01:39:559728 request.load_flags = 0;
9729
[email protected]8a0fc822013-06-27 20:52:439730 std::string alternate_protocol_http_header =
9731 GetAlternateProtocolHttpHeader();
9732
[email protected]2d6728692011-03-12 01:39:559733 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:529734 MockRead("HTTP/1.1 200 OK\r\n"),
9735 MockRead(alternate_protocol_http_header.c_str()),
9736 MockRead("\r\n"),
9737 MockRead("hello world"),
9738 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
9739 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:559740 };
9741
9742 StaticSocketDataProvider first_transaction(
9743 data_reads, arraysize(data_reads), NULL, 0);
9744 // Socket 1 is the HTTP transaction with the Alternate-Protocol header.
[email protected]bb88e1d32013-05-03 23:11:079745 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:559746
[email protected]d973e99a2012-02-17 21:02:369747 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559748 StaticSocketDataProvider hanging_socket(
9749 NULL, 0, NULL, 0);
9750 hanging_socket.set_connect_data(never_finishing_connect);
9751 // Socket 2 and 3 are the hanging Alternate-Protocol and
9752 // non-Alternate-Protocol jobs from the 2nd transaction.
[email protected]bb88e1d32013-05-03 23:11:079753 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
9754 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
[email protected]2d6728692011-03-12 01:39:559755
[email protected]8ddf8322012-02-23 18:08:069756 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029757 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:239758 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
9759 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:079760 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:559761
[email protected]cdf8f7e72013-05-23 10:56:469762 scoped_ptr<SpdyFrame> req1(
9763 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
9764 scoped_ptr<SpdyFrame> req2(
9765 spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
[email protected]2d6728692011-03-12 01:39:559766 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:139767 CreateMockWrite(*req1, 0), CreateMockWrite(*req2, 1),
[email protected]2d6728692011-03-12 01:39:559768 };
[email protected]23e482282013-06-14 16:08:029769 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9770 scoped_ptr<SpdyFrame> data1(spdy_util_.ConstructSpdyBodyFrame(1, true));
9771 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
9772 scoped_ptr<SpdyFrame> data2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]2d6728692011-03-12 01:39:559773 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:139774 CreateMockRead(*resp1, 2),
9775 CreateMockRead(*data1, 3),
9776 CreateMockRead(*resp2, 4),
9777 CreateMockRead(*data2, 5),
9778 MockRead(ASYNC, 0, 6),
[email protected]2d6728692011-03-12 01:39:559779 };
9780
rch8e6c6c42015-05-01 14:05:139781 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9782 arraysize(spdy_writes));
[email protected]2d6728692011-03-12 01:39:559783 // Socket 4 is the successful Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:079784 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:559785
9786 // Socket 5 is the unsuccessful non-Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:079787 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
[email protected]2d6728692011-03-12 01:39:559788
mmenke6b3af6e2015-09-12 02:06:069789 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:419790 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:509791 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:559792
[email protected]49639fa2011-12-20 23:22:419793 int rv = trans1.Start(&request, callback1.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559794 EXPECT_EQ(ERR_IO_PENDING, rv);
9795 EXPECT_EQ(OK, callback1.WaitForResult());
9796
9797 const HttpResponseInfo* response = trans1.GetResponseInfo();
9798 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509799 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559800 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9801
9802 std::string response_data;
9803 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
9804 EXPECT_EQ("hello world", response_data);
9805
[email protected]49639fa2011-12-20 23:22:419806 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:509807 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:419808 rv = trans2.Start(&request, callback2.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559809 EXPECT_EQ(ERR_IO_PENDING, rv);
9810
[email protected]49639fa2011-12-20 23:22:419811 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:509812 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:419813 rv = trans3.Start(&request, callback3.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559814 EXPECT_EQ(ERR_IO_PENDING, rv);
9815
9816 EXPECT_EQ(OK, callback2.WaitForResult());
9817 EXPECT_EQ(OK, callback3.WaitForResult());
9818
9819 response = trans2.GetResponseInfo();
9820 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509821 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559822 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9823 EXPECT_TRUE(response->was_fetched_via_spdy);
9824 EXPECT_TRUE(response->was_npn_negotiated);
9825 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
9826 EXPECT_EQ("hello!", response_data);
9827
9828 response = trans3.GetResponseInfo();
9829 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509830 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559831 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9832 EXPECT_TRUE(response->was_fetched_via_spdy);
9833 EXPECT_TRUE(response->was_npn_negotiated);
9834 ASSERT_EQ(OK, ReadTransaction(&trans3, &response_data));
9835 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:559836}
9837
[email protected]23e482282013-06-14 16:08:029838TEST_P(HttpNetworkTransactionTest, StallAlternateProtocolForNpnSpdy) {
bnc55ff9da2015-08-19 18:42:359839 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:239840 session_deps_.next_protos = SpdyNextProtos();
[email protected]2d6728692011-03-12 01:39:559841
9842 HttpRequestInfo request;
9843 request.method = "GET";
bncce36dca22015-04-21 22:11:239844 request.url = GURL("http://www.example.org/");
[email protected]2d6728692011-03-12 01:39:559845 request.load_flags = 0;
9846
[email protected]8a0fc822013-06-27 20:52:439847 std::string alternate_protocol_http_header =
9848 GetAlternateProtocolHttpHeader();
9849
[email protected]2d6728692011-03-12 01:39:559850 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:529851 MockRead("HTTP/1.1 200 OK\r\n"),
9852 MockRead(alternate_protocol_http_header.c_str()),
9853 MockRead("\r\n"),
9854 MockRead("hello world"),
9855 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
9856 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:559857 };
9858
9859 StaticSocketDataProvider first_transaction(
9860 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079861 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:559862
[email protected]8ddf8322012-02-23 18:08:069863 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029864 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:079865 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:559866
[email protected]d973e99a2012-02-17 21:02:369867 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559868 StaticSocketDataProvider hanging_alternate_protocol_socket(
9869 NULL, 0, NULL, 0);
9870 hanging_alternate_protocol_socket.set_connect_data(
9871 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:079872 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:559873 &hanging_alternate_protocol_socket);
9874
9875 // 2nd request is just a copy of the first one, over HTTP again.
[email protected]bb88e1d32013-05-03 23:11:079876 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:559877
[email protected]49639fa2011-12-20 23:22:419878 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:559879
mmenke6b3af6e2015-09-12 02:06:069880 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369881 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509882 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:559883
[email protected]49639fa2011-12-20 23:22:419884 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559885 EXPECT_EQ(ERR_IO_PENDING, rv);
9886 EXPECT_EQ(OK, callback.WaitForResult());
9887
9888 const HttpResponseInfo* response = trans->GetResponseInfo();
9889 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509890 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559891 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9892
9893 std::string response_data;
9894 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9895 EXPECT_EQ("hello world", response_data);
9896
[email protected]90499482013-06-01 00:39:509897 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:559898
[email protected]49639fa2011-12-20 23:22:419899 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559900 EXPECT_EQ(ERR_IO_PENDING, rv);
9901 EXPECT_EQ(OK, callback.WaitForResult());
9902
9903 response = trans->GetResponseInfo();
9904 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509905 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559906 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9907 EXPECT_FALSE(response->was_fetched_via_spdy);
9908 EXPECT_FALSE(response->was_npn_negotiated);
9909
9910 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9911 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:559912}
9913
[email protected]631f1322010-04-30 17:59:119914class CapturingProxyResolver : public ProxyResolver {
9915 public:
sammce90c9212015-05-27 23:43:359916 CapturingProxyResolver() {}
dchengb03027d2014-10-21 12:00:209917 ~CapturingProxyResolver() override {}
[email protected]631f1322010-04-30 17:59:119918
dchengb03027d2014-10-21 12:00:209919 int GetProxyForURL(const GURL& url,
9920 ProxyInfo* results,
9921 const CompletionCallback& callback,
9922 RequestHandle* request,
9923 const BoundNetLog& net_log) override {
[email protected]fae7669f2010-08-02 21:49:409924 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
9925 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:429926 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:119927 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:429928 return OK;
[email protected]631f1322010-04-30 17:59:119929 }
9930
dchengb03027d2014-10-21 12:00:209931 void CancelRequest(RequestHandle request) override { NOTREACHED(); }
[email protected]631f1322010-04-30 17:59:119932
dchengb03027d2014-10-21 12:00:209933 LoadState GetLoadState(RequestHandle request) const override {
[email protected]f2c971f2011-11-08 00:33:179934 NOTREACHED();
9935 return LOAD_STATE_IDLE;
9936 }
9937
[email protected]24476402010-07-20 20:55:179938 const std::vector<GURL>& resolved() const { return resolved_; }
9939
9940 private:
[email protected]631f1322010-04-30 17:59:119941 std::vector<GURL> resolved_;
9942
9943 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
9944};
9945
sammce64b2362015-04-29 03:50:239946class CapturingProxyResolverFactory : public ProxyResolverFactory {
9947 public:
9948 explicit CapturingProxyResolverFactory(CapturingProxyResolver* resolver)
9949 : ProxyResolverFactory(false), resolver_(resolver) {}
9950
9951 int CreateProxyResolver(
9952 const scoped_refptr<ProxyResolverScriptData>& pac_script,
9953 scoped_ptr<ProxyResolver>* resolver,
9954 const net::CompletionCallback& callback,
9955 scoped_ptr<Request>* request) override {
9956 resolver->reset(new ForwardingProxyResolver(resolver_));
9957 return OK;
9958 }
9959
9960 private:
9961 ProxyResolver* resolver_;
9962};
9963
[email protected]23e482282013-06-14 16:08:029964TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239965 UseAlternateProtocolForTunneledNpnSpdy) {
bnc55ff9da2015-08-19 18:42:359966 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:239967 session_deps_.next_protos = SpdyNextProtos();
[email protected]631f1322010-04-30 17:59:119968
9969 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:429970 proxy_config.set_auto_detect(true);
9971 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:119972
sammc5dd160c2015-04-02 02:43:139973 CapturingProxyResolver capturing_proxy_resolver;
[email protected]bb88e1d32013-05-03 23:11:079974 session_deps_.proxy_service.reset(new ProxyService(
sammc5dd160c2015-04-02 02:43:139975 new ProxyConfigServiceFixed(proxy_config),
9976 make_scoped_ptr(
sammce64b2362015-04-29 03:50:239977 new CapturingProxyResolverFactory(&capturing_proxy_resolver)),
[email protected]66761b952010-06-25 21:30:389978 NULL));
vishal.b62985ca92015-04-17 08:45:519979 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079980 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:119981
9982 HttpRequestInfo request;
9983 request.method = "GET";
bncce36dca22015-04-21 22:11:239984 request.url = GURL("http://www.example.org/");
[email protected]631f1322010-04-30 17:59:119985 request.load_flags = 0;
9986
[email protected]8a0fc822013-06-27 20:52:439987 std::string alternate_protocol_http_header =
9988 GetAlternateProtocolHttpHeader();
9989
[email protected]631f1322010-04-30 17:59:119990 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:529991 MockRead("HTTP/1.1 200 OK\r\n"),
9992 MockRead(alternate_protocol_http_header.c_str()),
9993 MockRead("\r\n"),
9994 MockRead("hello world"),
9995 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
9996 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:119997 };
9998
9999 StaticSocketDataProvider first_transaction(
10000 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710001 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]631f1322010-04-30 17:59:1110002
[email protected]8ddf8322012-02-23 18:08:0610003 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210004 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:2310005 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
10006 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:0710007 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]631f1322010-04-30 17:59:1110008
[email protected]cdf8f7e72013-05-23 10:56:4610009 scoped_ptr<SpdyFrame> req(
10010 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]631f1322010-04-30 17:59:1110011 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1310012 MockWrite(ASYNC, 0,
10013 "CONNECT www.example.org:443 HTTP/1.1\r\n"
10014 "Host: www.example.org\r\n"
10015 "Proxy-Connection: keep-alive\r\n\r\n"),
10016 CreateMockWrite(*req, 2),
[email protected]631f1322010-04-30 17:59:1110017 };
10018
[email protected]d911f1b2010-05-05 22:39:4210019 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
10020
[email protected]23e482282013-06-14 16:08:0210021 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10022 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]631f1322010-04-30 17:59:1110023 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1310024 MockRead(ASYNC, 1, kCONNECTResponse),
10025 CreateMockRead(*resp.get(), 3),
10026 CreateMockRead(*data.get(), 4),
10027 MockRead(ASYNC, ERR_IO_PENDING, 5),
[email protected]631f1322010-04-30 17:59:1110028 };
10029
rch8e6c6c42015-05-01 14:05:1310030 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10031 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710032 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:1110033
[email protected]d973e99a2012-02-17 21:02:3610034 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5510035 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
10036 NULL, 0, NULL, 0);
10037 hanging_non_alternate_protocol_socket.set_connect_data(
10038 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0710039 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5510040 &hanging_non_alternate_protocol_socket);
10041
[email protected]49639fa2011-12-20 23:22:4110042 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:1110043
mmenke6b3af6e2015-09-12 02:06:0610044 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610045 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010046 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:1110047
[email protected]49639fa2011-12-20 23:22:4110048 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:1110049 EXPECT_EQ(ERR_IO_PENDING, rv);
10050 EXPECT_EQ(OK, callback.WaitForResult());
10051
10052 const HttpResponseInfo* response = trans->GetResponseInfo();
10053 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010054 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]631f1322010-04-30 17:59:1110055 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5310056 EXPECT_FALSE(response->was_fetched_via_spdy);
10057 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:1110058
10059 std::string response_data;
10060 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10061 EXPECT_EQ("hello world", response_data);
10062
[email protected]90499482013-06-01 00:39:5010063 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:1110064
[email protected]49639fa2011-12-20 23:22:4110065 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:1110066 EXPECT_EQ(ERR_IO_PENDING, rv);
10067 EXPECT_EQ(OK, callback.WaitForResult());
10068
10069 response = trans->GetResponseInfo();
10070 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010071 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]631f1322010-04-30 17:59:1110072 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5310073 EXPECT_TRUE(response->was_fetched_via_spdy);
10074 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:1110075
10076 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10077 EXPECT_EQ("hello!", response_data);
sammc5dd160c2015-04-02 02:43:1310078 ASSERT_EQ(3u, capturing_proxy_resolver.resolved().size());
bncce36dca22015-04-21 22:11:2310079 EXPECT_EQ("http://www.example.org/",
sammc5dd160c2015-04-02 02:43:1310080 capturing_proxy_resolver.resolved()[0].spec());
bncce36dca22015-04-21 22:11:2310081 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1310082 capturing_proxy_resolver.resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:1110083
[email protected]029c83b62013-01-24 05:28:2010084 LoadTimingInfo load_timing_info;
10085 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10086 TestLoadTimingNotReusedWithPac(load_timing_info,
10087 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:1110088}
[email protected]631f1322010-04-30 17:59:1110089
[email protected]23e482282013-06-14 16:08:0210090TEST_P(HttpNetworkTransactionTest,
[email protected]2ff8b312010-04-26 22:20:5410091 UseAlternateProtocolForNpnSpdyWithExistingSpdySession) {
bnc55ff9da2015-08-19 18:42:3510092 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2310093 session_deps_.next_protos = SpdyNextProtos();
[email protected]2ff8b312010-04-26 22:20:5410094
10095 HttpRequestInfo request;
10096 request.method = "GET";
bncce36dca22015-04-21 22:11:2310097 request.url = GURL("http://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5410098 request.load_flags = 0;
10099
[email protected]8a0fc822013-06-27 20:52:4310100 std::string alternate_protocol_http_header =
10101 GetAlternateProtocolHttpHeader();
10102
[email protected]2ff8b312010-04-26 22:20:5410103 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210104 MockRead("HTTP/1.1 200 OK\r\n"),
10105 MockRead(alternate_protocol_http_header.c_str()),
10106 MockRead("\r\n"),
10107 MockRead("hello world"),
10108 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:5410109 };
10110
10111 StaticSocketDataProvider first_transaction(
10112 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710113 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:5410114
[email protected]8ddf8322012-02-23 18:08:0610115 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210116 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:2310117 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
10118 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:0710119 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:5410120
[email protected]cdf8f7e72013-05-23 10:56:4610121 scoped_ptr<SpdyFrame> req(
10122 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
rch8e6c6c42015-05-01 14:05:1310123 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]2ff8b312010-04-26 22:20:5410124
[email protected]23e482282013-06-14 16:08:0210125 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10126 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5410127 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1310128 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5410129 };
10130
rch8e6c6c42015-05-01 14:05:1310131 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10132 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710133 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5410134
[email protected]83039bb2011-12-09 18:43:5510135 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5410136
mmenke6b3af6e2015-09-12 02:06:0610137 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:5410138
[email protected]262eec82013-03-19 21:01:3610139 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010140 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5410141
[email protected]49639fa2011-12-20 23:22:4110142 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:5410143 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110144 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:5410145
10146 const HttpResponseInfo* response = trans->GetResponseInfo();
10147 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010148 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:5410149 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10150
10151 std::string response_data;
10152 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10153 EXPECT_EQ("hello world", response_data);
10154
10155 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2310156 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4010157 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5310158 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2710159 base::WeakPtr<SpdySession> spdy_session =
mmenke6b3af6e2015-09-12 02:06:0610160 CreateSecureSpdySession(session, key, BoundNetLog());
[email protected]02b0c342010-09-25 21:09:3810161
[email protected]90499482013-06-01 00:39:5010162 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5410163
[email protected]49639fa2011-12-20 23:22:4110164 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:5410165 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110166 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:5410167
10168 response = trans->GetResponseInfo();
10169 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010170 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:5410171 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5310172 EXPECT_TRUE(response->was_fetched_via_spdy);
10173 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5410174
10175 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10176 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:4210177}
10178
[email protected]044de0642010-06-17 10:42:1510179// GenerateAuthToken is a mighty big test.
10180// It tests all permutation of GenerateAuthToken behavior:
10181// - Synchronous and Asynchronous completion.
10182// - OK or error on completion.
10183// - Direct connection, non-authenticating proxy, and authenticating proxy.
10184// - HTTP or HTTPS backend (to include proxy tunneling).
10185// - Non-authenticating and authenticating backend.
10186//
[email protected]fe3b7dc2012-02-03 19:52:0910187// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:1510188// problems generating an auth token for an authenticating proxy, we don't
10189// need to test all permutations of the backend server).
10190//
10191// The test proceeds by going over each of the configuration cases, and
10192// potentially running up to three rounds in each of the tests. The TestConfig
10193// specifies both the configuration for the test as well as the expectations
10194// for the results.
[email protected]23e482282013-06-14 16:08:0210195TEST_P(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:5010196 static const char kServer[] = "http://www.example.com";
10197 static const char kSecureServer[] = "https://www.example.com";
10198 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:1510199 const int kAuthErr = ERR_INVALID_AUTH_CREDENTIALS;
10200
10201 enum AuthTiming {
10202 AUTH_NONE,
10203 AUTH_SYNC,
10204 AUTH_ASYNC,
10205 };
10206
10207 const MockWrite kGet(
10208 "GET / HTTP/1.1\r\n"
10209 "Host: www.example.com\r\n"
10210 "Connection: keep-alive\r\n\r\n");
10211 const MockWrite kGetProxy(
10212 "GET http://www.example.com/ HTTP/1.1\r\n"
10213 "Host: www.example.com\r\n"
10214 "Proxy-Connection: keep-alive\r\n\r\n");
10215 const MockWrite kGetAuth(
10216 "GET / HTTP/1.1\r\n"
10217 "Host: www.example.com\r\n"
10218 "Connection: keep-alive\r\n"
10219 "Authorization: auth_token\r\n\r\n");
10220 const MockWrite kGetProxyAuth(
10221 "GET http://www.example.com/ HTTP/1.1\r\n"
10222 "Host: www.example.com\r\n"
10223 "Proxy-Connection: keep-alive\r\n"
10224 "Proxy-Authorization: auth_token\r\n\r\n");
10225 const MockWrite kGetAuthThroughProxy(
10226 "GET http://www.example.com/ HTTP/1.1\r\n"
10227 "Host: www.example.com\r\n"
10228 "Proxy-Connection: keep-alive\r\n"
10229 "Authorization: auth_token\r\n\r\n");
10230 const MockWrite kGetAuthWithProxyAuth(
10231 "GET http://www.example.com/ HTTP/1.1\r\n"
10232 "Host: www.example.com\r\n"
10233 "Proxy-Connection: keep-alive\r\n"
10234 "Proxy-Authorization: auth_token\r\n"
10235 "Authorization: auth_token\r\n\r\n");
10236 const MockWrite kConnect(
10237 "CONNECT www.example.com:443 HTTP/1.1\r\n"
10238 "Host: www.example.com\r\n"
10239 "Proxy-Connection: keep-alive\r\n\r\n");
10240 const MockWrite kConnectProxyAuth(
10241 "CONNECT www.example.com:443 HTTP/1.1\r\n"
10242 "Host: www.example.com\r\n"
10243 "Proxy-Connection: keep-alive\r\n"
10244 "Proxy-Authorization: auth_token\r\n\r\n");
10245
10246 const MockRead kSuccess(
10247 "HTTP/1.1 200 OK\r\n"
10248 "Content-Type: text/html; charset=iso-8859-1\r\n"
10249 "Content-Length: 3\r\n\r\n"
10250 "Yes");
10251 const MockRead kFailure(
10252 "Should not be called.");
10253 const MockRead kServerChallenge(
10254 "HTTP/1.1 401 Unauthorized\r\n"
10255 "WWW-Authenticate: Mock realm=server\r\n"
10256 "Content-Type: text/html; charset=iso-8859-1\r\n"
10257 "Content-Length: 14\r\n\r\n"
10258 "Unauthorized\r\n");
10259 const MockRead kProxyChallenge(
10260 "HTTP/1.1 407 Unauthorized\r\n"
10261 "Proxy-Authenticate: Mock realm=proxy\r\n"
10262 "Proxy-Connection: close\r\n"
10263 "Content-Type: text/html; charset=iso-8859-1\r\n"
10264 "Content-Length: 14\r\n\r\n"
10265 "Unauthorized\r\n");
10266 const MockRead kProxyConnected(
10267 "HTTP/1.1 200 Connection Established\r\n\r\n");
10268
10269 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
10270 // no constructors, but the C++ compiler on Windows warns about
10271 // unspecified data in compound literals. So, moved to using constructors,
10272 // and TestRound's created with the default constructor should not be used.
10273 struct TestRound {
10274 TestRound()
10275 : expected_rv(ERR_UNEXPECTED),
10276 extra_write(NULL),
10277 extra_read(NULL) {
10278 }
10279 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
10280 int expected_rv_arg)
10281 : write(write_arg),
10282 read(read_arg),
10283 expected_rv(expected_rv_arg),
10284 extra_write(NULL),
10285 extra_read(NULL) {
10286 }
10287 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
10288 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:0110289 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:1510290 : write(write_arg),
10291 read(read_arg),
10292 expected_rv(expected_rv_arg),
10293 extra_write(extra_write_arg),
10294 extra_read(extra_read_arg) {
10295 }
10296 MockWrite write;
10297 MockRead read;
10298 int expected_rv;
10299 const MockWrite* extra_write;
10300 const MockRead* extra_read;
10301 };
10302
10303 static const int kNoSSL = 500;
10304
10305 struct TestConfig {
thestig9d3bb0c2015-01-24 00:49:5110306 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:1510307 AuthTiming proxy_auth_timing;
10308 int proxy_auth_rv;
thestig9d3bb0c2015-01-24 00:49:5110309 const char* const server_url;
[email protected]044de0642010-06-17 10:42:1510310 AuthTiming server_auth_timing;
10311 int server_auth_rv;
10312 int num_auth_rounds;
10313 int first_ssl_round;
10314 TestRound rounds[3];
10315 } test_configs[] = {
10316 // Non-authenticating HTTP server with a direct connection.
10317 { NULL, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
10318 { TestRound(kGet, kSuccess, OK)}},
10319 // Authenticating HTTP server with a direct connection.
10320 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
10321 { TestRound(kGet, kServerChallenge, OK),
10322 TestRound(kGetAuth, kSuccess, OK)}},
10323 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
10324 { TestRound(kGet, kServerChallenge, OK),
10325 TestRound(kGetAuth, kFailure, kAuthErr)}},
10326 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
10327 { TestRound(kGet, kServerChallenge, OK),
10328 TestRound(kGetAuth, kSuccess, OK)}},
10329 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
10330 { TestRound(kGet, kServerChallenge, OK),
10331 TestRound(kGetAuth, kFailure, kAuthErr)}},
10332 // Non-authenticating HTTP server through a non-authenticating proxy.
10333 { kProxy, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
10334 { TestRound(kGetProxy, kSuccess, OK)}},
10335 // Authenticating HTTP server through a non-authenticating proxy.
10336 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
10337 { TestRound(kGetProxy, kServerChallenge, OK),
10338 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
10339 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
10340 { TestRound(kGetProxy, kServerChallenge, OK),
10341 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
10342 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
10343 { TestRound(kGetProxy, kServerChallenge, OK),
10344 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
10345 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
10346 { TestRound(kGetProxy, kServerChallenge, OK),
10347 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
10348 // Non-authenticating HTTP server through an authenticating proxy.
10349 { kProxy, AUTH_SYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
10350 { TestRound(kGetProxy, kProxyChallenge, OK),
10351 TestRound(kGetProxyAuth, kSuccess, OK)}},
10352 { kProxy, AUTH_SYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
10353 { TestRound(kGetProxy, kProxyChallenge, OK),
10354 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
10355 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
10356 { TestRound(kGetProxy, kProxyChallenge, OK),
10357 TestRound(kGetProxyAuth, kSuccess, OK)}},
10358 { kProxy, AUTH_ASYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
10359 { TestRound(kGetProxy, kProxyChallenge, OK),
10360 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
10361 // Authenticating HTTP server through an authenticating proxy.
10362 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
10363 { TestRound(kGetProxy, kProxyChallenge, OK),
10364 TestRound(kGetProxyAuth, kServerChallenge, OK),
10365 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
10366 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
10367 { TestRound(kGetProxy, kProxyChallenge, OK),
10368 TestRound(kGetProxyAuth, kServerChallenge, OK),
10369 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
10370 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
10371 { TestRound(kGetProxy, kProxyChallenge, OK),
10372 TestRound(kGetProxyAuth, kServerChallenge, OK),
10373 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
10374 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
10375 { TestRound(kGetProxy, kProxyChallenge, OK),
10376 TestRound(kGetProxyAuth, kServerChallenge, OK),
10377 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
10378 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
10379 { TestRound(kGetProxy, kProxyChallenge, OK),
10380 TestRound(kGetProxyAuth, kServerChallenge, OK),
10381 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
10382 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
10383 { TestRound(kGetProxy, kProxyChallenge, OK),
10384 TestRound(kGetProxyAuth, kServerChallenge, OK),
10385 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
10386 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
10387 { TestRound(kGetProxy, kProxyChallenge, OK),
10388 TestRound(kGetProxyAuth, kServerChallenge, OK),
10389 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
10390 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
10391 { TestRound(kGetProxy, kProxyChallenge, OK),
10392 TestRound(kGetProxyAuth, kServerChallenge, OK),
10393 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
10394 // Non-authenticating HTTPS server with a direct connection.
10395 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
10396 { TestRound(kGet, kSuccess, OK)}},
10397 // Authenticating HTTPS server with a direct connection.
10398 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
10399 { TestRound(kGet, kServerChallenge, OK),
10400 TestRound(kGetAuth, kSuccess, OK)}},
10401 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
10402 { TestRound(kGet, kServerChallenge, OK),
10403 TestRound(kGetAuth, kFailure, kAuthErr)}},
10404 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
10405 { TestRound(kGet, kServerChallenge, OK),
10406 TestRound(kGetAuth, kSuccess, OK)}},
10407 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
10408 { TestRound(kGet, kServerChallenge, OK),
10409 TestRound(kGetAuth, kFailure, kAuthErr)}},
10410 // Non-authenticating HTTPS server with a non-authenticating proxy.
10411 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
10412 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
10413 // Authenticating HTTPS server through a non-authenticating proxy.
10414 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
10415 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
10416 TestRound(kGetAuth, kSuccess, OK)}},
10417 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
10418 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
10419 TestRound(kGetAuth, kFailure, kAuthErr)}},
10420 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
10421 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
10422 TestRound(kGetAuth, kSuccess, OK)}},
10423 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
10424 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
10425 TestRound(kGetAuth, kFailure, kAuthErr)}},
10426 // Non-Authenticating HTTPS server through an authenticating proxy.
10427 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
10428 { TestRound(kConnect, kProxyChallenge, OK),
10429 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
10430 { kProxy, AUTH_SYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
10431 { TestRound(kConnect, kProxyChallenge, OK),
10432 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
10433 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
10434 { TestRound(kConnect, kProxyChallenge, OK),
10435 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
10436 { kProxy, AUTH_ASYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
10437 { TestRound(kConnect, kProxyChallenge, OK),
10438 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
10439 // Authenticating HTTPS server through an authenticating proxy.
10440 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
10441 { TestRound(kConnect, kProxyChallenge, OK),
10442 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10443 &kGet, &kServerChallenge),
10444 TestRound(kGetAuth, kSuccess, OK)}},
10445 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
10446 { TestRound(kConnect, kProxyChallenge, OK),
10447 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10448 &kGet, &kServerChallenge),
10449 TestRound(kGetAuth, kFailure, kAuthErr)}},
10450 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
10451 { TestRound(kConnect, kProxyChallenge, OK),
10452 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10453 &kGet, &kServerChallenge),
10454 TestRound(kGetAuth, kSuccess, OK)}},
10455 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
10456 { TestRound(kConnect, kProxyChallenge, OK),
10457 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10458 &kGet, &kServerChallenge),
10459 TestRound(kGetAuth, kFailure, kAuthErr)}},
10460 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
10461 { TestRound(kConnect, kProxyChallenge, OK),
10462 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10463 &kGet, &kServerChallenge),
10464 TestRound(kGetAuth, kSuccess, OK)}},
10465 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
10466 { TestRound(kConnect, kProxyChallenge, OK),
10467 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10468 &kGet, &kServerChallenge),
10469 TestRound(kGetAuth, kFailure, kAuthErr)}},
10470 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
10471 { TestRound(kConnect, kProxyChallenge, OK),
10472 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10473 &kGet, &kServerChallenge),
10474 TestRound(kGetAuth, kSuccess, OK)}},
10475 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
10476 { TestRound(kConnect, kProxyChallenge, OK),
10477 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10478 &kGet, &kServerChallenge),
10479 TestRound(kGetAuth, kFailure, kAuthErr)}},
10480 };
10481
viettrungluue4a8b882014-10-16 06:17:3810482 for (size_t i = 0; i < arraysize(test_configs); ++i) {
[email protected]2d01c262011-08-11 23:07:0810483 HttpAuthHandlerMock::Factory* auth_factory(
10484 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0710485 session_deps_.http_auth_handler_factory.reset(auth_factory);
[email protected]044de0642010-06-17 10:42:1510486 const TestConfig& test_config = test_configs[i];
[email protected]65d34382010-07-01 18:12:2610487
10488 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:1510489 if (test_config.proxy_auth_timing != AUTH_NONE) {
[email protected]2d01c262011-08-11 23:07:0810490 for (int n = 0; n < 2; n++) {
10491 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
10492 std::string auth_challenge = "Mock realm=proxy";
10493 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:2410494 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
10495 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:0810496 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
10497 origin, BoundNetLog());
10498 auth_handler->SetGenerateExpectation(
10499 test_config.proxy_auth_timing == AUTH_ASYNC,
10500 test_config.proxy_auth_rv);
10501 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
10502 }
[email protected]044de0642010-06-17 10:42:1510503 }
10504 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:0010505 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:1510506 std::string auth_challenge = "Mock realm=server";
10507 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:2410508 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
10509 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:1510510 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
10511 origin, BoundNetLog());
10512 auth_handler->SetGenerateExpectation(
10513 test_config.server_auth_timing == AUTH_ASYNC,
10514 test_config.server_auth_rv);
[email protected]2d01c262011-08-11 23:07:0810515 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:1510516 }
10517 if (test_config.proxy_url) {
[email protected]bb88e1d32013-05-03 23:11:0710518 session_deps_.proxy_service.reset(
[email protected]6104ea5d2011-04-27 21:37:1210519 ProxyService::CreateFixed(test_config.proxy_url));
[email protected]044de0642010-06-17 10:42:1510520 } else {
[email protected]bb88e1d32013-05-03 23:11:0710521 session_deps_.proxy_service.reset(ProxyService::CreateDirect());
[email protected]044de0642010-06-17 10:42:1510522 }
10523
10524 HttpRequestInfo request;
10525 request.method = "GET";
10526 request.url = GURL(test_config.server_url);
10527 request.load_flags = 0;
10528
mmenke6b3af6e2015-09-12 02:06:0610529 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
dcheng48459ac22014-08-26 00:46:4110530 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]044de0642010-06-17 10:42:1510531
rchcb68dc62015-05-21 04:45:3610532 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
10533
10534 std::vector<std::vector<MockRead>> mock_reads(1);
10535 std::vector<std::vector<MockWrite>> mock_writes(1);
[email protected]044de0642010-06-17 10:42:1510536 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
10537 const TestRound& read_write_round = test_config.rounds[round];
10538
10539 // Set up expected reads and writes.
rchcb68dc62015-05-21 04:45:3610540 mock_reads.back().push_back(read_write_round.read);
10541 mock_writes.back().push_back(read_write_round.write);
10542
10543 // kProxyChallenge uses Proxy-Connection: close which means that the
10544 // socket is closed and a new one will be created for the next request.
mmenkee0b5c882015-08-26 20:29:1110545 if (read_write_round.read.data == kProxyChallenge.data) {
rchcb68dc62015-05-21 04:45:3610546 mock_reads.push_back(std::vector<MockRead>());
10547 mock_writes.push_back(std::vector<MockWrite>());
[email protected]044de0642010-06-17 10:42:1510548 }
10549
rchcb68dc62015-05-21 04:45:3610550 if (read_write_round.extra_read) {
10551 mock_reads.back().push_back(*read_write_round.extra_read);
[email protected]044de0642010-06-17 10:42:1510552 }
rchcb68dc62015-05-21 04:45:3610553 if (read_write_round.extra_write) {
10554 mock_writes.back().push_back(*read_write_round.extra_write);
10555 }
[email protected]044de0642010-06-17 10:42:1510556
10557 // Add an SSL sequence if necessary.
[email protected]044de0642010-06-17 10:42:1510558 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0710559 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1510560 &ssl_socket_data_provider);
rchcb68dc62015-05-21 04:45:3610561 }
[email protected]044de0642010-06-17 10:42:1510562
rchcb68dc62015-05-21 04:45:3610563 ScopedVector<StaticSocketDataProvider> data_providers;
10564 for (size_t i = 0; i < mock_reads.size(); ++i) {
10565 data_providers.push_back(new StaticSocketDataProvider(
10566 vector_as_array(&mock_reads[i]), mock_reads[i].size(),
10567 vector_as_array(&mock_writes[i]), mock_writes[i].size()));
10568 session_deps_.socket_factory->AddSocketDataProvider(
10569 data_providers.back());
10570 }
10571
10572 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
10573 const TestRound& read_write_round = test_config.rounds[round];
[email protected]044de0642010-06-17 10:42:1510574 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4110575 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1510576 int rv;
10577 if (round == 0) {
[email protected]49639fa2011-12-20 23:22:4110578 rv = trans.Start(&request, callback.callback(), BoundNetLog());
[email protected]044de0642010-06-17 10:42:1510579 } else {
[email protected]49639fa2011-12-20 23:22:4110580 rv = trans.RestartWithAuth(
10581 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1510582 }
10583 if (rv == ERR_IO_PENDING)
10584 rv = callback.WaitForResult();
10585
10586 // Compare results with expected data.
10587 EXPECT_EQ(read_write_round.expected_rv, rv);
[email protected]0b0bf032010-09-21 18:08:5010588 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttlec0c828492015-05-15 01:25:5510589 if (read_write_round.expected_rv != OK) {
[email protected]044de0642010-06-17 10:42:1510590 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
10591 continue;
10592 }
10593 if (round + 1 < test_config.num_auth_rounds) {
10594 EXPECT_FALSE(response->auth_challenge.get() == NULL);
10595 } else {
10596 EXPECT_TRUE(response->auth_challenge.get() == NULL);
10597 }
10598 }
[email protected]e5ae96a2010-04-14 20:12:4510599 }
10600}
10601
[email protected]23e482282013-06-14 16:08:0210602TEST_P(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1410603 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1410604 HttpAuthHandlerMock::Factory* auth_factory(
10605 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0710606 session_deps_.http_auth_handler_factory.reset(auth_factory);
10607 session_deps_.proxy_service.reset(ProxyService::CreateDirect());
10608 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
10609 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:1410610
10611 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
10612 auth_handler->set_connection_based(true);
10613 std::string auth_challenge = "Mock realm=server";
10614 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2410615 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
10616 auth_challenge.end());
[email protected]c871bce92010-07-15 21:51:1410617 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
10618 origin, BoundNetLog());
[email protected]2d01c262011-08-11 23:07:0810619 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1410620
[email protected]c871bce92010-07-15 21:51:1410621 int rv = OK;
10622 const HttpResponseInfo* response = NULL;
10623 HttpRequestInfo request;
10624 request.method = "GET";
10625 request.url = origin;
10626 request.load_flags = 0;
[email protected]cb9bf6ca2011-01-28 13:15:2710627
mmenke6b3af6e2015-09-12 02:06:0610628 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1010629
10630 // Use a TCP Socket Pool with only one connection per group. This is used
10631 // to validate that the TCP socket is not released to the pool between
10632 // each round of multi-round authentication.
mmenke6b3af6e2015-09-12 02:06:0610633 HttpNetworkSessionPeer session_peer(session);
[email protected]ab739042011-04-07 15:22:2810634 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:1010635 50, // Max sockets for pool
10636 1, // Max sockets per group
[email protected]bb88e1d32013-05-03 23:11:0710637 session_deps_.host_resolver.get(),
10638 session_deps_.socket_factory.get(),
10639 session_deps_.net_log);
[email protected]831e4a32013-11-14 02:14:4410640 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
10641 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:0210642 mock_pool_manager->SetTransportSocketPool(transport_pool);
dchenge3d1ddc2014-10-15 19:30:5110643 session_peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]7ef4cbbb2011-02-06 11:19:1010644
[email protected]262eec82013-03-19 21:01:3610645 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010646 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110647 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1410648
10649 const MockWrite kGet(
10650 "GET / HTTP/1.1\r\n"
10651 "Host: www.example.com\r\n"
10652 "Connection: keep-alive\r\n\r\n");
10653 const MockWrite kGetAuth(
10654 "GET / HTTP/1.1\r\n"
10655 "Host: www.example.com\r\n"
10656 "Connection: keep-alive\r\n"
10657 "Authorization: auth_token\r\n\r\n");
10658
10659 const MockRead kServerChallenge(
10660 "HTTP/1.1 401 Unauthorized\r\n"
10661 "WWW-Authenticate: Mock realm=server\r\n"
10662 "Content-Type: text/html; charset=iso-8859-1\r\n"
10663 "Content-Length: 14\r\n\r\n"
10664 "Unauthorized\r\n");
10665 const MockRead kSuccess(
10666 "HTTP/1.1 200 OK\r\n"
10667 "Content-Type: text/html; charset=iso-8859-1\r\n"
10668 "Content-Length: 3\r\n\r\n"
10669 "Yes");
10670
10671 MockWrite writes[] = {
10672 // First round
10673 kGet,
10674 // Second round
10675 kGetAuth,
10676 // Third round
10677 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3010678 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1010679 kGetAuth,
10680 // Competing request
10681 kGet,
[email protected]c871bce92010-07-15 21:51:1410682 };
10683 MockRead reads[] = {
10684 // First round
10685 kServerChallenge,
10686 // Second round
10687 kServerChallenge,
10688 // Third round
[email protected]eca50e122010-09-11 14:03:3010689 kServerChallenge,
10690 // Fourth round
[email protected]c871bce92010-07-15 21:51:1410691 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1010692 // Competing response
10693 kSuccess,
[email protected]c871bce92010-07-15 21:51:1410694 };
10695 StaticSocketDataProvider data_provider(reads, arraysize(reads),
10696 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:0710697 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1410698
thestig9d3bb0c2015-01-24 00:49:5110699 const char kSocketGroup[] = "www.example.com:80";
[email protected]7ef4cbbb2011-02-06 11:19:1010700
10701 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1410702 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4110703 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]c871bce92010-07-15 21:51:1410704 if (rv == ERR_IO_PENDING)
10705 rv = callback.WaitForResult();
10706 EXPECT_EQ(OK, rv);
10707 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010708 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:1410709 EXPECT_FALSE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2810710 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1410711
[email protected]7ef4cbbb2011-02-06 11:19:1010712 // In between rounds, another request comes in for the same domain.
10713 // It should not be able to grab the TCP socket that trans has already
10714 // claimed.
10715 scoped_ptr<HttpTransaction> trans_compete(
[email protected]90499482013-06-01 00:39:5010716 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110717 TestCompletionCallback callback_compete;
10718 rv = trans_compete->Start(
10719 &request, callback_compete.callback(), BoundNetLog());
[email protected]7ef4cbbb2011-02-06 11:19:1010720 EXPECT_EQ(ERR_IO_PENDING, rv);
10721 // callback_compete.WaitForResult at this point would stall forever,
10722 // since the HttpNetworkTransaction does not release the request back to
10723 // the pool until after authentication completes.
10724
10725 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1410726 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4110727 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1410728 if (rv == ERR_IO_PENDING)
10729 rv = callback.WaitForResult();
10730 EXPECT_EQ(OK, rv);
10731 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010732 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:1410733 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2810734 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1410735
[email protected]7ef4cbbb2011-02-06 11:19:1010736 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1410737 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4110738 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1410739 if (rv == ERR_IO_PENDING)
10740 rv = callback.WaitForResult();
10741 EXPECT_EQ(OK, rv);
10742 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010743 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:1410744 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2810745 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]eca50e122010-09-11 14:03:3010746
[email protected]7ef4cbbb2011-02-06 11:19:1010747 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3010748 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4110749 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3010750 if (rv == ERR_IO_PENDING)
10751 rv = callback.WaitForResult();
10752 EXPECT_EQ(OK, rv);
10753 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010754 ASSERT_TRUE(response != NULL);
[email protected]eca50e122010-09-11 14:03:3010755 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2810756 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1010757
10758 // Read the body since the fourth round was successful. This will also
10759 // release the socket back to the pool.
10760 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
[email protected]90499482013-06-01 00:39:5010761 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1010762 if (rv == ERR_IO_PENDING)
10763 rv = callback.WaitForResult();
10764 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:5010765 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1010766 EXPECT_EQ(0, rv);
10767 // There are still 0 idle sockets, since the trans_compete transaction
10768 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:2810769 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1010770
10771 // The competing request can now finish. Wait for the headers and then
10772 // read the body.
10773 rv = callback_compete.WaitForResult();
10774 EXPECT_EQ(OK, rv);
[email protected]90499482013-06-01 00:39:5010775 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1010776 if (rv == ERR_IO_PENDING)
10777 rv = callback.WaitForResult();
10778 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:5010779 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1010780 EXPECT_EQ(0, rv);
10781
10782 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:2810783 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1410784}
10785
[email protected]65041fa2010-05-21 06:56:5310786// This tests the case that a request is issued via http instead of spdy after
10787// npn is negotiated.
[email protected]23e482282013-06-14 16:08:0210788TEST_P(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
bnc55ff9da2015-08-19 18:42:3510789 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2310790 NextProtoVector next_protos;
[email protected]0ce3af82013-07-22 16:17:1610791 next_protos.push_back(kProtoHTTP11);
[email protected]d7599122014-05-24 03:37:2310792 session_deps_.next_protos = next_protos;
10793
[email protected]65041fa2010-05-21 06:56:5310794 HttpRequestInfo request;
10795 request.method = "GET";
bncce36dca22015-04-21 22:11:2310796 request.url = GURL("https://www.example.org/");
[email protected]65041fa2010-05-21 06:56:5310797 request.load_flags = 0;
10798
10799 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310800 MockWrite(
10801 "GET / HTTP/1.1\r\n"
10802 "Host: www.example.org\r\n"
10803 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5310804 };
10805
[email protected]8a0fc822013-06-27 20:52:4310806 std::string alternate_protocol_http_header =
10807 GetAlternateProtocolHttpHeader();
10808
[email protected]65041fa2010-05-21 06:56:5310809 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210810 MockRead("HTTP/1.1 200 OK\r\n"),
10811 MockRead(alternate_protocol_http_header.c_str()),
10812 MockRead("\r\n"),
10813 MockRead("hello world"),
10814 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5310815 };
10816
[email protected]8ddf8322012-02-23 18:08:0610817 SSLSocketDataProvider ssl(ASYNC, OK);
davidben6974bf72015-04-27 17:52:4810818 ssl.SetNextProto(kProtoHTTP11);
[email protected]65041fa2010-05-21 06:56:5310819
[email protected]bb88e1d32013-05-03 23:11:0710820 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5310821
10822 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
10823 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0710824 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5310825
[email protected]49639fa2011-12-20 23:22:4110826 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5310827
mmenke6b3af6e2015-09-12 02:06:0610828 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610829 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010830 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]65041fa2010-05-21 06:56:5310831
[email protected]49639fa2011-12-20 23:22:4110832 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]65041fa2010-05-21 06:56:5310833
10834 EXPECT_EQ(ERR_IO_PENDING, rv);
10835 EXPECT_EQ(OK, callback.WaitForResult());
10836
10837 const HttpResponseInfo* response = trans->GetResponseInfo();
10838 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010839 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]65041fa2010-05-21 06:56:5310840 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10841
10842 std::string response_data;
10843 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10844 EXPECT_EQ("hello world", response_data);
10845
10846 EXPECT_FALSE(response->was_fetched_via_spdy);
10847 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]65041fa2010-05-21 06:56:5310848}
[email protected]26ef6582010-06-24 02:30:4710849
bnc55ff9da2015-08-19 18:42:3510850// Simulate the SSL handshake completing with an NPN negotiation followed by an
10851// immediate server closing of the socket.
10852// Regression test for https://crbug.com/46369.
[email protected]23e482282013-06-14 16:08:0210853TEST_P(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
bnc55ff9da2015-08-19 18:42:3510854 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2310855 session_deps_.next_protos = SpdyNextProtos();
[email protected]26ef6582010-06-24 02:30:4710856
10857 HttpRequestInfo request;
10858 request.method = "GET";
bncce36dca22015-04-21 22:11:2310859 request.url = GURL("https://www.example.org/");
[email protected]26ef6582010-06-24 02:30:4710860 request.load_flags = 0;
10861
[email protected]8ddf8322012-02-23 18:08:0610862 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210863 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710864 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4710865
[email protected]cdf8f7e72013-05-23 10:56:4610866 scoped_ptr<SpdyFrame> req(
10867 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
rch8e6c6c42015-05-01 14:05:1310868 MockWrite spdy_writes[] = {CreateMockWrite(*req, 1)};
[email protected]26ef6582010-06-24 02:30:4710869
10870 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0610871 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4710872 };
10873
rch8e6c6c42015-05-01 14:05:1310874 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10875 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710876 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4710877
[email protected]49639fa2011-12-20 23:22:4110878 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4710879
mmenke6b3af6e2015-09-12 02:06:0610880 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610881 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010882 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]26ef6582010-06-24 02:30:4710883
[email protected]49639fa2011-12-20 23:22:4110884 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]26ef6582010-06-24 02:30:4710885 EXPECT_EQ(ERR_IO_PENDING, rv);
10886 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult());
[email protected]26ef6582010-06-24 02:30:4710887}
[email protected]65d34382010-07-01 18:12:2610888
[email protected]795cbf82013-07-22 09:37:2710889// A subclass of HttpAuthHandlerMock that records the request URL when
10890// it gets it. This is needed since the auth handler may get destroyed
10891// before we get a chance to query it.
10892class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
10893 public:
10894 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
10895
dchengb03027d2014-10-21 12:00:2010896 ~UrlRecordingHttpAuthHandlerMock() override {}
[email protected]795cbf82013-07-22 09:37:2710897
10898 protected:
dchengb03027d2014-10-21 12:00:2010899 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
10900 const HttpRequestInfo* request,
10901 const CompletionCallback& callback,
10902 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2710903 *url_ = request->url;
10904 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
10905 credentials, request, callback, auth_token);
10906 }
10907
10908 private:
10909 GURL* url_;
10910};
10911
bnc55ff9da2015-08-19 18:42:3510912// This test ensures that the URL passed into the proxy is upgraded to https
10913// when doing an Alternate Protocol upgrade.
[email protected]23e482282013-06-14 16:08:0210914TEST_P(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) {
bnc55ff9da2015-08-19 18:42:3510915 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2310916 session_deps_.next_protos = SpdyNextProtos();
[email protected]f45c1ee2010-08-03 00:54:3010917
[email protected]bb88e1d32013-05-03 23:11:0710918 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:2010919 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
vishal.b62985ca92015-04-17 08:45:5110920 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710921 session_deps_.net_log = &net_log;
[email protected]795cbf82013-07-22 09:37:2710922 GURL request_url;
10923 {
10924 HttpAuthHandlerMock::Factory* auth_factory =
10925 new HttpAuthHandlerMock::Factory();
10926 UrlRecordingHttpAuthHandlerMock* auth_handler =
10927 new UrlRecordingHttpAuthHandlerMock(&request_url);
10928 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
10929 auth_factory->set_do_init_from_challenge(true);
10930 session_deps_.http_auth_handler_factory.reset(auth_factory);
10931 }
[email protected]f45c1ee2010-08-03 00:54:3010932
10933 HttpRequestInfo request;
10934 request.method = "GET";
bncce36dca22015-04-21 22:11:2310935 request.url = GURL("http://www.example.org");
[email protected]f45c1ee2010-08-03 00:54:3010936 request.load_flags = 0;
10937
10938 // First round goes unauthenticated through the proxy.
10939 MockWrite data_writes_1[] = {
bncce36dca22015-04-21 22:11:2310940 MockWrite(
10941 "GET http://www.example.org/ HTTP/1.1\r\n"
10942 "Host: www.example.org\r\n"
10943 "Proxy-Connection: keep-alive\r\n"
10944 "\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3010945 };
10946 MockRead data_reads_1[] = {
[email protected]8ddf8322012-02-23 18:08:0610947 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
bnc33b8cef42014-11-19 17:30:3810948 MockRead("HTTP/1.1 200 OK\r\n"),
10949 MockRead("Alternate-Protocol: 443:"),
10950 MockRead(GetAlternateProtocolFromParam()),
10951 MockRead("\r\n"),
10952 MockRead("Proxy-Connection: close\r\n"),
10953 MockRead("\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3010954 };
10955 StaticSocketDataProvider data_1(data_reads_1, arraysize(data_reads_1),
10956 data_writes_1, arraysize(data_writes_1));
10957
bncce36dca22015-04-21 22:11:2310958 // Second round tries to tunnel to www.example.org due to the
[email protected]f45c1ee2010-08-03 00:54:3010959 // Alternate-Protocol announcement in the first round. It fails due
10960 // to a proxy authentication challenge.
bncce36dca22015-04-21 22:11:2310961 // After the failure, a tunnel is established to www.example.org using
[email protected]394816e92010-08-03 07:38:5910962 // Proxy-Authorization headers. There is then a SPDY request round.
10963 //
[email protected]fe3b7dc2012-02-03 19:52:0910964 // NOTE: Despite the "Proxy-Connection: Close", these are done on the
10965 // same MockTCPClientSocket since the underlying HttpNetworkClientSocket
10966 // does a Disconnect and Connect on the same socket, rather than trying
10967 // to obtain a new one.
10968 //
[email protected]394816e92010-08-03 07:38:5910969 // NOTE: Originally, the proxy response to the second CONNECT request
10970 // simply returned another 407 so the unit test could skip the SSL connection
10971 // establishment and SPDY framing issues. Alas, the
10972 // retry-http-when-alternate-protocol fails logic kicks in, which was more
[email protected]f45c1ee2010-08-03 00:54:3010973 // complicated to set up expectations for than the SPDY session.
[email protected]394816e92010-08-03 07:38:5910974
[email protected]cdf8f7e72013-05-23 10:56:4610975 scoped_ptr<SpdyFrame> req(
10976 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]23e482282013-06-14 16:08:0210977 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10978 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]f45c1ee2010-08-03 00:54:3010979
[email protected]394816e92010-08-03 07:38:5910980 MockWrite data_writes_2[] = {
bncce36dca22015-04-21 22:11:2310981 // First connection attempt without Proxy-Authorization.
rch8e6c6c42015-05-01 14:05:1310982 MockWrite(ASYNC, 0,
10983 "CONNECT www.example.org:443 HTTP/1.1\r\n"
10984 "Host: www.example.org\r\n"
10985 "Proxy-Connection: keep-alive\r\n"
10986 "\r\n"),
[email protected]394816e92010-08-03 07:38:5910987
bncce36dca22015-04-21 22:11:2310988 // Second connection attempt with Proxy-Authorization.
rch8e6c6c42015-05-01 14:05:1310989 MockWrite(ASYNC, 2,
10990 "CONNECT www.example.org:443 HTTP/1.1\r\n"
10991 "Host: www.example.org\r\n"
10992 "Proxy-Connection: keep-alive\r\n"
10993 "Proxy-Authorization: auth_token\r\n"
10994 "\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3010995
bncce36dca22015-04-21 22:11:2310996 // SPDY request
rch8e6c6c42015-05-01 14:05:1310997 CreateMockWrite(*req, 4),
[email protected]f45c1ee2010-08-03 00:54:3010998 };
[email protected]394816e92010-08-03 07:38:5910999 MockRead data_reads_2[] = {
rch8e6c6c42015-05-01 14:05:1311000 // First connection attempt fails
mmenkee0b5c882015-08-26 20:29:1111001 MockRead(ASYNC, 1,
11002 "HTTP/1.1 407 Unauthorized\r\n"
11003 "Proxy-Authenticate: Mock\r\n"
11004 "Content-Length: 0\r\n"
11005 "Proxy-Connection: keep-alive\r\n"
11006 "\r\n"),
[email protected]394816e92010-08-03 07:38:5911007
rch8e6c6c42015-05-01 14:05:1311008 // Second connection attempt passes
mmenkee0b5c882015-08-26 20:29:1111009 MockRead(ASYNC, 3, "HTTP/1.1 200 Connected\r\n\r\n"),
[email protected]394816e92010-08-03 07:38:5911010
rch8e6c6c42015-05-01 14:05:1311011 // SPDY response
mmenkee0b5c882015-08-26 20:29:1111012 CreateMockRead(*resp.get(), 5), CreateMockRead(*data.get(), 6),
rch8e6c6c42015-05-01 14:05:1311013 MockRead(ASYNC, 0, 0, 7),
[email protected]394816e92010-08-03 07:38:5911014 };
rch8e6c6c42015-05-01 14:05:1311015 SequencedSocketData data_2(data_reads_2, arraysize(data_reads_2),
11016 data_writes_2, arraysize(data_writes_2));
[email protected]f45c1ee2010-08-03 00:54:3011017
[email protected]8ddf8322012-02-23 18:08:0611018 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211019 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:2311020 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
11021 ASSERT_TRUE(ssl.cert.get());
[email protected]f45c1ee2010-08-03 00:54:3011022
[email protected]d973e99a2012-02-17 21:02:3611023 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511024 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
11025 NULL, 0, NULL, 0);
11026 hanging_non_alternate_protocol_socket.set_connect_data(
11027 never_finishing_connect);
11028
[email protected]bb88e1d32013-05-03 23:11:0711029 session_deps_.socket_factory->AddSocketDataProvider(&data_1);
11030 session_deps_.socket_factory->AddSocketDataProvider(&data_2);
11031 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11032 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511033 &hanging_non_alternate_protocol_socket);
mmenke6b3af6e2015-09-12 02:06:0611034 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f45c1ee2010-08-03 00:54:3011035
11036 // First round should work and provide the Alternate-Protocol state.
[email protected]49639fa2011-12-20 23:22:4111037 TestCompletionCallback callback_1;
[email protected]262eec82013-03-19 21:01:3611038 scoped_ptr<HttpTransaction> trans_1(
[email protected]90499482013-06-01 00:39:5011039 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4111040 int rv = trans_1->Start(&request, callback_1.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:3011041 EXPECT_EQ(ERR_IO_PENDING, rv);
11042 EXPECT_EQ(OK, callback_1.WaitForResult());
11043
11044 // Second round should attempt a tunnel connect and get an auth challenge.
[email protected]49639fa2011-12-20 23:22:4111045 TestCompletionCallback callback_2;
[email protected]262eec82013-03-19 21:01:3611046 scoped_ptr<HttpTransaction> trans_2(
[email protected]90499482013-06-01 00:39:5011047 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4111048 rv = trans_2->Start(&request, callback_2.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:3011049 EXPECT_EQ(ERR_IO_PENDING, rv);
11050 EXPECT_EQ(OK, callback_2.WaitForResult());
11051 const HttpResponseInfo* response = trans_2->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5011052 ASSERT_TRUE(response != NULL);
[email protected]f45c1ee2010-08-03 00:54:3011053 ASSERT_FALSE(response->auth_challenge.get() == NULL);
11054
11055 // Restart with auth. Tunnel should work and response received.
[email protected]49639fa2011-12-20 23:22:4111056 TestCompletionCallback callback_3;
11057 rv = trans_2->RestartWithAuth(
11058 AuthCredentials(kFoo, kBar), callback_3.callback());
[email protected]f45c1ee2010-08-03 00:54:3011059 EXPECT_EQ(ERR_IO_PENDING, rv);
11060 EXPECT_EQ(OK, callback_3.WaitForResult());
11061
11062 // After all that work, these two lines (or actually, just the scheme) are
11063 // what this test is all about. Make sure it happens correctly.
[email protected]f45c1ee2010-08-03 00:54:3011064 EXPECT_EQ("https", request_url.scheme());
bncce36dca22015-04-21 22:11:2311065 EXPECT_EQ("www.example.org", request_url.host());
[email protected]f45c1ee2010-08-03 00:54:3011066
[email protected]029c83b62013-01-24 05:28:2011067 LoadTimingInfo load_timing_info;
11068 EXPECT_TRUE(trans_2->GetLoadTimingInfo(&load_timing_info));
11069 TestLoadTimingNotReusedWithPac(load_timing_info,
11070 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]8e6441ca2010-08-19 05:56:3811071}
11072
11073// Test that if we cancel the transaction as the connection is completing, that
11074// everything tears down correctly.
[email protected]23e482282013-06-14 16:08:0211075TEST_P(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3811076 // Setup everything about the connection to complete synchronously, so that
11077 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
11078 // for is the callback from the HttpStreamRequest.
11079 // Then cancel the transaction.
11080 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3611081 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3811082 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0611083 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
11084 MockRead(SYNCHRONOUS, "hello world"),
11085 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3811086 };
11087
[email protected]8e6441ca2010-08-19 05:56:3811088 HttpRequestInfo request;
11089 request.method = "GET";
bncce36dca22015-04-21 22:11:2311090 request.url = GURL("http://www.example.org/");
[email protected]8e6441ca2010-08-19 05:56:3811091 request.load_flags = 0;
11092
[email protected]bb88e1d32013-05-03 23:11:0711093 session_deps_.host_resolver->set_synchronous_mode(true);
mmenke6b3af6e2015-09-12 02:06:0611094 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:2711095 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4111096 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:2711097
[email protected]8e6441ca2010-08-19 05:56:3811098 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
11099 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711100 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3811101
[email protected]49639fa2011-12-20 23:22:4111102 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3811103
vishal.b62985ca92015-04-17 08:45:5111104 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4111105 int rv = trans->Start(&request, callback.callback(), log.bound());
[email protected]8e6441ca2010-08-19 05:56:3811106 EXPECT_EQ(ERR_IO_PENDING, rv);
11107 trans.reset(); // Cancel the transaction here.
11108
[email protected]2da659e2013-05-23 20:51:3411109 base::MessageLoop::current()->RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3011110}
11111
[email protected]ecab6e052014-05-16 14:58:1211112// Test that if a transaction is cancelled after receiving the headers, the
11113// stream is drained properly and added back to the socket pool. The main
11114// purpose of this test is to make sure that an HttpStreamParser can be read
11115// from after the HttpNetworkTransaction and the objects it owns have been
11116// deleted.
11117// See http://crbug.com/368418
11118TEST_P(HttpNetworkTransactionTest, CancelAfterHeaders) {
11119 MockRead data_reads[] = {
11120 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
11121 MockRead(ASYNC, "Content-Length: 2\r\n"),
11122 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
11123 MockRead(ASYNC, "1"),
11124 // 2 async reads are necessary to trigger a ReadResponseBody call after the
11125 // HttpNetworkTransaction has been deleted.
11126 MockRead(ASYNC, "2"),
11127 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
11128 };
11129 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
11130 session_deps_.socket_factory->AddSocketDataProvider(&data);
11131
mmenke6b3af6e2015-09-12 02:06:0611132 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]ecab6e052014-05-16 14:58:1211133
11134 {
11135 HttpRequestInfo request;
11136 request.method = "GET";
bncce36dca22015-04-21 22:11:2311137 request.url = GURL("http://www.example.org/");
[email protected]ecab6e052014-05-16 14:58:1211138 request.load_flags = 0;
11139
dcheng48459ac22014-08-26 00:46:4111140 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1211141 TestCompletionCallback callback;
11142
11143 int rv = trans.Start(&request, callback.callback(), BoundNetLog());
11144 EXPECT_EQ(ERR_IO_PENDING, rv);
11145 callback.WaitForResult();
11146
11147 const HttpResponseInfo* response = trans.GetResponseInfo();
11148 ASSERT_TRUE(response != NULL);
11149 EXPECT_TRUE(response->headers.get() != NULL);
11150 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11151
11152 // The transaction and HttpRequestInfo are deleted.
11153 }
11154
11155 // Let the HttpResponseBodyDrainer drain the socket.
11156 base::MessageLoop::current()->RunUntilIdle();
11157
11158 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4111159 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1211160}
11161
[email protected]76a505b2010-08-25 06:23:0011162// Test a basic GET request through a proxy.
[email protected]23e482282013-06-14 16:08:0211163TEST_P(HttpNetworkTransactionTest, ProxyGet) {
[email protected]bb88e1d32013-05-03 23:11:0711164 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:2011165 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
vishal.b62985ca92015-04-17 08:45:5111166 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0711167 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:0611168 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0011169
[email protected]76a505b2010-08-25 06:23:0011170 HttpRequestInfo request;
11171 request.method = "GET";
bncce36dca22015-04-21 22:11:2311172 request.url = GURL("http://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0011173
11174 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2311175 MockWrite(
11176 "GET http://www.example.org/ HTTP/1.1\r\n"
11177 "Host: www.example.org\r\n"
11178 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0011179 };
11180
11181 MockRead data_reads1[] = {
11182 MockRead("HTTP/1.1 200 OK\r\n"),
11183 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11184 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0611185 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0011186 };
11187
11188 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
11189 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0711190 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0011191
[email protected]49639fa2011-12-20 23:22:4111192 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0011193
[email protected]262eec82013-03-19 21:01:3611194 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011195 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]597a1ab2014-06-26 08:12:2711196 BeforeProxyHeadersSentHandler proxy_headers_handler;
11197 trans->SetBeforeProxyHeadersSentCallback(
11198 base::Bind(&BeforeProxyHeadersSentHandler::OnBeforeProxyHeadersSent,
11199 base::Unretained(&proxy_headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5011200
[email protected]49639fa2011-12-20 23:22:4111201 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0011202 EXPECT_EQ(ERR_IO_PENDING, rv);
11203
11204 rv = callback1.WaitForResult();
11205 EXPECT_EQ(OK, rv);
11206
11207 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5011208 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:0011209
11210 EXPECT_TRUE(response->headers->IsKeepAlive());
11211 EXPECT_EQ(200, response->headers->response_code());
11212 EXPECT_EQ(100, response->headers->GetContentLength());
11213 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]d8fc4722014-06-13 13:17:1511214 EXPECT_TRUE(
11215 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
[email protected]597a1ab2014-06-26 08:12:2711216 EXPECT_TRUE(proxy_headers_handler.observed_before_proxy_headers_sent());
11217 EXPECT_EQ("myproxy:70", proxy_headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0011218 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2011219
11220 LoadTimingInfo load_timing_info;
11221 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
11222 TestLoadTimingNotReusedWithPac(load_timing_info,
11223 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0011224}
11225
11226// Test a basic HTTPS GET request through a proxy.
[email protected]23e482282013-06-14 16:08:0211227TEST_P(HttpNetworkTransactionTest, ProxyTunnelGet) {
[email protected]bb88e1d32013-05-03 23:11:0711228 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:2011229 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
vishal.b62985ca92015-04-17 08:45:5111230 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0711231 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:0611232 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0011233
[email protected]76a505b2010-08-25 06:23:0011234 HttpRequestInfo request;
11235 request.method = "GET";
bncce36dca22015-04-21 22:11:2311236 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0011237
11238 // Since we have proxy, should try to establish tunnel.
11239 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2311240 MockWrite(
11241 "CONNECT www.example.org:443 HTTP/1.1\r\n"
11242 "Host: www.example.org\r\n"
11243 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0011244
bncce36dca22015-04-21 22:11:2311245 MockWrite(
11246 "GET / HTTP/1.1\r\n"
11247 "Host: www.example.org\r\n"
11248 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0011249 };
11250
11251 MockRead data_reads1[] = {
11252 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
11253
11254 MockRead("HTTP/1.1 200 OK\r\n"),
11255 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11256 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0611257 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0011258 };
11259
11260 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
11261 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0711262 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0611263 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0711264 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0011265
[email protected]49639fa2011-12-20 23:22:4111266 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0011267
[email protected]262eec82013-03-19 21:01:3611268 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011269 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5011270
[email protected]49639fa2011-12-20 23:22:4111271 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0011272 EXPECT_EQ(ERR_IO_PENDING, rv);
11273
11274 rv = callback1.WaitForResult();
11275 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:4611276 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4011277 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0011278 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4011279 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0011280 NetLog::PHASE_NONE);
11281 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4011282 entries, pos,
[email protected]76a505b2010-08-25 06:23:0011283 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
11284 NetLog::PHASE_NONE);
11285
11286 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5011287 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:0011288
11289 EXPECT_TRUE(response->headers->IsKeepAlive());
11290 EXPECT_EQ(200, response->headers->response_code());
11291 EXPECT_EQ(100, response->headers->GetContentLength());
11292 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
11293 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]d8fc4722014-06-13 13:17:1511294 EXPECT_TRUE(
11295 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
[email protected]029c83b62013-01-24 05:28:2011296
11297 LoadTimingInfo load_timing_info;
11298 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
11299 TestLoadTimingNotReusedWithPac(load_timing_info,
11300 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0011301}
11302
11303// Test a basic HTTPS GET request through a proxy, but the server hangs up
11304// while establishing the tunnel.
[email protected]23e482282013-06-14 16:08:0211305TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
[email protected]bb88e1d32013-05-03 23:11:0711306 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
vishal.b62985ca92015-04-17 08:45:5111307 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0711308 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:0611309 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0011310
[email protected]76a505b2010-08-25 06:23:0011311 HttpRequestInfo request;
11312 request.method = "GET";
bncce36dca22015-04-21 22:11:2311313 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0011314
11315 // Since we have proxy, should try to establish tunnel.
11316 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2311317 MockWrite(
11318 "CONNECT www.example.org:443 HTTP/1.1\r\n"
11319 "Host: www.example.org\r\n"
11320 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0011321
bncce36dca22015-04-21 22:11:2311322 MockWrite(
11323 "GET / HTTP/1.1\r\n"
11324 "Host: www.example.org\r\n"
11325 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0011326 };
11327
11328 MockRead data_reads1[] = {
[email protected]8ddf8322012-02-23 18:08:0611329 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:0011330 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0611331 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0011332 };
11333
11334 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
11335 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0711336 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0611337 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0711338 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0011339
[email protected]49639fa2011-12-20 23:22:4111340 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0011341
[email protected]262eec82013-03-19 21:01:3611342 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011343 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5011344
[email protected]49639fa2011-12-20 23:22:4111345 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0011346 EXPECT_EQ(ERR_IO_PENDING, rv);
11347
11348 rv = callback1.WaitForResult();
11349 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
mmenke43758e62015-05-04 21:09:4611350 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4011351 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0011352 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4011353 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0011354 NetLog::PHASE_NONE);
11355 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4011356 entries, pos,
[email protected]76a505b2010-08-25 06:23:0011357 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
11358 NetLog::PHASE_NONE);
11359}
11360
[email protected]749eefa82010-09-13 22:14:0311361// Test for crbug.com/55424.
[email protected]23e482282013-06-14 16:08:0211362TEST_P(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
[email protected]cdf8f7e72013-05-23 10:56:4611363 scoped_ptr<SpdyFrame> req(
bncce36dca22015-04-21 22:11:2311364 spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
rch8e6c6c42015-05-01 14:05:1311365 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]749eefa82010-09-13 22:14:0311366
[email protected]23e482282013-06-14 16:08:0211367 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11368 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0311369 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1311370 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0311371 };
11372
rch8e6c6c42015-05-01 14:05:1311373 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11374 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711375 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0311376
[email protected]8ddf8322012-02-23 18:08:0611377 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211378 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711379 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0311380
mmenke6b3af6e2015-09-12 02:06:0611381 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0311382
11383 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2311384 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4011385 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5311386 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2711387 base::WeakPtr<SpdySession> spdy_session =
mmenke6b3af6e2015-09-12 02:06:0611388 CreateInsecureSpdySession(session, key, BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0311389
11390 HttpRequestInfo request;
11391 request.method = "GET";
bncce36dca22015-04-21 22:11:2311392 request.url = GURL("https://www.example.org/");
[email protected]749eefa82010-09-13 22:14:0311393 request.load_flags = 0;
11394
11395 // This is the important line that marks this as a preconnect.
11396 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
11397
[email protected]262eec82013-03-19 21:01:3611398 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011399 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]749eefa82010-09-13 22:14:0311400
[email protected]41d64e82013-07-03 22:44:2611401 TestCompletionCallback callback;
[email protected]49639fa2011-12-20 23:22:4111402 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0311403 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111404 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]749eefa82010-09-13 22:14:0311405}
11406
[email protected]73b8dd222010-11-11 19:55:2411407// Given a net error, cause that error to be returned from the first Write()
11408// call and verify that the HttpTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0211409void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0711410 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2911411 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2711412 request_info.url = GURL("https://www.example.com/");
11413 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2911414 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2711415
[email protected]8ddf8322012-02-23 18:08:0611416 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2911417 MockWrite data_writes[] = {
11418 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2411419 };
ttuttle859dc7a2015-04-23 19:42:2911420 StaticSocketDataProvider data(NULL, 0, data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0711421 session_deps_.socket_factory->AddSocketDataProvider(&data);
11422 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2411423
mmenke6b3af6e2015-09-12 02:06:0611424 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3611425 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011426 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]73b8dd222010-11-11 19:55:2411427
[email protected]49639fa2011-12-20 23:22:4111428 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2911429 int rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
11430 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2411431 rv = callback.WaitForResult();
11432 ASSERT_EQ(error, rv);
11433}
11434
[email protected]23e482282013-06-14 16:08:0211435TEST_P(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2411436 // Just check a grab bag of cert errors.
11437 static const int kErrors[] = {
11438 ERR_CERT_COMMON_NAME_INVALID,
11439 ERR_CERT_AUTHORITY_INVALID,
11440 ERR_CERT_DATE_INVALID,
11441 };
11442 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0611443 CheckErrorIsPassedBack(kErrors[i], ASYNC);
11444 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2411445 }
11446}
11447
[email protected]bd0b6772011-01-11 19:59:3011448// Ensure that a client certificate is removed from the SSL client auth
11449// cache when:
11450// 1) No proxy is involved.
11451// 2) TLS False Start is disabled.
11452// 3) The initial TLS handshake requests a client certificate.
11453// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0211454TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2311455 ClientAuthCertCache_Direct_NoFalseStart) {
ttuttle859dc7a2015-04-23 19:42:2911456 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2711457 request_info.url = GURL("https://www.example.com/");
11458 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2911459 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2711460
[email protected]bd0b6772011-01-11 19:59:3011461 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4111462 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3011463
11464 // [ssl_]data1 contains the data for the first SSL handshake. When a
11465 // CertificateRequest is received for the first time, the handshake will
11466 // be aborted to allow the caller to provide a certificate.
ttuttle859dc7a2015-04-23 19:42:2911467 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3011468 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711469 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2911470 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711471 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3011472
11473 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
11474 // False Start is not being used, the result of the SSL handshake will be
11475 // returned as part of the SSLClientSocket::Connect() call. This test
11476 // matches the result of a server sending a handshake_failure alert,
11477 // rather than a Finished message, because it requires a client
11478 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2911479 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3011480 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711481 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2911482 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711483 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3011484
11485 // [ssl_]data3 contains the data for the third SSL handshake. When a
11486 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4211487 // HttpNetworkTransaction will attempt to fallback to TLSv1.1 if the previous
11488 // connection was attempted with TLSv1.2. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3011489 // of the HttpNetworkTransaction. Because this test failure is due to
11490 // requiring a client certificate, this fallback handshake should also
11491 // fail.
ttuttle859dc7a2015-04-23 19:42:2911492 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3011493 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711494 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2911495 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711496 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3011497
[email protected]80c75f682012-05-26 16:22:1711498 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
11499 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4211500 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
11501 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]80c75f682012-05-26 16:22:1711502 // of the HttpNetworkTransaction. Because this test failure is due to
11503 // requiring a client certificate, this fallback handshake should also
11504 // fail.
ttuttle859dc7a2015-04-23 19:42:2911505 SSLSocketDataProvider ssl_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1711506 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711507 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2911508 StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711509 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1711510
mmenke6b3af6e2015-09-12 02:06:0611511 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3611512 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011513 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3011514
[email protected]bd0b6772011-01-11 19:59:3011515 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4111516 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2911517 int rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
11518 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3011519
11520 // Complete the SSL handshake, which should abort due to requiring a
11521 // client certificate.
11522 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911523 ASSERT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
[email protected]bd0b6772011-01-11 19:59:3011524
11525 // Indicate that no certificate should be supplied. From the perspective
11526 // of SSLClientCertCache, NULL is just as meaningful as a real
11527 // certificate, so this is the same as supply a
11528 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4111529 rv = trans->RestartWithCertificate(NULL, callback.callback());
ttuttle859dc7a2015-04-23 19:42:2911530 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3011531
11532 // Ensure the certificate was added to the client auth cache before
11533 // allowing the connection to continue restarting.
11534 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4111535 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
11536 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3011537 ASSERT_EQ(NULL, client_cert.get());
11538
11539 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1711540 // then consume ssl_data3 and ssl_data4, both of which should also fail.
11541 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3011542 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911543 ASSERT_EQ(ERR_SSL_PROTOCOL_ERROR, rv);
[email protected]bd0b6772011-01-11 19:59:3011544
11545 // Ensure that the client certificate is removed from the cache on a
11546 // handshake failure.
[email protected]791879c2013-12-17 07:22:4111547 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11548 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3011549}
11550
11551// Ensure that a client certificate is removed from the SSL client auth
11552// cache when:
11553// 1) No proxy is involved.
11554// 2) TLS False Start is enabled.
11555// 3) The initial TLS handshake requests a client certificate.
11556// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0211557TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2311558 ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2911559 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2711560 request_info.url = GURL("https://www.example.com/");
11561 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2911562 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2711563
[email protected]bd0b6772011-01-11 19:59:3011564 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4111565 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3011566
11567 // When TLS False Start is used, SSLClientSocket::Connect() calls will
11568 // return successfully after reading up to the peer's Certificate message.
11569 // This is to allow the caller to call SSLClientSocket::Write(), which can
11570 // enqueue application data to be sent in the same packet as the
11571 // ChangeCipherSpec and Finished messages.
11572 // The actual handshake will be finished when SSLClientSocket::Read() is
11573 // called, which expects to process the peer's ChangeCipherSpec and
11574 // Finished messages. If there was an error negotiating with the peer,
11575 // such as due to the peer requiring a client certificate when none was
11576 // supplied, the alert sent by the peer won't be processed until Read() is
11577 // called.
11578
11579 // Like the non-False Start case, when a client certificate is requested by
11580 // the peer, the handshake is aborted during the Connect() call.
11581 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2911582 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3011583 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711584 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2911585 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711586 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3011587
11588 // When a client certificate is supplied, Connect() will not be aborted
11589 // when the peer requests the certificate. Instead, the handshake will
11590 // artificially succeed, allowing the caller to write the HTTP request to
11591 // the socket. The handshake messages are not processed until Read() is
11592 // called, which then detects that the handshake was aborted, due to the
11593 // peer sending a handshake_failure because it requires a client
11594 // certificate.
ttuttle859dc7a2015-04-23 19:42:2911595 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3011596 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711597 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2911598 MockRead data2_reads[] = {
11599 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3011600 };
ttuttle859dc7a2015-04-23 19:42:2911601 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711602 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3011603
11604 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1711605 // the data for the SSL handshake once the TLSv1.1 connection falls back to
11606 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2911607 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3011608 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711609 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2911610 StaticSocketDataProvider data3(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711611 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3011612
[email protected]80c75f682012-05-26 16:22:1711613 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
11614 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2911615 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1711616 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711617 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2911618 StaticSocketDataProvider data4(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711619 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1711620
[email protected]7799de12013-05-30 05:52:5111621 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2911622 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5111623 ssl_data5.cert_request_info = cert_request.get();
11624 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
ttuttle859dc7a2015-04-23 19:42:2911625 StaticSocketDataProvider data5(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]7799de12013-05-30 05:52:5111626 session_deps_.socket_factory->AddSocketDataProvider(&data5);
11627
mmenke6b3af6e2015-09-12 02:06:0611628 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3611629 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011630 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3011631
[email protected]bd0b6772011-01-11 19:59:3011632 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4111633 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2911634 int rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
11635 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3011636
11637 // Complete the SSL handshake, which should abort due to requiring a
11638 // client certificate.
11639 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911640 ASSERT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
[email protected]bd0b6772011-01-11 19:59:3011641
11642 // Indicate that no certificate should be supplied. From the perspective
11643 // of SSLClientCertCache, NULL is just as meaningful as a real
11644 // certificate, so this is the same as supply a
11645 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4111646 rv = trans->RestartWithCertificate(NULL, callback.callback());
ttuttle859dc7a2015-04-23 19:42:2911647 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3011648
11649 // Ensure the certificate was added to the client auth cache before
11650 // allowing the connection to continue restarting.
11651 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4111652 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
11653 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3011654 ASSERT_EQ(NULL, client_cert.get());
11655
[email protected]bd0b6772011-01-11 19:59:3011656 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1711657 // then consume ssl_data3 and ssl_data4, both of which should also fail.
11658 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3011659 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911660 ASSERT_EQ(ERR_SSL_PROTOCOL_ERROR, rv);
[email protected]bd0b6772011-01-11 19:59:3011661
11662 // Ensure that the client certificate is removed from the cache on a
11663 // handshake failure.
[email protected]791879c2013-12-17 07:22:4111664 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11665 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3011666}
11667
[email protected]8c405132011-01-11 22:03:1811668// Ensure that a client certificate is removed from the SSL client auth
11669// cache when:
11670// 1) An HTTPS proxy is involved.
11671// 3) The HTTPS proxy requests a client certificate.
11672// 4) The client supplies an invalid/unacceptable certificate for the
11673// proxy.
11674// The test is repeated twice, first for connecting to an HTTPS endpoint,
11675// then for connecting to an HTTP endpoint.
[email protected]23e482282013-06-14 16:08:0211676TEST_P(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
[email protected]bb88e1d32013-05-03 23:11:0711677 session_deps_.proxy_service.reset(
[email protected]8c405132011-01-11 22:03:1811678 ProxyService::CreateFixed("https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:5111679 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0711680 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1811681
11682 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4111683 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1811684
11685 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
11686 // [ssl_]data[1-3]. Rather than represending the endpoint
11687 // (www.example.com:443), they represent failures with the HTTPS proxy
11688 // (proxy:70).
ttuttle859dc7a2015-04-23 19:42:2911689 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1811690 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711691 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2911692 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711693 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1811694
ttuttle859dc7a2015-04-23 19:42:2911695 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1811696 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711697 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2911698 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711699 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1811700
[email protected]80c75f682012-05-26 16:22:1711701 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
11702#if 0
ttuttle859dc7a2015-04-23 19:42:2911703 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1811704 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711705 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2911706 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711707 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1711708#endif
[email protected]8c405132011-01-11 22:03:1811709
ttuttle859dc7a2015-04-23 19:42:2911710 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1811711 requests[0].url = GURL("https://www.example.com/");
11712 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2911713 requests[0].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1811714
11715 requests[1].url = GURL("http://www.example.com/");
11716 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2911717 requests[1].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1811718
11719 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0711720 session_deps_.socket_factory->ResetNextMockIndexes();
mmenke6b3af6e2015-09-12 02:06:0611721 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c405132011-01-11 22:03:1811722 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5011723 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c405132011-01-11 22:03:1811724
11725 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4111726 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2911727 int rv = trans->Start(&requests[i], callback.callback(), BoundNetLog());
11728 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]8c405132011-01-11 22:03:1811729
11730 // Complete the SSL handshake, which should abort due to requiring a
11731 // client certificate.
11732 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911733 ASSERT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
[email protected]8c405132011-01-11 22:03:1811734
11735 // Indicate that no certificate should be supplied. From the perspective
11736 // of SSLClientCertCache, NULL is just as meaningful as a real
11737 // certificate, so this is the same as supply a
11738 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4111739 rv = trans->RestartWithCertificate(NULL, callback.callback());
ttuttle859dc7a2015-04-23 19:42:2911740 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]8c405132011-01-11 22:03:1811741
11742 // Ensure the certificate was added to the client auth cache before
11743 // allowing the connection to continue restarting.
11744 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4111745 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
11746 HostPortPair("proxy", 70), &client_cert));
[email protected]8c405132011-01-11 22:03:1811747 ASSERT_EQ(NULL, client_cert.get());
11748 // Ensure the certificate was NOT cached for the endpoint. This only
11749 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4111750 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11751 HostPortPair("www.example.com", 443), &client_cert));
[email protected]8c405132011-01-11 22:03:1811752
11753 // Restart the handshake. This will consume ssl_data2, which fails, and
11754 // then consume ssl_data3, which should also fail. The result code is
11755 // checked against what ssl_data3 should return.
11756 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911757 ASSERT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
[email protected]8c405132011-01-11 22:03:1811758
11759 // Now that the new handshake has failed, ensure that the client
11760 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4111761 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11762 HostPortPair("proxy", 70), &client_cert));
11763 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11764 HostPortPair("www.example.com", 443), &client_cert));
[email protected]8c405132011-01-11 22:03:1811765 }
11766}
11767
mmenke5c642132015-06-02 16:05:1311768TEST_P(HttpNetworkTransactionTest, UseIPConnectionPooling) {
bnc55ff9da2015-08-19 18:42:3511769 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2311770 session_deps_.next_protos = SpdyNextProtos();
[email protected]e3ceb682011-06-28 23:55:4611771
11772 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0711773 session_deps_.host_resolver.reset(new MockCachingHostResolver());
mmenke6b3af6e2015-09-12 02:06:0611774 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2611775 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
11776 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4611777
[email protected]8ddf8322012-02-23 18:08:0611778 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211779 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711780 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4611781
[email protected]cdf8f7e72013-05-23 10:56:4611782 scoped_ptr<SpdyFrame> host1_req(
bncce36dca22015-04-21 22:11:2311783 spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
[email protected]cdf8f7e72013-05-23 10:56:4611784 scoped_ptr<SpdyFrame> host2_req(
11785 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4611786 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1311787 CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4611788 };
[email protected]23e482282013-06-14 16:08:0211789 scoped_ptr<SpdyFrame> host1_resp(
11790 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11791 scoped_ptr<SpdyFrame> host1_resp_body(
11792 spdy_util_.ConstructSpdyBodyFrame(1, true));
11793 scoped_ptr<SpdyFrame> host2_resp(
11794 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11795 scoped_ptr<SpdyFrame> host2_resp_body(
11796 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4611797 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1311798 CreateMockRead(*host1_resp, 1),
11799 CreateMockRead(*host1_resp_body, 2),
11800 CreateMockRead(*host2_resp, 4),
11801 CreateMockRead(*host2_resp_body, 5),
11802 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4611803 };
11804
[email protected]d2b5f092012-06-08 23:55:0211805 IPAddressNumber ip;
11806 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
11807 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11808 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1311809 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
11810 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711811 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4611812
[email protected]aa22b242011-11-16 18:58:2911813 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4611814 HttpRequestInfo request1;
11815 request1.method = "GET";
bncce36dca22015-04-21 22:11:2311816 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4611817 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011818 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611819
[email protected]49639fa2011-12-20 23:22:4111820 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611821 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111822 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611823
11824 const HttpResponseInfo* response = trans1.GetResponseInfo();
11825 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011826 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611827 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11828
11829 std::string response_data;
11830 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
11831 EXPECT_EQ("hello!", response_data);
11832
11833 // Preload www.gmail.com into HostCache.
11834 HostPortPair host_port("www.gmail.com", 443);
[email protected]5109c1952013-08-20 18:44:1011835 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4611836 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1011837 rv = session_deps_.host_resolver->Resolve(resolve_info,
11838 DEFAULT_PRIORITY,
11839 &ignored,
11840 callback.callback(),
11841 NULL,
11842 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4711843 EXPECT_EQ(ERR_IO_PENDING, rv);
11844 rv = callback.WaitForResult();
11845 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4611846
11847 HttpRequestInfo request2;
11848 request2.method = "GET";
11849 request2.url = GURL("https://www.gmail.com/");
11850 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011851 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611852
[email protected]49639fa2011-12-20 23:22:4111853 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611854 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111855 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611856
11857 response = trans2.GetResponseInfo();
11858 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011859 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611860 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11861 EXPECT_TRUE(response->was_fetched_via_spdy);
11862 EXPECT_TRUE(response->was_npn_negotiated);
11863 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
11864 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4611865}
11866
[email protected]23e482282013-06-14 16:08:0211867TEST_P(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
bnc55ff9da2015-08-19 18:42:3511868 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2311869 session_deps_.next_protos = SpdyNextProtos();
[email protected]d2b5f092012-06-08 23:55:0211870
11871 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0711872 session_deps_.host_resolver.reset(new MockCachingHostResolver());
mmenke6b3af6e2015-09-12 02:06:0611873 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0211874 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
11875 pool_peer.DisableDomainAuthenticationVerification();
11876
11877 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211878 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711879 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]d2b5f092012-06-08 23:55:0211880
[email protected]cdf8f7e72013-05-23 10:56:4611881 scoped_ptr<SpdyFrame> host1_req(
bncce36dca22015-04-21 22:11:2311882 spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
[email protected]cdf8f7e72013-05-23 10:56:4611883 scoped_ptr<SpdyFrame> host2_req(
11884 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0211885 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1311886 CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0211887 };
[email protected]23e482282013-06-14 16:08:0211888 scoped_ptr<SpdyFrame> host1_resp(
11889 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11890 scoped_ptr<SpdyFrame> host1_resp_body(
11891 spdy_util_.ConstructSpdyBodyFrame(1, true));
11892 scoped_ptr<SpdyFrame> host2_resp(
11893 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11894 scoped_ptr<SpdyFrame> host2_resp_body(
11895 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0211896 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1311897 CreateMockRead(*host1_resp, 1),
11898 CreateMockRead(*host1_resp_body, 2),
11899 CreateMockRead(*host2_resp, 4),
11900 CreateMockRead(*host2_resp_body, 5),
11901 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0211902 };
11903
11904 IPAddressNumber ip;
11905 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
11906 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11907 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1311908 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
11909 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711910 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0211911
11912 TestCompletionCallback callback;
11913 HttpRequestInfo request1;
11914 request1.method = "GET";
bncce36dca22015-04-21 22:11:2311915 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0211916 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011917 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0211918
11919 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
11920 EXPECT_EQ(ERR_IO_PENDING, rv);
11921 EXPECT_EQ(OK, callback.WaitForResult());
11922
11923 const HttpResponseInfo* response = trans1.GetResponseInfo();
11924 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011925 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d2b5f092012-06-08 23:55:0211926 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11927
11928 std::string response_data;
11929 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
11930 EXPECT_EQ("hello!", response_data);
11931
11932 HttpRequestInfo request2;
11933 request2.method = "GET";
11934 request2.url = GURL("https://www.gmail.com/");
11935 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011936 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0211937
11938 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
11939 EXPECT_EQ(ERR_IO_PENDING, rv);
11940 EXPECT_EQ(OK, callback.WaitForResult());
11941
11942 response = trans2.GetResponseInfo();
11943 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011944 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d2b5f092012-06-08 23:55:0211945 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11946 EXPECT_TRUE(response->was_fetched_via_spdy);
11947 EXPECT_TRUE(response->was_npn_negotiated);
11948 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
11949 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0211950}
11951
ttuttle859dc7a2015-04-23 19:42:2911952class OneTimeCachingHostResolver : public HostResolver {
[email protected]e3ceb682011-06-28 23:55:4611953 public:
11954 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
11955 : host_port_(host_port) {}
dchengb03027d2014-10-21 12:00:2011956 ~OneTimeCachingHostResolver() override {}
[email protected]e3ceb682011-06-28 23:55:4611957
11958 RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); }
11959
11960 // HostResolver methods:
dchengb03027d2014-10-21 12:00:2011961 int Resolve(const RequestInfo& info,
11962 RequestPriority priority,
11963 AddressList* addresses,
11964 const CompletionCallback& callback,
11965 RequestHandle* out_req,
11966 const BoundNetLog& net_log) override {
[email protected]95a214c2011-08-04 21:50:4011967 return host_resolver_.Resolve(
[email protected]5109c1952013-08-20 18:44:1011968 info, priority, addresses, callback, out_req, net_log);
[email protected]95a214c2011-08-04 21:50:4011969 }
11970
dchengb03027d2014-10-21 12:00:2011971 int ResolveFromCache(const RequestInfo& info,
11972 AddressList* addresses,
11973 const BoundNetLog& net_log) override {
[email protected]95a214c2011-08-04 21:50:4011974 int rv = host_resolver_.ResolveFromCache(info, addresses, net_log);
11975 if (rv == OK && info.host_port_pair().Equals(host_port_))
[email protected]98e1cd012011-11-08 15:33:0911976 host_resolver_.GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4611977 return rv;
11978 }
11979
dchengb03027d2014-10-21 12:00:2011980 void CancelRequest(RequestHandle req) override {
[email protected]e3ceb682011-06-28 23:55:4611981 host_resolver_.CancelRequest(req);
11982 }
11983
[email protected]46da33be2011-07-19 21:58:0411984 MockCachingHostResolver* GetMockHostResolver() {
11985 return &host_resolver_;
11986 }
11987
[email protected]e3ceb682011-06-28 23:55:4611988 private:
11989 MockCachingHostResolver host_resolver_;
11990 const HostPortPair host_port_;
11991};
11992
mmenke5c642132015-06-02 16:05:1311993TEST_P(HttpNetworkTransactionTest,
11994 UseIPConnectionPoolingWithHostCacheExpiration) {
bnc55ff9da2015-08-19 18:42:3511995 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2311996 session_deps_.next_protos = SpdyNextProtos();
[email protected]e3ceb682011-06-28 23:55:4611997
11998 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
[email protected]e3ceb682011-06-28 23:55:4611999 OneTimeCachingHostResolver host_resolver(HostPortPair("www.gmail.com", 443));
[email protected]c6bf8152012-12-02 07:43:3412000 HttpNetworkSession::Params params =
[email protected]bb88e1d32013-05-03 23:11:0712001 SpdySessionDependencies::CreateSessionParams(&session_deps_);
[email protected]e3ceb682011-06-28 23:55:4612002 params.host_resolver = &host_resolver;
mmenke6b3af6e2015-09-12 02:06:0612003 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2612004 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
12005 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4612006
[email protected]8ddf8322012-02-23 18:08:0612007 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212008 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0712009 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4612010
[email protected]cdf8f7e72013-05-23 10:56:4612011 scoped_ptr<SpdyFrame> host1_req(
bncce36dca22015-04-21 22:11:2312012 spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
[email protected]cdf8f7e72013-05-23 10:56:4612013 scoped_ptr<SpdyFrame> host2_req(
12014 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4612015 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1312016 CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4612017 };
[email protected]23e482282013-06-14 16:08:0212018 scoped_ptr<SpdyFrame> host1_resp(
12019 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12020 scoped_ptr<SpdyFrame> host1_resp_body(
12021 spdy_util_.ConstructSpdyBodyFrame(1, true));
12022 scoped_ptr<SpdyFrame> host2_resp(
12023 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
12024 scoped_ptr<SpdyFrame> host2_resp_body(
12025 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4612026 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1312027 CreateMockRead(*host1_resp, 1),
12028 CreateMockRead(*host1_resp_body, 2),
12029 CreateMockRead(*host2_resp, 4),
12030 CreateMockRead(*host2_resp_body, 5),
12031 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4612032 };
12033
[email protected]d2b5f092012-06-08 23:55:0212034 IPAddressNumber ip;
12035 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
12036 IPEndPoint peer_addr = IPEndPoint(ip, 443);
12037 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1312038 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
12039 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712040 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4612041
[email protected]aa22b242011-11-16 18:58:2912042 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4612043 HttpRequestInfo request1;
12044 request1.method = "GET";
bncce36dca22015-04-21 22:11:2312045 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4612046 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012047 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4612048
[email protected]49639fa2011-12-20 23:22:4112049 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4612050 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4112051 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4612052
12053 const HttpResponseInfo* response = trans1.GetResponseInfo();
12054 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5012055 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4612056 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12057
12058 std::string response_data;
12059 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
12060 EXPECT_EQ("hello!", response_data);
12061
12062 // Preload cache entries into HostCache.
[email protected]5109c1952013-08-20 18:44:1012063 HostResolver::RequestInfo resolve_info(HostPortPair("www.gmail.com", 443));
[email protected]e3ceb682011-06-28 23:55:4612064 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1012065 rv = host_resolver.Resolve(resolve_info,
12066 DEFAULT_PRIORITY,
12067 &ignored,
12068 callback.callback(),
12069 NULL,
12070 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4712071 EXPECT_EQ(ERR_IO_PENDING, rv);
12072 rv = callback.WaitForResult();
12073 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4612074
12075 HttpRequestInfo request2;
12076 request2.method = "GET";
12077 request2.url = GURL("https://www.gmail.com/");
12078 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012079 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4612080
[email protected]49639fa2011-12-20 23:22:4112081 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4612082 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4112083 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4612084
12085 response = trans2.GetResponseInfo();
12086 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5012087 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4612088 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12089 EXPECT_TRUE(response->was_fetched_via_spdy);
12090 EXPECT_TRUE(response->was_npn_negotiated);
12091 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
12092 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4612093}
12094
[email protected]23e482282013-06-14 16:08:0212095TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2312096 const std::string https_url = "https://www.example.org:8080/";
12097 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0412098
12099 // SPDY GET for HTTPS URL
[email protected]cdf8f7e72013-05-23 10:56:4612100 scoped_ptr<SpdyFrame> req1(
12101 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0412102
12103 MockWrite writes1[] = {
12104 CreateMockWrite(*req1, 0),
12105 };
12106
[email protected]23e482282013-06-14 16:08:0212107 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12108 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8450d722012-07-02 19:14:0412109 MockRead reads1[] = {
12110 CreateMockRead(*resp1, 1),
12111 CreateMockRead(*body1, 2),
12112 MockRead(ASYNC, ERR_IO_PENDING, 3)
12113 };
12114
rch8e6c6c42015-05-01 14:05:1312115 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
12116 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0412117 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5712118 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0412119
12120 // HTTP GET for the HTTP URL
12121 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1312122 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3412123 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2312124 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3412125 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0412126 };
12127
12128 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1312129 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
12130 MockRead(ASYNC, 2, "hello"),
12131 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0412132 };
12133
rch8e6c6c42015-05-01 14:05:1312134 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
12135 arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0412136
[email protected]8450d722012-07-02 19:14:0412137 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212138 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0712139 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12140 session_deps_.socket_factory->AddSocketDataProvider(&data1);
12141 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0412142
mmenke6b3af6e2015-09-12 02:06:0612143 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0412144
12145 // Start the first transaction to set up the SpdySession
12146 HttpRequestInfo request1;
12147 request1.method = "GET";
12148 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0412149 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012150 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0412151 TestCompletionCallback callback1;
12152 EXPECT_EQ(ERR_IO_PENDING,
12153 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412154 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0412155
12156 EXPECT_EQ(OK, callback1.WaitForResult());
12157 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
12158
12159 // Now, start the HTTP request
12160 HttpRequestInfo request2;
12161 request2.method = "GET";
12162 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0412163 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012164 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0412165 TestCompletionCallback callback2;
12166 EXPECT_EQ(ERR_IO_PENDING,
12167 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412168 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0412169
12170 EXPECT_EQ(OK, callback2.WaitForResult());
12171 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
12172}
12173
bnc1b0e36852015-04-28 15:32:5912174class AltSvcCertificateVerificationTest : public HttpNetworkTransactionTest {
12175 public:
12176 void Run(bool pooling, bool valid) {
12177 HostPortPair origin(valid ? "mail.example.org" : "invalid.example.org",
12178 443);
12179 HostPortPair alternative("www.example.org", 443);
12180
12181 base::FilePath certs_dir = GetTestCertsDirectory();
12182 scoped_refptr<X509Certificate> cert(
12183 ImportCertFromFile(certs_dir, "spdy_pooling.pem"));
12184 ASSERT_TRUE(cert.get());
12185 bool common_name_fallback_used;
12186 EXPECT_EQ(valid,
12187 cert->VerifyNameMatch(origin.host(), &common_name_fallback_used));
12188 EXPECT_TRUE(
12189 cert->VerifyNameMatch(alternative.host(), &common_name_fallback_used));
12190 SSLSocketDataProvider ssl(ASYNC, OK);
12191 ssl.SetNextProto(GetParam());
12192 ssl.cert = cert;
12193 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12194
12195 // If pooling, then start a request to alternative first to create a
12196 // SpdySession.
12197 std::string url0 = "https://www.example.org:443";
12198 // Second request to origin, which has an alternative service, and could
12199 // open a connection to the alternative host or pool to the existing one.
12200 std::string url1("https://");
12201 url1.append(origin.host());
12202 url1.append(":443");
12203
12204 scoped_ptr<SpdyFrame> req0;
12205 scoped_ptr<SpdyFrame> req1;
12206 scoped_ptr<SpdyFrame> resp0;
12207 scoped_ptr<SpdyFrame> body0;
12208 scoped_ptr<SpdyFrame> resp1;
12209 scoped_ptr<SpdyFrame> body1;
12210 std::vector<MockWrite> writes;
12211 std::vector<MockRead> reads;
12212
12213 if (pooling) {
12214 req0.reset(spdy_util_.ConstructSpdyGet(url0.c_str(), false, 1, LOWEST));
12215 req1.reset(spdy_util_.ConstructSpdyGet(url1.c_str(), false, 3, LOWEST));
12216
12217 writes.push_back(CreateMockWrite(*req0, 0));
12218 writes.push_back(CreateMockWrite(*req1, 3));
12219
12220 resp0.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12221 body0.reset(spdy_util_.ConstructSpdyBodyFrame(1, true));
12222 resp1.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
12223 body1.reset(spdy_util_.ConstructSpdyBodyFrame(3, true));
12224
12225 reads.push_back(CreateMockRead(*resp0, 1));
12226 reads.push_back(CreateMockRead(*body0, 2));
12227 reads.push_back(MockRead(ASYNC, ERR_IO_PENDING, 4));
12228 reads.push_back(CreateMockRead(*resp1, 5));
12229 reads.push_back(CreateMockRead(*body1, 6));
12230 reads.push_back(MockRead(ASYNC, OK, 7));
12231 } else {
12232 req1.reset(spdy_util_.ConstructSpdyGet(url1.c_str(), false, 1, LOWEST));
12233
12234 writes.push_back(CreateMockWrite(*req1, 0));
12235
12236 resp1.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12237 body1.reset(spdy_util_.ConstructSpdyBodyFrame(1, true));
12238
12239 reads.push_back(CreateMockRead(*resp1, 1));
12240 reads.push_back(CreateMockRead(*body1, 2));
12241 reads.push_back(MockRead(ASYNC, OK, 3));
12242 }
12243
rch32320842015-05-16 15:57:0912244 SequencedSocketData data(vector_as_array(&reads), reads.size(),
12245 vector_as_array(&writes), writes.size());
bnc1b0e36852015-04-28 15:32:5912246 session_deps_.socket_factory->AddSocketDataProvider(&data);
12247
12248 // Connection to the origin fails.
12249 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
12250 StaticSocketDataProvider data_refused;
12251 data_refused.set_connect_data(mock_connect);
12252 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
12253
bnc55ff9da2015-08-19 18:42:3512254 session_deps_.use_alternative_services = true;
mmenke6b3af6e2015-09-12 02:06:0612255 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc1b0e36852015-04-28 15:32:5912256 base::WeakPtr<HttpServerProperties> http_server_properties =
12257 session->http_server_properties();
12258 AlternativeService alternative_service(
12259 AlternateProtocolFromNextProto(GetParam()), alternative);
bnc7dc7e1b42015-07-28 14:43:1212260 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnc1b0e36852015-04-28 15:32:5912261 http_server_properties->SetAlternativeService(origin, alternative_service,
bnc7dc7e1b42015-07-28 14:43:1212262 1.0, expiration);
bnc1b0e36852015-04-28 15:32:5912263
12264 // First request to alternative.
12265 if (pooling) {
12266 scoped_ptr<HttpTransaction> trans0(
12267 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12268 HttpRequestInfo request0;
12269 request0.method = "GET";
12270 request0.url = GURL(url0);
12271 request0.load_flags = 0;
12272 TestCompletionCallback callback0;
12273
12274 int rv = trans0->Start(&request0, callback0.callback(), BoundNetLog());
12275 EXPECT_EQ(ERR_IO_PENDING, rv);
12276 rv = callback0.WaitForResult();
12277 EXPECT_EQ(OK, rv);
12278 }
12279
12280 // Second request to origin.
12281 scoped_ptr<HttpTransaction> trans1(
12282 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12283 HttpRequestInfo request1;
12284 request1.method = "GET";
12285 request1.url = GURL(url1);
12286 request1.load_flags = 0;
12287 TestCompletionCallback callback1;
12288
12289 int rv = trans1->Start(&request1, callback1.callback(), BoundNetLog());
12290 EXPECT_EQ(ERR_IO_PENDING, rv);
rch32320842015-05-16 15:57:0912291 base::MessageLoop::current()->RunUntilIdle();
12292 if (data.IsReadPaused()) {
12293 data.CompleteRead();
12294 }
bnc1b0e36852015-04-28 15:32:5912295 rv = callback1.WaitForResult();
12296 if (valid) {
12297 EXPECT_EQ(OK, rv);
12298 } else {
12299 if (pooling) {
12300 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
12301 } else {
12302 EXPECT_EQ(ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN, rv);
12303 }
12304 }
12305 }
12306};
12307
12308INSTANTIATE_TEST_CASE_P(NextProto,
12309 AltSvcCertificateVerificationTest,
12310 testing::Values(kProtoSPDY31,
bnc06d22432015-06-29 12:39:4312311 kProtoHTTP2));
bnc1b0e36852015-04-28 15:32:5912312
12313// The alternative service host must exhibit a certificate that is valid for the
12314// origin host. Test that this is enforced when pooling to an existing
12315// connection.
12316TEST_P(AltSvcCertificateVerificationTest, PoolingValid) {
12317 Run(true, true);
12318}
12319
12320TEST_P(AltSvcCertificateVerificationTest, PoolingInvalid) {
12321 Run(true, false);
12322}
12323
12324// The alternative service host must exhibit a certificate that is valid for the
12325// origin host. Test that this is enforced when opening a new connection.
12326TEST_P(AltSvcCertificateVerificationTest, NewConnectionValid) {
12327 Run(false, true);
12328}
12329
12330TEST_P(AltSvcCertificateVerificationTest, NewConnectionInvalid) {
12331 Run(false, false);
12332}
12333
bnc5452e2a2015-05-08 16:27:4212334// Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
12335// with the alternative server. That connection should not be used.
12336TEST_P(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
12337 HostPortPair origin("origin.example.org", 443);
12338 HostPortPair alternative("alternative.example.org", 443);
12339
12340 // Negotiate HTTP/1.1 with alternative.example.org.
12341 SSLSocketDataProvider ssl(ASYNC, OK);
12342 ssl.SetNextProto(kProtoHTTP11);
12343 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12344
12345 // No data should be read from the alternative, because HTTP/1.1 is
12346 // negotiated.
12347 StaticSocketDataProvider data;
12348 session_deps_.socket_factory->AddSocketDataProvider(&data);
12349
12350 // This test documents that an alternate Job should not be used if HTTP/1.1 is
12351 // negotiated. In order to test this, a failed connection to the origin is
12352 // mocked. This way the request relies on the alternate Job.
12353 StaticSocketDataProvider data_refused;
12354 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
12355 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
12356
12357 // Set up alternative service for origin.
bnc55ff9da2015-08-19 18:42:3512358 session_deps_.use_alternative_services = true;
mmenke6b3af6e2015-09-12 02:06:0612359 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc5452e2a2015-05-08 16:27:4212360 base::WeakPtr<HttpServerProperties> http_server_properties =
12361 session->http_server_properties();
12362 AlternativeService alternative_service(
12363 AlternateProtocolFromNextProto(GetParam()), alternative);
bnc7dc7e1b42015-07-28 14:43:1212364 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnc5452e2a2015-05-08 16:27:4212365 http_server_properties->SetAlternativeService(origin, alternative_service,
bnc7dc7e1b42015-07-28 14:43:1212366 1.0, expiration);
bnc5452e2a2015-05-08 16:27:4212367
12368 scoped_ptr<HttpTransaction> trans(
12369 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12370 HttpRequestInfo request;
12371 request.method = "GET";
12372 request.url = GURL("https://origin.example.org:443");
12373 request.load_flags = 0;
12374 TestCompletionCallback callback;
12375
12376 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
12377 // negotiated, the alternate Job should fail with ERR_NPN_NEGOTIATION_FAILED.
12378 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12379 EXPECT_EQ(ERR_NPN_NEGOTIATION_FAILED, callback.GetResult(rv));
12380}
12381
bnc40448a532015-05-11 19:13:1412382// A request to a server with an alternative service fires two Jobs: one to the
12383// origin, and an alternate one to the alternative server. If the former
12384// succeeds, the request should succeed, even if the latter fails because
12385// HTTP/1.1 is negotiated which is insufficient for alternative service.
12386TEST_P(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
12387 HostPortPair origin("origin.example.org", 443);
12388 HostPortPair alternative("alternative.example.org", 443);
12389
12390 // Negotiate HTTP/1.1 with alternative.
12391 SSLSocketDataProvider alternative_ssl(ASYNC, OK);
12392 alternative_ssl.SetNextProto(kProtoHTTP11);
12393 session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
12394
12395 // No data should be read from the alternative, because HTTP/1.1 is
12396 // negotiated.
12397 StaticSocketDataProvider data;
12398 session_deps_.socket_factory->AddSocketDataProvider(&data);
12399
12400 // Negotiate HTTP/1.1 with origin.
12401 SSLSocketDataProvider origin_ssl(ASYNC, OK);
12402 origin_ssl.SetNextProto(kProtoHTTP11);
12403 session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
12404
12405 MockWrite http_writes[] = {
12406 MockWrite(
12407 "GET / HTTP/1.1\r\n"
12408 "Host: origin.example.org\r\n"
12409 "Connection: keep-alive\r\n\r\n"),
12410 MockWrite(
12411 "GET /second HTTP/1.1\r\n"
12412 "Host: origin.example.org\r\n"
12413 "Connection: keep-alive\r\n\r\n"),
12414 };
12415
12416 MockRead http_reads[] = {
12417 MockRead("HTTP/1.1 200 OK\r\n"),
12418 MockRead("Content-Type: text/html\r\n"),
12419 MockRead("Content-Length: 6\r\n\r\n"),
12420 MockRead("foobar"),
12421 MockRead("HTTP/1.1 200 OK\r\n"),
12422 MockRead("Content-Type: text/html\r\n"),
12423 MockRead("Content-Length: 7\r\n\r\n"),
12424 MockRead("another"),
12425 };
12426 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
12427 http_writes, arraysize(http_writes));
12428 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12429
12430 // Set up alternative service for origin.
bnc55ff9da2015-08-19 18:42:3512431 session_deps_.use_alternative_services = true;
mmenke6b3af6e2015-09-12 02:06:0612432 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc40448a532015-05-11 19:13:1412433 base::WeakPtr<HttpServerProperties> http_server_properties =
12434 session->http_server_properties();
12435 AlternativeService alternative_service(
12436 AlternateProtocolFromNextProto(GetParam()), alternative);
bnc7dc7e1b42015-07-28 14:43:1212437 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnc40448a532015-05-11 19:13:1412438 http_server_properties->SetAlternativeService(origin, alternative_service,
bnc7dc7e1b42015-07-28 14:43:1212439 1.0, expiration);
bnc40448a532015-05-11 19:13:1412440
12441 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
12442 HttpRequestInfo request1;
12443 request1.method = "GET";
12444 request1.url = GURL("https://origin.example.org:443");
12445 request1.load_flags = 0;
12446 TestCompletionCallback callback1;
12447
12448 int rv = trans1.Start(&request1, callback1.callback(), BoundNetLog());
12449 rv = callback1.GetResult(rv);
12450 EXPECT_EQ(OK, rv);
12451
12452 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
12453 ASSERT_TRUE(response1 != nullptr);
12454 ASSERT_TRUE(response1->headers.get() != nullptr);
12455 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
12456
12457 std::string response_data1;
12458 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data1));
12459 EXPECT_EQ("foobar", response_data1);
12460
12461 // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
12462 // for alternative service.
12463 EXPECT_TRUE(
12464 http_server_properties->IsAlternativeServiceBroken(alternative_service));
12465
12466 // Since |alternative_service| is broken, a second transaction to origin
12467 // should not start an alternate Job. It should pool to existing connection
12468 // to origin.
12469 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
12470 HttpRequestInfo request2;
12471 request2.method = "GET";
12472 request2.url = GURL("https://origin.example.org:443/second");
12473 request2.load_flags = 0;
12474 TestCompletionCallback callback2;
12475
12476 rv = trans2.Start(&request2, callback2.callback(), BoundNetLog());
12477 rv = callback2.GetResult(rv);
12478 EXPECT_EQ(OK, rv);
12479
12480 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
12481 ASSERT_TRUE(response2 != nullptr);
12482 ASSERT_TRUE(response2->headers.get() != nullptr);
12483 EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
12484
12485 std::string response_data2;
12486 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data2));
12487 EXPECT_EQ("another", response_data2);
12488}
12489
bnc5452e2a2015-05-08 16:27:4212490// Alternative service requires HTTP/2 (or SPDY), but there is already a
12491// HTTP/1.1 socket open to the alternative server. That socket should not be
12492// used.
12493TEST_P(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
12494 HostPortPair origin("origin.example.org", 443);
12495 HostPortPair alternative("alternative.example.org", 443);
12496 std::string origin_url = "https://origin.example.org:443";
12497 std::string alternative_url = "https://alternative.example.org:443";
12498
12499 // Negotiate HTTP/1.1 with alternative.example.org.
12500 SSLSocketDataProvider ssl(ASYNC, OK);
12501 ssl.SetNextProto(kProtoHTTP11);
12502 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12503
12504 // HTTP/1.1 data for |request1| and |request2|.
12505 MockWrite http_writes[] = {
12506 MockWrite(
12507 "GET / HTTP/1.1\r\n"
12508 "Host: alternative.example.org\r\n"
12509 "Connection: keep-alive\r\n\r\n"),
12510 MockWrite(
12511 "GET / HTTP/1.1\r\n"
12512 "Host: alternative.example.org\r\n"
12513 "Connection: keep-alive\r\n\r\n"),
12514 };
12515
12516 MockRead http_reads[] = {
12517 MockRead(
12518 "HTTP/1.1 200 OK\r\n"
12519 "Content-Type: text/html; charset=iso-8859-1\r\n"
12520 "Content-Length: 40\r\n\r\n"
12521 "first HTTP/1.1 response from alternative"),
12522 MockRead(
12523 "HTTP/1.1 200 OK\r\n"
12524 "Content-Type: text/html; charset=iso-8859-1\r\n"
12525 "Content-Length: 41\r\n\r\n"
12526 "second HTTP/1.1 response from alternative"),
12527 };
12528 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
12529 http_writes, arraysize(http_writes));
12530 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12531
12532 // This test documents that an alternate Job should not pool to an already
12533 // existing HTTP/1.1 connection. In order to test this, a failed connection
12534 // to the origin is mocked. This way |request2| relies on the alternate Job.
12535 StaticSocketDataProvider data_refused;
12536 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
12537 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
12538
12539 // Set up alternative service for origin.
bnc55ff9da2015-08-19 18:42:3512540 session_deps_.use_alternative_services = true;
mmenke6b3af6e2015-09-12 02:06:0612541 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc5452e2a2015-05-08 16:27:4212542 base::WeakPtr<HttpServerProperties> http_server_properties =
12543 session->http_server_properties();
12544 AlternativeService alternative_service(
12545 AlternateProtocolFromNextProto(GetParam()), alternative);
bnc7dc7e1b42015-07-28 14:43:1212546 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnc5452e2a2015-05-08 16:27:4212547 http_server_properties->SetAlternativeService(origin, alternative_service,
bnc7dc7e1b42015-07-28 14:43:1212548 1.0, expiration);
bnc5452e2a2015-05-08 16:27:4212549
12550 // First transaction to alternative to open an HTTP/1.1 socket.
12551 scoped_ptr<HttpTransaction> trans1(
12552 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12553 HttpRequestInfo request1;
12554 request1.method = "GET";
12555 request1.url = GURL(alternative_url);
12556 request1.load_flags = 0;
12557 TestCompletionCallback callback1;
12558
12559 int rv = trans1->Start(&request1, callback1.callback(), BoundNetLog());
12560 EXPECT_EQ(OK, callback1.GetResult(rv));
12561 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
12562 ASSERT_TRUE(response1);
12563 ASSERT_TRUE(response1->headers.get());
12564 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
12565 EXPECT_TRUE(response1->was_npn_negotiated);
12566 EXPECT_FALSE(response1->was_fetched_via_spdy);
12567 std::string response_data1;
12568 ASSERT_EQ(OK, ReadTransaction(trans1.get(), &response_data1));
12569 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
12570
12571 // Request for origin.example.org, which has an alternative service. This
12572 // will start two Jobs: the alternative looks for connections to pool to,
12573 // finds one which is HTTP/1.1, and should ignore it, and should not try to
12574 // open other connections to alternative server. The Job to origin fails, so
12575 // this request fails.
12576 scoped_ptr<HttpTransaction> trans2(
12577 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12578 HttpRequestInfo request2;
12579 request2.method = "GET";
12580 request2.url = GURL(origin_url);
12581 request2.load_flags = 0;
12582 TestCompletionCallback callback2;
12583
12584 rv = trans2->Start(&request2, callback2.callback(), BoundNetLog());
12585 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback2.GetResult(rv));
12586
12587 // Another transaction to alternative. This is to test that the HTTP/1.1
12588 // socket is still open and in the pool.
12589 scoped_ptr<HttpTransaction> trans3(
12590 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12591 HttpRequestInfo request3;
12592 request3.method = "GET";
12593 request3.url = GURL(alternative_url);
12594 request3.load_flags = 0;
12595 TestCompletionCallback callback3;
12596
12597 rv = trans3->Start(&request3, callback3.callback(), BoundNetLog());
12598 EXPECT_EQ(OK, callback3.GetResult(rv));
12599 const HttpResponseInfo* response3 = trans3->GetResponseInfo();
12600 ASSERT_TRUE(response3);
12601 ASSERT_TRUE(response3->headers.get());
12602 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
12603 EXPECT_TRUE(response3->was_npn_negotiated);
12604 EXPECT_FALSE(response3->was_fetched_via_spdy);
12605 std::string response_data3;
12606 ASSERT_EQ(OK, ReadTransaction(trans3.get(), &response_data3));
12607 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
12608}
12609
[email protected]23e482282013-06-14 16:08:0212610TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2312611 const std::string https_url = "https://www.example.org:8080/";
12612 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0412613
12614 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2312615 const HostPortPair host_port_pair("www.example.org", 8080);
lgarrona91df87f2014-12-05 00:51:3412616 scoped_ptr<SpdyFrame> connect(
12617 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
[email protected]cdf8f7e72013-05-23 10:56:4612618 scoped_ptr<SpdyFrame> req1(
12619 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]23e482282013-06-14 16:08:0212620 scoped_ptr<SpdyFrame> wrapped_req1(
12621 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3912622
12623 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
[email protected]745aa9c2014-06-27 02:21:2912624 SpdyHeaderBlock req2_block;
12625 req2_block[spdy_util_.GetMethodKey()] = "GET";
bnc33b8cef42014-11-19 17:30:3812626 req2_block[spdy_util_.GetPathKey()] = "/";
bncce36dca22015-04-21 22:11:2312627 req2_block[spdy_util_.GetHostKey()] = "www.example.org:8080";
[email protected]745aa9c2014-06-27 02:21:2912628 req2_block[spdy_util_.GetSchemeKey()] = "http";
12629 spdy_util_.MaybeAddVersionHeader(&req2_block);
[email protected]601e03f12014-04-06 16:26:3912630 scoped_ptr<SpdyFrame> req2(
[email protected]745aa9c2014-06-27 02:21:2912631 spdy_util_.ConstructSpdySyn(3, req2_block, MEDIUM, false, true));
[email protected]8450d722012-07-02 19:14:0412632
12633 MockWrite writes1[] = {
12634 CreateMockWrite(*connect, 0),
12635 CreateMockWrite(*wrapped_req1, 2),
12636 CreateMockWrite(*req2, 5),
12637 };
12638
[email protected]23e482282013-06-14 16:08:0212639 scoped_ptr<SpdyFrame> conn_resp(
12640 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12641 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12642 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
12643 scoped_ptr<SpdyFrame> wrapped_resp1(
12644 spdy_util_.ConstructWrappedSpdyFrame(resp1, 1));
12645 scoped_ptr<SpdyFrame> wrapped_body1(
12646 spdy_util_.ConstructWrappedSpdyFrame(body1, 1));
12647 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
12648 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]8450d722012-07-02 19:14:0412649 MockRead reads1[] = {
12650 CreateMockRead(*conn_resp, 1),
12651 CreateMockRead(*wrapped_resp1, 3),
12652 CreateMockRead(*wrapped_body1, 4),
12653 CreateMockRead(*resp2, 6),
12654 CreateMockRead(*body2, 7),
12655 MockRead(ASYNC, ERR_IO_PENDING, 8)
12656 };
12657
[email protected]dd54bd82012-07-19 23:44:5712658 DeterministicSocketData data1(reads1, arraysize(reads1),
12659 writes1, arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0412660 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5712661 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0412662
[email protected]bb88e1d32013-05-03 23:11:0712663 session_deps_.proxy_service.reset(
[email protected]f6c63db52013-02-02 00:35:2212664 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
vishal.b62985ca92015-04-17 08:45:5112665 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712666 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0412667 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
[email protected]23e482282013-06-14 16:08:0212668 ssl1.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0712669 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0412670 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
[email protected]23e482282013-06-14 16:08:0212671 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0712672 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
12673 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0412674
mmenke6b3af6e2015-09-12 02:06:0612675 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0712676 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]8450d722012-07-02 19:14:0412677
12678 // Start the first transaction to set up the SpdySession
12679 HttpRequestInfo request1;
12680 request1.method = "GET";
12681 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0412682 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012683 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0412684 TestCompletionCallback callback1;
12685 EXPECT_EQ(ERR_IO_PENDING,
12686 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412687 base::MessageLoop::current()->RunUntilIdle();
[email protected]dd54bd82012-07-19 23:44:5712688 data1.RunFor(4);
[email protected]8450d722012-07-02 19:14:0412689
12690 EXPECT_EQ(OK, callback1.WaitForResult());
12691 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
12692
[email protected]f6c63db52013-02-02 00:35:2212693 LoadTimingInfo load_timing_info1;
12694 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
12695 TestLoadTimingNotReusedWithPac(load_timing_info1,
12696 CONNECT_TIMING_HAS_SSL_TIMES);
12697
[email protected]8450d722012-07-02 19:14:0412698 // Now, start the HTTP request
12699 HttpRequestInfo request2;
12700 request2.method = "GET";
12701 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0412702 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012703 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0412704 TestCompletionCallback callback2;
12705 EXPECT_EQ(ERR_IO_PENDING,
12706 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412707 base::MessageLoop::current()->RunUntilIdle();
[email protected]dd54bd82012-07-19 23:44:5712708 data1.RunFor(3);
[email protected]8450d722012-07-02 19:14:0412709
12710 EXPECT_EQ(OK, callback2.WaitForResult());
12711 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2212712
12713 LoadTimingInfo load_timing_info2;
12714 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
12715 // The established SPDY sessions is considered reused by the HTTP request.
12716 TestLoadTimingReusedWithPac(load_timing_info2);
12717 // HTTP requests over a SPDY session should have a different connection
12718 // socket_log_id than requests over a tunnel.
12719 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0412720}
12721
[email protected]2d88e7d2012-07-19 17:55:1712722// Test that in the case where we have a SPDY session to a SPDY proxy
12723// that we do not pool other origins that resolve to the same IP when
12724// the certificate does not match the new origin.
12725// http://crbug.com/134690
[email protected]23e482282013-06-14 16:08:0212726TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2312727 const std::string url1 = "http://www.example.org/";
12728 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1712729 const std::string ip_addr = "1.2.3.4";
12730
12731 // SPDY GET for HTTP URL (through SPDY proxy)
[email protected]23e482282013-06-14 16:08:0212732 scoped_ptr<SpdyHeaderBlock> headers(
bncce36dca22015-04-21 22:11:2312733 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
[email protected]745aa9c2014-06-27 02:21:2912734 scoped_ptr<SpdyFrame> req1(
12735 spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, false, true));
[email protected]2d88e7d2012-07-19 17:55:1712736
12737 MockWrite writes1[] = {
12738 CreateMockWrite(*req1, 0),
12739 };
12740
[email protected]23e482282013-06-14 16:08:0212741 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12742 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1712743 MockRead reads1[] = {
bncb9e20fc62015-08-17 17:19:3712744 CreateMockRead(*resp1, 1),
12745 CreateMockRead(*body1, 2),
12746 MockRead(ASYNC, OK, 3) // EOF
[email protected]2d88e7d2012-07-19 17:55:1712747 };
12748
12749 scoped_ptr<DeterministicSocketData> data1(
12750 new DeterministicSocketData(reads1, arraysize(reads1),
12751 writes1, arraysize(writes1)));
12752 IPAddressNumber ip;
12753 ASSERT_TRUE(ParseIPLiteralToNumber(ip_addr, &ip));
12754 IPEndPoint peer_addr = IPEndPoint(ip, 443);
12755 MockConnect connect_data1(ASYNC, OK, peer_addr);
12756 data1->set_connect_data(connect_data1);
12757
12758 // SPDY GET for HTTPS URL (direct)
[email protected]cdf8f7e72013-05-23 10:56:4612759 scoped_ptr<SpdyFrame> req2(
12760 spdy_util_.ConstructSpdyGet(url2.c_str(), false, 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1712761
12762 MockWrite writes2[] = {
12763 CreateMockWrite(*req2, 0),
12764 };
12765
[email protected]23e482282013-06-14 16:08:0212766 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12767 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1712768 MockRead reads2[] = {
bncb9e20fc62015-08-17 17:19:3712769 CreateMockRead(*resp2, 1),
12770 CreateMockRead(*body2, 2),
12771 MockRead(ASYNC, OK, 3) // EOF
[email protected]2d88e7d2012-07-19 17:55:1712772 };
12773
12774 scoped_ptr<DeterministicSocketData> data2(
12775 new DeterministicSocketData(reads2, arraysize(reads2),
12776 writes2, arraysize(writes2)));
12777 MockConnect connect_data2(ASYNC, OK);
12778 data2->set_connect_data(connect_data2);
12779
12780 // Set up a proxy config that sends HTTP requests to a proxy, and
12781 // all others direct.
12782 ProxyConfig proxy_config;
12783 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
[email protected]bb88e1d32013-05-03 23:11:0712784 session_deps_.proxy_service.reset(new ProxyService(
sammc5dd160c2015-04-02 02:43:1312785 new ProxyConfigServiceFixed(proxy_config), nullptr, NULL));
[email protected]2d88e7d2012-07-19 17:55:1712786
bncce36dca22015-04-21 22:11:2312787 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
12788 ssl1.SetNextProto(GetParam());
[email protected]2d88e7d2012-07-19 17:55:1712789 // Load a valid cert. Note, that this does not need to
12790 // be valid for proxy because the MockSSLClientSocket does
12791 // not actually verify it. But SpdySession will use this
12792 // to see if it is valid for the new origin
bncce36dca22015-04-21 22:11:2312793 ssl1.cert = ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
12794 ASSERT_TRUE(ssl1.cert.get());
[email protected]bb88e1d32013-05-03 23:11:0712795 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
12796 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
12797 data1.get());
[email protected]2d88e7d2012-07-19 17:55:1712798
12799 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
[email protected]23e482282013-06-14 16:08:0212800 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0712801 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
12802 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
12803 data2.get());
[email protected]2d88e7d2012-07-19 17:55:1712804
[email protected]bb88e1d32013-05-03 23:11:0712805 session_deps_.host_resolver.reset(new MockCachingHostResolver());
bncce36dca22015-04-21 22:11:2312806 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0712807 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1712808
mmenke6b3af6e2015-09-12 02:06:0612809 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0712810 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]2d88e7d2012-07-19 17:55:1712811
12812 // Start the first transaction to set up the SpdySession
12813 HttpRequestInfo request1;
12814 request1.method = "GET";
12815 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1712816 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012817 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1712818 TestCompletionCallback callback1;
12819 ASSERT_EQ(ERR_IO_PENDING,
12820 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
12821 data1->RunFor(3);
12822
12823 ASSERT_TRUE(callback1.have_result());
12824 EXPECT_EQ(OK, callback1.WaitForResult());
12825 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
12826
12827 // Now, start the HTTP request
12828 HttpRequestInfo request2;
12829 request2.method = "GET";
12830 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1712831 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012832 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1712833 TestCompletionCallback callback2;
12834 EXPECT_EQ(ERR_IO_PENDING,
12835 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412836 base::MessageLoop::current()->RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1712837 data2->RunFor(3);
12838
12839 ASSERT_TRUE(callback2.have_result());
12840 EXPECT_EQ(OK, callback2.WaitForResult());
12841 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
12842}
12843
[email protected]85f97342013-04-17 06:12:2412844// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
12845// error) in SPDY session, removes the socket from pool and closes the SPDY
12846// session. Verify that new url's from the same HttpNetworkSession (and a new
12847// SpdySession) do work. http://crbug.com/224701
[email protected]23e482282013-06-14 16:08:0212848TEST_P(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2312849 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2412850
12851 MockRead reads1[] = {
12852 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
12853 };
12854
mmenke11eb5152015-06-09 14:50:5012855 SequencedSocketData data1(reads1, arraysize(reads1), NULL, 0);
[email protected]85f97342013-04-17 06:12:2412856
[email protected]cdf8f7e72013-05-23 10:56:4612857 scoped_ptr<SpdyFrame> req2(
12858 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2412859 MockWrite writes2[] = {
12860 CreateMockWrite(*req2, 0),
12861 };
12862
[email protected]23e482282013-06-14 16:08:0212863 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12864 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]85f97342013-04-17 06:12:2412865 MockRead reads2[] = {
12866 CreateMockRead(*resp2, 1),
12867 CreateMockRead(*body2, 2),
12868 MockRead(ASYNC, OK, 3) // EOF
12869 };
12870
mmenke11eb5152015-06-09 14:50:5012871 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
12872 arraysize(writes2));
[email protected]85f97342013-04-17 06:12:2412873
[email protected]85f97342013-04-17 06:12:2412874 SSLSocketDataProvider ssl1(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212875 ssl1.SetNextProto(GetParam());
mmenke11eb5152015-06-09 14:50:5012876 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
12877 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]85f97342013-04-17 06:12:2412878
12879 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212880 ssl2.SetNextProto(GetParam());
mmenke11eb5152015-06-09 14:50:5012881 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
12882 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]85f97342013-04-17 06:12:2412883
mmenke6b3af6e2015-09-12 02:06:0612884 scoped_refptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:5012885 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]85f97342013-04-17 06:12:2412886
12887 // Start the first transaction to set up the SpdySession and verify that
12888 // connection was closed.
12889 HttpRequestInfo request1;
12890 request1.method = "GET";
12891 request1.url = GURL(https_url);
12892 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012893 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2412894 TestCompletionCallback callback1;
12895 EXPECT_EQ(ERR_IO_PENDING,
12896 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]85f97342013-04-17 06:12:2412897 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback1.WaitForResult());
12898
12899 // Now, start the second request and make sure it succeeds.
12900 HttpRequestInfo request2;
12901 request2.method = "GET";
12902 request2.url = GURL(https_url);
12903 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012904 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2412905 TestCompletionCallback callback2;
12906 EXPECT_EQ(ERR_IO_PENDING,
12907 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]85f97342013-04-17 06:12:2412908
mmenke11eb5152015-06-09 14:50:5012909 ASSERT_EQ(OK, callback2.WaitForResult());
[email protected]85f97342013-04-17 06:12:2412910 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
12911}
12912
[email protected]23e482282013-06-14 16:08:0212913TEST_P(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]d7599122014-05-24 03:37:2312914 session_deps_.next_protos = SpdyNextProtos();
[email protected]483fa202013-05-14 01:07:0312915 ClientSocketPoolManager::set_max_sockets_per_group(
12916 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12917 ClientSocketPoolManager::set_max_sockets_per_pool(
12918 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12919
12920 // Use two different hosts with different IPs so they don't get pooled.
12921 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
12922 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
mmenke6b3af6e2015-09-12 02:06:0612923 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]483fa202013-05-14 01:07:0312924
12925 SSLSocketDataProvider ssl1(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212926 ssl1.SetNextProto(GetParam());
[email protected]483fa202013-05-14 01:07:0312927 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212928 ssl2.SetNextProto(GetParam());
[email protected]483fa202013-05-14 01:07:0312929 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
12930 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
12931
[email protected]cdf8f7e72013-05-23 10:56:4612932 scoped_ptr<SpdyFrame> host1_req(spdy_util_.ConstructSpdyGet(
[email protected]483fa202013-05-14 01:07:0312933 "https://www.a.com", false, 1, DEFAULT_PRIORITY));
12934 MockWrite spdy1_writes[] = {
rch8e6c6c42015-05-01 14:05:1312935 CreateMockWrite(*host1_req, 0),
[email protected]483fa202013-05-14 01:07:0312936 };
[email protected]23e482282013-06-14 16:08:0212937 scoped_ptr<SpdyFrame> host1_resp(
12938 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12939 scoped_ptr<SpdyFrame> host1_resp_body(
12940 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0312941 MockRead spdy1_reads[] = {
rch8e6c6c42015-05-01 14:05:1312942 CreateMockRead(*host1_resp, 1),
12943 CreateMockRead(*host1_resp_body, 2),
12944 MockRead(ASYNC, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0312945 };
12946
rch8e6c6c42015-05-01 14:05:1312947 scoped_ptr<SequencedSocketData> spdy1_data(
12948 new SequencedSocketData(spdy1_reads, arraysize(spdy1_reads), spdy1_writes,
12949 arraysize(spdy1_writes)));
[email protected]483fa202013-05-14 01:07:0312950 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
12951
[email protected]cdf8f7e72013-05-23 10:56:4612952 scoped_ptr<SpdyFrame> host2_req(spdy_util_.ConstructSpdyGet(
[email protected]483fa202013-05-14 01:07:0312953 "https://www.b.com", false, 1, DEFAULT_PRIORITY));
12954 MockWrite spdy2_writes[] = {
rch8e6c6c42015-05-01 14:05:1312955 CreateMockWrite(*host2_req, 0),
[email protected]483fa202013-05-14 01:07:0312956 };
[email protected]23e482282013-06-14 16:08:0212957 scoped_ptr<SpdyFrame> host2_resp(
12958 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12959 scoped_ptr<SpdyFrame> host2_resp_body(
12960 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0312961 MockRead spdy2_reads[] = {
rch8e6c6c42015-05-01 14:05:1312962 CreateMockRead(*host2_resp, 1),
12963 CreateMockRead(*host2_resp_body, 2),
12964 MockRead(ASYNC, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0312965 };
12966
rch8e6c6c42015-05-01 14:05:1312967 scoped_ptr<SequencedSocketData> spdy2_data(
12968 new SequencedSocketData(spdy2_reads, arraysize(spdy2_reads), spdy2_writes,
12969 arraysize(spdy2_writes)));
[email protected]483fa202013-05-14 01:07:0312970 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
12971
12972 MockWrite http_write[] = {
12973 MockWrite("GET / HTTP/1.1\r\n"
12974 "Host: www.a.com\r\n"
12975 "Connection: keep-alive\r\n\r\n"),
12976 };
12977
12978 MockRead http_read[] = {
12979 MockRead("HTTP/1.1 200 OK\r\n"),
12980 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12981 MockRead("Content-Length: 6\r\n\r\n"),
12982 MockRead("hello!"),
12983 };
12984 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
12985 http_write, arraysize(http_write));
12986 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12987
12988 HostPortPair host_port_pair_a("www.a.com", 443);
[email protected]e6d017652013-05-17 18:01:4012989 SpdySessionKey spdy_session_key_a(
[email protected]314b03992014-04-01 01:28:5312990 host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0312991 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2612992 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0312993
12994 TestCompletionCallback callback;
12995 HttpRequestInfo request1;
12996 request1.method = "GET";
12997 request1.url = GURL("https://www.a.com/");
12998 request1.load_flags = 0;
12999 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5013000 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0313001
13002 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
13003 EXPECT_EQ(ERR_IO_PENDING, rv);
13004 EXPECT_EQ(OK, callback.WaitForResult());
13005
13006 const HttpResponseInfo* response = trans->GetResponseInfo();
13007 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5013008 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0313009 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13010 EXPECT_TRUE(response->was_fetched_via_spdy);
13011 EXPECT_TRUE(response->was_npn_negotiated);
13012
13013 std::string response_data;
13014 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
13015 EXPECT_EQ("hello!", response_data);
13016 trans.reset();
13017 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2613018 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0313019
13020 HostPortPair host_port_pair_b("www.b.com", 443);
[email protected]e6d017652013-05-17 18:01:4013021 SpdySessionKey spdy_session_key_b(
[email protected]314b03992014-04-01 01:28:5313022 host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0313023 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2613024 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0313025 HttpRequestInfo request2;
13026 request2.method = "GET";
13027 request2.url = GURL("https://www.b.com/");
13028 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013029 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0313030
13031 rv = trans->Start(&request2, callback.callback(), BoundNetLog());
13032 EXPECT_EQ(ERR_IO_PENDING, rv);
13033 EXPECT_EQ(OK, callback.WaitForResult());
13034
13035 response = trans->GetResponseInfo();
13036 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5013037 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0313038 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13039 EXPECT_TRUE(response->was_fetched_via_spdy);
13040 EXPECT_TRUE(response->was_npn_negotiated);
13041 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
13042 EXPECT_EQ("hello!", response_data);
13043 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2613044 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0313045 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2613046 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0313047
13048 HostPortPair host_port_pair_a1("www.a.com", 80);
[email protected]e6d017652013-05-17 18:01:4013049 SpdySessionKey spdy_session_key_a1(
[email protected]314b03992014-04-01 01:28:5313050 host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0313051 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2613052 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0313053 HttpRequestInfo request3;
13054 request3.method = "GET";
13055 request3.url = GURL("http://www.a.com/");
13056 request3.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013057 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0313058
13059 rv = trans->Start(&request3, callback.callback(), BoundNetLog());
13060 EXPECT_EQ(ERR_IO_PENDING, rv);
13061 EXPECT_EQ(OK, callback.WaitForResult());
13062
13063 response = trans->GetResponseInfo();
13064 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5013065 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0313066 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13067 EXPECT_FALSE(response->was_fetched_via_spdy);
13068 EXPECT_FALSE(response->was_npn_negotiated);
13069 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
13070 EXPECT_EQ("hello!", response_data);
13071 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2613072 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0313073 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2613074 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0313075}
13076
[email protected]79e1fd62013-06-20 06:50:0413077TEST_P(HttpNetworkTransactionTest, HttpSyncConnectError) {
13078 HttpRequestInfo request;
13079 request.method = "GET";
bncce36dca22015-04-21 22:11:2313080 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0413081 request.load_flags = 0;
13082
mmenke6b3af6e2015-09-12 02:06:0613083 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0413084 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113085 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0413086
13087 MockConnect mock_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
13088 StaticSocketDataProvider data;
13089 data.set_connect_data(mock_connect);
13090 session_deps_.socket_factory->AddSocketDataProvider(&data);
13091
13092 TestCompletionCallback callback;
13093
13094 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13095 EXPECT_EQ(ERR_IO_PENDING, rv);
13096
13097 rv = callback.WaitForResult();
13098 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
13099
[email protected]79e1fd62013-06-20 06:50:0413100 // We don't care whether this succeeds or fails, but it shouldn't crash.
13101 HttpRequestHeaders request_headers;
13102 trans->GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4713103
13104 ConnectionAttempts attempts;
13105 trans->GetConnectionAttempts(&attempts);
13106 ASSERT_EQ(1u, attempts.size());
13107 EXPECT_EQ(ERR_CONNECTION_REFUSED, attempts[0].result);
[email protected]79e1fd62013-06-20 06:50:0413108}
13109
13110TEST_P(HttpNetworkTransactionTest, HttpAsyncConnectError) {
13111 HttpRequestInfo request;
13112 request.method = "GET";
bncce36dca22015-04-21 22:11:2313113 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0413114 request.load_flags = 0;
13115
mmenke6b3af6e2015-09-12 02:06:0613116 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0413117 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113118 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0413119
13120 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
13121 StaticSocketDataProvider data;
13122 data.set_connect_data(mock_connect);
13123 session_deps_.socket_factory->AddSocketDataProvider(&data);
13124
13125 TestCompletionCallback callback;
13126
13127 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13128 EXPECT_EQ(ERR_IO_PENDING, rv);
13129
13130 rv = callback.WaitForResult();
13131 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
13132
[email protected]79e1fd62013-06-20 06:50:0413133 // We don't care whether this succeeds or fails, but it shouldn't crash.
13134 HttpRequestHeaders request_headers;
13135 trans->GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4713136
13137 ConnectionAttempts attempts;
13138 trans->GetConnectionAttempts(&attempts);
13139 ASSERT_EQ(1u, attempts.size());
13140 EXPECT_EQ(ERR_CONNECTION_REFUSED, attempts[0].result);
[email protected]79e1fd62013-06-20 06:50:0413141}
13142
13143TEST_P(HttpNetworkTransactionTest, HttpSyncWriteError) {
13144 HttpRequestInfo request;
13145 request.method = "GET";
bncce36dca22015-04-21 22:11:2313146 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0413147 request.load_flags = 0;
13148
mmenke6b3af6e2015-09-12 02:06:0613149 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0413150 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113151 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0413152
13153 MockWrite data_writes[] = {
13154 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13155 };
13156 MockRead data_reads[] = {
13157 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
13158 };
13159
13160 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
13161 data_writes, arraysize(data_writes));
13162 session_deps_.socket_factory->AddSocketDataProvider(&data);
13163
13164 TestCompletionCallback callback;
13165
13166 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13167 EXPECT_EQ(ERR_IO_PENDING, rv);
13168
13169 rv = callback.WaitForResult();
13170 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13171
[email protected]79e1fd62013-06-20 06:50:0413172 HttpRequestHeaders request_headers;
13173 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
13174 EXPECT_TRUE(request_headers.HasHeader("Host"));
13175}
13176
13177TEST_P(HttpNetworkTransactionTest, HttpAsyncWriteError) {
13178 HttpRequestInfo request;
13179 request.method = "GET";
bncce36dca22015-04-21 22:11:2313180 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0413181 request.load_flags = 0;
13182
mmenke6b3af6e2015-09-12 02:06:0613183 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0413184 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113185 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0413186
13187 MockWrite data_writes[] = {
13188 MockWrite(ASYNC, ERR_CONNECTION_RESET),
13189 };
13190 MockRead data_reads[] = {
13191 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
13192 };
13193
13194 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
13195 data_writes, arraysize(data_writes));
13196 session_deps_.socket_factory->AddSocketDataProvider(&data);
13197
13198 TestCompletionCallback callback;
13199
13200 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13201 EXPECT_EQ(ERR_IO_PENDING, rv);
13202
13203 rv = callback.WaitForResult();
13204 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13205
[email protected]79e1fd62013-06-20 06:50:0413206 HttpRequestHeaders request_headers;
13207 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
13208 EXPECT_TRUE(request_headers.HasHeader("Host"));
13209}
13210
13211TEST_P(HttpNetworkTransactionTest, HttpSyncReadError) {
13212 HttpRequestInfo request;
13213 request.method = "GET";
bncce36dca22015-04-21 22:11:2313214 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0413215 request.load_flags = 0;
13216
mmenke6b3af6e2015-09-12 02:06:0613217 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0413218 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113219 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0413220
13221 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2313222 MockWrite(
13223 "GET / HTTP/1.1\r\n"
13224 "Host: www.example.org\r\n"
13225 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0413226 };
13227 MockRead data_reads[] = {
13228 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
13229 };
13230
13231 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
13232 data_writes, arraysize(data_writes));
13233 session_deps_.socket_factory->AddSocketDataProvider(&data);
13234
13235 TestCompletionCallback callback;
13236
13237 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13238 EXPECT_EQ(ERR_IO_PENDING, rv);
13239
13240 rv = callback.WaitForResult();
13241 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13242
[email protected]79e1fd62013-06-20 06:50:0413243 HttpRequestHeaders request_headers;
13244 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
13245 EXPECT_TRUE(request_headers.HasHeader("Host"));
13246}
13247
13248TEST_P(HttpNetworkTransactionTest, HttpAsyncReadError) {
13249 HttpRequestInfo request;
13250 request.method = "GET";
bncce36dca22015-04-21 22:11:2313251 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0413252 request.load_flags = 0;
13253
mmenke6b3af6e2015-09-12 02:06:0613254 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0413255 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113256 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0413257
13258 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2313259 MockWrite(
13260 "GET / HTTP/1.1\r\n"
13261 "Host: www.example.org\r\n"
13262 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0413263 };
13264 MockRead data_reads[] = {
13265 MockRead(ASYNC, ERR_CONNECTION_RESET),
13266 };
13267
13268 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
13269 data_writes, arraysize(data_writes));
13270 session_deps_.socket_factory->AddSocketDataProvider(&data);
13271
13272 TestCompletionCallback callback;
13273
13274 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13275 EXPECT_EQ(ERR_IO_PENDING, rv);
13276
13277 rv = callback.WaitForResult();
13278 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13279
[email protected]79e1fd62013-06-20 06:50:0413280 HttpRequestHeaders request_headers;
13281 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
13282 EXPECT_TRUE(request_headers.HasHeader("Host"));
13283}
13284
13285TEST_P(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
13286 HttpRequestInfo request;
13287 request.method = "GET";
bncce36dca22015-04-21 22:11:2313288 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0413289 request.load_flags = 0;
13290 request.extra_headers.SetHeader("X-Foo", "bar");
13291
mmenke6b3af6e2015-09-12 02:06:0613292 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0413293 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113294 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0413295
13296 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2313297 MockWrite(
13298 "GET / HTTP/1.1\r\n"
13299 "Host: www.example.org\r\n"
13300 "Connection: keep-alive\r\n"
13301 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0413302 };
13303 MockRead data_reads[] = {
13304 MockRead("HTTP/1.1 200 OK\r\n"
13305 "Content-Length: 5\r\n\r\n"
13306 "hello"),
13307 MockRead(ASYNC, ERR_UNEXPECTED),
13308 };
13309
13310 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
13311 data_writes, arraysize(data_writes));
13312 session_deps_.socket_factory->AddSocketDataProvider(&data);
13313
13314 TestCompletionCallback callback;
13315
13316 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13317 EXPECT_EQ(ERR_IO_PENDING, rv);
13318
13319 rv = callback.WaitForResult();
13320 EXPECT_EQ(OK, rv);
13321
13322 HttpRequestHeaders request_headers;
13323 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
13324 std::string foo;
13325 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
13326 EXPECT_EQ("bar", foo);
13327}
13328
[email protected]bf828982013-08-14 18:01:4713329namespace {
13330
yhiranoa7e05bb2014-11-06 05:40:3913331// Fake HttpStream that simply records calls to SetPriority().
13332class FakeStream : public HttpStream,
[email protected]e86839fd2013-08-14 18:29:0313333 public base::SupportsWeakPtr<FakeStream> {
13334 public:
13335 explicit FakeStream(RequestPriority priority) : priority_(priority) {}
dchengb03027d2014-10-21 12:00:2013336 ~FakeStream() override {}
[email protected]e86839fd2013-08-14 18:29:0313337
13338 RequestPriority priority() const { return priority_; }
13339
dchengb03027d2014-10-21 12:00:2013340 int InitializeStream(const HttpRequestInfo* request_info,
13341 RequestPriority priority,
13342 const BoundNetLog& net_log,
13343 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0313344 return ERR_IO_PENDING;
13345 }
13346
dchengb03027d2014-10-21 12:00:2013347 int SendRequest(const HttpRequestHeaders& request_headers,
13348 HttpResponseInfo* response,
13349 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0313350 ADD_FAILURE();
13351 return ERR_UNEXPECTED;
13352 }
13353
dchengb03027d2014-10-21 12:00:2013354 int ReadResponseHeaders(const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0313355 ADD_FAILURE();
13356 return ERR_UNEXPECTED;
13357 }
13358
dchengb03027d2014-10-21 12:00:2013359 int ReadResponseBody(IOBuffer* buf,
13360 int buf_len,
13361 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0313362 ADD_FAILURE();
13363 return ERR_UNEXPECTED;
13364 }
13365
dchengb03027d2014-10-21 12:00:2013366 void Close(bool not_reusable) override {}
[email protected]e86839fd2013-08-14 18:29:0313367
dchengb03027d2014-10-21 12:00:2013368 bool IsResponseBodyComplete() const override {
[email protected]e86839fd2013-08-14 18:29:0313369 ADD_FAILURE();
13370 return false;
13371 }
13372
dchengb03027d2014-10-21 12:00:2013373 bool IsConnectionReused() const override {
[email protected]e86839fd2013-08-14 18:29:0313374 ADD_FAILURE();
13375 return false;
13376 }
13377
dchengb03027d2014-10-21 12:00:2013378 void SetConnectionReused() override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0313379
mmenkebd84c392015-09-02 14:12:3413380 bool CanReuseConnection() const override { return false; }
[email protected]e86839fd2013-08-14 18:29:0313381
dchengb03027d2014-10-21 12:00:2013382 int64 GetTotalReceivedBytes() const override {
[email protected]bc92bc972013-12-13 08:32:5913383 ADD_FAILURE();
13384 return 0;
13385 }
13386
sclittlebe1ccf62015-09-02 19:40:3613387 int64_t GetTotalSentBytes() const override {
13388 ADD_FAILURE();
13389 return 0;
13390 }
13391
dchengb03027d2014-10-21 12:00:2013392 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
[email protected]e86839fd2013-08-14 18:29:0313393 ADD_FAILURE();
13394 return false;
13395 }
13396
dchengb03027d2014-10-21 12:00:2013397 void GetSSLInfo(SSLInfo* ssl_info) override { ADD_FAILURE(); }
13398
13399 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
[email protected]e86839fd2013-08-14 18:29:0313400 ADD_FAILURE();
13401 }
13402
dchengb03027d2014-10-21 12:00:2013403 void Drain(HttpNetworkSession* session) override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0313404
dchengb03027d2014-10-21 12:00:2013405 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]e86839fd2013-08-14 18:29:0313406
yhiranoa7e05bb2014-11-06 05:40:3913407 UploadProgress GetUploadProgress() const override { return UploadProgress(); }
13408
13409 HttpStream* RenewStreamForAuth() override { return NULL; }
13410
[email protected]e86839fd2013-08-14 18:29:0313411 private:
13412 RequestPriority priority_;
13413
13414 DISALLOW_COPY_AND_ASSIGN(FakeStream);
13415};
13416
13417// Fake HttpStreamRequest that simply records calls to SetPriority()
13418// and vends FakeStreams with its current priority.
[email protected]bf828982013-08-14 18:01:4713419class FakeStreamRequest : public HttpStreamRequest,
13420 public base::SupportsWeakPtr<FakeStreamRequest> {
13421 public:
[email protected]e86839fd2013-08-14 18:29:0313422 FakeStreamRequest(RequestPriority priority,
13423 HttpStreamRequest::Delegate* delegate)
13424 : priority_(priority),
[email protected]831e4a32013-11-14 02:14:4413425 delegate_(delegate),
13426 websocket_stream_create_helper_(NULL) {}
13427
13428 FakeStreamRequest(RequestPriority priority,
13429 HttpStreamRequest::Delegate* delegate,
13430 WebSocketHandshakeStreamBase::CreateHelper* create_helper)
13431 : priority_(priority),
13432 delegate_(delegate),
13433 websocket_stream_create_helper_(create_helper) {}
[email protected]e86839fd2013-08-14 18:29:0313434
dchengb03027d2014-10-21 12:00:2013435 ~FakeStreamRequest() override {}
[email protected]bf828982013-08-14 18:01:4713436
13437 RequestPriority priority() const { return priority_; }
13438
[email protected]831e4a32013-11-14 02:14:4413439 const WebSocketHandshakeStreamBase::CreateHelper*
13440 websocket_stream_create_helper() const {
13441 return websocket_stream_create_helper_;
13442 }
13443
[email protected]e86839fd2013-08-14 18:29:0313444 // Create a new FakeStream and pass it to the request's
13445 // delegate. Returns a weak pointer to the FakeStream.
13446 base::WeakPtr<FakeStream> FinishStreamRequest() {
13447 FakeStream* fake_stream = new FakeStream(priority_);
13448 // Do this before calling OnStreamReady() as OnStreamReady() may
13449 // immediately delete |fake_stream|.
13450 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
13451 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), fake_stream);
13452 return weak_stream;
13453 }
13454
dchengb03027d2014-10-21 12:00:2013455 int RestartTunnelWithProxyAuth(const AuthCredentials& credentials) override {
[email protected]bf828982013-08-14 18:01:4713456 ADD_FAILURE();
13457 return ERR_UNEXPECTED;
13458 }
13459
dchengb03027d2014-10-21 12:00:2013460 LoadState GetLoadState() const override {
[email protected]bf828982013-08-14 18:01:4713461 ADD_FAILURE();
13462 return LoadState();
13463 }
13464
dchengb03027d2014-10-21 12:00:2013465 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]bf828982013-08-14 18:01:4713466
dchengb03027d2014-10-21 12:00:2013467 bool was_npn_negotiated() const override { return false; }
[email protected]bf828982013-08-14 18:01:4713468
dchengb03027d2014-10-21 12:00:2013469 NextProto protocol_negotiated() const override { return kProtoUnknown; }
[email protected]bf828982013-08-14 18:01:4713470
dchengb03027d2014-10-21 12:00:2013471 bool using_spdy() const override { return false; }
[email protected]bf828982013-08-14 18:01:4713472
ttuttle1f2d7e92015-04-28 16:17:4713473 const ConnectionAttempts& connection_attempts() const override {
13474 static ConnectionAttempts no_attempts;
13475 return no_attempts;
13476 }
13477
[email protected]bf828982013-08-14 18:01:4713478 private:
13479 RequestPriority priority_;
[email protected]e86839fd2013-08-14 18:29:0313480 HttpStreamRequest::Delegate* const delegate_;
[email protected]831e4a32013-11-14 02:14:4413481 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
[email protected]bf828982013-08-14 18:01:4713482
13483 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
13484};
13485
13486// Fake HttpStreamFactory that vends FakeStreamRequests.
13487class FakeStreamFactory : public HttpStreamFactory {
13488 public:
13489 FakeStreamFactory() {}
dchengb03027d2014-10-21 12:00:2013490 ~FakeStreamFactory() override {}
[email protected]bf828982013-08-14 18:01:4713491
13492 // Returns a WeakPtr<> to the last HttpStreamRequest returned by
13493 // RequestStream() (which may be NULL if it was destroyed already).
13494 base::WeakPtr<FakeStreamRequest> last_stream_request() {
13495 return last_stream_request_;
13496 }
13497
dchengb03027d2014-10-21 12:00:2013498 HttpStreamRequest* RequestStream(const HttpRequestInfo& info,
13499 RequestPriority priority,
13500 const SSLConfig& server_ssl_config,
13501 const SSLConfig& proxy_ssl_config,
13502 HttpStreamRequest::Delegate* delegate,
13503 const BoundNetLog& net_log) override {
[email protected]e86839fd2013-08-14 18:29:0313504 FakeStreamRequest* fake_request = new FakeStreamRequest(priority, delegate);
[email protected]bf828982013-08-14 18:01:4713505 last_stream_request_ = fake_request->AsWeakPtr();
13506 return fake_request;
13507 }
13508
dchengb03027d2014-10-21 12:00:2013509 HttpStreamRequest* RequestWebSocketHandshakeStream(
[email protected]bf828982013-08-14 18:01:4713510 const HttpRequestInfo& info,
13511 RequestPriority priority,
13512 const SSLConfig& server_ssl_config,
13513 const SSLConfig& proxy_ssl_config,
13514 HttpStreamRequest::Delegate* delegate,
[email protected]467086b2013-11-12 08:19:4613515 WebSocketHandshakeStreamBase::CreateHelper* create_helper,
mostynbba063d6032014-10-09 11:01:1313516 const BoundNetLog& net_log) override {
[email protected]831e4a32013-11-14 02:14:4413517 FakeStreamRequest* fake_request =
13518 new FakeStreamRequest(priority, delegate, create_helper);
13519 last_stream_request_ = fake_request->AsWeakPtr();
13520 return fake_request;
[email protected]bf828982013-08-14 18:01:4713521 }
13522
dchengb03027d2014-10-21 12:00:2013523 void PreconnectStreams(int num_streams,
13524 const HttpRequestInfo& info,
dchengb03027d2014-10-21 12:00:2013525 const SSLConfig& server_ssl_config,
13526 const SSLConfig& proxy_ssl_config) override {
[email protected]bf828982013-08-14 18:01:4713527 ADD_FAILURE();
13528 }
13529
dchengb03027d2014-10-21 12:00:2013530 const HostMappingRules* GetHostMappingRules() const override {
[email protected]bf828982013-08-14 18:01:4713531 ADD_FAILURE();
13532 return NULL;
13533 }
13534
13535 private:
13536 base::WeakPtr<FakeStreamRequest> last_stream_request_;
13537
13538 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
13539};
13540
Adam Rice425cf122015-01-19 06:18:2413541// TODO(ricea): Maybe unify this with the one in
13542// url_request_http_job_unittest.cc ?
13543class FakeWebSocketBasicHandshakeStream : public WebSocketHandshakeStreamBase {
13544 public:
13545 FakeWebSocketBasicHandshakeStream(scoped_ptr<ClientSocketHandle> connection,
13546 bool using_proxy)
13547 : state_(connection.release(), using_proxy) {}
13548
13549 // Fake implementation of HttpStreamBase methods.
13550 // This ends up being quite "real" because this object has to really send data
13551 // on the mock socket. It might be easier to use the real implementation, but
13552 // the fact that the WebSocket code is not compiled on iOS makes that
13553 // difficult.
13554 int InitializeStream(const HttpRequestInfo* request_info,
13555 RequestPriority priority,
13556 const BoundNetLog& net_log,
13557 const CompletionCallback& callback) override {
13558 state_.Initialize(request_info, priority, net_log, callback);
13559 return OK;
13560 }
13561
13562 int SendRequest(const HttpRequestHeaders& request_headers,
13563 HttpResponseInfo* response,
13564 const CompletionCallback& callback) override {
13565 return parser()->SendRequest(state_.GenerateRequestLine(), request_headers,
13566 response, callback);
13567 }
13568
13569 int ReadResponseHeaders(const CompletionCallback& callback) override {
13570 return parser()->ReadResponseHeaders(callback);
13571 }
13572
13573 int ReadResponseBody(IOBuffer* buf,
13574 int buf_len,
13575 const CompletionCallback& callback) override {
13576 NOTREACHED();
13577 return ERR_IO_PENDING;
13578 }
13579
13580 void Close(bool not_reusable) override {
13581 if (parser())
13582 parser()->Close(true);
13583 }
13584
13585 bool IsResponseBodyComplete() const override {
13586 NOTREACHED();
13587 return false;
13588 }
13589
Adam Rice425cf122015-01-19 06:18:2413590 bool IsConnectionReused() const override {
13591 NOTREACHED();
13592 return false;
13593 }
13594 void SetConnectionReused() override { NOTREACHED(); }
13595
mmenkebd84c392015-09-02 14:12:3413596 bool CanReuseConnection() const override { return false; }
Adam Rice425cf122015-01-19 06:18:2413597
13598 int64 GetTotalReceivedBytes() const override {
13599 NOTREACHED();
13600 return 0;
13601 }
13602
sclittlebe1ccf62015-09-02 19:40:3613603 int64_t GetTotalSentBytes() const override {
13604 NOTREACHED();
13605 return 0;
13606 }
13607
Adam Rice425cf122015-01-19 06:18:2413608 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
13609 NOTREACHED();
13610 return false;
13611 }
13612
Adam Ricecb76ac62015-02-20 05:33:2513613 void GetSSLInfo(SSLInfo* ssl_info) override {}
Adam Rice425cf122015-01-19 06:18:2413614
13615 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
13616 NOTREACHED();
13617 }
13618
Adam Rice425cf122015-01-19 06:18:2413619 void Drain(HttpNetworkSession* session) override { NOTREACHED(); }
13620
13621 void SetPriority(RequestPriority priority) override { NOTREACHED(); }
13622
13623 UploadProgress GetUploadProgress() const override {
13624 NOTREACHED();
13625 return UploadProgress();
13626 }
13627
13628 HttpStream* RenewStreamForAuth() override {
13629 NOTREACHED();
13630 return nullptr;
13631 }
13632
13633 // Fake implementation of WebSocketHandshakeStreamBase method(s)
13634 scoped_ptr<WebSocketStream> Upgrade() override {
13635 NOTREACHED();
13636 return scoped_ptr<WebSocketStream>();
13637 }
13638
13639 private:
13640 HttpStreamParser* parser() const { return state_.parser(); }
13641 HttpBasicState state_;
13642
13643 DISALLOW_COPY_AND_ASSIGN(FakeWebSocketBasicHandshakeStream);
13644};
13645
[email protected]831e4a32013-11-14 02:14:4413646// TODO(yhirano): Split this class out into a net/websockets file, if it is
13647// worth doing.
13648class FakeWebSocketStreamCreateHelper :
13649 public WebSocketHandshakeStreamBase::CreateHelper {
13650 public:
dchengb03027d2014-10-21 12:00:2013651 WebSocketHandshakeStreamBase* CreateBasicStream(
[email protected]7e841a52013-11-22 09:04:2113652 scoped_ptr<ClientSocketHandle> connection,
mostynbba063d6032014-10-09 11:01:1313653 bool using_proxy) override {
Adam Rice425cf122015-01-19 06:18:2413654 return new FakeWebSocketBasicHandshakeStream(connection.Pass(),
13655 using_proxy);
[email protected]831e4a32013-11-14 02:14:4413656 }
13657
dchengb03027d2014-10-21 12:00:2013658 WebSocketHandshakeStreamBase* CreateSpdyStream(
[email protected]831e4a32013-11-14 02:14:4413659 const base::WeakPtr<SpdySession>& session,
mostynbba063d6032014-10-09 11:01:1313660 bool use_relative_url) override {
[email protected]831e4a32013-11-14 02:14:4413661 NOTREACHED();
13662 return NULL;
13663 };
13664
dchengb03027d2014-10-21 12:00:2013665 ~FakeWebSocketStreamCreateHelper() override {}
[email protected]831e4a32013-11-14 02:14:4413666
13667 virtual scoped_ptr<WebSocketStream> Upgrade() {
13668 NOTREACHED();
13669 return scoped_ptr<WebSocketStream>();
13670 }
13671};
13672
[email protected]bf828982013-08-14 18:01:4713673} // namespace
13674
13675// Make sure that HttpNetworkTransaction passes on its priority to its
13676// stream request on start.
13677TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
mmenke6b3af6e2015-09-12 02:06:0613678 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13679 HttpNetworkSessionPeer peer(session);
[email protected]bf828982013-08-14 18:01:4713680 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4413681 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4713682
dcheng48459ac22014-08-26 00:46:4113683 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4713684
13685 ASSERT_TRUE(fake_factory->last_stream_request() == NULL);
13686
13687 HttpRequestInfo request;
13688 TestCompletionCallback callback;
13689 EXPECT_EQ(ERR_IO_PENDING,
13690 trans.Start(&request, callback.callback(), BoundNetLog()));
13691
13692 base::WeakPtr<FakeStreamRequest> fake_request =
13693 fake_factory->last_stream_request();
13694 ASSERT_TRUE(fake_request != NULL);
13695 EXPECT_EQ(LOW, fake_request->priority());
13696}
13697
13698// Make sure that HttpNetworkTransaction passes on its priority
13699// updates to its stream request.
13700TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriority) {
mmenke6b3af6e2015-09-12 02:06:0613701 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13702 HttpNetworkSessionPeer peer(session);
[email protected]bf828982013-08-14 18:01:4713703 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4413704 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4713705
dcheng48459ac22014-08-26 00:46:4113706 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4713707
13708 HttpRequestInfo request;
13709 TestCompletionCallback callback;
13710 EXPECT_EQ(ERR_IO_PENDING,
13711 trans.Start(&request, callback.callback(), BoundNetLog()));
13712
13713 base::WeakPtr<FakeStreamRequest> fake_request =
13714 fake_factory->last_stream_request();
13715 ASSERT_TRUE(fake_request != NULL);
13716 EXPECT_EQ(LOW, fake_request->priority());
13717
13718 trans.SetPriority(LOWEST);
13719 ASSERT_TRUE(fake_request != NULL);
13720 EXPECT_EQ(LOWEST, fake_request->priority());
13721}
13722
[email protected]e86839fd2013-08-14 18:29:0313723// Make sure that HttpNetworkTransaction passes on its priority
13724// updates to its stream.
13725TEST_P(HttpNetworkTransactionTest, SetStreamPriority) {
mmenke6b3af6e2015-09-12 02:06:0613726 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13727 HttpNetworkSessionPeer peer(session);
[email protected]e86839fd2013-08-14 18:29:0313728 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4413729 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]e86839fd2013-08-14 18:29:0313730
dcheng48459ac22014-08-26 00:46:4113731 HttpNetworkTransaction trans(LOW, session.get());
[email protected]e86839fd2013-08-14 18:29:0313732
13733 HttpRequestInfo request;
13734 TestCompletionCallback callback;
13735 EXPECT_EQ(ERR_IO_PENDING,
13736 trans.Start(&request, callback.callback(), BoundNetLog()));
13737
13738 base::WeakPtr<FakeStreamRequest> fake_request =
13739 fake_factory->last_stream_request();
13740 ASSERT_TRUE(fake_request != NULL);
13741 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
13742 ASSERT_TRUE(fake_stream != NULL);
13743 EXPECT_EQ(LOW, fake_stream->priority());
13744
13745 trans.SetPriority(LOWEST);
13746 EXPECT_EQ(LOWEST, fake_stream->priority());
13747}
13748
[email protected]831e4a32013-11-14 02:14:4413749TEST_P(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
13750 // The same logic needs to be tested for both ws: and wss: schemes, but this
13751 // test is already parameterised on NextProto, so it uses a loop to verify
13752 // that the different schemes work.
bncce36dca22015-04-21 22:11:2313753 std::string test_cases[] = {"ws://www.example.org/",
13754 "wss://www.example.org/"};
[email protected]831e4a32013-11-14 02:14:4413755 for (size_t i = 0; i < arraysize(test_cases); ++i) {
mmenke6b3af6e2015-09-12 02:06:0613756 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13757 HttpNetworkSessionPeer peer(session);
[email protected]831e4a32013-11-14 02:14:4413758 FakeStreamFactory* fake_factory = new FakeStreamFactory();
13759 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
[email protected]0191b51c2013-11-18 10:55:2313760 peer.SetHttpStreamFactoryForWebSocket(
[email protected]831e4a32013-11-14 02:14:4413761 scoped_ptr<HttpStreamFactory>(fake_factory));
13762
dcheng48459ac22014-08-26 00:46:4113763 HttpNetworkTransaction trans(LOW, session.get());
[email protected]831e4a32013-11-14 02:14:4413764 trans.SetWebSocketHandshakeStreamCreateHelper(
13765 &websocket_stream_create_helper);
13766
13767 HttpRequestInfo request;
13768 TestCompletionCallback callback;
13769 request.method = "GET";
13770 request.url = GURL(test_cases[i]);
13771
13772 EXPECT_EQ(ERR_IO_PENDING,
13773 trans.Start(&request, callback.callback(), BoundNetLog()));
13774
13775 base::WeakPtr<FakeStreamRequest> fake_request =
13776 fake_factory->last_stream_request();
13777 ASSERT_TRUE(fake_request != NULL);
13778 EXPECT_EQ(&websocket_stream_create_helper,
13779 fake_request->websocket_stream_create_helper());
13780 }
13781}
13782
[email protected]043b68c82013-08-22 23:41:5213783// Tests that when a used socket is returned to the SSL socket pool, it's closed
13784// if the transport socket pool is stalled on the global socket limit.
13785TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
13786 ClientSocketPoolManager::set_max_sockets_per_group(
13787 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13788 ClientSocketPoolManager::set_max_sockets_per_pool(
13789 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13790
13791 // Set up SSL request.
13792
13793 HttpRequestInfo ssl_request;
13794 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2313795 ssl_request.url = GURL("https://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5213796
13797 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2313798 MockWrite(
13799 "GET / HTTP/1.1\r\n"
13800 "Host: www.example.org\r\n"
13801 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5213802 };
13803 MockRead ssl_reads[] = {
13804 MockRead("HTTP/1.1 200 OK\r\n"),
13805 MockRead("Content-Length: 11\r\n\r\n"),
13806 MockRead("hello world"),
13807 MockRead(SYNCHRONOUS, OK),
13808 };
13809 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
13810 ssl_writes, arraysize(ssl_writes));
13811 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
13812
13813 SSLSocketDataProvider ssl(ASYNC, OK);
13814 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13815
13816 // Set up HTTP request.
13817
13818 HttpRequestInfo http_request;
13819 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2313820 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5213821
13822 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2313823 MockWrite(
13824 "GET / HTTP/1.1\r\n"
13825 "Host: www.example.org\r\n"
13826 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5213827 };
13828 MockRead http_reads[] = {
13829 MockRead("HTTP/1.1 200 OK\r\n"),
13830 MockRead("Content-Length: 7\r\n\r\n"),
13831 MockRead("falafel"),
13832 MockRead(SYNCHRONOUS, OK),
13833 };
13834 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
13835 http_writes, arraysize(http_writes));
13836 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13837
mmenke6b3af6e2015-09-12 02:06:0613838 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5213839
13840 // Start the SSL request.
13841 TestCompletionCallback ssl_callback;
13842 scoped_ptr<HttpTransaction> ssl_trans(
13843 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13844 ASSERT_EQ(ERR_IO_PENDING,
13845 ssl_trans->Start(&ssl_request, ssl_callback.callback(),
13846 BoundNetLog()));
13847
13848 // Start the HTTP request. Pool should stall.
13849 TestCompletionCallback http_callback;
13850 scoped_ptr<HttpTransaction> http_trans(
13851 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13852 ASSERT_EQ(ERR_IO_PENDING,
13853 http_trans->Start(&http_request, http_callback.callback(),
13854 BoundNetLog()));
dcheng48459ac22014-08-26 00:46:4113855 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5213856
13857 // Wait for response from SSL request.
13858 ASSERT_EQ(OK, ssl_callback.WaitForResult());
13859 std::string response_data;
13860 ASSERT_EQ(OK, ReadTransaction(ssl_trans.get(), &response_data));
13861 EXPECT_EQ("hello world", response_data);
13862
13863 // The SSL socket should automatically be closed, so the HTTP request can
13864 // start.
dcheng48459ac22014-08-26 00:46:4113865 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
13866 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5213867
13868 // The HTTP request can now complete.
13869 ASSERT_EQ(OK, http_callback.WaitForResult());
13870 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
13871 EXPECT_EQ("falafel", response_data);
13872
dcheng48459ac22014-08-26 00:46:4113873 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5213874}
13875
13876// Tests that when a SSL connection is established but there's no corresponding
13877// request that needs it, the new socket is closed if the transport socket pool
13878// is stalled on the global socket limit.
13879TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
13880 ClientSocketPoolManager::set_max_sockets_per_group(
13881 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13882 ClientSocketPoolManager::set_max_sockets_per_pool(
13883 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13884
13885 // Set up an ssl request.
13886
13887 HttpRequestInfo ssl_request;
13888 ssl_request.method = "GET";
13889 ssl_request.url = GURL("https://www.foopy.com/");
13890
13891 // No data will be sent on the SSL socket.
13892 StaticSocketDataProvider ssl_data;
13893 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
13894
13895 SSLSocketDataProvider ssl(ASYNC, OK);
13896 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13897
13898 // Set up HTTP request.
13899
13900 HttpRequestInfo http_request;
13901 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2313902 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5213903
13904 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2313905 MockWrite(
13906 "GET / HTTP/1.1\r\n"
13907 "Host: www.example.org\r\n"
13908 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5213909 };
13910 MockRead http_reads[] = {
13911 MockRead("HTTP/1.1 200 OK\r\n"),
13912 MockRead("Content-Length: 7\r\n\r\n"),
13913 MockRead("falafel"),
13914 MockRead(SYNCHRONOUS, OK),
13915 };
13916 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
13917 http_writes, arraysize(http_writes));
13918 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13919
mmenke6b3af6e2015-09-12 02:06:0613920 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5213921
13922 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
13923 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2913924 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
13925 SSLConfig ssl_config;
[email protected]043b68c82013-08-22 23:41:5213926 session->ssl_config_service()->GetSSLConfig(&ssl_config);
mmenked1205bd2015-07-15 22:26:3513927 http_stream_factory->PreconnectStreams(1, ssl_request, ssl_config,
13928 ssl_config);
dcheng48459ac22014-08-26 00:46:4113929 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5213930
13931 // Start the HTTP request. Pool should stall.
13932 TestCompletionCallback http_callback;
13933 scoped_ptr<HttpTransaction> http_trans(
13934 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13935 ASSERT_EQ(ERR_IO_PENDING,
13936 http_trans->Start(&http_request, http_callback.callback(),
13937 BoundNetLog()));
dcheng48459ac22014-08-26 00:46:4113938 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5213939
13940 // The SSL connection will automatically be closed once the connection is
13941 // established, to let the HTTP request start.
13942 ASSERT_EQ(OK, http_callback.WaitForResult());
13943 std::string response_data;
13944 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
13945 EXPECT_EQ("falafel", response_data);
13946
dcheng48459ac22014-08-26 00:46:4113947 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5213948}
13949
[email protected]02d74a02014-04-23 18:10:5413950TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
13951 ScopedVector<UploadElementReader> element_readers;
13952 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713953 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413954
13955 HttpRequestInfo request;
13956 request.method = "POST";
13957 request.url = GURL("http://www.foo.com/");
13958 request.upload_data_stream = &upload_data_stream;
13959 request.load_flags = 0;
13960
mmenke6b3af6e2015-09-12 02:06:0613961 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5413962 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113963 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413964 // Send headers successfully, but get an error while sending the body.
13965 MockWrite data_writes[] = {
13966 MockWrite("POST / HTTP/1.1\r\n"
13967 "Host: www.foo.com\r\n"
13968 "Connection: keep-alive\r\n"
13969 "Content-Length: 3\r\n\r\n"),
13970 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13971 };
13972
13973 MockRead data_reads[] = {
13974 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
13975 MockRead("hello world"),
13976 MockRead(SYNCHRONOUS, OK),
13977 };
13978 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13979 arraysize(data_writes));
13980 session_deps_.socket_factory->AddSocketDataProvider(&data);
13981
13982 TestCompletionCallback callback;
13983
13984 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13985 EXPECT_EQ(ERR_IO_PENDING, rv);
13986
13987 rv = callback.WaitForResult();
13988 EXPECT_EQ(OK, rv);
13989
13990 const HttpResponseInfo* response = trans->GetResponseInfo();
13991 ASSERT_TRUE(response != NULL);
13992
13993 EXPECT_TRUE(response->headers.get() != NULL);
13994 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
13995
13996 std::string response_data;
13997 rv = ReadTransaction(trans.get(), &response_data);
13998 EXPECT_EQ(OK, rv);
13999 EXPECT_EQ("hello world", response_data);
14000}
14001
14002// This test makes sure the retry logic doesn't trigger when reading an error
14003// response from a server that rejected a POST with a CONNECTION_RESET.
14004TEST_P(HttpNetworkTransactionTest,
14005 PostReadsErrorResponseAfterResetOnReusedSocket) {
mmenke6b3af6e2015-09-12 02:06:0614006 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5414007 MockWrite data_writes[] = {
14008 MockWrite("GET / HTTP/1.1\r\n"
14009 "Host: www.foo.com\r\n"
14010 "Connection: keep-alive\r\n\r\n"),
14011 MockWrite("POST / HTTP/1.1\r\n"
14012 "Host: www.foo.com\r\n"
14013 "Connection: keep-alive\r\n"
14014 "Content-Length: 3\r\n\r\n"),
14015 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14016 };
14017
14018 MockRead data_reads[] = {
14019 MockRead("HTTP/1.1 200 Peachy\r\n"
14020 "Content-Length: 14\r\n\r\n"),
14021 MockRead("first response"),
14022 MockRead("HTTP/1.1 400 Not OK\r\n"
14023 "Content-Length: 15\r\n\r\n"),
14024 MockRead("second response"),
14025 MockRead(SYNCHRONOUS, OK),
14026 };
14027 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14028 arraysize(data_writes));
14029 session_deps_.socket_factory->AddSocketDataProvider(&data);
14030
14031 TestCompletionCallback callback;
14032 HttpRequestInfo request1;
14033 request1.method = "GET";
14034 request1.url = GURL("http://www.foo.com/");
14035 request1.load_flags = 0;
14036
14037 scoped_ptr<HttpTransaction> trans1(
dcheng48459ac22014-08-26 00:46:4114038 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414039 int rv = trans1->Start(&request1, callback.callback(), BoundNetLog());
14040 EXPECT_EQ(ERR_IO_PENDING, rv);
14041
14042 rv = callback.WaitForResult();
14043 EXPECT_EQ(OK, rv);
14044
14045 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
14046 ASSERT_TRUE(response1 != NULL);
14047
14048 EXPECT_TRUE(response1->headers.get() != NULL);
14049 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
14050
14051 std::string response_data1;
14052 rv = ReadTransaction(trans1.get(), &response_data1);
14053 EXPECT_EQ(OK, rv);
14054 EXPECT_EQ("first response", response_data1);
14055 // Delete the transaction to release the socket back into the socket pool.
14056 trans1.reset();
14057
14058 ScopedVector<UploadElementReader> element_readers;
14059 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714060 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5414061
14062 HttpRequestInfo request2;
14063 request2.method = "POST";
14064 request2.url = GURL("http://www.foo.com/");
14065 request2.upload_data_stream = &upload_data_stream;
14066 request2.load_flags = 0;
14067
14068 scoped_ptr<HttpTransaction> trans2(
dcheng48459ac22014-08-26 00:46:4114069 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414070 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
14071 EXPECT_EQ(ERR_IO_PENDING, rv);
14072
14073 rv = callback.WaitForResult();
14074 EXPECT_EQ(OK, rv);
14075
14076 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
14077 ASSERT_TRUE(response2 != NULL);
14078
14079 EXPECT_TRUE(response2->headers.get() != NULL);
14080 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
14081
14082 std::string response_data2;
14083 rv = ReadTransaction(trans2.get(), &response_data2);
14084 EXPECT_EQ(OK, rv);
14085 EXPECT_EQ("second response", response_data2);
14086}
14087
14088TEST_P(HttpNetworkTransactionTest,
14089 PostReadsErrorResponseAfterResetPartialBodySent) {
14090 ScopedVector<UploadElementReader> element_readers;
14091 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714092 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5414093
14094 HttpRequestInfo request;
14095 request.method = "POST";
14096 request.url = GURL("http://www.foo.com/");
14097 request.upload_data_stream = &upload_data_stream;
14098 request.load_flags = 0;
14099
mmenke6b3af6e2015-09-12 02:06:0614100 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5414101 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114102 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414103 // Send headers successfully, but get an error while sending the body.
14104 MockWrite data_writes[] = {
14105 MockWrite("POST / HTTP/1.1\r\n"
14106 "Host: www.foo.com\r\n"
14107 "Connection: keep-alive\r\n"
14108 "Content-Length: 3\r\n\r\n"
14109 "fo"),
14110 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14111 };
14112
14113 MockRead data_reads[] = {
14114 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
14115 MockRead("hello world"),
14116 MockRead(SYNCHRONOUS, OK),
14117 };
14118 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14119 arraysize(data_writes));
14120 session_deps_.socket_factory->AddSocketDataProvider(&data);
14121
14122 TestCompletionCallback callback;
14123
14124 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14125 EXPECT_EQ(ERR_IO_PENDING, rv);
14126
14127 rv = callback.WaitForResult();
14128 EXPECT_EQ(OK, rv);
14129
14130 const HttpResponseInfo* response = trans->GetResponseInfo();
14131 ASSERT_TRUE(response != NULL);
14132
14133 EXPECT_TRUE(response->headers.get() != NULL);
14134 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
14135
14136 std::string response_data;
14137 rv = ReadTransaction(trans.get(), &response_data);
14138 EXPECT_EQ(OK, rv);
14139 EXPECT_EQ("hello world", response_data);
14140}
14141
14142// This tests the more common case than the previous test, where headers and
14143// body are not merged into a single request.
14144TEST_P(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
14145 ScopedVector<UploadElementReader> element_readers;
14146 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714147 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5414148
14149 HttpRequestInfo request;
14150 request.method = "POST";
14151 request.url = GURL("http://www.foo.com/");
14152 request.upload_data_stream = &upload_data_stream;
14153 request.load_flags = 0;
14154
mmenke6b3af6e2015-09-12 02:06:0614155 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5414156 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114157 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414158 // Send headers successfully, but get an error while sending the body.
14159 MockWrite data_writes[] = {
14160 MockWrite("POST / HTTP/1.1\r\n"
14161 "Host: www.foo.com\r\n"
14162 "Connection: keep-alive\r\n"
14163 "Transfer-Encoding: chunked\r\n\r\n"),
14164 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14165 };
14166
14167 MockRead data_reads[] = {
14168 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
14169 MockRead("hello world"),
14170 MockRead(SYNCHRONOUS, OK),
14171 };
14172 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14173 arraysize(data_writes));
14174 session_deps_.socket_factory->AddSocketDataProvider(&data);
14175
14176 TestCompletionCallback callback;
14177
14178 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14179 EXPECT_EQ(ERR_IO_PENDING, rv);
14180 // Make sure the headers are sent before adding a chunk. This ensures that
14181 // they can't be merged with the body in a single send. Not currently
14182 // necessary since a chunked body is never merged with headers, but this makes
14183 // the test more future proof.
14184 base::RunLoop().RunUntilIdle();
14185
mmenkecbc2b712014-10-09 20:29:0714186 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5414187
14188 rv = callback.WaitForResult();
14189 EXPECT_EQ(OK, rv);
14190
14191 const HttpResponseInfo* response = trans->GetResponseInfo();
14192 ASSERT_TRUE(response != NULL);
14193
14194 EXPECT_TRUE(response->headers.get() != NULL);
14195 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
14196
14197 std::string response_data;
14198 rv = ReadTransaction(trans.get(), &response_data);
14199 EXPECT_EQ(OK, rv);
14200 EXPECT_EQ("hello world", response_data);
14201}
14202
14203TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
14204 ScopedVector<UploadElementReader> element_readers;
14205 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714206 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5414207
14208 HttpRequestInfo request;
14209 request.method = "POST";
14210 request.url = GURL("http://www.foo.com/");
14211 request.upload_data_stream = &upload_data_stream;
14212 request.load_flags = 0;
14213
mmenke6b3af6e2015-09-12 02:06:0614214 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5414215 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114216 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414217
14218 MockWrite data_writes[] = {
14219 MockWrite("POST / HTTP/1.1\r\n"
14220 "Host: www.foo.com\r\n"
14221 "Connection: keep-alive\r\n"
14222 "Content-Length: 3\r\n\r\n"),
14223 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14224 };
14225
14226 MockRead data_reads[] = {
14227 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
14228 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
14229 MockRead("hello world"),
14230 MockRead(SYNCHRONOUS, OK),
14231 };
14232 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14233 arraysize(data_writes));
14234 session_deps_.socket_factory->AddSocketDataProvider(&data);
14235
14236 TestCompletionCallback callback;
14237
14238 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14239 EXPECT_EQ(ERR_IO_PENDING, rv);
14240
14241 rv = callback.WaitForResult();
14242 EXPECT_EQ(OK, rv);
14243
14244 const HttpResponseInfo* response = trans->GetResponseInfo();
14245 ASSERT_TRUE(response != NULL);
14246
14247 EXPECT_TRUE(response->headers.get() != NULL);
14248 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
14249
14250 std::string response_data;
14251 rv = ReadTransaction(trans.get(), &response_data);
14252 EXPECT_EQ(OK, rv);
14253 EXPECT_EQ("hello world", response_data);
14254}
14255
14256TEST_P(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
14257 ScopedVector<UploadElementReader> element_readers;
14258 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714259 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5414260
14261 HttpRequestInfo request;
14262 request.method = "POST";
14263 request.url = GURL("http://www.foo.com/");
14264 request.upload_data_stream = &upload_data_stream;
14265 request.load_flags = 0;
14266
mmenke6b3af6e2015-09-12 02:06:0614267 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5414268 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114269 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414270 // Send headers successfully, but get an error while sending the body.
14271 MockWrite data_writes[] = {
14272 MockWrite("POST / HTTP/1.1\r\n"
14273 "Host: www.foo.com\r\n"
14274 "Connection: keep-alive\r\n"
14275 "Content-Length: 3\r\n\r\n"),
14276 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14277 };
14278
14279 MockRead data_reads[] = {
14280 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
14281 MockRead("hello world"),
14282 MockRead(SYNCHRONOUS, OK),
14283 };
14284 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14285 arraysize(data_writes));
14286 session_deps_.socket_factory->AddSocketDataProvider(&data);
14287
14288 TestCompletionCallback callback;
14289
14290 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14291 EXPECT_EQ(ERR_IO_PENDING, rv);
14292
14293 rv = callback.WaitForResult();
14294 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5414295}
14296
14297TEST_P(HttpNetworkTransactionTest,
14298 PostIgnoresNonErrorResponseAfterResetAnd100) {
14299 ScopedVector<UploadElementReader> element_readers;
14300 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714301 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5414302
14303 HttpRequestInfo request;
14304 request.method = "POST";
14305 request.url = GURL("http://www.foo.com/");
14306 request.upload_data_stream = &upload_data_stream;
14307 request.load_flags = 0;
14308
mmenke6b3af6e2015-09-12 02:06:0614309 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5414310 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114311 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414312 // Send headers successfully, but get an error while sending the body.
14313 MockWrite data_writes[] = {
14314 MockWrite("POST / HTTP/1.1\r\n"
14315 "Host: www.foo.com\r\n"
14316 "Connection: keep-alive\r\n"
14317 "Content-Length: 3\r\n\r\n"),
14318 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14319 };
14320
14321 MockRead data_reads[] = {
14322 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
14323 MockRead("HTTP/1.0 302 Redirect\r\n"),
14324 MockRead("Location: http://somewhere-else.com/\r\n"),
14325 MockRead("Content-Length: 0\r\n\r\n"),
14326 MockRead(SYNCHRONOUS, OK),
14327 };
14328 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14329 arraysize(data_writes));
14330 session_deps_.socket_factory->AddSocketDataProvider(&data);
14331
14332 TestCompletionCallback callback;
14333
14334 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14335 EXPECT_EQ(ERR_IO_PENDING, rv);
14336
14337 rv = callback.WaitForResult();
14338 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5414339}
14340
14341TEST_P(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
14342 ScopedVector<UploadElementReader> element_readers;
14343 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714344 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5414345
14346 HttpRequestInfo request;
14347 request.method = "POST";
14348 request.url = GURL("http://www.foo.com/");
14349 request.upload_data_stream = &upload_data_stream;
14350 request.load_flags = 0;
14351
mmenke6b3af6e2015-09-12 02:06:0614352 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5414353 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114354 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414355 // Send headers successfully, but get an error while sending the body.
14356 MockWrite data_writes[] = {
14357 MockWrite("POST / HTTP/1.1\r\n"
14358 "Host: www.foo.com\r\n"
14359 "Connection: keep-alive\r\n"
14360 "Content-Length: 3\r\n\r\n"),
14361 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14362 };
14363
14364 MockRead data_reads[] = {
14365 MockRead("HTTP 0.9 rocks!"),
14366 MockRead(SYNCHRONOUS, OK),
14367 };
14368 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14369 arraysize(data_writes));
14370 session_deps_.socket_factory->AddSocketDataProvider(&data);
14371
14372 TestCompletionCallback callback;
14373
14374 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14375 EXPECT_EQ(ERR_IO_PENDING, rv);
14376
14377 rv = callback.WaitForResult();
14378 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5414379}
14380
14381TEST_P(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
14382 ScopedVector<UploadElementReader> element_readers;
14383 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714384 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5414385
14386 HttpRequestInfo request;
14387 request.method = "POST";
14388 request.url = GURL("http://www.foo.com/");
14389 request.upload_data_stream = &upload_data_stream;
14390 request.load_flags = 0;
14391
mmenke6b3af6e2015-09-12 02:06:0614392 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5414393 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114394 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414395 // Send headers successfully, but get an error while sending the body.
14396 MockWrite data_writes[] = {
14397 MockWrite("POST / HTTP/1.1\r\n"
14398 "Host: www.foo.com\r\n"
14399 "Connection: keep-alive\r\n"
14400 "Content-Length: 3\r\n\r\n"),
14401 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14402 };
14403
14404 MockRead data_reads[] = {
14405 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
14406 MockRead(SYNCHRONOUS, OK),
14407 };
14408 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14409 arraysize(data_writes));
14410 session_deps_.socket_factory->AddSocketDataProvider(&data);
14411
14412 TestCompletionCallback callback;
14413
14414 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14415 EXPECT_EQ(ERR_IO_PENDING, rv);
14416
14417 rv = callback.WaitForResult();
14418 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5414419}
14420
Adam Rice425cf122015-01-19 06:18:2414421// Verify that proxy headers are not sent to the destination server when
14422// establishing a tunnel for a secure WebSocket connection.
14423TEST_P(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
14424 HttpRequestInfo request;
14425 request.method = "GET";
bncce36dca22015-04-21 22:11:2314426 request.url = GURL("wss://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2414427 AddWebSocketHeaders(&request.extra_headers);
14428
14429 // Configure against proxy server "myproxy:70".
14430 session_deps_.proxy_service.reset(
14431 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
14432
mmenke6b3af6e2015-09-12 02:06:0614433 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2414434
14435 // Since a proxy is configured, try to establish a tunnel.
14436 MockWrite data_writes[] = {
14437 MockWrite(
bncce36dca22015-04-21 22:11:2314438 "CONNECT www.example.org:443 HTTP/1.1\r\n"
14439 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414440 "Proxy-Connection: keep-alive\r\n\r\n"),
14441
14442 // After calling trans->RestartWithAuth(), this is the request we should
14443 // be issuing -- the final header line contains the credentials.
14444 MockWrite(
bncce36dca22015-04-21 22:11:2314445 "CONNECT www.example.org:443 HTTP/1.1\r\n"
14446 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414447 "Proxy-Connection: keep-alive\r\n"
14448 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
14449
14450 MockWrite(
14451 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2314452 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414453 "Connection: Upgrade\r\n"
14454 "Upgrade: websocket\r\n"
bncce36dca22015-04-21 22:11:2314455 "Origin: http://www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414456 "Sec-WebSocket-Version: 13\r\n"
14457 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
14458 };
14459
14460 // The proxy responds to the connect with a 407, using a persistent
14461 // connection.
14462 MockRead data_reads[] = {
14463 // No credentials.
14464 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
14465 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
mmenkee0b5c882015-08-26 20:29:1114466 MockRead("Content-Length: 0\r\n"),
14467 MockRead("Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2414468
14469 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
14470
14471 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
14472 MockRead("Upgrade: websocket\r\n"),
14473 MockRead("Connection: Upgrade\r\n"),
14474 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
14475 };
14476
14477 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14478 arraysize(data_writes));
14479 session_deps_.socket_factory->AddSocketDataProvider(&data);
14480 SSLSocketDataProvider ssl(ASYNC, OK);
14481 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14482
14483 scoped_ptr<HttpTransaction> trans(
14484 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
14485 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
14486 trans->SetWebSocketHandshakeStreamCreateHelper(
14487 &websocket_stream_create_helper);
14488
14489 {
14490 TestCompletionCallback callback;
14491
14492 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14493 EXPECT_EQ(ERR_IO_PENDING, rv);
14494
14495 rv = callback.WaitForResult();
14496 EXPECT_EQ(OK, rv);
14497 }
14498
14499 const HttpResponseInfo* response = trans->GetResponseInfo();
14500 ASSERT_TRUE(response);
14501 ASSERT_TRUE(response->headers.get());
14502 EXPECT_EQ(407, response->headers->response_code());
14503
14504 {
14505 TestCompletionCallback callback;
14506
14507 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
14508 callback.callback());
14509 EXPECT_EQ(ERR_IO_PENDING, rv);
14510
14511 rv = callback.WaitForResult();
14512 EXPECT_EQ(OK, rv);
14513 }
14514
14515 response = trans->GetResponseInfo();
14516 ASSERT_TRUE(response);
14517 ASSERT_TRUE(response->headers.get());
14518
14519 EXPECT_EQ(101, response->headers->response_code());
14520
14521 trans.reset();
14522 session->CloseAllConnections();
14523}
14524
14525// Verify that proxy headers are not sent to the destination server when
14526// establishing a tunnel for an insecure WebSocket connection.
14527// This requires the authentication info to be injected into the auth cache
14528// due to crbug.com/395064
14529// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
14530TEST_P(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
14531 HttpRequestInfo request;
14532 request.method = "GET";
bncce36dca22015-04-21 22:11:2314533 request.url = GURL("ws://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2414534 AddWebSocketHeaders(&request.extra_headers);
14535
14536 // Configure against proxy server "myproxy:70".
14537 session_deps_.proxy_service.reset(
14538 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
14539
mmenke6b3af6e2015-09-12 02:06:0614540 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2414541
14542 MockWrite data_writes[] = {
14543 // Try to establish a tunnel for the WebSocket connection, with
14544 // credentials. Because WebSockets have a separate set of socket pools,
14545 // they cannot and will not use the same TCP/IP connection as the
14546 // preflight HTTP request.
14547 MockWrite(
bncce36dca22015-04-21 22:11:2314548 "CONNECT www.example.org:80 HTTP/1.1\r\n"
14549 "Host: www.example.org:80\r\n"
Adam Rice425cf122015-01-19 06:18:2414550 "Proxy-Connection: keep-alive\r\n"
14551 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
14552
14553 MockWrite(
14554 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2314555 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414556 "Connection: Upgrade\r\n"
14557 "Upgrade: websocket\r\n"
bncce36dca22015-04-21 22:11:2314558 "Origin: http://www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414559 "Sec-WebSocket-Version: 13\r\n"
14560 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
14561 };
14562
14563 MockRead data_reads[] = {
14564 // HTTP CONNECT with credentials.
14565 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
14566
14567 // WebSocket connection established inside tunnel.
14568 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
14569 MockRead("Upgrade: websocket\r\n"),
14570 MockRead("Connection: Upgrade\r\n"),
14571 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
14572 };
14573
14574 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14575 arraysize(data_writes));
14576 session_deps_.socket_factory->AddSocketDataProvider(&data);
14577
14578 session->http_auth_cache()->Add(
14579 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
14580 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
14581
14582 scoped_ptr<HttpTransaction> trans(
14583 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
14584 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
14585 trans->SetWebSocketHandshakeStreamCreateHelper(
14586 &websocket_stream_create_helper);
14587
14588 TestCompletionCallback callback;
14589
14590 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14591 EXPECT_EQ(ERR_IO_PENDING, rv);
14592
14593 rv = callback.WaitForResult();
14594 EXPECT_EQ(OK, rv);
14595
14596 const HttpResponseInfo* response = trans->GetResponseInfo();
14597 ASSERT_TRUE(response);
14598 ASSERT_TRUE(response->headers.get());
14599
14600 EXPECT_EQ(101, response->headers->response_code());
14601
14602 trans.reset();
14603 session->CloseAllConnections();
14604}
14605
sclittlefb249892015-09-10 21:33:2214606TEST_P(HttpNetworkTransactionTest, TotalNetworkBytesPost) {
14607 ScopedVector<UploadElementReader> element_readers;
14608 element_readers.push_back(new UploadBytesElementReader("foo", 3));
14609 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
14610
14611 HttpRequestInfo request;
14612 request.method = "POST";
14613 request.url = GURL("http://www.foo.com/");
14614 request.upload_data_stream = &upload_data_stream;
14615
mmenke6b3af6e2015-09-12 02:06:0614616 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
sclittlefb249892015-09-10 21:33:2214617 scoped_ptr<HttpTransaction> trans(
14618 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
14619 MockWrite data_writes[] = {
14620 MockWrite("POST / HTTP/1.1\r\n"
14621 "Host: www.foo.com\r\n"
14622 "Connection: keep-alive\r\n"
14623 "Content-Length: 3\r\n\r\n"),
14624 MockWrite("foo"),
14625 };
14626
14627 MockRead data_reads[] = {
14628 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
14629 MockRead(SYNCHRONOUS, OK),
14630 };
14631 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14632 arraysize(data_writes));
14633 session_deps_.socket_factory->AddSocketDataProvider(&data);
14634
14635 TestCompletionCallback callback;
14636
14637 EXPECT_EQ(ERR_IO_PENDING,
14638 trans->Start(&request, callback.callback(), BoundNetLog()));
14639 EXPECT_EQ(OK, callback.WaitForResult());
14640
14641 std::string response_data;
14642 EXPECT_EQ(OK, ReadTransaction(trans.get(), &response_data));
14643
14644 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
14645 trans->GetTotalSentBytes());
14646 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
14647 trans->GetTotalReceivedBytes());
14648}
14649
14650TEST_P(HttpNetworkTransactionTest, TotalNetworkBytesPost100Continue) {
14651 ScopedVector<UploadElementReader> element_readers;
14652 element_readers.push_back(new UploadBytesElementReader("foo", 3));
14653 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
14654
14655 HttpRequestInfo request;
14656 request.method = "POST";
14657 request.url = GURL("http://www.foo.com/");
14658 request.upload_data_stream = &upload_data_stream;
14659
mmenke6b3af6e2015-09-12 02:06:0614660 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
sclittlefb249892015-09-10 21:33:2214661 scoped_ptr<HttpTransaction> trans(
14662 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
14663 MockWrite data_writes[] = {
14664 MockWrite("POST / HTTP/1.1\r\n"
14665 "Host: www.foo.com\r\n"
14666 "Connection: keep-alive\r\n"
14667 "Content-Length: 3\r\n\r\n"),
14668 MockWrite("foo"),
14669 };
14670
14671 MockRead data_reads[] = {
14672 MockRead("HTTP/1.1 100 Continue\r\n\r\n"),
14673 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
14674 MockRead(SYNCHRONOUS, OK),
14675 };
14676 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14677 arraysize(data_writes));
14678 session_deps_.socket_factory->AddSocketDataProvider(&data);
14679
14680 TestCompletionCallback callback;
14681
14682 EXPECT_EQ(ERR_IO_PENDING,
14683 trans->Start(&request, callback.callback(), BoundNetLog()));
14684 EXPECT_EQ(OK, callback.WaitForResult());
14685
14686 std::string response_data;
14687 EXPECT_EQ(OK, ReadTransaction(trans.get(), &response_data));
14688
14689 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
14690 trans->GetTotalSentBytes());
14691 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
14692 trans->GetTotalReceivedBytes());
14693}
14694
14695TEST_P(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) {
14696 ScopedVector<UploadElementReader> element_readers;
14697 element_readers.push_back(new UploadBytesElementReader("foo", 3));
14698 ChunkedUploadDataStream upload_data_stream(0);
14699
14700 HttpRequestInfo request;
14701 request.method = "POST";
14702 request.url = GURL("http://www.foo.com/");
14703 request.upload_data_stream = &upload_data_stream;
14704
mmenke6b3af6e2015-09-12 02:06:0614705 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
sclittlefb249892015-09-10 21:33:2214706 scoped_ptr<HttpTransaction> trans(
14707 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
14708 // Send headers successfully, but get an error while sending the body.
14709 MockWrite data_writes[] = {
14710 MockWrite("POST / HTTP/1.1\r\n"
14711 "Host: www.foo.com\r\n"
14712 "Connection: keep-alive\r\n"
14713 "Transfer-Encoding: chunked\r\n\r\n"),
14714 MockWrite("1\r\nf\r\n"), MockWrite("2\r\noo\r\n"), MockWrite("0\r\n\r\n"),
14715 };
14716
14717 MockRead data_reads[] = {
14718 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
14719 MockRead(SYNCHRONOUS, OK),
14720 };
14721 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14722 arraysize(data_writes));
14723 session_deps_.socket_factory->AddSocketDataProvider(&data);
14724
14725 TestCompletionCallback callback;
14726
14727 EXPECT_EQ(ERR_IO_PENDING,
14728 trans->Start(&request, callback.callback(), BoundNetLog()));
14729
14730 base::RunLoop().RunUntilIdle();
14731 upload_data_stream.AppendData("f", 1, false);
14732
14733 base::RunLoop().RunUntilIdle();
14734 upload_data_stream.AppendData("oo", 2, true);
14735
14736 EXPECT_EQ(OK, callback.WaitForResult());
14737
14738 std::string response_data;
14739 EXPECT_EQ(OK, ReadTransaction(trans.get(), &response_data));
14740
14741 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
14742 trans->GetTotalSentBytes());
14743 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
14744 trans->GetTotalReceivedBytes());
14745}
14746
[email protected]89ceba9a2009-03-21 03:46:0614747} // namespace net