blob: 37efedc01a234044d0dd6160214850560f6ac287 [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;
ttuttled9dbc652015-09-29 20:00:59272 IPEndPoint remote_endpoint_after_start;
[email protected]e3ceb682011-06-28 23:55:46273 };
274
dcheng67be2b1f2014-10-27 21:47:29275 void SetUp() override {
[email protected]0b0bf032010-09-21 18:08:50276 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:34277 base::MessageLoop::current()->RunUntilIdle();
[email protected]2ff8b312010-04-26 22:20:54278 }
279
dcheng67be2b1f2014-10-27 21:47:29280 void TearDown() override {
[email protected]0b0bf032010-09-21 18:08:50281 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:34282 base::MessageLoop::current()->RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09283 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:34284 base::MessageLoop::current()->RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09285 PlatformTest::TearDown();
[email protected]0b0bf032010-09-21 18:08:50286 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:34287 base::MessageLoop::current()->RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09288 }
289
bnc33b8cef42014-11-19 17:30:38290 const char* GetAlternateProtocolFromParam() {
291 return
292 AlternateProtocolToString(AlternateProtocolFromNextProto(GetParam()));
293 }
294
bncc958faa2015-07-31 18:14:52295 std::string GetAlternativeServiceHttpHeader() {
296 return std::string("Alt-Svc: ") + GetAlternateProtocolFromParam() +
297 "=\"www.example.com:443\"\r\n";
298 }
299
[email protected]8a0fc822013-06-27 20:52:43300 std::string GetAlternateProtocolHttpHeader() {
bnc33b8cef42014-11-19 17:30:38301 return std::string("Alternate-Protocol: 443:") +
bncc958faa2015-07-31 18:14:52302 GetAlternateProtocolFromParam() + "\r\n";
[email protected]8a0fc822013-06-27 20:52:43303 }
304
[email protected]202965992011-12-07 23:04:51305 // Either |write_failure| specifies a write failure or |read_failure|
306 // specifies a read failure when using a reused socket. In either case, the
307 // failure should cause the network transaction to resend the request, and the
308 // other argument should be NULL.
309 void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
310 const MockRead* read_failure);
initial.commit586acc5fe2008-07-26 22:42:52311
[email protected]a34f61ee2014-03-18 20:59:49312 // Either |write_failure| specifies a write failure or |read_failure|
313 // specifies a read failure when using a reused socket. In either case, the
314 // failure should cause the network transaction to resend the request, and the
315 // other argument should be NULL.
316 void PreconnectErrorResendRequestTest(const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:10317 const MockRead* read_failure,
318 bool use_spdy);
[email protected]a34f61ee2014-03-18 20:59:49319
[email protected]5a60c8b2011-10-19 20:14:29320 SimpleGetHelperResult SimpleGetHelperForData(StaticSocketDataProvider* data[],
321 size_t data_count) {
[email protected]ff007e162009-05-23 09:13:15322 SimpleGetHelperResult out;
initial.commit586acc5fe2008-07-26 22:42:52323
[email protected]ff007e162009-05-23 09:13:15324 HttpRequestInfo request;
325 request.method = "GET";
bncce36dca22015-04-21 22:11:23326 request.url = GURL("http://www.example.org/");
[email protected]ff007e162009-05-23 09:13:15327 request.load_flags = 0;
initial.commit586acc5fe2008-07-26 22:42:52328
vishal.b62985ca92015-04-17 08:45:51329 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:07330 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:06331 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:27332 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:41333 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:27334
[email protected]5a60c8b2011-10-19 20:14:29335 for (size_t i = 0; i < data_count; ++i) {
[email protected]bb88e1d32013-05-03 23:11:07336 session_deps_.socket_factory->AddSocketDataProvider(data[i]);
[email protected]5a60c8b2011-10-19 20:14:29337 }
initial.commit586acc5fe2008-07-26 22:42:52338
[email protected]49639fa2011-12-20 23:22:41339 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52340
eroman24bc6a12015-05-06 19:55:48341 EXPECT_TRUE(log.bound().IsCapturing());
[email protected]49639fa2011-12-20 23:22:41342 int rv = trans->Start(&request, callback.callback(), log.bound());
[email protected]ff007e162009-05-23 09:13:15343 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:52344
[email protected]ff007e162009-05-23 09:13:15345 out.rv = callback.WaitForResult();
sclittlefb249892015-09-10 21:33:22346 out.total_received_bytes = trans->GetTotalReceivedBytes();
347 out.total_sent_bytes = trans->GetTotalSentBytes();
[email protected]58e32bb2013-01-21 18:23:25348
349 // Even in the failure cases that use this function, connections are always
350 // successfully established before the error.
351 EXPECT_TRUE(trans->GetLoadTimingInfo(&out.load_timing_info));
352 TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
353
[email protected]ff007e162009-05-23 09:13:15354 if (out.rv != OK)
355 return out;
356
357 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50358 // Can't use ASSERT_* inside helper functions like this, so
359 // return an error.
[email protected]90499482013-06-01 00:39:50360 if (response == NULL || response->headers.get() == NULL) {
[email protected]fe2255a2011-09-20 19:37:50361 out.rv = ERR_UNEXPECTED;
362 return out;
363 }
[email protected]ff007e162009-05-23 09:13:15364 out.status_line = response->headers->GetStatusLine();
365
[email protected]80a09a82012-11-16 17:40:06366 EXPECT_EQ("127.0.0.1", response->socket_address.host());
367 EXPECT_EQ(80, response->socket_address.port());
[email protected]6d81b482011-02-22 19:47:19368
ttuttled9dbc652015-09-29 20:00:59369 bool got_endpoint =
370 trans->GetRemoteEndpoint(&out.remote_endpoint_after_start);
371 EXPECT_EQ(got_endpoint,
372 out.remote_endpoint_after_start.address().size() > 0);
373
[email protected]ff007e162009-05-23 09:13:15374 rv = ReadTransaction(trans.get(), &out.response_data);
375 EXPECT_EQ(OK, rv);
[email protected]b2fcd0e2010-12-01 15:19:40376
mmenke43758e62015-05-04 21:09:46377 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40378 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:39379 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:40380 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
[email protected]169d0012010-05-10 23:20:12381 NetLog::PHASE_NONE);
[email protected]dbb83db2010-05-11 18:13:39382 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:40383 entries, pos,
[email protected]dbb83db2010-05-11 18:13:39384 NetLog::TYPE_HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
385 NetLog::PHASE_NONE);
[email protected]ff007e162009-05-23 09:13:15386
[email protected]f3da152d2012-06-02 01:00:57387 std::string line;
388 EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
389 EXPECT_EQ("GET / HTTP/1.1\r\n", line);
390
[email protected]79e1fd62013-06-20 06:50:04391 HttpRequestHeaders request_headers;
392 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
393 std::string value;
394 EXPECT_TRUE(request_headers.GetHeader("Host", &value));
bncce36dca22015-04-21 22:11:23395 EXPECT_EQ("www.example.org", value);
[email protected]79e1fd62013-06-20 06:50:04396 EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
397 EXPECT_EQ("keep-alive", value);
398
399 std::string response_headers;
400 EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
bncce36dca22015-04-21 22:11:23401 EXPECT_EQ("['Host: www.example.org','Connection: keep-alive']",
[email protected]79e1fd62013-06-20 06:50:04402 response_headers);
[email protected]3deb9a52010-11-11 00:24:40403
sclittlefb249892015-09-10 21:33:22404 out.total_received_bytes = trans->GetTotalReceivedBytes();
405 // The total number of sent bytes should not have changed.
406 EXPECT_EQ(out.total_sent_bytes, trans->GetTotalSentBytes());
407
ttuttle1f2d7e92015-04-28 16:17:47408 trans->GetConnectionAttempts(&out.connection_attempts);
[email protected]aecfbf22008-10-16 02:02:47409 return out;
[email protected]ff007e162009-05-23 09:13:15410 }
initial.commit586acc5fe2008-07-26 22:42:52411
[email protected]5a60c8b2011-10-19 20:14:29412 SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[],
413 size_t reads_count) {
sclittlefb249892015-09-10 21:33:22414 MockWrite data_writes[] = {
415 MockWrite("GET / HTTP/1.1\r\n"
416 "Host: www.example.org\r\n"
417 "Connection: keep-alive\r\n\r\n"),
418 };
[email protected]5a60c8b2011-10-19 20:14:29419
sclittlefb249892015-09-10 21:33:22420 StaticSocketDataProvider reads(data_reads, reads_count, data_writes,
421 arraysize(data_writes));
422 StaticSocketDataProvider* data[] = {&reads};
423 SimpleGetHelperResult out = SimpleGetHelperForData(data, 1);
424
425 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
426 out.total_sent_bytes);
427 return out;
[email protected]b8015c42013-12-24 15:18:19428 }
429
[email protected]ff007e162009-05-23 09:13:15430 void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
431 int expected_status);
initial.commit586acc5fe2008-07-26 22:42:52432
[email protected]ff007e162009-05-23 09:13:15433 void ConnectStatusHelper(const MockRead& status);
[email protected]bb88e1d32013-05-03 23:11:07434
435 void BypassHostCacheOnRefreshHelper(int load_flags);
436
437 void CheckErrorIsPassedBack(int error, IoMode mode);
438
[email protected]4bd46222013-05-14 19:32:23439 SpdyTestUtil spdy_util_;
[email protected]bb88e1d32013-05-03 23:11:07440 SpdySessionDependencies session_deps_;
[email protected]483fa202013-05-14 01:07:03441
442 // Original socket limits. Some tests set these. Safest to always restore
443 // them once each test has been run.
444 int old_max_group_sockets_;
445 int old_max_pool_sockets_;
[email protected]ff007e162009-05-23 09:13:15446};
[email protected]231d5a32008-09-13 00:45:27447
bnc57685ae62015-03-10 21:27:20448INSTANTIATE_TEST_CASE_P(NextProto,
449 HttpNetworkTransactionTest,
450 testing::Values(kProtoSPDY31,
bnc06d22432015-06-29 12:39:43451 kProtoHTTP2));
[email protected]23e482282013-06-14 16:08:02452
[email protected]448d4ca52012-03-04 04:12:23453namespace {
454
[email protected]1826a402014-01-08 15:40:48455class BeforeNetworkStartHandler {
456 public:
457 explicit BeforeNetworkStartHandler(bool defer)
458 : defer_on_before_network_start_(defer),
459 observed_before_network_start_(false) {}
460
461 void OnBeforeNetworkStart(bool* defer) {
462 *defer = defer_on_before_network_start_;
463 observed_before_network_start_ = true;
464 }
465
466 bool observed_before_network_start() const {
467 return observed_before_network_start_;
468 }
469
470 private:
471 const bool defer_on_before_network_start_;
472 bool observed_before_network_start_;
473
474 DISALLOW_COPY_AND_ASSIGN(BeforeNetworkStartHandler);
475};
476
[email protected]597a1ab2014-06-26 08:12:27477class BeforeProxyHeadersSentHandler {
478 public:
479 BeforeProxyHeadersSentHandler()
480 : observed_before_proxy_headers_sent_(false) {}
481
[email protected]1252d42f2014-07-01 21:20:20482 void OnBeforeProxyHeadersSent(const ProxyInfo& proxy_info,
483 HttpRequestHeaders* request_headers) {
[email protected]597a1ab2014-06-26 08:12:27484 observed_before_proxy_headers_sent_ = true;
485 observed_proxy_server_uri_ = proxy_info.proxy_server().ToURI();
486 }
487
488 bool observed_before_proxy_headers_sent() const {
489 return observed_before_proxy_headers_sent_;
490 }
491
492 std::string observed_proxy_server_uri() const {
493 return observed_proxy_server_uri_;
494 }
495
496 private:
497 bool observed_before_proxy_headers_sent_;
498 std::string observed_proxy_server_uri_;
499
500 DISALLOW_COPY_AND_ASSIGN(BeforeProxyHeadersSentHandler);
501};
502
[email protected]15a5ccf82008-10-23 19:57:43503// Fill |str| with a long header list that consumes >= |size| bytes.
504void FillLargeHeadersString(std::string* str, int size) {
thestig9d3bb0c2015-01-24 00:49:51505 const char row[] =
[email protected]4ddaf2502008-10-23 18:26:19506 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
507 const int sizeof_row = strlen(row);
508 const int num_rows = static_cast<int>(
509 ceil(static_cast<float>(size) / sizeof_row));
510 const int sizeof_data = num_rows * sizeof_row;
511 DCHECK(sizeof_data >= size);
[email protected]15a5ccf82008-10-23 19:57:43512 str->reserve(sizeof_data);
[email protected]372d34a2008-11-05 21:30:51513
[email protected]4ddaf2502008-10-23 18:26:19514 for (int i = 0; i < num_rows; ++i)
[email protected]15a5ccf82008-10-23 19:57:43515 str->append(row, sizeof_row);
[email protected]4ddaf2502008-10-23 18:26:19516}
517
thakis84dff942015-07-28 20:47:38518#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29519// Alternative functions that eliminate randomness and dependency on the local
520// host name so that the generated NTLM messages are reproducible.
[email protected]fe2bc6a2009-03-23 16:52:20521void MockGenerateRandom1(uint8* output, size_t n) {
[email protected]385a4672009-03-11 22:21:29522 static const uint8 bytes[] = {
523 0x55, 0x29, 0x66, 0x26, 0x6b, 0x9c, 0x73, 0x54
524 };
525 static size_t current_byte = 0;
526 for (size_t i = 0; i < n; ++i) {
527 output[i] = bytes[current_byte++];
528 current_byte %= arraysize(bytes);
529 }
530}
531
[email protected]fe2bc6a2009-03-23 16:52:20532void MockGenerateRandom2(uint8* output, size_t n) {
[email protected]385a4672009-03-11 22:21:29533 static const uint8 bytes[] = {
534 0x96, 0x79, 0x85, 0xe7, 0x49, 0x93, 0x70, 0xa1,
535 0x4e, 0xe7, 0x87, 0x45, 0x31, 0x5b, 0xd3, 0x1f
536 };
537 static size_t current_byte = 0;
538 for (size_t i = 0; i < n; ++i) {
539 output[i] = bytes[current_byte++];
540 current_byte %= arraysize(bytes);
541 }
542}
543
[email protected]fe2bc6a2009-03-23 16:52:20544std::string MockGetHostName() {
545 return "WTC-WIN7";
[email protected]385a4672009-03-11 22:21:29546}
thakis84dff942015-07-28 20:47:38547#endif // defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29548
[email protected]e60e47a2010-07-14 03:37:18549template<typename ParentPool>
550class CaptureGroupNameSocketPool : public ParentPool {
[email protected]04e5be32009-06-26 20:00:31551 public:
[email protected]9e1bdd32011-02-03 21:48:34552 CaptureGroupNameSocketPool(HostResolver* host_resolver,
553 CertVerifier* cert_verifier);
[email protected]e60e47a2010-07-14 03:37:18554
[email protected]d80a4322009-08-14 07:07:49555 const std::string last_group_name_received() const {
556 return last_group_name_;
557 }
558
dmichaeld6e570d2014-12-18 22:30:57559 int RequestSocket(const std::string& group_name,
560 const void* socket_params,
561 RequestPriority priority,
562 ClientSocketHandle* handle,
563 const CompletionCallback& callback,
564 const BoundNetLog& net_log) override {
[email protected]04e5be32009-06-26 20:00:31565 last_group_name_ = group_name;
566 return ERR_IO_PENDING;
567 }
dmichaeld6e570d2014-12-18 22:30:57568 void CancelRequest(const std::string& group_name,
569 ClientSocketHandle* handle) override {}
570 void ReleaseSocket(const std::string& group_name,
571 scoped_ptr<StreamSocket> socket,
572 int id) override {}
573 void CloseIdleSockets() override {}
574 int IdleSocketCount() const override { return 0; }
575 int IdleSocketCountInGroup(const std::string& group_name) const override {
[email protected]04e5be32009-06-26 20:00:31576 return 0;
577 }
dmichaeld6e570d2014-12-18 22:30:57578 LoadState GetLoadState(const std::string& group_name,
579 const ClientSocketHandle* handle) const override {
[email protected]04e5be32009-06-26 20:00:31580 return LOAD_STATE_IDLE;
581 }
dmichaeld6e570d2014-12-18 22:30:57582 base::TimeDelta ConnectionTimeout() const override {
[email protected]a796bcec2010-03-22 17:17:26583 return base::TimeDelta();
584 }
[email protected]d80a4322009-08-14 07:07:49585
586 private:
[email protected]04e5be32009-06-26 20:00:31587 std::string last_group_name_;
588};
589
[email protected]ab739042011-04-07 15:22:28590typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
591CaptureGroupNameTransportSocketPool;
[email protected]e772db3f2010-07-12 18:11:13592typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
593CaptureGroupNameHttpProxySocketPool;
[email protected]2d731a32010-04-29 01:04:06594typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
[email protected]2227c692010-05-04 15:36:11595CaptureGroupNameSOCKSSocketPool;
[email protected]e60e47a2010-07-14 03:37:18596typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
597CaptureGroupNameSSLSocketPool;
598
rkaplowd90695c2015-03-25 22:12:41599template <typename ParentPool>
[email protected]e60e47a2010-07-14 03:37:18600CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34601 HostResolver* host_resolver,
602 CertVerifier* /* cert_verifier */)
rkaplowd90695c2015-03-25 22:12:41603 : ParentPool(0, 0, host_resolver, NULL, NULL) {
604}
[email protected]e60e47a2010-07-14 03:37:18605
hashimoto0d3e4fb2015-01-09 05:02:50606template <>
[email protected]2df19bb2010-08-25 20:13:46607CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21608 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34609 CertVerifier* /* cert_verifier */)
rkaplowd90695c2015-03-25 22:12:41610 : HttpProxyClientSocketPool(0, 0, NULL, NULL, NULL) {
hashimoto0d3e4fb2015-01-09 05:02:50611}
[email protected]2df19bb2010-08-25 20:13:46612
[email protected]007b3f82013-04-09 08:46:45613template <>
[email protected]e60e47a2010-07-14 03:37:18614CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21615 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34616 CertVerifier* cert_verifier)
[email protected]007b3f82013-04-09 08:46:45617 : SSLClientSocketPool(0,
618 0,
[email protected]007b3f82013-04-09 08:46:45619 cert_verifier,
620 NULL,
621 NULL,
[email protected]284303b62013-11-28 15:11:54622 NULL,
eranm6571b2b2014-12-03 15:53:23623 NULL,
[email protected]007b3f82013-04-09 08:46:45624 std::string(),
625 NULL,
626 NULL,
627 NULL,
628 NULL,
629 NULL,
[email protected]8e458552014-08-05 00:02:15630 NULL) {
631}
[email protected]2227c692010-05-04 15:36:11632
[email protected]231d5a32008-09-13 00:45:27633//-----------------------------------------------------------------------------
634
[email protected]79cb5c12011-09-12 13:12:04635// Helper functions for validating that AuthChallengeInfo's are correctly
636// configured for common cases.
637bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
638 if (!auth_challenge)
639 return false;
640 EXPECT_FALSE(auth_challenge->is_proxy);
bncce36dca22015-04-21 22:11:23641 EXPECT_EQ("www.example.org:80", auth_challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:04642 EXPECT_EQ("MyRealm1", auth_challenge->realm);
643 EXPECT_EQ("basic", auth_challenge->scheme);
644 return true;
645}
646
647bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
648 if (!auth_challenge)
649 return false;
650 EXPECT_TRUE(auth_challenge->is_proxy);
651 EXPECT_EQ("myproxy:70", auth_challenge->challenger.ToString());
652 EXPECT_EQ("MyRealm1", auth_challenge->realm);
653 EXPECT_EQ("basic", auth_challenge->scheme);
654 return true;
655}
656
657bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
658 if (!auth_challenge)
659 return false;
660 EXPECT_FALSE(auth_challenge->is_proxy);
bncce36dca22015-04-21 22:11:23661 EXPECT_EQ("www.example.org:80", auth_challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:04662 EXPECT_EQ("digestive", auth_challenge->realm);
663 EXPECT_EQ("digest", auth_challenge->scheme);
664 return true;
665}
666
thakis84dff942015-07-28 20:47:38667#if defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04668bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
669 if (!auth_challenge)
670 return false;
671 EXPECT_FALSE(auth_challenge->is_proxy);
672 EXPECT_EQ("172.22.68.17:80", auth_challenge->challenger.ToString());
673 EXPECT_EQ(std::string(), auth_challenge->realm);
674 EXPECT_EQ("ntlm", auth_challenge->scheme);
675 return true;
676}
thakis84dff942015-07-28 20:47:38677#endif // defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04678
[email protected]448d4ca52012-03-04 04:12:23679} // namespace
680
[email protected]23e482282013-06-14 16:08:02681TEST_P(HttpNetworkTransactionTest, Basic) {
mmenke6b3af6e2015-09-12 02:06:06682 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:40683 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:41684 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]231d5a32008-09-13 00:45:27685}
686
[email protected]23e482282013-06-14 16:08:02687TEST_P(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27688 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35689 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
690 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06691 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27692 };
[email protected]31a2bfe2010-02-09 08:03:39693 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
694 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42695 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27696 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
697 EXPECT_EQ("hello world", out.response_data);
sclittlefb249892015-09-10 21:33:22698 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
699 EXPECT_EQ(reads_size, out.total_received_bytes);
ttuttle1f2d7e92015-04-28 16:17:47700 EXPECT_EQ(0u, out.connection_attempts.size());
ttuttled9dbc652015-09-29 20:00:59701
702 EXPECT_FALSE(out.remote_endpoint_after_start.address().empty());
[email protected]231d5a32008-09-13 00:45:27703}
704
705// Response with no status line.
[email protected]23e482282013-06-14 16:08:02706TEST_P(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27707 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35708 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06709 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27710 };
[email protected]31a2bfe2010-02-09 08:03:39711 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
712 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42713 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27714 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
715 EXPECT_EQ("hello world", out.response_data);
sclittlefb249892015-09-10 21:33:22716 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
717 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27718}
719
720// Allow up to 4 bytes of junk to precede status line.
[email protected]23e482282013-06-14 16:08:02721TEST_P(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27722 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35723 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06724 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27725 };
[email protected]31a2bfe2010-02-09 08:03:39726 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
727 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42728 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27729 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
730 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22731 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
732 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27733}
734
735// Allow up to 4 bytes of junk to precede status line.
[email protected]23e482282013-06-14 16:08:02736TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27737 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35738 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06739 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27740 };
[email protected]31a2bfe2010-02-09 08:03:39741 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
742 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42743 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27744 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
745 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22746 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
747 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27748}
749
750// Beyond 4 bytes of slop and it should fail to find a status line.
[email protected]23e482282013-06-14 16:08:02751TEST_P(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27752 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35753 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06754 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27755 };
[email protected]31a2bfe2010-02-09 08:03:39756 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
757 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42758 EXPECT_EQ(OK, out.rv);
[email protected]3d2a59b2008-09-26 19:44:25759 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
760 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
sclittlefb249892015-09-10 21:33:22761 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
762 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27763}
764
765// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
[email protected]23e482282013-06-14 16:08:02766TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27767 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35768 MockRead("\n"),
769 MockRead("\n"),
770 MockRead("Q"),
771 MockRead("J"),
772 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06773 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27774 };
[email protected]31a2bfe2010-02-09 08:03:39775 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
776 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42777 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27778 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
779 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22780 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
781 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27782}
783
784// Close the connection before enough bytes to have a status line.
[email protected]23e482282013-06-14 16:08:02785TEST_P(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:27786 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35787 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:06788 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27789 };
[email protected]31a2bfe2010-02-09 08:03:39790 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
791 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42792 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27793 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
794 EXPECT_EQ("HTT", out.response_data);
sclittlefb249892015-09-10 21:33:22795 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
796 EXPECT_EQ(reads_size, out.total_received_bytes);
initial.commit586acc5fe2008-07-26 22:42:52797}
798
[email protected]f9d44aa2008-09-23 23:57:17799// Simulate a 204 response, lacking a Content-Length header, sent over a
800// persistent connection. The response should still terminate since a 204
801// cannot have a response body.
[email protected]23e482282013-06-14 16:08:02802TEST_P(HttpNetworkTransactionTest, StopsReading204) {
[email protected]b8015c42013-12-24 15:18:19803 char junk[] = "junk";
[email protected]f9d44aa2008-09-23 23:57:17804 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35805 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
[email protected]b8015c42013-12-24 15:18:19806 MockRead(junk), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:06807 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:17808 };
[email protected]31a2bfe2010-02-09 08:03:39809 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
810 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42811 EXPECT_EQ(OK, out.rv);
[email protected]f9d44aa2008-09-23 23:57:17812 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
813 EXPECT_EQ("", out.response_data);
sclittlefb249892015-09-10 21:33:22814 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
815 int64_t response_size = reads_size - strlen(junk);
816 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]f9d44aa2008-09-23 23:57:17817}
818
[email protected]0877e3d2009-10-17 22:29:57819// A simple request using chunked encoding with some extra data after.
[email protected]23e482282013-06-14 16:08:02820TEST_P(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]b8015c42013-12-24 15:18:19821 std::string final_chunk = "0\r\n\r\n";
822 std::string extra_data = "HTTP/1.1 200 OK\r\n";
823 std::string last_read = final_chunk + extra_data;
[email protected]0877e3d2009-10-17 22:29:57824 MockRead data_reads[] = {
825 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
826 MockRead("5\r\nHello\r\n"),
827 MockRead("1\r\n"),
828 MockRead(" \r\n"),
829 MockRead("5\r\nworld\r\n"),
[email protected]b8015c42013-12-24 15:18:19830 MockRead(last_read.data()),
[email protected]8ddf8322012-02-23 18:08:06831 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:57832 };
[email protected]31a2bfe2010-02-09 08:03:39833 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
834 arraysize(data_reads));
[email protected]0877e3d2009-10-17 22:29:57835 EXPECT_EQ(OK, out.rv);
836 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
837 EXPECT_EQ("Hello world", out.response_data);
sclittlefb249892015-09-10 21:33:22838 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
839 int64_t response_size = reads_size - extra_data.size();
840 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]0877e3d2009-10-17 22:29:57841}
842
[email protected]9fe44f52010-09-23 18:36:00843// Next tests deal with http://crbug.com/56344.
844
[email protected]23e482282013-06-14 16:08:02845TEST_P(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00846 MultipleContentLengthHeadersNoTransferEncoding) {
847 MockRead data_reads[] = {
848 MockRead("HTTP/1.1 200 OK\r\n"),
849 MockRead("Content-Length: 10\r\n"),
850 MockRead("Content-Length: 5\r\n\r\n"),
851 };
852 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
853 arraysize(data_reads));
854 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
855}
856
[email protected]23e482282013-06-14 16:08:02857TEST_P(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04858 DuplicateContentLengthHeadersNoTransferEncoding) {
859 MockRead data_reads[] = {
860 MockRead("HTTP/1.1 200 OK\r\n"),
861 MockRead("Content-Length: 5\r\n"),
862 MockRead("Content-Length: 5\r\n\r\n"),
863 MockRead("Hello"),
864 };
865 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
866 arraysize(data_reads));
867 EXPECT_EQ(OK, out.rv);
868 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
869 EXPECT_EQ("Hello", out.response_data);
870}
871
[email protected]23e482282013-06-14 16:08:02872TEST_P(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04873 ComplexContentLengthHeadersNoTransferEncoding) {
874 // More than 2 dupes.
875 {
876 MockRead data_reads[] = {
877 MockRead("HTTP/1.1 200 OK\r\n"),
878 MockRead("Content-Length: 5\r\n"),
879 MockRead("Content-Length: 5\r\n"),
880 MockRead("Content-Length: 5\r\n\r\n"),
881 MockRead("Hello"),
882 };
883 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
884 arraysize(data_reads));
885 EXPECT_EQ(OK, out.rv);
886 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
887 EXPECT_EQ("Hello", out.response_data);
888 }
889 // HTTP/1.0
890 {
891 MockRead data_reads[] = {
892 MockRead("HTTP/1.0 200 OK\r\n"),
893 MockRead("Content-Length: 5\r\n"),
894 MockRead("Content-Length: 5\r\n"),
895 MockRead("Content-Length: 5\r\n\r\n"),
896 MockRead("Hello"),
897 };
898 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
899 arraysize(data_reads));
900 EXPECT_EQ(OK, out.rv);
901 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
902 EXPECT_EQ("Hello", out.response_data);
903 }
904 // 2 dupes and one mismatched.
905 {
906 MockRead data_reads[] = {
907 MockRead("HTTP/1.1 200 OK\r\n"),
908 MockRead("Content-Length: 10\r\n"),
909 MockRead("Content-Length: 10\r\n"),
910 MockRead("Content-Length: 5\r\n\r\n"),
911 };
912 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
913 arraysize(data_reads));
914 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
915 }
916}
917
[email protected]23e482282013-06-14 16:08:02918TEST_P(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00919 MultipleContentLengthHeadersTransferEncoding) {
920 MockRead data_reads[] = {
921 MockRead("HTTP/1.1 200 OK\r\n"),
922 MockRead("Content-Length: 666\r\n"),
923 MockRead("Content-Length: 1337\r\n"),
924 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
925 MockRead("5\r\nHello\r\n"),
926 MockRead("1\r\n"),
927 MockRead(" \r\n"),
928 MockRead("5\r\nworld\r\n"),
929 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:06930 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:00931 };
932 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
933 arraysize(data_reads));
934 EXPECT_EQ(OK, out.rv);
935 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
936 EXPECT_EQ("Hello world", out.response_data);
937}
938
[email protected]1628fe92011-10-04 23:04:55939// Next tests deal with http://crbug.com/98895.
940
941// Checks that a single Content-Disposition header results in no error.
[email protected]23e482282013-06-14 16:08:02942TEST_P(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:55943 MockRead data_reads[] = {
944 MockRead("HTTP/1.1 200 OK\r\n"),
945 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
946 MockRead("Content-Length: 5\r\n\r\n"),
947 MockRead("Hello"),
948 };
949 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
950 arraysize(data_reads));
951 EXPECT_EQ(OK, out.rv);
952 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
953 EXPECT_EQ("Hello", out.response_data);
954}
955
[email protected]54a9c6e52012-03-21 20:10:59956// Checks that two identical Content-Disposition headers result in no error.
[email protected]23e482282013-06-14 16:08:02957TEST_P(HttpNetworkTransactionTest,
[email protected]54a9c6e52012-03-21 20:10:59958 TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:55959 MockRead data_reads[] = {
960 MockRead("HTTP/1.1 200 OK\r\n"),
961 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
962 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
963 MockRead("Content-Length: 5\r\n\r\n"),
964 MockRead("Hello"),
965 };
966 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
967 arraysize(data_reads));
[email protected]54a9c6e52012-03-21 20:10:59968 EXPECT_EQ(OK, out.rv);
969 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
970 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:55971}
972
973// Checks that two distinct Content-Disposition headers result in an error.
[email protected]23e482282013-06-14 16:08:02974TEST_P(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:55975 MockRead data_reads[] = {
976 MockRead("HTTP/1.1 200 OK\r\n"),
977 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
978 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
979 MockRead("Content-Length: 5\r\n\r\n"),
980 MockRead("Hello"),
981 };
982 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
983 arraysize(data_reads));
984 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION, out.rv);
985}
986
[email protected]54a9c6e52012-03-21 20:10:59987// Checks that two identical Location headers result in no error.
988// Also tests Location header behavior.
[email protected]23e482282013-06-14 16:08:02989TEST_P(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:55990 MockRead data_reads[] = {
991 MockRead("HTTP/1.1 302 Redirect\r\n"),
992 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:59993 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:55994 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:06995 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:55996 };
997
998 HttpRequestInfo request;
999 request.method = "GET";
1000 request.url = GURL("http://redirect.com/");
1001 request.load_flags = 0;
1002
mmenke6b3af6e2015-09-12 02:06:061003 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1628fe92011-10-04 23:04:551004 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411005 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]1628fe92011-10-04 23:04:551006
1007 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071008 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:551009
[email protected]49639fa2011-12-20 23:22:411010 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:551011
[email protected]49639fa2011-12-20 23:22:411012 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1628fe92011-10-04 23:04:551013 EXPECT_EQ(ERR_IO_PENDING, rv);
1014
1015 EXPECT_EQ(OK, callback.WaitForResult());
1016
1017 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]90499482013-06-01 00:39:501018 ASSERT_TRUE(response != NULL && response->headers.get() != NULL);
[email protected]1628fe92011-10-04 23:04:551019 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
1020 std::string url;
1021 EXPECT_TRUE(response->headers->IsRedirect(&url));
1022 EXPECT_EQ("http://good.com/", url);
[email protected]d8fc4722014-06-13 13:17:151023 EXPECT_TRUE(response->proxy_server.IsEmpty());
[email protected]1628fe92011-10-04 23:04:551024}
1025
[email protected]1628fe92011-10-04 23:04:551026// Checks that two distinct Location headers result in an error.
[email protected]23e482282013-06-14 16:08:021027TEST_P(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551028 MockRead data_reads[] = {
1029 MockRead("HTTP/1.1 302 Redirect\r\n"),
1030 MockRead("Location: http://good.com/\r\n"),
1031 MockRead("Location: http://evil.com/\r\n"),
1032 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061033 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551034 };
1035 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1036 arraysize(data_reads));
1037 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION, out.rv);
1038}
1039
[email protected]ef0faf2e72009-03-05 23:27:231040// Do a request using the HEAD method. Verify that we don't try to read the
1041// message body (since HEAD has none).
[email protected]23e482282013-06-14 16:08:021042TEST_P(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:421043 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:231044 request.method = "HEAD";
bncce36dca22015-04-21 22:11:231045 request.url = GURL("http://www.example.org/");
[email protected]ef0faf2e72009-03-05 23:27:231046 request.load_flags = 0;
1047
mmenke6b3af6e2015-09-12 02:06:061048 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271049 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411050 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]597a1ab2014-06-26 08:12:271051 BeforeProxyHeadersSentHandler proxy_headers_handler;
1052 trans->SetBeforeProxyHeadersSentCallback(
1053 base::Bind(&BeforeProxyHeadersSentHandler::OnBeforeProxyHeadersSent,
1054 base::Unretained(&proxy_headers_handler)));
[email protected]cb9bf6ca2011-01-28 13:15:271055
[email protected]ef0faf2e72009-03-05 23:27:231056 MockWrite data_writes1[] = {
csharrisonf473dd192015-08-18 13:54:131057 MockWrite("HEAD / HTTP/1.1\r\n"
1058 "Host: www.example.org\r\n"
1059 "Connection: keep-alive\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231060 };
1061 MockRead data_reads1[] = {
1062 MockRead("HTTP/1.1 404 Not Found\r\n"),
1063 MockRead("Server: Blah\r\n"),
1064 MockRead("Content-Length: 1234\r\n\r\n"),
1065
1066 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:061067 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]ef0faf2e72009-03-05 23:27:231068 };
1069
[email protected]31a2bfe2010-02-09 08:03:391070 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1071 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:071072 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:231073
[email protected]49639fa2011-12-20 23:22:411074 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:231075
[email protected]49639fa2011-12-20 23:22:411076 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421077 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]ef0faf2e72009-03-05 23:27:231078
1079 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421080 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:231081
[email protected]1c773ea12009-04-28 19:58:421082 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501083 ASSERT_TRUE(response != NULL);
[email protected]ef0faf2e72009-03-05 23:27:231084
1085 // Check that the headers got parsed.
[email protected]90499482013-06-01 00:39:501086 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]ef0faf2e72009-03-05 23:27:231087 EXPECT_EQ(1234, response->headers->GetContentLength());
1088 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
[email protected]d8fc4722014-06-13 13:17:151089 EXPECT_TRUE(response->proxy_server.IsEmpty());
[email protected]597a1ab2014-06-26 08:12:271090 EXPECT_FALSE(proxy_headers_handler.observed_before_proxy_headers_sent());
[email protected]ef0faf2e72009-03-05 23:27:231091
1092 std::string server_header;
1093 void* iter = NULL;
1094 bool has_server_header = response->headers->EnumerateHeader(
1095 &iter, "Server", &server_header);
1096 EXPECT_TRUE(has_server_header);
1097 EXPECT_EQ("Blah", server_header);
1098
1099 // Reading should give EOF right away, since there is no message body
1100 // (despite non-zero content-length).
1101 std::string response_data;
1102 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421103 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:231104 EXPECT_EQ("", response_data);
1105}
1106
[email protected]23e482282013-06-14 16:08:021107TEST_P(HttpNetworkTransactionTest, ReuseConnection) {
mmenke6b3af6e2015-09-12 02:06:061108 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:521109
1110 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351111 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1112 MockRead("hello"),
1113 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1114 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061115 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521116 };
[email protected]31a2bfe2010-02-09 08:03:391117 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071118 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521119
[email protected]0b0bf032010-09-21 18:08:501120 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521121 "hello", "world"
1122 };
1123
1124 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:421125 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521126 request.method = "GET";
bncce36dca22015-04-21 22:11:231127 request.url = GURL("http://www.example.org/");
initial.commit586acc5fe2008-07-26 22:42:521128 request.load_flags = 0;
1129
[email protected]262eec82013-03-19 21:01:361130 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501131 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271132
[email protected]49639fa2011-12-20 23:22:411133 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521134
[email protected]49639fa2011-12-20 23:22:411135 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421136 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521137
1138 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421139 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521140
[email protected]1c773ea12009-04-28 19:58:421141 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501142 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521143
[email protected]90499482013-06-01 00:39:501144 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251145 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]d8fc4722014-06-13 13:17:151146 EXPECT_TRUE(response->proxy_server.IsEmpty());
initial.commit586acc5fe2008-07-26 22:42:521147
1148 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571149 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421150 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251151 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521152 }
1153}
1154
[email protected]23e482282013-06-14 16:08:021155TEST_P(HttpNetworkTransactionTest, Ignores100) {
[email protected]b2d26cfd2012-12-11 10:36:061156 ScopedVector<UploadElementReader> element_readers;
1157 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:071158 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:271159
[email protected]1c773ea12009-04-28 19:58:421160 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521161 request.method = "POST";
1162 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271163 request.upload_data_stream = &upload_data_stream;
initial.commit586acc5fe2008-07-26 22:42:521164 request.load_flags = 0;
1165
mmenke6b3af6e2015-09-12 02:06:061166 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271167 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411168 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271169
initial.commit586acc5fe2008-07-26 22:42:521170 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351171 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1172 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1173 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061174 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521175 };
[email protected]31a2bfe2010-02-09 08:03:391176 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071177 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521178
[email protected]49639fa2011-12-20 23:22:411179 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521180
[email protected]49639fa2011-12-20 23:22:411181 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421182 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521183
1184 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421185 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521186
[email protected]1c773ea12009-04-28 19:58:421187 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501188 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521189
[email protected]90499482013-06-01 00:39:501190 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251191 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521192
1193 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571194 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421195 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251196 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521197}
1198
[email protected]3a2d3662009-03-27 03:49:141199// This test is almost the same as Ignores100 above, but the response contains
1200// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571201// HTTP/1.1 and the two status headers are read in one read.
[email protected]23e482282013-06-14 16:08:021202TEST_P(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421203 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141204 request.method = "GET";
1205 request.url = GURL("http://www.foo.com/");
1206 request.load_flags = 0;
1207
mmenke6b3af6e2015-09-12 02:06:061208 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271209 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411210 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271211
[email protected]3a2d3662009-03-27 03:49:141212 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571213 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1214 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141215 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061216 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141217 };
[email protected]31a2bfe2010-02-09 08:03:391218 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071219 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141220
[email protected]49639fa2011-12-20 23:22:411221 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141222
[email protected]49639fa2011-12-20 23:22:411223 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421224 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3a2d3662009-03-27 03:49:141225
1226 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421227 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:141228
[email protected]1c773ea12009-04-28 19:58:421229 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501230 ASSERT_TRUE(response != NULL);
[email protected]3a2d3662009-03-27 03:49:141231
[email protected]90499482013-06-01 00:39:501232 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3a2d3662009-03-27 03:49:141233 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1234
1235 std::string response_data;
1236 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421237 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:141238 EXPECT_EQ("hello world", response_data);
1239}
1240
[email protected]23e482282013-06-14 16:08:021241TEST_P(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
zmo9528c9f42015-08-04 22:12:081242 HttpRequestInfo request;
1243 request.method = "POST";
1244 request.url = GURL("http://www.foo.com/");
1245 request.load_flags = 0;
1246
mmenke6b3af6e2015-09-12 02:06:061247 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
zmo9528c9f42015-08-04 22:12:081248 scoped_ptr<HttpTransaction> trans(
1249 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1250
1251 MockRead data_reads[] = {
1252 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1253 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381254 };
zmo9528c9f42015-08-04 22:12:081255 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1256 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381257
zmo9528c9f42015-08-04 22:12:081258 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381259
zmo9528c9f42015-08-04 22:12:081260 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1261 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]ee9410e72010-01-07 01:42:381262
zmo9528c9f42015-08-04 22:12:081263 rv = callback.WaitForResult();
1264 EXPECT_EQ(OK, rv);
[email protected]ee9410e72010-01-07 01:42:381265
zmo9528c9f42015-08-04 22:12:081266 std::string response_data;
1267 rv = ReadTransaction(trans.get(), &response_data);
1268 EXPECT_EQ(OK, rv);
1269 EXPECT_EQ("", response_data);
[email protected]ee9410e72010-01-07 01:42:381270}
1271
[email protected]23e482282013-06-14 16:08:021272TEST_P(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381273 HttpRequestInfo request;
1274 request.method = "POST";
1275 request.url = GURL("http://www.foo.com/");
1276 request.load_flags = 0;
1277
mmenke6b3af6e2015-09-12 02:06:061278 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271279 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411280 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271281
[email protected]ee9410e72010-01-07 01:42:381282 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061283 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381284 };
[email protected]31a2bfe2010-02-09 08:03:391285 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071286 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381287
[email protected]49639fa2011-12-20 23:22:411288 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381289
[email protected]49639fa2011-12-20 23:22:411290 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]ee9410e72010-01-07 01:42:381291 EXPECT_EQ(ERR_IO_PENDING, rv);
1292
1293 rv = callback.WaitForResult();
1294 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
1295}
1296
[email protected]23e482282013-06-14 16:08:021297void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511298 const MockWrite* write_failure,
1299 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421300 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521301 request.method = "GET";
1302 request.url = GURL("http://www.foo.com/");
1303 request.load_flags = 0;
1304
vishal.b62985ca92015-04-17 08:45:511305 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071306 session_deps_.net_log = &net_log;
mmenke6b3af6e2015-09-12 02:06:061307 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271308
[email protected]202965992011-12-07 23:04:511309 // Written data for successfully sending both requests.
1310 MockWrite data1_writes[] = {
1311 MockWrite("GET / HTTP/1.1\r\n"
1312 "Host: www.foo.com\r\n"
1313 "Connection: keep-alive\r\n\r\n"),
1314 MockWrite("GET / HTTP/1.1\r\n"
1315 "Host: www.foo.com\r\n"
1316 "Connection: keep-alive\r\n\r\n")
1317 };
1318
1319 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521320 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351321 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1322 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061323 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521324 };
[email protected]202965992011-12-07 23:04:511325
1326 if (write_failure) {
[email protected]a34f61ee2014-03-18 20:59:491327 ASSERT_FALSE(read_failure);
[email protected]202965992011-12-07 23:04:511328 data1_writes[1] = *write_failure;
1329 } else {
1330 ASSERT_TRUE(read_failure);
1331 data1_reads[2] = *read_failure;
1332 }
1333
1334 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
1335 data1_writes, arraysize(data1_writes));
[email protected]bb88e1d32013-05-03 23:11:071336 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521337
1338 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351339 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1340 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061341 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521342 };
[email protected]31a2bfe2010-02-09 08:03:391343 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071344 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521345
thestig9d3bb0c2015-01-24 00:49:511346 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521347 "hello", "world"
1348 };
1349
[email protected]58e32bb2013-01-21 18:23:251350 uint32 first_socket_log_id = NetLog::Source::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521351 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411352 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521353
[email protected]262eec82013-03-19 21:01:361354 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501355 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
initial.commit586acc5fe2008-07-26 22:42:521356
[email protected]49639fa2011-12-20 23:22:411357 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421358 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521359
1360 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421361 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521362
[email protected]58e32bb2013-01-21 18:23:251363 LoadTimingInfo load_timing_info;
1364 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1365 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1366 if (i == 0) {
1367 first_socket_log_id = load_timing_info.socket_log_id;
1368 } else {
1369 // The second request should be using a new socket.
1370 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1371 }
1372
[email protected]1c773ea12009-04-28 19:58:421373 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501374 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521375
[email protected]90499482013-06-01 00:39:501376 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251377 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521378
1379 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571380 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421381 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251382 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521383 }
1384}
[email protected]3d2a59b2008-09-26 19:44:251385
[email protected]a34f61ee2014-03-18 20:59:491386void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1387 const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:101388 const MockRead* read_failure,
1389 bool use_spdy) {
[email protected]a34f61ee2014-03-18 20:59:491390 HttpRequestInfo request;
1391 request.method = "GET";
[email protected]09356c652014-03-25 15:36:101392 request.url = GURL("https://www.foo.com/");
[email protected]a34f61ee2014-03-18 20:59:491393 request.load_flags = 0;
1394
vishal.b62985ca92015-04-17 08:45:511395 TestNetLog net_log;
[email protected]a34f61ee2014-03-18 20:59:491396 session_deps_.net_log = &net_log;
mmenke6b3af6e2015-09-12 02:06:061397 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a34f61ee2014-03-18 20:59:491398
[email protected]09356c652014-03-25 15:36:101399 SSLSocketDataProvider ssl1(ASYNC, OK);
1400 SSLSocketDataProvider ssl2(ASYNC, OK);
1401 if (use_spdy) {
1402 ssl1.SetNextProto(GetParam());
1403 ssl2.SetNextProto(GetParam());
1404 }
1405 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1406 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]a34f61ee2014-03-18 20:59:491407
[email protected]09356c652014-03-25 15:36:101408 // SPDY versions of the request and response.
1409 scoped_ptr<SpdyFrame> spdy_request(spdy_util_.ConstructSpdyGet(
1410 request.url.spec().c_str(), false, 1, DEFAULT_PRIORITY));
1411 scoped_ptr<SpdyFrame> spdy_response(
1412 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
1413 scoped_ptr<SpdyFrame> spdy_data(
1414 spdy_util_.ConstructSpdyBodyFrame(1, "hello", 5, true));
[email protected]a34f61ee2014-03-18 20:59:491415
[email protected]09356c652014-03-25 15:36:101416 // HTTP/1.1 versions of the request and response.
1417 const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1418 "Host: www.foo.com\r\n"
1419 "Connection: keep-alive\r\n\r\n";
1420 const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1421 const char kHttpData[] = "hello";
1422
1423 std::vector<MockRead> data1_reads;
1424 std::vector<MockWrite> data1_writes;
[email protected]a34f61ee2014-03-18 20:59:491425 if (write_failure) {
1426 ASSERT_FALSE(read_failure);
[email protected]09356c652014-03-25 15:36:101427 data1_writes.push_back(*write_failure);
1428 data1_reads.push_back(MockRead(ASYNC, OK));
[email protected]a34f61ee2014-03-18 20:59:491429 } else {
1430 ASSERT_TRUE(read_failure);
[email protected]09356c652014-03-25 15:36:101431 if (use_spdy) {
1432 data1_writes.push_back(CreateMockWrite(*spdy_request));
1433 } else {
1434 data1_writes.push_back(MockWrite(kHttpRequest));
1435 }
1436 data1_reads.push_back(*read_failure);
[email protected]a34f61ee2014-03-18 20:59:491437 }
1438
[email protected]09356c652014-03-25 15:36:101439 StaticSocketDataProvider data1(&data1_reads[0], data1_reads.size(),
1440 &data1_writes[0], data1_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491441 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1442
[email protected]09356c652014-03-25 15:36:101443 std::vector<MockRead> data2_reads;
1444 std::vector<MockWrite> data2_writes;
1445
1446 if (use_spdy) {
1447 data2_writes.push_back(CreateMockWrite(*spdy_request, 0, ASYNC));
1448
1449 data2_reads.push_back(CreateMockRead(*spdy_response, 1, ASYNC));
1450 data2_reads.push_back(CreateMockRead(*spdy_data, 2, ASYNC));
1451 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1452 } else {
1453 data2_writes.push_back(
1454 MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1455
1456 data2_reads.push_back(
1457 MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1458 data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1459 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1460 }
rch8e6c6c42015-05-01 14:05:131461 SequencedSocketData data2(&data2_reads[0], data2_reads.size(),
1462 &data2_writes[0], data2_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491463 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1464
1465 // Preconnect a socket.
ttuttle859dc7a2015-04-23 19:42:291466 SSLConfig ssl_config;
[email protected]a34f61ee2014-03-18 20:59:491467 session->ssl_config_service()->GetSSLConfig(&ssl_config);
[email protected]d7599122014-05-24 03:37:231468 session->GetNextProtos(&ssl_config.next_protos);
mmenked1205bd2015-07-15 22:26:351469 session->http_stream_factory()->PreconnectStreams(1, request, ssl_config,
1470 ssl_config);
[email protected]a34f61ee2014-03-18 20:59:491471 // Wait for the preconnect to complete.
1472 // TODO(davidben): Some way to wait for an idle socket count might be handy.
1473 base::RunLoop().RunUntilIdle();
[email protected]09356c652014-03-25 15:36:101474 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]a34f61ee2014-03-18 20:59:491475
1476 // Make the request.
1477 TestCompletionCallback callback;
1478
1479 scoped_ptr<HttpTransaction> trans(
1480 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1481
1482 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1483 EXPECT_EQ(ERR_IO_PENDING, rv);
1484
1485 rv = callback.WaitForResult();
1486 EXPECT_EQ(OK, rv);
1487
1488 LoadTimingInfo load_timing_info;
1489 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
[email protected]09356c652014-03-25 15:36:101490 TestLoadTimingNotReused(
1491 load_timing_info,
1492 CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]a34f61ee2014-03-18 20:59:491493
1494 const HttpResponseInfo* response = trans->GetResponseInfo();
1495 ASSERT_TRUE(response != NULL);
1496
1497 EXPECT_TRUE(response->headers.get() != NULL);
1498 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1499
1500 std::string response_data;
1501 rv = ReadTransaction(trans.get(), &response_data);
1502 EXPECT_EQ(OK, rv);
[email protected]09356c652014-03-25 15:36:101503 EXPECT_EQ(kHttpData, response_data);
[email protected]a34f61ee2014-03-18 20:59:491504}
1505
[email protected]23e482282013-06-14 16:08:021506TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:231507 KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061508 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]202965992011-12-07 23:04:511509 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1510}
1511
[email protected]23e482282013-06-14 16:08:021512TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061513 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]202965992011-12-07 23:04:511514 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251515}
1516
[email protected]23e482282013-06-14 16:08:021517TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061518 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]202965992011-12-07 23:04:511519 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251520}
1521
[email protected]d58ceea82014-06-04 10:55:541522// Make sure that on a 408 response (Request Timeout), the request is retried,
1523// if the socket was a reused keep alive socket.
1524TEST_P(HttpNetworkTransactionTest, KeepAlive408) {
1525 MockRead read_failure(SYNCHRONOUS,
1526 "HTTP/1.1 408 Request Timeout\r\n"
1527 "Connection: Keep-Alive\r\n"
1528 "Content-Length: 6\r\n\r\n"
1529 "Pickle");
1530 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1531}
1532
[email protected]a34f61ee2014-03-18 20:59:491533TEST_P(HttpNetworkTransactionTest,
1534 PreconnectErrorNotConnectedOnWrite) {
1535 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]09356c652014-03-25 15:36:101536 PreconnectErrorResendRequestTest(&write_failure, NULL, false);
[email protected]a34f61ee2014-03-18 20:59:491537}
1538
1539TEST_P(HttpNetworkTransactionTest, PreconnectErrorReset) {
1540 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]09356c652014-03-25 15:36:101541 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
[email protected]a34f61ee2014-03-18 20:59:491542}
1543
1544TEST_P(HttpNetworkTransactionTest, PreconnectErrorEOF) {
1545 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]09356c652014-03-25 15:36:101546 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1547}
1548
1549TEST_P(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
1550 MockRead read_failure(ASYNC, OK); // EOF
1551 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1552}
1553
[email protected]d58ceea82014-06-04 10:55:541554// Make sure that on a 408 response (Request Timeout), the request is retried,
1555// if the socket was a preconnected (UNUSED_IDLE) socket.
1556TEST_P(HttpNetworkTransactionTest, RetryOnIdle408) {
1557 MockRead read_failure(SYNCHRONOUS,
1558 "HTTP/1.1 408 Request Timeout\r\n"
1559 "Connection: Keep-Alive\r\n"
1560 "Content-Length: 6\r\n\r\n"
1561 "Pickle");
1562 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1563 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1564}
1565
[email protected]09356c652014-03-25 15:36:101566TEST_P(HttpNetworkTransactionTest,
1567 SpdyPreconnectErrorNotConnectedOnWrite) {
1568 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1569 PreconnectErrorResendRequestTest(&write_failure, NULL, true);
1570}
1571
1572TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
1573 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1574 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1575}
1576
1577TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
1578 MockRead read_failure(SYNCHRONOUS, OK); // EOF
1579 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1580}
1581
1582TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
1583 MockRead read_failure(ASYNC, OK); // EOF
1584 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
[email protected]a34f61ee2014-03-18 20:59:491585}
1586
[email protected]23e482282013-06-14 16:08:021587TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:421588 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:251589 request.method = "GET";
bncce36dca22015-04-21 22:11:231590 request.url = GURL("http://www.example.org/");
[email protected]3d2a59b2008-09-26 19:44:251591 request.load_flags = 0;
1592
mmenke6b3af6e2015-09-12 02:06:061593 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271594 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411595 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271596
[email protected]3d2a59b2008-09-26 19:44:251597 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061598 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:351599 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1600 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061601 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251602 };
[email protected]31a2bfe2010-02-09 08:03:391603 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071604 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:251605
[email protected]49639fa2011-12-20 23:22:411606 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:251607
[email protected]49639fa2011-12-20 23:22:411608 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421609 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3d2a59b2008-09-26 19:44:251610
1611 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421612 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
ttuttled9dbc652015-09-29 20:00:591613
1614 IPEndPoint endpoint;
1615 EXPECT_TRUE(trans->GetRemoteEndpoint(&endpoint));
1616 EXPECT_LT(0u, endpoint.address().size());
[email protected]3d2a59b2008-09-26 19:44:251617}
1618
1619// What do various browsers do when the server closes a non-keepalive
1620// connection without sending any response header or body?
1621//
1622// IE7: error page
1623// Safari 3.1.2 (Windows): error page
1624// Firefox 3.0.1: blank page
1625// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:421626// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1627// Us: error page (EMPTY_RESPONSE)
[email protected]23e482282013-06-14 16:08:021628TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:251629 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061630 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:351631 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1632 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061633 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251634 };
[email protected]31a2bfe2010-02-09 08:03:391635 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1636 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:421637 EXPECT_EQ(ERR_EMPTY_RESPONSE, out.rv);
[email protected]3d2a59b2008-09-26 19:44:251638}
[email protected]038e9a32008-10-08 22:40:161639
[email protected]1826a402014-01-08 15:40:481640// Test that network access can be deferred and resumed.
1641TEST_P(HttpNetworkTransactionTest, ThrottleBeforeNetworkStart) {
1642 HttpRequestInfo request;
1643 request.method = "GET";
bncce36dca22015-04-21 22:11:231644 request.url = GURL("http://www.example.org/");
[email protected]1826a402014-01-08 15:40:481645 request.load_flags = 0;
1646
mmenke6b3af6e2015-09-12 02:06:061647 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1826a402014-01-08 15:40:481648 scoped_ptr<HttpTransaction> trans(
1649 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1650
1651 // Defer on OnBeforeNetworkStart.
1652 BeforeNetworkStartHandler net_start_handler(true); // defer
1653 trans->SetBeforeNetworkStartCallback(
1654 base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
1655 base::Unretained(&net_start_handler)));
1656
1657 MockRead data_reads[] = {
1658 MockRead("HTTP/1.0 200 OK\r\n"),
1659 MockRead("Content-Length: 5\r\n\r\n"),
1660 MockRead("hello"),
1661 MockRead(SYNCHRONOUS, 0),
1662 };
1663 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1664 session_deps_.socket_factory->AddSocketDataProvider(&data);
1665
1666 TestCompletionCallback callback;
1667
1668 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1669 EXPECT_EQ(ERR_IO_PENDING, rv);
1670 base::MessageLoop::current()->RunUntilIdle();
1671
1672 // Should have deferred for network start.
1673 EXPECT_TRUE(net_start_handler.observed_before_network_start());
1674 EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
[email protected]1826a402014-01-08 15:40:481675
1676 trans->ResumeNetworkStart();
1677 rv = callback.WaitForResult();
1678 EXPECT_EQ(OK, rv);
1679 EXPECT_TRUE(trans->GetResponseInfo() != NULL);
1680
1681 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
1682 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
1683 if (rv == ERR_IO_PENDING)
1684 rv = callback.WaitForResult();
1685 EXPECT_EQ(5, rv);
1686 trans.reset();
1687}
1688
1689// Test that network use can be deferred and canceled.
1690TEST_P(HttpNetworkTransactionTest, ThrottleAndCancelBeforeNetworkStart) {
1691 HttpRequestInfo request;
1692 request.method = "GET";
bncce36dca22015-04-21 22:11:231693 request.url = GURL("http://www.example.org/");
[email protected]1826a402014-01-08 15:40:481694 request.load_flags = 0;
1695
mmenke6b3af6e2015-09-12 02:06:061696 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1826a402014-01-08 15:40:481697 scoped_ptr<HttpTransaction> trans(
1698 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1699
1700 // Defer on OnBeforeNetworkStart.
1701 BeforeNetworkStartHandler net_start_handler(true); // defer
1702 trans->SetBeforeNetworkStartCallback(
1703 base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
1704 base::Unretained(&net_start_handler)));
1705
1706 TestCompletionCallback callback;
1707
1708 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1709 EXPECT_EQ(ERR_IO_PENDING, rv);
1710 base::MessageLoop::current()->RunUntilIdle();
1711
1712 // Should have deferred for network start.
1713 EXPECT_TRUE(net_start_handler.observed_before_network_start());
1714 EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
[email protected]1826a402014-01-08 15:40:481715}
1716
[email protected]7a5378b2012-11-04 03:25:171717// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
1718// tests. There was a bug causing HttpNetworkTransaction to hang in the
1719// destructor in such situations.
1720// See http://crbug.com/154712 and http://crbug.com/156609.
[email protected]23e482282013-06-14 16:08:021721TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:171722 HttpRequestInfo request;
1723 request.method = "GET";
bncce36dca22015-04-21 22:11:231724 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171725 request.load_flags = 0;
1726
mmenke6b3af6e2015-09-12 02:06:061727 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:361728 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501729 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171730
1731 MockRead data_reads[] = {
1732 MockRead("HTTP/1.0 200 OK\r\n"),
1733 MockRead("Connection: keep-alive\r\n"),
1734 MockRead("Content-Length: 100\r\n\r\n"),
1735 MockRead("hello"),
1736 MockRead(SYNCHRONOUS, 0),
1737 };
1738 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071739 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171740
1741 TestCompletionCallback callback;
1742
1743 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1744 EXPECT_EQ(ERR_IO_PENDING, rv);
1745
1746 rv = callback.WaitForResult();
1747 EXPECT_EQ(OK, rv);
1748
1749 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501750 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171751 if (rv == ERR_IO_PENDING)
1752 rv = callback.WaitForResult();
1753 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:501754 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171755 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1756
1757 trans.reset();
[email protected]2da659e2013-05-23 20:51:341758 base::MessageLoop::current()->RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171759 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1760}
1761
[email protected]23e482282013-06-14 16:08:021762TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:171763 HttpRequestInfo request;
1764 request.method = "GET";
bncce36dca22015-04-21 22:11:231765 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171766 request.load_flags = 0;
1767
mmenke6b3af6e2015-09-12 02:06:061768 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:361769 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501770 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171771
1772 MockRead data_reads[] = {
1773 MockRead("HTTP/1.0 200 OK\r\n"),
1774 MockRead("Connection: keep-alive\r\n"),
1775 MockRead("Content-Length: 100\r\n\r\n"),
1776 MockRead(SYNCHRONOUS, 0),
1777 };
1778 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071779 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171780
1781 TestCompletionCallback callback;
1782
1783 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1784 EXPECT_EQ(ERR_IO_PENDING, rv);
1785
1786 rv = callback.WaitForResult();
1787 EXPECT_EQ(OK, rv);
1788
1789 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501790 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171791 if (rv == ERR_IO_PENDING)
1792 rv = callback.WaitForResult();
1793 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1794
1795 trans.reset();
[email protected]2da659e2013-05-23 20:51:341796 base::MessageLoop::current()->RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171797 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1798}
1799
[email protected]0b0bf032010-09-21 18:08:501800// Test that we correctly reuse a keep-alive connection after not explicitly
1801// reading the body.
[email protected]23e482282013-06-14 16:08:021802TEST_P(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:131803 HttpRequestInfo request;
1804 request.method = "GET";
1805 request.url = GURL("http://www.foo.com/");
1806 request.load_flags = 0;
1807
vishal.b62985ca92015-04-17 08:45:511808 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071809 session_deps_.net_log = &net_log;
mmenke6b3af6e2015-09-12 02:06:061810 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271811
[email protected]0b0bf032010-09-21 18:08:501812 // Note that because all these reads happen in the same
1813 // StaticSocketDataProvider, it shows that the same socket is being reused for
1814 // all transactions.
[email protected]fc31d6a42010-06-24 18:05:131815 MockRead data1_reads[] = {
[email protected]0b0bf032010-09-21 18:08:501816 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
1817 MockRead("HTTP/1.1 205 Reset Content\r\n\r\n"),
[email protected]fc31d6a42010-06-24 18:05:131818 MockRead("HTTP/1.1 304 Not Modified\r\n\r\n"),
[email protected]0b0bf032010-09-21 18:08:501819 MockRead("HTTP/1.1 302 Found\r\n"
1820 "Content-Length: 0\r\n\r\n"),
1821 MockRead("HTTP/1.1 302 Found\r\n"
1822 "Content-Length: 5\r\n\r\n"
1823 "hello"),
1824 MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1825 "Content-Length: 0\r\n\r\n"),
1826 MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1827 "Content-Length: 5\r\n\r\n"
1828 "hello"),
[email protected]fc31d6a42010-06-24 18:05:131829 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1830 MockRead("hello"),
1831 };
1832 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071833 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]fc31d6a42010-06-24 18:05:131834
1835 MockRead data2_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061836 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]fc31d6a42010-06-24 18:05:131837 };
1838 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071839 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]fc31d6a42010-06-24 18:05:131840
[email protected]0b0bf032010-09-21 18:08:501841 const int kNumUnreadBodies = arraysize(data1_reads) - 2;
1842 std::string response_lines[kNumUnreadBodies];
1843
[email protected]58e32bb2013-01-21 18:23:251844 uint32 first_socket_log_id = NetLog::Source::kInvalidId;
[email protected]0b0bf032010-09-21 18:08:501845 for (size_t i = 0; i < arraysize(data1_reads) - 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411846 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:131847
[email protected]262eec82013-03-19 21:01:361848 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501849 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]fc31d6a42010-06-24 18:05:131850
[email protected]49639fa2011-12-20 23:22:411851 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]fc31d6a42010-06-24 18:05:131852 EXPECT_EQ(ERR_IO_PENDING, rv);
1853
1854 rv = callback.WaitForResult();
1855 EXPECT_EQ(OK, rv);
1856
[email protected]58e32bb2013-01-21 18:23:251857 LoadTimingInfo load_timing_info;
1858 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1859 if (i == 0) {
1860 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1861 first_socket_log_id = load_timing_info.socket_log_id;
1862 } else {
1863 TestLoadTimingReused(load_timing_info);
1864 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
1865 }
1866
[email protected]fc31d6a42010-06-24 18:05:131867 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]0b0bf032010-09-21 18:08:501868 ASSERT_TRUE(response != NULL);
[email protected]fc31d6a42010-06-24 18:05:131869
[email protected]90499482013-06-01 00:39:501870 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]0b0bf032010-09-21 18:08:501871 response_lines[i] = response->headers->GetStatusLine();
1872
1873 // We intentionally don't read the response bodies.
[email protected]fc31d6a42010-06-24 18:05:131874 }
[email protected]0b0bf032010-09-21 18:08:501875
1876 const char* const kStatusLines[] = {
1877 "HTTP/1.1 204 No Content",
1878 "HTTP/1.1 205 Reset Content",
1879 "HTTP/1.1 304 Not Modified",
1880 "HTTP/1.1 302 Found",
1881 "HTTP/1.1 302 Found",
1882 "HTTP/1.1 301 Moved Permanently",
1883 "HTTP/1.1 301 Moved Permanently",
1884 };
1885
mostynb91e0da982015-01-20 19:17:271886 static_assert(kNumUnreadBodies == arraysize(kStatusLines),
1887 "forgot to update kStatusLines");
[email protected]0b0bf032010-09-21 18:08:501888
1889 for (int i = 0; i < kNumUnreadBodies; ++i)
1890 EXPECT_EQ(kStatusLines[i], response_lines[i]);
1891
[email protected]49639fa2011-12-20 23:22:411892 TestCompletionCallback callback;
[email protected]262eec82013-03-19 21:01:361893 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501894 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:411895 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0b0bf032010-09-21 18:08:501896 EXPECT_EQ(ERR_IO_PENDING, rv);
1897 rv = callback.WaitForResult();
1898 EXPECT_EQ(OK, rv);
1899 const HttpResponseInfo* response = trans->GetResponseInfo();
1900 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:501901 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]0b0bf032010-09-21 18:08:501902 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1903 std::string response_data;
1904 rv = ReadTransaction(trans.get(), &response_data);
1905 EXPECT_EQ(OK, rv);
1906 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:131907}
1908
[email protected]038e9a32008-10-08 22:40:161909// Test the request-challenge-retry sequence for basic auth.
1910// (basic auth is the easiest to mock, because it has no randomness).
[email protected]23e482282013-06-14 16:08:021911TEST_P(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:421912 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:161913 request.method = "GET";
bncce36dca22015-04-21 22:11:231914 request.url = GURL("http://www.example.org/");
[email protected]038e9a32008-10-08 22:40:161915 request.load_flags = 0;
1916
vishal.b62985ca92015-04-17 08:45:511917 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:071918 session_deps_.net_log = &log;
mmenke6b3af6e2015-09-12 02:06:061919 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271920 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411921 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271922
[email protected]f9ee6b52008-11-08 06:46:231923 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:231924 MockWrite(
1925 "GET / HTTP/1.1\r\n"
1926 "Host: www.example.org\r\n"
1927 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:231928 };
1929
[email protected]038e9a32008-10-08 22:40:161930 MockRead data_reads1[] = {
1931 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
1932 // Give a couple authenticate options (only the middle one is actually
1933 // supported).
[email protected]22927ad2009-09-21 19:56:191934 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:161935 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1936 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
1937 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1938 // Large content-length -- won't matter, as connection will be reset.
1939 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061940 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:161941 };
1942
1943 // After calling trans->RestartWithAuth(), this is the request we should
1944 // be issuing -- the final header line contains the credentials.
1945 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:231946 MockWrite(
1947 "GET / HTTP/1.1\r\n"
1948 "Host: www.example.org\r\n"
1949 "Connection: keep-alive\r\n"
1950 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:161951 };
1952
1953 // Lastly, the server responds with the actual content.
1954 MockRead data_reads2[] = {
1955 MockRead("HTTP/1.0 200 OK\r\n"),
1956 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1957 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061958 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:161959 };
1960
[email protected]31a2bfe2010-02-09 08:03:391961 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1962 data_writes1, arraysize(data_writes1));
1963 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1964 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:071965 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1966 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:161967
[email protected]49639fa2011-12-20 23:22:411968 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:161969
[email protected]49639fa2011-12-20 23:22:411970 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421971 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:161972
1973 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421974 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:161975
[email protected]58e32bb2013-01-21 18:23:251976 LoadTimingInfo load_timing_info1;
1977 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
1978 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
1979
sclittlefb249892015-09-10 21:33:221980 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
1981 EXPECT_EQ(writes_size1, trans->GetTotalSentBytes());
1982 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
[email protected]b8015c42013-12-24 15:18:191983 EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
1984
[email protected]1c773ea12009-04-28 19:58:421985 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501986 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:041987 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:161988
[email protected]49639fa2011-12-20 23:22:411989 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:161990
[email protected]49639fa2011-12-20 23:22:411991 rv = trans->RestartWithAuth(
1992 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:421993 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:161994
1995 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421996 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:161997
[email protected]58e32bb2013-01-21 18:23:251998 LoadTimingInfo load_timing_info2;
1999 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
2000 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2001 // The load timing after restart should have a new socket ID, and times after
2002 // those of the first load timing.
2003 EXPECT_LE(load_timing_info1.receive_headers_end,
2004 load_timing_info2.connect_timing.connect_start);
2005 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2006
sclittlefb249892015-09-10 21:33:222007 int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
2008 EXPECT_EQ(writes_size1 + writes_size2, trans->GetTotalSentBytes());
2009 int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
[email protected]b8015c42013-12-24 15:18:192010 EXPECT_EQ(reads_size1 + reads_size2, trans->GetTotalReceivedBytes());
2011
[email protected]038e9a32008-10-08 22:40:162012 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502013 ASSERT_TRUE(response != NULL);
[email protected]038e9a32008-10-08 22:40:162014 EXPECT_TRUE(response->auth_challenge.get() == NULL);
2015 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:162016}
2017
ttuttled9dbc652015-09-29 20:00:592018// Test the request-challenge-retry sequence for basic auth.
2019// (basic auth is the easiest to mock, because it has no randomness).
2020TEST_P(HttpNetworkTransactionTest, BasicAuthWithAddressChange) {
2021 HttpRequestInfo request;
2022 request.method = "GET";
2023 request.url = GURL("http://www.example.org/");
2024 request.load_flags = 0;
2025
2026 TestNetLog log;
2027 MockHostResolver* resolver = new MockHostResolver();
2028 session_deps_.net_log = &log;
2029 session_deps_.host_resolver.reset(resolver);
2030 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2031 scoped_ptr<HttpTransaction> trans(
2032 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2033
2034 resolver->rules()->ClearRules();
2035 resolver->rules()->AddRule("www.example.org", "127.0.0.1");
2036
2037 MockWrite data_writes1[] = {
2038 MockWrite("GET / HTTP/1.1\r\n"
2039 "Host: www.example.org\r\n"
2040 "Connection: keep-alive\r\n\r\n"),
2041 };
2042
2043 MockRead data_reads1[] = {
2044 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2045 // Give a couple authenticate options (only the middle one is actually
2046 // supported).
2047 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
2048 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2049 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2050 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2051 // Large content-length -- won't matter, as connection will be reset.
2052 MockRead("Content-Length: 10000\r\n\r\n"),
2053 MockRead(SYNCHRONOUS, ERR_FAILED),
2054 };
2055
2056 // After calling trans->RestartWithAuth(), this is the request we should
2057 // be issuing -- the final header line contains the credentials.
2058 MockWrite data_writes2[] = {
2059 MockWrite("GET / HTTP/1.1\r\n"
2060 "Host: www.example.org\r\n"
2061 "Connection: keep-alive\r\n"
2062 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2063 };
2064
2065 // Lastly, the server responds with the actual content.
2066 MockRead data_reads2[] = {
2067 MockRead("HTTP/1.0 200 OK\r\n"),
2068 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2069 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, OK),
2070 };
2071
2072 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2073 data_writes1, arraysize(data_writes1));
2074 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2075 data_writes2, arraysize(data_writes2));
2076 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2077 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2078
2079 TestCompletionCallback callback1;
2080
2081 EXPECT_EQ(OK, callback1.GetResult(trans->Start(&request, callback1.callback(),
2082 BoundNetLog())));
2083
2084 LoadTimingInfo load_timing_info1;
2085 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
2086 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2087
2088 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
2089 EXPECT_EQ(writes_size1, trans->GetTotalSentBytes());
2090 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
2091 EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
2092
2093 const HttpResponseInfo* response = trans->GetResponseInfo();
2094 ASSERT_TRUE(response);
2095 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2096
2097 IPEndPoint endpoint;
2098 EXPECT_TRUE(trans->GetRemoteEndpoint(&endpoint));
2099 ASSERT_FALSE(endpoint.address().empty());
2100 EXPECT_EQ("127.0.0.1:80", endpoint.ToString());
2101
2102 resolver->rules()->ClearRules();
2103 resolver->rules()->AddRule("www.example.org", "127.0.0.2");
2104
2105 TestCompletionCallback callback2;
2106
2107 EXPECT_EQ(OK, callback2.GetResult(trans->RestartWithAuth(
2108 AuthCredentials(kFoo, kBar), callback2.callback())));
2109
2110 LoadTimingInfo load_timing_info2;
2111 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
2112 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2113 // The load timing after restart should have a new socket ID, and times after
2114 // those of the first load timing.
2115 EXPECT_LE(load_timing_info1.receive_headers_end,
2116 load_timing_info2.connect_timing.connect_start);
2117 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2118
2119 int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
2120 EXPECT_EQ(writes_size1 + writes_size2, trans->GetTotalSentBytes());
2121 int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
2122 EXPECT_EQ(reads_size1 + reads_size2, trans->GetTotalReceivedBytes());
2123
2124 response = trans->GetResponseInfo();
2125 ASSERT_TRUE(response);
2126 EXPECT_FALSE(response->auth_challenge.get());
2127 EXPECT_EQ(100, response->headers->GetContentLength());
2128
2129 EXPECT_TRUE(trans->GetRemoteEndpoint(&endpoint));
2130 ASSERT_FALSE(endpoint.address().empty());
2131 EXPECT_EQ("127.0.0.2:80", endpoint.ToString());
2132}
2133
[email protected]23e482282013-06-14 16:08:022134TEST_P(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:462135 HttpRequestInfo request;
2136 request.method = "GET";
bncce36dca22015-04-21 22:11:232137 request.url = GURL("http://www.example.org/");
ttuttle859dc7a2015-04-23 19:42:292138 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]861fcd52009-08-26 02:33:462139
mmenke6b3af6e2015-09-12 02:06:062140 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272141 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:412142 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:272143
[email protected]861fcd52009-08-26 02:33:462144 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:232145 MockWrite(
2146 "GET / HTTP/1.1\r\n"
2147 "Host: www.example.org\r\n"
2148 "Connection: keep-alive\r\n\r\n"),
[email protected]861fcd52009-08-26 02:33:462149 };
2150
2151 MockRead data_reads[] = {
2152 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2153 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2154 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2155 // Large content-length -- won't matter, as connection will be reset.
2156 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062157 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:462158 };
2159
[email protected]31a2bfe2010-02-09 08:03:392160 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2161 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072162 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:412163 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:462164
[email protected]49639fa2011-12-20 23:22:412165 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]861fcd52009-08-26 02:33:462166 EXPECT_EQ(ERR_IO_PENDING, rv);
2167
2168 rv = callback.WaitForResult();
2169 EXPECT_EQ(0, rv);
2170
sclittlefb249892015-09-10 21:33:222171 int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
2172 EXPECT_EQ(writes_size, trans->GetTotalSentBytes());
2173 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
[email protected]b8015c42013-12-24 15:18:192174 EXPECT_EQ(reads_size, trans->GetTotalReceivedBytes());
2175
[email protected]861fcd52009-08-26 02:33:462176 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502177 ASSERT_TRUE(response != NULL);
[email protected]861fcd52009-08-26 02:33:462178 EXPECT_TRUE(response->auth_challenge.get() == NULL);
2179}
2180
[email protected]2d2697f92009-02-18 21:00:322181// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2182// connection.
[email protected]23e482282013-06-14 16:08:022183TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
[email protected]1c773ea12009-04-28 19:58:422184 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322185 request.method = "GET";
bncce36dca22015-04-21 22:11:232186 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322187 request.load_flags = 0;
2188
vishal.b62985ca92015-04-17 08:45:512189 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072190 session_deps_.net_log = &log;
mmenke6b3af6e2015-09-12 02:06:062191 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272192
[email protected]2d2697f92009-02-18 21:00:322193 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232194 MockWrite(
2195 "GET / HTTP/1.1\r\n"
2196 "Host: www.example.org\r\n"
2197 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322198
bncce36dca22015-04-21 22:11:232199 // After calling trans->RestartWithAuth(), this is the request we should
2200 // be issuing -- the final header line contains the credentials.
2201 MockWrite(
2202 "GET / HTTP/1.1\r\n"
2203 "Host: www.example.org\r\n"
2204 "Connection: keep-alive\r\n"
2205 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322206 };
2207
2208 MockRead data_reads1[] = {
2209 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2210 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2211 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2212 MockRead("Content-Length: 14\r\n\r\n"),
2213 MockRead("Unauthorized\r\n"),
2214
2215 // Lastly, the server responds with the actual content.
2216 MockRead("HTTP/1.1 200 OK\r\n"),
2217 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502218 MockRead("Content-Length: 5\r\n\r\n"),
2219 MockRead("Hello"),
[email protected]2d2697f92009-02-18 21:00:322220 };
2221
[email protected]2d0a4f92011-05-05 16:38:462222 // If there is a regression where we disconnect a Keep-Alive
2223 // connection during an auth roundtrip, we'll end up reading this.
2224 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062225 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462226 };
2227
[email protected]31a2bfe2010-02-09 08:03:392228 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2229 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462230 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2231 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072232 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2233 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322234
[email protected]49639fa2011-12-20 23:22:412235 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322236
[email protected]262eec82013-03-19 21:01:362237 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502238 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412239 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422240 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322241
2242 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422243 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322244
[email protected]58e32bb2013-01-21 18:23:252245 LoadTimingInfo load_timing_info1;
2246 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
2247 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2248
[email protected]1c773ea12009-04-28 19:58:422249 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502250 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042251 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322252
[email protected]49639fa2011-12-20 23:22:412253 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322254
[email protected]49639fa2011-12-20 23:22:412255 rv = trans->RestartWithAuth(
2256 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422257 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322258
2259 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422260 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322261
[email protected]58e32bb2013-01-21 18:23:252262 LoadTimingInfo load_timing_info2;
2263 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
2264 TestLoadTimingReused(load_timing_info2);
2265 // The load timing after restart should have the same socket ID, and times
2266 // those of the first load timing.
2267 EXPECT_LE(load_timing_info1.receive_headers_end,
2268 load_timing_info2.send_start);
2269 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2270
[email protected]2d2697f92009-02-18 21:00:322271 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502272 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322273 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502274 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]b8015c42013-12-24 15:18:192275
2276 std::string response_data;
2277 rv = ReadTransaction(trans.get(), &response_data);
2278 EXPECT_EQ(OK, rv);
sclittlefb249892015-09-10 21:33:222279
2280 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
2281 EXPECT_EQ(writes_size1, trans->GetTotalSentBytes());
2282 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
[email protected]b8015c42013-12-24 15:18:192283 EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
[email protected]2d2697f92009-02-18 21:00:322284}
2285
2286// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2287// connection and with no response body to drain.
[email protected]23e482282013-06-14 16:08:022288TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:422289 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322290 request.method = "GET";
bncce36dca22015-04-21 22:11:232291 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322292 request.load_flags = 0;
2293
mmenke6b3af6e2015-09-12 02:06:062294 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272295
[email protected]2d2697f92009-02-18 21:00:322296 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232297 MockWrite(
2298 "GET / HTTP/1.1\r\n"
2299 "Host: www.example.org\r\n"
2300 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322301
bncce36dca22015-04-21 22:11:232302 // After calling trans->RestartWithAuth(), this is the request we should
2303 // be issuing -- the final header line contains the credentials.
2304 MockWrite(
2305 "GET / HTTP/1.1\r\n"
2306 "Host: www.example.org\r\n"
2307 "Connection: keep-alive\r\n"
2308 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322309 };
2310
[email protected]2d2697f92009-02-18 21:00:322311 MockRead data_reads1[] = {
2312 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2313 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:312314 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:322315
2316 // Lastly, the server responds with the actual content.
2317 MockRead("HTTP/1.1 200 OK\r\n"),
2318 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502319 MockRead("Content-Length: 5\r\n\r\n"),
2320 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322321 };
2322
[email protected]2d0a4f92011-05-05 16:38:462323 // An incorrect reconnect would cause this to be read.
2324 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062325 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462326 };
2327
[email protected]31a2bfe2010-02-09 08:03:392328 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2329 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462330 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2331 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072332 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2333 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322334
[email protected]49639fa2011-12-20 23:22:412335 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322336
[email protected]262eec82013-03-19 21:01:362337 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502338 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412339 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422340 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322341
2342 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422343 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322344
[email protected]1c773ea12009-04-28 19:58:422345 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502346 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042347 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322348
[email protected]49639fa2011-12-20 23:22:412349 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322350
[email protected]49639fa2011-12-20 23:22:412351 rv = trans->RestartWithAuth(
2352 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422353 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322354
2355 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422356 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322357
2358 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502359 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322360 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502361 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322362}
2363
2364// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2365// connection and with a large response body to drain.
[email protected]23e482282013-06-14 16:08:022366TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:422367 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322368 request.method = "GET";
bncce36dca22015-04-21 22:11:232369 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322370 request.load_flags = 0;
2371
mmenke6b3af6e2015-09-12 02:06:062372 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272373
[email protected]2d2697f92009-02-18 21:00:322374 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232375 MockWrite(
2376 "GET / HTTP/1.1\r\n"
2377 "Host: www.example.org\r\n"
2378 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322379
bncce36dca22015-04-21 22:11:232380 // After calling trans->RestartWithAuth(), this is the request we should
2381 // be issuing -- the final header line contains the credentials.
2382 MockWrite(
2383 "GET / HTTP/1.1\r\n"
2384 "Host: www.example.org\r\n"
2385 "Connection: keep-alive\r\n"
2386 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322387 };
2388
2389 // Respond with 5 kb of response body.
2390 std::string large_body_string("Unauthorized");
2391 large_body_string.append(5 * 1024, ' ');
2392 large_body_string.append("\r\n");
2393
2394 MockRead data_reads1[] = {
2395 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2396 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2397 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2398 // 5134 = 12 + 5 * 1024 + 2
2399 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062400 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:322401
2402 // Lastly, the server responds with the actual content.
2403 MockRead("HTTP/1.1 200 OK\r\n"),
2404 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502405 MockRead("Content-Length: 5\r\n\r\n"),
2406 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322407 };
2408
[email protected]2d0a4f92011-05-05 16:38:462409 // An incorrect reconnect would cause this to be read.
2410 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062411 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462412 };
2413
[email protected]31a2bfe2010-02-09 08:03:392414 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2415 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462416 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2417 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072418 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2419 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322420
[email protected]49639fa2011-12-20 23:22:412421 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322422
[email protected]262eec82013-03-19 21:01:362423 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502424 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412425 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422426 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322427
2428 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422429 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322430
[email protected]1c773ea12009-04-28 19:58:422431 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502432 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042433 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322434
[email protected]49639fa2011-12-20 23:22:412435 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322436
[email protected]49639fa2011-12-20 23:22:412437 rv = trans->RestartWithAuth(
2438 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422439 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322440
2441 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422442 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322443
2444 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502445 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322446 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502447 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322448}
2449
2450// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:312451// connection, but the server gets impatient and closes the connection.
[email protected]23e482282013-06-14 16:08:022452TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:312453 HttpRequestInfo request;
2454 request.method = "GET";
bncce36dca22015-04-21 22:11:232455 request.url = GURL("http://www.example.org/");
[email protected]11203f012009-11-12 23:02:312456 request.load_flags = 0;
2457
mmenke6b3af6e2015-09-12 02:06:062458 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272459
[email protected]11203f012009-11-12 23:02:312460 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232461 MockWrite(
2462 "GET / HTTP/1.1\r\n"
2463 "Host: www.example.org\r\n"
2464 "Connection: keep-alive\r\n\r\n"),
2465 // This simulates the seemingly successful write to a closed connection
2466 // if the bug is not fixed.
2467 MockWrite(
2468 "GET / HTTP/1.1\r\n"
2469 "Host: www.example.org\r\n"
2470 "Connection: keep-alive\r\n"
2471 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312472 };
2473
2474 MockRead data_reads1[] = {
2475 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2476 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2477 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2478 MockRead("Content-Length: 14\r\n\r\n"),
2479 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:062480 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:312481 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:062482 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:312483 };
2484
2485 // After calling trans->RestartWithAuth(), this is the request we should
2486 // be issuing -- the final header line contains the credentials.
2487 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232488 MockWrite(
2489 "GET / HTTP/1.1\r\n"
2490 "Host: www.example.org\r\n"
2491 "Connection: keep-alive\r\n"
2492 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312493 };
2494
2495 // Lastly, the server responds with the actual content.
2496 MockRead data_reads2[] = {
2497 MockRead("HTTP/1.1 200 OK\r\n"),
2498 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502499 MockRead("Content-Length: 5\r\n\r\n"),
2500 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:312501 };
2502
[email protected]31a2bfe2010-02-09 08:03:392503 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2504 data_writes1, arraysize(data_writes1));
2505 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2506 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072507 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2508 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:312509
[email protected]49639fa2011-12-20 23:22:412510 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:312511
[email protected]262eec82013-03-19 21:01:362512 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502513 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412514 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]11203f012009-11-12 23:02:312515 EXPECT_EQ(ERR_IO_PENDING, rv);
2516
2517 rv = callback1.WaitForResult();
2518 EXPECT_EQ(OK, rv);
2519
2520 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502521 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042522 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:312523
[email protected]49639fa2011-12-20 23:22:412524 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:312525
[email protected]49639fa2011-12-20 23:22:412526 rv = trans->RestartWithAuth(
2527 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]11203f012009-11-12 23:02:312528 EXPECT_EQ(ERR_IO_PENDING, rv);
2529
2530 rv = callback2.WaitForResult();
2531 EXPECT_EQ(OK, rv);
2532
2533 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502534 ASSERT_TRUE(response != NULL);
[email protected]11203f012009-11-12 23:02:312535 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502536 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:312537}
2538
[email protected]394816e92010-08-03 07:38:592539// Test the request-challenge-retry sequence for basic auth, over a connection
2540// that requires a restart when setting up an SSL tunnel.
ttuttle34f63b52015-03-05 04:33:012541TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
2542 HttpRequestInfo request;
2543 request.method = "GET";
bncce36dca22015-04-21 22:11:232544 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:012545 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292546 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:012547
2548 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:032549 session_deps_.proxy_service =
2550 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:512551 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:012552 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:062553 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:012554
2555 // Since we have proxy, should try to establish tunnel.
2556 MockWrite data_writes1[] = {
mmenkee0b5c882015-08-26 20:29:112557 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
2558 "Host: www.example.org\r\n"
2559 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:012560 };
2561
mmenkee0b5c882015-08-26 20:29:112562 // The proxy responds to the connect with a 407, using a non-persistent
ttuttle34f63b52015-03-05 04:33:012563 // connection.
2564 MockRead data_reads1[] = {
2565 // No credentials.
2566 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
2567 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
mmenkee0b5c882015-08-26 20:29:112568 };
ttuttle34f63b52015-03-05 04:33:012569
mmenkee0b5c882015-08-26 20:29:112570 // Since the first connection couldn't be reused, need to establish another
2571 // once given credentials.
2572 MockWrite data_writes2[] = {
2573 // After calling trans->RestartWithAuth(), this is the request we should
2574 // be issuing -- the final header line contains the credentials.
2575 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
2576 "Host: www.example.org\r\n"
2577 "Proxy-Connection: keep-alive\r\n"
2578 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2579
2580 MockWrite("GET / HTTP/1.1\r\n"
2581 "Host: www.example.org\r\n"
2582 "Connection: keep-alive\r\n\r\n"),
2583 };
2584
2585 MockRead data_reads2[] = {
ttuttle34f63b52015-03-05 04:33:012586 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
2587
2588 MockRead("HTTP/1.1 200 OK\r\n"),
2589 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2590 MockRead("Content-Length: 5\r\n\r\n"),
2591 MockRead(SYNCHRONOUS, "hello"),
2592 };
2593
2594 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2595 data_writes1, arraysize(data_writes1));
2596 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee0b5c882015-08-26 20:29:112597 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2598 data_writes2, arraysize(data_writes2));
2599 session_deps_.socket_factory->AddSocketDataProvider(&data2);
ttuttle34f63b52015-03-05 04:33:012600 SSLSocketDataProvider ssl(ASYNC, OK);
2601 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
2602
2603 TestCompletionCallback callback1;
2604
2605 scoped_ptr<HttpTransaction> trans(
2606 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2607
2608 int rv = trans->Start(&request, callback1.callback(), log.bound());
2609 EXPECT_EQ(ERR_IO_PENDING, rv);
2610
2611 rv = callback1.WaitForResult();
2612 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:462613 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:012614 log.GetEntries(&entries);
2615 size_t pos = ExpectLogContainsSomewhere(
2616 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
2617 NetLog::PHASE_NONE);
2618 ExpectLogContainsSomewhere(
2619 entries, pos, NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2620 NetLog::PHASE_NONE);
2621
2622 const HttpResponseInfo* response = trans->GetResponseInfo();
2623 ASSERT_TRUE(response != NULL);
2624 EXPECT_FALSE(response->headers->IsKeepAlive());
2625 ASSERT_FALSE(response->headers.get() == NULL);
2626 EXPECT_EQ(407, response->headers->response_code());
2627 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
2628 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2629
2630 LoadTimingInfo load_timing_info;
2631 // CONNECT requests and responses are handled at the connect job level, so
2632 // the transaction does not yet have a connection.
2633 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
2634
2635 TestCompletionCallback callback2;
2636
2637 rv =
2638 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
2639 EXPECT_EQ(ERR_IO_PENDING, rv);
2640
2641 rv = callback2.WaitForResult();
2642 EXPECT_EQ(OK, rv);
2643
2644 response = trans->GetResponseInfo();
2645 ASSERT_TRUE(response != NULL);
2646
2647 EXPECT_TRUE(response->headers->IsKeepAlive());
2648 EXPECT_EQ(200, response->headers->response_code());
2649 EXPECT_EQ(5, response->headers->GetContentLength());
2650 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2651
2652 // The password prompt info should not be set.
2653 EXPECT_TRUE(response->auth_challenge.get() == NULL);
2654
2655 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2656 TestLoadTimingNotReusedWithPac(load_timing_info,
2657 CONNECT_TIMING_HAS_SSL_TIMES);
2658
2659 trans.reset();
2660 session->CloseAllConnections();
2661}
2662
2663// Test the request-challenge-retry sequence for basic auth, over a connection
2664// that requires a restart when setting up an SSL tunnel.
2665TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) {
[email protected]394816e92010-08-03 07:38:592666 HttpRequestInfo request;
2667 request.method = "GET";
bncce36dca22015-04-21 22:11:232668 request.url = GURL("https://www.example.org/");
[email protected]394816e92010-08-03 07:38:592669 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292670 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]394816e92010-08-03 07:38:592671
[email protected]cb9bf6ca2011-01-28 13:15:272672 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:032673 session_deps_.proxy_service =
2674 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:512675 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072676 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:062677 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272678
[email protected]394816e92010-08-03 07:38:592679 // Since we have proxy, should try to establish tunnel.
2680 MockWrite data_writes1[] = {
mmenkee0b5c882015-08-26 20:29:112681 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
2682 "Host: www.example.org\r\n"
2683 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]394816e92010-08-03 07:38:592684 };
2685
mmenkee0b5c882015-08-26 20:29:112686 // The proxy responds to the connect with a 407, using a non-persistent
[email protected]394816e92010-08-03 07:38:592687 // connection.
2688 MockRead data_reads1[] = {
mmenkee0b5c882015-08-26 20:29:112689 // No credentials.
2690 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2691 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2692 MockRead("Proxy-Connection: close\r\n\r\n"),
2693 };
[email protected]394816e92010-08-03 07:38:592694
mmenkee0b5c882015-08-26 20:29:112695 MockWrite data_writes2[] = {
2696 // After calling trans->RestartWithAuth(), this is the request we should
2697 // be issuing -- the final header line contains the credentials.
2698 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
2699 "Host: www.example.org\r\n"
2700 "Proxy-Connection: keep-alive\r\n"
2701 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]394816e92010-08-03 07:38:592702
mmenkee0b5c882015-08-26 20:29:112703 MockWrite("GET / HTTP/1.1\r\n"
2704 "Host: www.example.org\r\n"
2705 "Connection: keep-alive\r\n\r\n"),
2706 };
2707
2708 MockRead data_reads2[] = {
2709 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2710
2711 MockRead("HTTP/1.1 200 OK\r\n"),
2712 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2713 MockRead("Content-Length: 5\r\n\r\n"),
2714 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:592715 };
2716
2717 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2718 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072719 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee0b5c882015-08-26 20:29:112720 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2721 data_writes2, arraysize(data_writes2));
2722 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8ddf8322012-02-23 18:08:062723 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072724 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:592725
[email protected]49639fa2011-12-20 23:22:412726 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:592727
[email protected]262eec82013-03-19 21:01:362728 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502729 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:502730
[email protected]49639fa2011-12-20 23:22:412731 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]394816e92010-08-03 07:38:592732 EXPECT_EQ(ERR_IO_PENDING, rv);
2733
2734 rv = callback1.WaitForResult();
2735 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:462736 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:402737 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:592738 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402739 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]394816e92010-08-03 07:38:592740 NetLog::PHASE_NONE);
2741 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402742 entries, pos,
[email protected]394816e92010-08-03 07:38:592743 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2744 NetLog::PHASE_NONE);
2745
2746 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502747 ASSERT_TRUE(response != NULL);
ttuttle34f63b52015-03-05 04:33:012748 EXPECT_FALSE(response->headers->IsKeepAlive());
[email protected]90499482013-06-01 00:39:502749 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]394816e92010-08-03 07:38:592750 EXPECT_EQ(407, response->headers->response_code());
2751 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042752 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:592753
[email protected]029c83b62013-01-24 05:28:202754 LoadTimingInfo load_timing_info;
2755 // CONNECT requests and responses are handled at the connect job level, so
2756 // the transaction does not yet have a connection.
2757 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
2758
[email protected]49639fa2011-12-20 23:22:412759 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:592760
[email protected]49639fa2011-12-20 23:22:412761 rv = trans->RestartWithAuth(
2762 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]394816e92010-08-03 07:38:592763 EXPECT_EQ(ERR_IO_PENDING, rv);
2764
2765 rv = callback2.WaitForResult();
2766 EXPECT_EQ(OK, rv);
2767
2768 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502769 ASSERT_TRUE(response != NULL);
[email protected]394816e92010-08-03 07:38:592770
2771 EXPECT_TRUE(response->headers->IsKeepAlive());
2772 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:502773 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:592774 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2775
2776 // The password prompt info should not be set.
2777 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502778
[email protected]029c83b62013-01-24 05:28:202779 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2780 TestLoadTimingNotReusedWithPac(load_timing_info,
2781 CONNECT_TIMING_HAS_SSL_TIMES);
2782
[email protected]0b0bf032010-09-21 18:08:502783 trans.reset();
[email protected]102e27c2011-02-23 01:01:312784 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:592785}
2786
[email protected]11203f012009-11-12 23:02:312787// Test the request-challenge-retry sequence for basic auth, over a keep-alive
ttuttle34f63b52015-03-05 04:33:012788// proxy connection with HTTP/1.0 responses, when setting up an SSL tunnel.
2789TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
2790 HttpRequestInfo request;
2791 request.method = "GET";
bncce36dca22015-04-21 22:11:232792 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:012793 // Ensure that proxy authentication is attempted even
2794 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292795 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:012796
2797 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:032798 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:512799 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:012800 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:062801 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:012802
2803 scoped_ptr<HttpTransaction> trans(
2804 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2805
2806 // Since we have proxy, should try to establish tunnel.
2807 MockWrite data_writes1[] = {
2808 MockWrite(
bncce36dca22015-04-21 22:11:232809 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2810 "Host: www.example.org\r\n"
ttuttle34f63b52015-03-05 04:33:012811 "Proxy-Connection: keep-alive\r\n\r\n"),
2812
2813 // After calling trans->RestartWithAuth(), this is the request we should
2814 // be issuing -- the final header line contains the credentials.
2815 MockWrite(
bncce36dca22015-04-21 22:11:232816 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2817 "Host: www.example.org\r\n"
ttuttle34f63b52015-03-05 04:33:012818 "Proxy-Connection: keep-alive\r\n"
2819 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
2820 };
2821
2822 // The proxy responds to the connect with a 407, using a persistent
2823 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
2824 MockRead data_reads1[] = {
2825 // No credentials.
2826 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
2827 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2828 MockRead("Proxy-Connection: keep-alive\r\n"),
2829 MockRead("Content-Length: 10\r\n\r\n"),
2830 MockRead("0123456789"),
2831
2832 // Wrong credentials (wrong password).
2833 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
2834 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2835 MockRead("Proxy-Connection: keep-alive\r\n"),
2836 MockRead("Content-Length: 10\r\n\r\n"),
2837 // No response body because the test stops reading here.
2838 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
2839 };
2840
2841 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2842 data_writes1, arraysize(data_writes1));
2843 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2844
2845 TestCompletionCallback callback1;
2846
2847 int rv = trans->Start(&request, callback1.callback(), log.bound());
2848 EXPECT_EQ(ERR_IO_PENDING, rv);
2849
2850 rv = callback1.WaitForResult();
2851 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:462852 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:012853 log.GetEntries(&entries);
2854 size_t pos = ExpectLogContainsSomewhere(
2855 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
2856 NetLog::PHASE_NONE);
2857 ExpectLogContainsSomewhere(
2858 entries, pos, NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2859 NetLog::PHASE_NONE);
2860
2861 const HttpResponseInfo* response = trans->GetResponseInfo();
2862 ASSERT_TRUE(response);
2863 ASSERT_TRUE(response->headers);
2864 EXPECT_TRUE(response->headers->IsKeepAlive());
2865 EXPECT_EQ(407, response->headers->response_code());
2866 EXPECT_EQ(10, response->headers->GetContentLength());
2867 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
2868 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2869
2870 TestCompletionCallback callback2;
2871
2872 // Wrong password (should be "bar").
2873 rv =
2874 trans->RestartWithAuth(AuthCredentials(kFoo, kBaz), callback2.callback());
2875 EXPECT_EQ(ERR_IO_PENDING, rv);
2876
2877 rv = callback2.WaitForResult();
2878 EXPECT_EQ(OK, rv);
2879
2880 response = trans->GetResponseInfo();
2881 ASSERT_TRUE(response);
2882 ASSERT_TRUE(response->headers);
2883 EXPECT_TRUE(response->headers->IsKeepAlive());
2884 EXPECT_EQ(407, response->headers->response_code());
2885 EXPECT_EQ(10, response->headers->GetContentLength());
2886 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
2887 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2888
2889 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
2890 // out of scope.
2891 session->CloseAllConnections();
2892}
2893
2894// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2895// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel.
2896TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
[email protected]cb9bf6ca2011-01-28 13:15:272897 HttpRequestInfo request;
2898 request.method = "GET";
bncce36dca22015-04-21 22:11:232899 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:272900 // Ensure that proxy authentication is attempted even
2901 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292902 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]cb9bf6ca2011-01-28 13:15:272903
[email protected]2d2697f92009-02-18 21:00:322904 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:032905 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:512906 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072907 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:062908 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:322909
[email protected]262eec82013-03-19 21:01:362910 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502911 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d2697f92009-02-18 21:00:322912
[email protected]2d2697f92009-02-18 21:00:322913 // Since we have proxy, should try to establish tunnel.
2914 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232915 MockWrite(
2916 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2917 "Host: www.example.org\r\n"
2918 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322919
bncce36dca22015-04-21 22:11:232920 // After calling trans->RestartWithAuth(), this is the request we should
2921 // be issuing -- the final header line contains the credentials.
2922 MockWrite(
2923 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2924 "Host: www.example.org\r\n"
2925 "Proxy-Connection: keep-alive\r\n"
2926 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322927 };
2928
2929 // The proxy responds to the connect with a 407, using a persistent
2930 // connection.
2931 MockRead data_reads1[] = {
2932 // No credentials.
2933 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2934 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2935 MockRead("Content-Length: 10\r\n\r\n"),
2936 MockRead("0123456789"),
2937
2938 // Wrong credentials (wrong password).
2939 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2940 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2941 MockRead("Content-Length: 10\r\n\r\n"),
2942 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:062943 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]2d2697f92009-02-18 21:00:322944 };
2945
[email protected]31a2bfe2010-02-09 08:03:392946 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2947 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072948 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d2697f92009-02-18 21:00:322949
[email protected]49639fa2011-12-20 23:22:412950 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322951
[email protected]49639fa2011-12-20 23:22:412952 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]1c773ea12009-04-28 19:58:422953 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322954
2955 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422956 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:462957 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:402958 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:392959 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402960 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]dbb83db2010-05-11 18:13:392961 NetLog::PHASE_NONE);
2962 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402963 entries, pos,
[email protected]dbb83db2010-05-11 18:13:392964 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2965 NetLog::PHASE_NONE);
[email protected]2d2697f92009-02-18 21:00:322966
[email protected]1c773ea12009-04-28 19:58:422967 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:242968 ASSERT_TRUE(response);
2969 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:322970 EXPECT_TRUE(response->headers->IsKeepAlive());
2971 EXPECT_EQ(407, response->headers->response_code());
ttuttle34f63b52015-03-05 04:33:012972 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422973 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042974 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322975
[email protected]49639fa2011-12-20 23:22:412976 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322977
2978 // Wrong password (should be "bar").
[email protected]49639fa2011-12-20 23:22:412979 rv = trans->RestartWithAuth(
2980 AuthCredentials(kFoo, kBaz), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422981 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322982
2983 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422984 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322985
2986 response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:242987 ASSERT_TRUE(response);
2988 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:322989 EXPECT_TRUE(response->headers->IsKeepAlive());
2990 EXPECT_EQ(407, response->headers->response_code());
ttuttle34f63b52015-03-05 04:33:012991 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422992 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042993 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]e772db3f2010-07-12 18:11:132994
[email protected]e60e47a2010-07-14 03:37:182995 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
2996 // out of scope.
[email protected]102e27c2011-02-23 01:01:312997 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:322998}
2999
mmenkee0b5c882015-08-26 20:29:113000// Test the case a proxy closes a socket while the challenge body is being
3001// drained.
3002TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHangupDuringBody) {
3003 HttpRequestInfo request;
3004 request.method = "GET";
3005 request.url = GURL("https://www.example.org/");
3006 // Ensure that proxy authentication is attempted even
3007 // when the no authentication data flag is set.
3008 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
3009
3010 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033011 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
mmenke6b3af6e2015-09-12 02:06:063012 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee0b5c882015-08-26 20:29:113013
3014 scoped_ptr<HttpTransaction> trans(
3015 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3016
3017 // Since we have proxy, should try to establish tunnel.
3018 MockWrite data_writes1[] = {
3019 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3020 "Host: www.example.org\r\n"
3021 "Proxy-Connection: keep-alive\r\n\r\n"),
3022 };
3023
3024 // The proxy responds to the connect with a 407, using a persistent
3025 // connection.
3026 MockRead data_reads1[] = {
3027 // No credentials.
3028 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3029 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3030 MockRead("Content-Length: 10\r\n\r\n"), MockRead("spam!"),
3031 // Server hands up in the middle of the body.
3032 MockRead(ASYNC, ERR_CONNECTION_CLOSED),
3033 };
3034
3035 MockWrite data_writes2[] = {
3036 // After calling trans->RestartWithAuth(), this is the request we should
3037 // be issuing -- the final header line contains the credentials.
3038 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3039 "Host: www.example.org\r\n"
3040 "Proxy-Connection: keep-alive\r\n"
3041 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3042
3043 MockWrite("GET / HTTP/1.1\r\n"
3044 "Host: www.example.org\r\n"
3045 "Connection: keep-alive\r\n\r\n"),
3046 };
3047
3048 MockRead data_reads2[] = {
3049 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3050
3051 MockRead("HTTP/1.1 200 OK\r\n"),
3052 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3053 MockRead("Content-Length: 5\r\n\r\n"),
3054 MockRead(SYNCHRONOUS, "hello"),
3055 };
3056
3057 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3058 data_writes1, arraysize(data_writes1));
3059 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3060 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3061 data_writes2, arraysize(data_writes2));
3062 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3063 SSLSocketDataProvider ssl(ASYNC, OK);
3064 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3065
3066 TestCompletionCallback callback;
3067
3068 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
3069 EXPECT_EQ(OK, callback.GetResult(rv));
3070
3071 const HttpResponseInfo* response = trans->GetResponseInfo();
3072 ASSERT_TRUE(response);
3073 ASSERT_TRUE(response->headers);
3074 EXPECT_TRUE(response->headers->IsKeepAlive());
3075 EXPECT_EQ(407, response->headers->response_code());
3076 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3077
3078 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
3079 EXPECT_EQ(OK, callback.GetResult(rv));
3080
3081 response = trans->GetResponseInfo();
3082 ASSERT_TRUE(response);
3083 ASSERT_TRUE(response->headers);
3084 EXPECT_TRUE(response->headers->IsKeepAlive());
3085 EXPECT_EQ(200, response->headers->response_code());
3086 std::string body;
3087 EXPECT_EQ(OK, ReadTransaction(trans.get(), &body));
3088 EXPECT_EQ("hello", body);
3089}
3090
[email protected]a8e9b162009-03-12 00:06:443091// Test that we don't read the response body when we fail to establish a tunnel,
3092// even if the user cancels the proxy's auth attempt.
[email protected]23e482282013-06-14 16:08:023093TEST_P(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:273094 HttpRequestInfo request;
3095 request.method = "GET";
bncce36dca22015-04-21 22:11:233096 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273097 request.load_flags = 0;
3098
[email protected]a8e9b162009-03-12 00:06:443099 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033100 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]a8e9b162009-03-12 00:06:443101
mmenke6b3af6e2015-09-12 02:06:063102 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:443103
[email protected]262eec82013-03-19 21:01:363104 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503105 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]a8e9b162009-03-12 00:06:443106
[email protected]a8e9b162009-03-12 00:06:443107 // Since we have proxy, should try to establish tunnel.
3108 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:233109 MockWrite(
3110 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3111 "Host: www.example.org\r\n"
3112 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:443113 };
3114
3115 // The proxy responds to the connect with a 407.
3116 MockRead data_reads[] = {
ttuttle7933c112015-01-06 00:55:243117 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3118 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3119 MockRead("Content-Length: 10\r\n\r\n"),
3120 MockRead("0123456789"), // Should not be reached.
3121 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]a8e9b162009-03-12 00:06:443122 };
3123
[email protected]31a2bfe2010-02-09 08:03:393124 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
3125 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:073126 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:443127
[email protected]49639fa2011-12-20 23:22:413128 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:443129
[email protected]49639fa2011-12-20 23:22:413130 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:423131 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a8e9b162009-03-12 00:06:443132
3133 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:423134 EXPECT_EQ(OK, rv);
[email protected]a8e9b162009-03-12 00:06:443135
[email protected]1c773ea12009-04-28 19:58:423136 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243137 ASSERT_TRUE(response);
3138 ASSERT_TRUE(response->headers);
[email protected]a8e9b162009-03-12 00:06:443139 EXPECT_TRUE(response->headers->IsKeepAlive());
3140 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423141 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:443142
3143 std::string response_data;
3144 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:423145 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]e60e47a2010-07-14 03:37:183146
3147 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:313148 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:443149}
3150
ttuttle7933c112015-01-06 00:55:243151// Test that we don't pass extraneous headers from the proxy's response to the
3152// caller when the proxy responds to CONNECT with 407.
3153TEST_P(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
3154 HttpRequestInfo request;
3155 request.method = "GET";
bncce36dca22015-04-21 22:11:233156 request.url = GURL("https://www.example.org/");
ttuttle7933c112015-01-06 00:55:243157 request.load_flags = 0;
3158
3159 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033160 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
ttuttle7933c112015-01-06 00:55:243161
mmenke6b3af6e2015-09-12 02:06:063162 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle7933c112015-01-06 00:55:243163
3164 scoped_ptr<HttpTransaction> trans(
3165 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3166
3167 // Since we have proxy, should try to establish tunnel.
3168 MockWrite data_writes[] = {
3169 MockWrite(
bncce36dca22015-04-21 22:11:233170 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3171 "Host: www.example.org\r\n"
ttuttle7933c112015-01-06 00:55:243172 "Proxy-Connection: keep-alive\r\n\r\n"),
3173 };
3174
3175 // The proxy responds to the connect with a 407.
3176 MockRead data_reads[] = {
3177 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3178 MockRead("X-Foo: bar\r\n"),
3179 MockRead("Set-Cookie: foo=bar\r\n"),
3180 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3181 MockRead("Content-Length: 10\r\n\r\n"),
3182 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
3183 };
3184
3185 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
3186 arraysize(data_writes));
3187 session_deps_.socket_factory->AddSocketDataProvider(&data);
3188
3189 TestCompletionCallback callback;
3190
3191 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
3192 EXPECT_EQ(ERR_IO_PENDING, rv);
3193
3194 rv = callback.WaitForResult();
3195 EXPECT_EQ(OK, rv);
3196
3197 const HttpResponseInfo* response = trans->GetResponseInfo();
3198 ASSERT_TRUE(response);
3199 ASSERT_TRUE(response->headers);
3200 EXPECT_TRUE(response->headers->IsKeepAlive());
3201 EXPECT_EQ(407, response->headers->response_code());
3202 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3203 EXPECT_FALSE(response->headers->HasHeader("X-Foo"));
3204 EXPECT_FALSE(response->headers->HasHeader("Set-Cookie"));
3205
3206 std::string response_data;
3207 rv = ReadTransaction(trans.get(), &response_data);
3208 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
3209
3210 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
3211 session->CloseAllConnections();
3212}
3213
[email protected]8fdbcd22010-05-05 02:54:523214// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
3215// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
[email protected]23e482282013-06-14 16:08:023216TEST_P(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:523217 HttpRequestInfo request;
3218 request.method = "GET";
bncce36dca22015-04-21 22:11:233219 request.url = GURL("http://www.example.org/");
[email protected]8fdbcd22010-05-05 02:54:523220 request.load_flags = 0;
3221
[email protected]cb9bf6ca2011-01-28 13:15:273222 // We are using a DIRECT connection (i.e. no proxy) for this session.
mmenke6b3af6e2015-09-12 02:06:063223 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273224 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:413225 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:273226
[email protected]8fdbcd22010-05-05 02:54:523227 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233228 MockWrite(
3229 "GET / HTTP/1.1\r\n"
3230 "Host: www.example.org\r\n"
3231 "Connection: keep-alive\r\n\r\n"),
[email protected]8fdbcd22010-05-05 02:54:523232 };
3233
3234 MockRead data_reads1[] = {
3235 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
3236 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3237 // Large content-length -- won't matter, as connection will be reset.
3238 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063239 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:523240 };
3241
3242 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3243 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073244 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:523245
[email protected]49639fa2011-12-20 23:22:413246 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:523247
[email protected]49639fa2011-12-20 23:22:413248 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]8fdbcd22010-05-05 02:54:523249 EXPECT_EQ(ERR_IO_PENDING, rv);
3250
3251 rv = callback.WaitForResult();
3252 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
3253}
3254
[email protected]7a67a8152010-11-05 18:31:103255// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
3256// through a non-authenticating proxy. The request should fail with
3257// ERR_UNEXPECTED_PROXY_AUTH.
3258// Note that it is impossible to detect if an HTTP server returns a 407 through
3259// a non-authenticating proxy - there is nothing to indicate whether the
3260// response came from the proxy or the server, so it is treated as if the proxy
3261// issued the challenge.
[email protected]23e482282013-06-14 16:08:023262TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:233263 HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:273264 HttpRequestInfo request;
3265 request.method = "GET";
bncce36dca22015-04-21 22:11:233266 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273267
rdsmith82957ad2015-09-16 19:42:033268 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:513269 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073270 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:063271 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:103272
[email protected]7a67a8152010-11-05 18:31:103273 // Since we have proxy, should try to establish tunnel.
3274 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233275 MockWrite(
3276 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3277 "Host: www.example.org\r\n"
3278 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103279
bncce36dca22015-04-21 22:11:233280 MockWrite(
3281 "GET / HTTP/1.1\r\n"
3282 "Host: www.example.org\r\n"
3283 "Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103284 };
3285
3286 MockRead data_reads1[] = {
3287 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3288
3289 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
3290 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3291 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:063292 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:103293 };
3294
3295 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3296 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073297 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063298 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073299 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:103300
[email protected]49639fa2011-12-20 23:22:413301 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:103302
[email protected]262eec82013-03-19 21:01:363303 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503304 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a67a8152010-11-05 18:31:103305
[email protected]49639fa2011-12-20 23:22:413306 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7a67a8152010-11-05 18:31:103307 EXPECT_EQ(ERR_IO_PENDING, rv);
3308
3309 rv = callback1.WaitForResult();
3310 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
mmenke43758e62015-05-04 21:09:463311 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403312 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:103313 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403314 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]7a67a8152010-11-05 18:31:103315 NetLog::PHASE_NONE);
3316 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403317 entries, pos,
[email protected]7a67a8152010-11-05 18:31:103318 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3319 NetLog::PHASE_NONE);
3320}
[email protected]2df19bb2010-08-25 20:13:463321
[email protected]029c83b62013-01-24 05:28:203322// Test the load timing for HTTPS requests with an HTTP proxy.
[email protected]23e482282013-06-14 16:08:023323TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:203324 HttpRequestInfo request1;
3325 request1.method = "GET";
bncce36dca22015-04-21 22:11:233326 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:203327
3328 HttpRequestInfo request2;
3329 request2.method = "GET";
bncce36dca22015-04-21 22:11:233330 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:203331
3332 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033333 session_deps_.proxy_service = ProxyService::CreateFixed("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513334 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073335 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:063336 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:203337
3338 // Since we have proxy, should try to establish tunnel.
3339 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233340 MockWrite(
3341 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3342 "Host: www.example.org\r\n"
3343 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203344
bncce36dca22015-04-21 22:11:233345 MockWrite(
3346 "GET /1 HTTP/1.1\r\n"
3347 "Host: www.example.org\r\n"
3348 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203349
bncce36dca22015-04-21 22:11:233350 MockWrite(
3351 "GET /2 HTTP/1.1\r\n"
3352 "Host: www.example.org\r\n"
3353 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203354 };
3355
3356 // The proxy responds to the connect with a 407, using a persistent
3357 // connection.
3358 MockRead data_reads1[] = {
3359 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3360
3361 MockRead("HTTP/1.1 200 OK\r\n"),
3362 MockRead("Content-Length: 1\r\n\r\n"),
3363 MockRead(SYNCHRONOUS, "1"),
3364
3365 MockRead("HTTP/1.1 200 OK\r\n"),
3366 MockRead("Content-Length: 2\r\n\r\n"),
3367 MockRead(SYNCHRONOUS, "22"),
3368 };
3369
3370 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3371 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073372 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:203373 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073374 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:203375
3376 TestCompletionCallback callback1;
[email protected]262eec82013-03-19 21:01:363377 scoped_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:503378 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:203379
3380 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
3381 EXPECT_EQ(ERR_IO_PENDING, rv);
3382
3383 rv = callback1.WaitForResult();
3384 EXPECT_EQ(OK, rv);
3385
3386 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
3387 ASSERT_TRUE(response1 != NULL);
[email protected]90499482013-06-01 00:39:503388 ASSERT_TRUE(response1->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:203389 EXPECT_EQ(1, response1->headers->GetContentLength());
3390
3391 LoadTimingInfo load_timing_info1;
3392 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
3393 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
3394
3395 trans1.reset();
3396
3397 TestCompletionCallback callback2;
[email protected]262eec82013-03-19 21:01:363398 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503399 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:203400
3401 rv = trans2->Start(&request2, callback2.callback(), log.bound());
3402 EXPECT_EQ(ERR_IO_PENDING, rv);
3403
3404 rv = callback2.WaitForResult();
3405 EXPECT_EQ(OK, rv);
3406
3407 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
3408 ASSERT_TRUE(response2 != NULL);
[email protected]90499482013-06-01 00:39:503409 ASSERT_TRUE(response2->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:203410 EXPECT_EQ(2, response2->headers->GetContentLength());
3411
3412 LoadTimingInfo load_timing_info2;
3413 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3414 TestLoadTimingReused(load_timing_info2);
3415
3416 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
3417
3418 trans2.reset();
3419 session->CloseAllConnections();
3420}
3421
3422// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
[email protected]23e482282013-06-14 16:08:023423TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:203424 HttpRequestInfo request1;
3425 request1.method = "GET";
bncce36dca22015-04-21 22:11:233426 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:203427
3428 HttpRequestInfo request2;
3429 request2.method = "GET";
bncce36dca22015-04-21 22:11:233430 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:203431
3432 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033433 session_deps_.proxy_service =
3434 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513435 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073436 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:063437 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:203438
3439 // Since we have proxy, should try to establish tunnel.
3440 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233441 MockWrite(
3442 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3443 "Host: www.example.org\r\n"
3444 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203445
bncce36dca22015-04-21 22:11:233446 MockWrite(
3447 "GET /1 HTTP/1.1\r\n"
3448 "Host: www.example.org\r\n"
3449 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203450
bncce36dca22015-04-21 22:11:233451 MockWrite(
3452 "GET /2 HTTP/1.1\r\n"
3453 "Host: www.example.org\r\n"
3454 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203455 };
3456
3457 // The proxy responds to the connect with a 407, using a persistent
3458 // connection.
3459 MockRead data_reads1[] = {
3460 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3461
3462 MockRead("HTTP/1.1 200 OK\r\n"),
3463 MockRead("Content-Length: 1\r\n\r\n"),
3464 MockRead(SYNCHRONOUS, "1"),
3465
3466 MockRead("HTTP/1.1 200 OK\r\n"),
3467 MockRead("Content-Length: 2\r\n\r\n"),
3468 MockRead(SYNCHRONOUS, "22"),
3469 };
3470
3471 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3472 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073473 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:203474 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073475 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:203476
3477 TestCompletionCallback callback1;
[email protected]262eec82013-03-19 21:01:363478 scoped_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:503479 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:203480
3481 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
3482 EXPECT_EQ(ERR_IO_PENDING, rv);
3483
3484 rv = callback1.WaitForResult();
3485 EXPECT_EQ(OK, rv);
3486
3487 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
3488 ASSERT_TRUE(response1 != NULL);
[email protected]90499482013-06-01 00:39:503489 ASSERT_TRUE(response1->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:203490 EXPECT_EQ(1, response1->headers->GetContentLength());
3491
3492 LoadTimingInfo load_timing_info1;
3493 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
3494 TestLoadTimingNotReusedWithPac(load_timing_info1,
3495 CONNECT_TIMING_HAS_SSL_TIMES);
3496
3497 trans1.reset();
3498
3499 TestCompletionCallback callback2;
[email protected]262eec82013-03-19 21:01:363500 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503501 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:203502
3503 rv = trans2->Start(&request2, callback2.callback(), log.bound());
3504 EXPECT_EQ(ERR_IO_PENDING, rv);
3505
3506 rv = callback2.WaitForResult();
3507 EXPECT_EQ(OK, rv);
3508
3509 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
3510 ASSERT_TRUE(response2 != NULL);
[email protected]90499482013-06-01 00:39:503511 ASSERT_TRUE(response2->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:203512 EXPECT_EQ(2, response2->headers->GetContentLength());
3513
3514 LoadTimingInfo load_timing_info2;
3515 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3516 TestLoadTimingReusedWithPac(load_timing_info2);
3517
3518 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
3519
3520 trans2.reset();
3521 session->CloseAllConnections();
3522}
3523
[email protected]2df19bb2010-08-25 20:13:463524// Test a simple get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023525TEST_P(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:273526 HttpRequestInfo request;
3527 request.method = "GET";
bncce36dca22015-04-21 22:11:233528 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273529
[email protected]2df19bb2010-08-25 20:13:463530 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:033531 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:513532 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073533 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:063534 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:463535
[email protected]2df19bb2010-08-25 20:13:463536 // Since we have proxy, should use full url
3537 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233538 MockWrite(
3539 "GET http://www.example.org/ HTTP/1.1\r\n"
3540 "Host: www.example.org\r\n"
3541 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:463542 };
3543
3544 MockRead data_reads1[] = {
3545 MockRead("HTTP/1.1 200 OK\r\n"),
3546 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3547 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063548 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:463549 };
3550
3551 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3552 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073553 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063554 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073555 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:463556
[email protected]49639fa2011-12-20 23:22:413557 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:463558
[email protected]262eec82013-03-19 21:01:363559 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503560 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503561
[email protected]49639fa2011-12-20 23:22:413562 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:463563 EXPECT_EQ(ERR_IO_PENDING, rv);
3564
3565 rv = callback1.WaitForResult();
3566 EXPECT_EQ(OK, rv);
3567
[email protected]58e32bb2013-01-21 18:23:253568 LoadTimingInfo load_timing_info;
3569 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3570 TestLoadTimingNotReused(load_timing_info,
3571 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3572
[email protected]2df19bb2010-08-25 20:13:463573 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503574 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:463575
3576 EXPECT_TRUE(response->headers->IsKeepAlive());
3577 EXPECT_EQ(200, response->headers->response_code());
3578 EXPECT_EQ(100, response->headers->GetContentLength());
3579 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3580
3581 // The password prompt info should not be set.
3582 EXPECT_TRUE(response->auth_challenge.get() == NULL);
3583}
3584
[email protected]7642b5ae2010-09-01 20:55:173585// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023586TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:273587 HttpRequestInfo request;
3588 request.method = "GET";
bncce36dca22015-04-21 22:11:233589 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273590 request.load_flags = 0;
3591
[email protected]7642b5ae2010-09-01 20:55:173592 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:033593 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:513594 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073595 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:063596 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:173597
bncce36dca22015-04-21 22:11:233598 // fetch http://www.example.org/ via SPDY
[email protected]cdf8f7e72013-05-23 10:56:463599 scoped_ptr<SpdyFrame> req(
3600 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
rch8e6c6c42015-05-01 14:05:133601 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]7642b5ae2010-09-01 20:55:173602
[email protected]23e482282013-06-14 16:08:023603 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3604 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:173605 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:133606 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]7642b5ae2010-09-01 20:55:173607 };
3608
rch8e6c6c42015-05-01 14:05:133609 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3610 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073611 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:173612
[email protected]8ddf8322012-02-23 18:08:063613 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023614 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073615 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:173616
[email protected]49639fa2011-12-20 23:22:413617 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:173618
[email protected]262eec82013-03-19 21:01:363619 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503620 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503621
[email protected]49639fa2011-12-20 23:22:413622 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7642b5ae2010-09-01 20:55:173623 EXPECT_EQ(ERR_IO_PENDING, rv);
3624
3625 rv = callback1.WaitForResult();
3626 EXPECT_EQ(OK, rv);
3627
[email protected]58e32bb2013-01-21 18:23:253628 LoadTimingInfo load_timing_info;
3629 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3630 TestLoadTimingNotReused(load_timing_info,
3631 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3632
[email protected]7642b5ae2010-09-01 20:55:173633 const HttpResponseInfo* response = trans->GetResponseInfo();
3634 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503635 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]7642b5ae2010-09-01 20:55:173636 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3637
3638 std::string response_data;
3639 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:233640 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:173641}
3642
[email protected]1c173852014-06-19 12:51:503643// Verifies that a session which races and wins against the owning transaction
3644// (completing prior to host resolution), doesn't fail the transaction.
3645// Regression test for crbug.com/334413.
3646TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
3647 HttpRequestInfo request;
3648 request.method = "GET";
bncce36dca22015-04-21 22:11:233649 request.url = GURL("http://www.example.org/");
[email protected]1c173852014-06-19 12:51:503650 request.load_flags = 0;
3651
3652 // Configure SPDY proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:033653 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:513654 BoundTestNetLog log;
[email protected]1c173852014-06-19 12:51:503655 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:063656 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1c173852014-06-19 12:51:503657
bncce36dca22015-04-21 22:11:233658 // Fetch http://www.example.org/ through the SPDY proxy.
[email protected]1c173852014-06-19 12:51:503659 scoped_ptr<SpdyFrame> req(
3660 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
rch8e6c6c42015-05-01 14:05:133661 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]1c173852014-06-19 12:51:503662
3663 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3664 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
3665 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:133666 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]1c173852014-06-19 12:51:503667 };
3668
rch8e6c6c42015-05-01 14:05:133669 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3670 arraysize(spdy_writes));
[email protected]1c173852014-06-19 12:51:503671 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
3672
3673 SSLSocketDataProvider ssl(ASYNC, OK);
3674 ssl.SetNextProto(GetParam());
3675 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3676
3677 TestCompletionCallback callback1;
3678
3679 scoped_ptr<HttpTransaction> trans(
3680 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3681
3682 // Stall the hostname resolution begun by the transaction.
3683 session_deps_.host_resolver->set_synchronous_mode(false);
3684 session_deps_.host_resolver->set_ondemand_mode(true);
3685
3686 int rv = trans->Start(&request, callback1.callback(), log.bound());
3687 EXPECT_EQ(ERR_IO_PENDING, rv);
3688
3689 // Race a session to the proxy, which completes first.
3690 session_deps_.host_resolver->set_ondemand_mode(false);
3691 SpdySessionKey key(
3692 HostPortPair("proxy", 70), ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
3693 base::WeakPtr<SpdySession> spdy_session =
mmenke6b3af6e2015-09-12 02:06:063694 CreateSecureSpdySession(session, key, log.bound());
[email protected]1c173852014-06-19 12:51:503695
3696 // Unstall the resolution begun by the transaction.
3697 session_deps_.host_resolver->set_ondemand_mode(true);
3698 session_deps_.host_resolver->ResolveAllPending();
3699
3700 EXPECT_FALSE(callback1.have_result());
3701 rv = callback1.WaitForResult();
3702 EXPECT_EQ(OK, rv);
3703
3704 const HttpResponseInfo* response = trans->GetResponseInfo();
3705 ASSERT_TRUE(response != NULL);
3706 ASSERT_TRUE(response->headers.get() != NULL);
3707 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3708
3709 std::string response_data;
3710 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
3711 EXPECT_EQ(kUploadData, response_data);
3712}
3713
[email protected]dc7bd1c52010-11-12 00:01:133714// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023715TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:273716 HttpRequestInfo request;
3717 request.method = "GET";
bncce36dca22015-04-21 22:11:233718 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273719 request.load_flags = 0;
3720
[email protected]79cb5c12011-09-12 13:12:043721 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033722 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:513723 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073724 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:063725 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:133726
[email protected]dc7bd1c52010-11-12 00:01:133727 // The first request will be a bare GET, the second request will be a
3728 // GET with a Proxy-Authorization header.
[email protected]ff98d7f02012-03-22 21:44:193729 scoped_ptr<SpdyFrame> req_get(
[email protected]cdf8f7e72013-05-23 10:56:463730 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]dc7bd1c52010-11-12 00:01:133731 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:463732 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:133733 };
[email protected]ff98d7f02012-03-22 21:44:193734 scoped_ptr<SpdyFrame> req_get_authorization(
[email protected]cdf8f7e72013-05-23 10:56:463735 spdy_util_.ConstructSpdyGet(kExtraAuthorizationHeaders,
3736 arraysize(kExtraAuthorizationHeaders) / 2,
3737 false,
3738 3,
3739 LOWEST,
3740 false));
[email protected]dc7bd1c52010-11-12 00:01:133741 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:133742 CreateMockWrite(*req_get, 0), CreateMockWrite(*req_get_authorization, 3),
[email protected]dc7bd1c52010-11-12 00:01:133743 };
3744
3745 // The first response is a 407 proxy authentication challenge, and the second
3746 // response will be a 200 response since the second request includes a valid
3747 // Authorization header.
3748 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:463749 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:133750 };
[email protected]ff98d7f02012-03-22 21:44:193751 scoped_ptr<SpdyFrame> resp_authentication(
[email protected]23e482282013-06-14 16:08:023752 spdy_util_.ConstructSpdySynReplyError(
[email protected]dc7bd1c52010-11-12 00:01:133753 "407 Proxy Authentication Required",
3754 kExtraAuthenticationHeaders, arraysize(kExtraAuthenticationHeaders)/2,
3755 1));
[email protected]ff98d7f02012-03-22 21:44:193756 scoped_ptr<SpdyFrame> body_authentication(
[email protected]23e482282013-06-14 16:08:023757 spdy_util_.ConstructSpdyBodyFrame(1, true));
3758 scoped_ptr<SpdyFrame> resp_data(
3759 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
3760 scoped_ptr<SpdyFrame> body_data(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:133761 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:133762 CreateMockRead(*resp_authentication, 1),
3763 CreateMockRead(*body_authentication, 2),
3764 CreateMockRead(*resp_data, 4),
3765 CreateMockRead(*body_data, 5),
3766 MockRead(ASYNC, 0, 6),
[email protected]dc7bd1c52010-11-12 00:01:133767 };
3768
rch8e6c6c42015-05-01 14:05:133769 SequencedSocketData data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3770 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073771 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:133772
[email protected]8ddf8322012-02-23 18:08:063773 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023774 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073775 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:133776
[email protected]49639fa2011-12-20 23:22:413777 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:133778
[email protected]262eec82013-03-19 21:01:363779 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503780 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]dc7bd1c52010-11-12 00:01:133781
[email protected]49639fa2011-12-20 23:22:413782 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]dc7bd1c52010-11-12 00:01:133783 EXPECT_EQ(ERR_IO_PENDING, rv);
3784
3785 rv = callback1.WaitForResult();
3786 EXPECT_EQ(OK, rv);
3787
3788 const HttpResponseInfo* const response = trans->GetResponseInfo();
3789
3790 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503791 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]dc7bd1c52010-11-12 00:01:133792 EXPECT_EQ(407, response->headers->response_code());
3793 EXPECT_TRUE(response->was_fetched_via_spdy);
[email protected]79cb5c12011-09-12 13:12:043794 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:133795
[email protected]49639fa2011-12-20 23:22:413796 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:133797
[email protected]49639fa2011-12-20 23:22:413798 rv = trans->RestartWithAuth(
3799 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]dc7bd1c52010-11-12 00:01:133800 EXPECT_EQ(ERR_IO_PENDING, rv);
3801
3802 rv = callback2.WaitForResult();
3803 EXPECT_EQ(OK, rv);
3804
3805 const HttpResponseInfo* const response_restart = trans->GetResponseInfo();
3806
3807 ASSERT_TRUE(response_restart != NULL);
[email protected]90499482013-06-01 00:39:503808 ASSERT_TRUE(response_restart->headers.get() != NULL);
[email protected]dc7bd1c52010-11-12 00:01:133809 EXPECT_EQ(200, response_restart->headers->response_code());
3810 // The password prompt info should not be set.
3811 EXPECT_TRUE(response_restart->auth_challenge.get() == NULL);
3812}
3813
[email protected]d9da5fe2010-10-13 22:37:163814// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
[email protected]23e482282013-06-14 16:08:023815TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:273816 HttpRequestInfo request;
3817 request.method = "GET";
bncce36dca22015-04-21 22:11:233818 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273819 request.load_flags = 0;
3820
[email protected]d9da5fe2010-10-13 22:37:163821 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:033822 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:513823 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073824 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:063825 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:163826
[email protected]262eec82013-03-19 21:01:363827 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503828 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:163829
bncce36dca22015-04-21 22:11:233830 // CONNECT to www.example.org:443 via SPDY
lgarrona91df87f2014-12-05 00:51:343831 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:233832 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
3833 // fetch https://www.example.org/ via HTTP
[email protected]d9da5fe2010-10-13 22:37:163834
bncce36dca22015-04-21 22:11:233835 const char get[] =
3836 "GET / HTTP/1.1\r\n"
3837 "Host: www.example.org\r\n"
3838 "Connection: keep-alive\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:193839 scoped_ptr<SpdyFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:023840 spdy_util_.ConstructSpdyBodyFrame(1, get, strlen(get), false));
3841 scoped_ptr<SpdyFrame> conn_resp(
3842 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:163843 const char resp[] = "HTTP/1.1 200 OK\r\n"
3844 "Content-Length: 10\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:193845 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:023846 spdy_util_.ConstructSpdyBodyFrame(1, resp, strlen(resp), false));
[email protected]ff98d7f02012-03-22 21:44:193847 scoped_ptr<SpdyFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:023848 spdy_util_.ConstructSpdyBodyFrame(1, "1234567890", 10, false));
[email protected]ff98d7f02012-03-22 21:44:193849 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203850 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
[email protected]8d2f7012012-02-16 00:08:043851
3852 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:133853 CreateMockWrite(*connect, 0),
3854 CreateMockWrite(*wrapped_get, 2),
3855 CreateMockWrite(*window_update, 6),
[email protected]8d2f7012012-02-16 00:08:043856 };
3857
[email protected]d9da5fe2010-10-13 22:37:163858 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:133859 CreateMockRead(*conn_resp, 1, ASYNC),
3860 CreateMockRead(*wrapped_get_resp, 3, ASYNC),
3861 CreateMockRead(*wrapped_body, 4, ASYNC),
3862 CreateMockRead(*wrapped_body, 5, ASYNC),
3863 MockRead(ASYNC, 0, 7),
[email protected]d9da5fe2010-10-13 22:37:163864 };
3865
rch8e6c6c42015-05-01 14:05:133866 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3867 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073868 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163869
[email protected]8ddf8322012-02-23 18:08:063870 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023871 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073872 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063873 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073874 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163875
[email protected]49639fa2011-12-20 23:22:413876 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163877
[email protected]49639fa2011-12-20 23:22:413878 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163879 EXPECT_EQ(ERR_IO_PENDING, rv);
3880
3881 rv = callback1.WaitForResult();
rch8e6c6c42015-05-01 14:05:133882 ASSERT_EQ(OK, rv);
[email protected]d9da5fe2010-10-13 22:37:163883
[email protected]58e32bb2013-01-21 18:23:253884 LoadTimingInfo load_timing_info;
3885 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3886 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3887
[email protected]d9da5fe2010-10-13 22:37:163888 const HttpResponseInfo* response = trans->GetResponseInfo();
3889 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503890 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d9da5fe2010-10-13 22:37:163891 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3892
3893 std::string response_data;
3894 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
3895 EXPECT_EQ("1234567890", response_data);
3896}
3897
3898// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
[email protected]23e482282013-06-14 16:08:023899TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
[email protected]cb9bf6ca2011-01-28 13:15:273900 HttpRequestInfo request;
3901 request.method = "GET";
bncce36dca22015-04-21 22:11:233902 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273903 request.load_flags = 0;
3904
[email protected]d9da5fe2010-10-13 22:37:163905 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:033906 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:513907 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073908 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:063909 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:163910
[email protected]262eec82013-03-19 21:01:363911 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503912 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:163913
bncce36dca22015-04-21 22:11:233914 // CONNECT to www.example.org:443 via SPDY
lgarrona91df87f2014-12-05 00:51:343915 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:233916 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
3917 // fetch https://www.example.org/ via SPDY
3918 const char kMyUrl[] = "https://www.example.org/";
[email protected]cdf8f7e72013-05-23 10:56:463919 scoped_ptr<SpdyFrame> get(
3920 spdy_util_.ConstructSpdyGet(kMyUrl, false, 1, LOWEST));
[email protected]23e482282013-06-14 16:08:023921 scoped_ptr<SpdyFrame> wrapped_get(
3922 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
3923 scoped_ptr<SpdyFrame> conn_resp(
3924 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3925 scoped_ptr<SpdyFrame> get_resp(
3926 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]ff98d7f02012-03-22 21:44:193927 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:023928 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
3929 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
3930 scoped_ptr<SpdyFrame> wrapped_body(
3931 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
[email protected]ff98d7f02012-03-22 21:44:193932 scoped_ptr<SpdyFrame> window_update_get_resp(
[email protected]c10b20852013-05-15 21:29:203933 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
[email protected]ff98d7f02012-03-22 21:44:193934 scoped_ptr<SpdyFrame> window_update_body(
[email protected]c10b20852013-05-15 21:29:203935 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body->size()));
[email protected]8d2f7012012-02-16 00:08:043936
3937 MockWrite spdy_writes[] = {
rch32320842015-05-16 15:57:093938 CreateMockWrite(*connect, 0),
3939 CreateMockWrite(*wrapped_get, 2),
3940 CreateMockWrite(*window_update_get_resp, 6),
[email protected]8d2f7012012-02-16 00:08:043941 CreateMockWrite(*window_update_body, 7),
3942 };
3943
[email protected]d9da5fe2010-10-13 22:37:163944 MockRead spdy_reads[] = {
rch32320842015-05-16 15:57:093945 CreateMockRead(*conn_resp, 1, ASYNC),
3946 MockRead(ASYNC, ERR_IO_PENDING, 3),
rch8e6c6c42015-05-01 14:05:133947 CreateMockRead(*wrapped_get_resp, 4, ASYNC),
rch32320842015-05-16 15:57:093948 CreateMockRead(*wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:133949 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:163950 };
3951
rch32320842015-05-16 15:57:093952 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3953 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073954 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163955
[email protected]8ddf8322012-02-23 18:08:063956 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023957 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073958 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063959 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023960 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073961 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163962
[email protected]49639fa2011-12-20 23:22:413963 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163964
[email protected]49639fa2011-12-20 23:22:413965 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163966 EXPECT_EQ(ERR_IO_PENDING, rv);
3967
rch32320842015-05-16 15:57:093968 // Allow the SpdyProxyClientSocket's write callback to complete.
3969 base::MessageLoop::current()->RunUntilIdle();
3970 // Now allow the read of the response to complete.
3971 spdy_data.CompleteRead();
[email protected]d9da5fe2010-10-13 22:37:163972 rv = callback1.WaitForResult();
3973 EXPECT_EQ(OK, rv);
3974
[email protected]58e32bb2013-01-21 18:23:253975 LoadTimingInfo load_timing_info;
3976 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3977 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3978
[email protected]d9da5fe2010-10-13 22:37:163979 const HttpResponseInfo* response = trans->GetResponseInfo();
3980 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503981 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d9da5fe2010-10-13 22:37:163982 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3983
3984 std::string response_data;
3985 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:233986 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:163987}
3988
3989// Test a SPDY CONNECT failure through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023990TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:273991 HttpRequestInfo request;
3992 request.method = "GET";
bncce36dca22015-04-21 22:11:233993 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273994 request.load_flags = 0;
3995
[email protected]d9da5fe2010-10-13 22:37:163996 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:033997 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:513998 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073999 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:064000 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:164001
[email protected]262eec82013-03-19 21:01:364002 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504003 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:164004
bncce36dca22015-04-21 22:11:234005 // CONNECT to www.example.org:443 via SPDY
lgarrona91df87f2014-12-05 00:51:344006 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234007 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]c10b20852013-05-15 21:29:204008 scoped_ptr<SpdyFrame> get(
4009 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:164010
4011 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:134012 CreateMockWrite(*connect, 0), CreateMockWrite(*get, 2),
[email protected]d9da5fe2010-10-13 22:37:164013 };
4014
[email protected]23e482282013-06-14 16:08:024015 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdySynReplyError(1));
4016 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:164017 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:134018 CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 3),
[email protected]d9da5fe2010-10-13 22:37:164019 };
4020
rch8e6c6c42015-05-01 14:05:134021 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4022 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074023 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:164024
[email protected]8ddf8322012-02-23 18:08:064025 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:024026 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:074027 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:064028 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:024029 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:074030 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:164031
[email protected]49639fa2011-12-20 23:22:414032 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:164033
[email protected]49639fa2011-12-20 23:22:414034 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:164035 EXPECT_EQ(ERR_IO_PENDING, rv);
4036
4037 rv = callback1.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:174038 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]d9da5fe2010-10-13 22:37:164039
[email protected]4eddbc732012-08-09 05:40:174040 // TODO(ttuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:164041}
4042
[email protected]f6c63db52013-02-02 00:35:224043// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
4044// HTTPS Proxy to different servers.
[email protected]23e482282013-06-14 16:08:024045TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:224046 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
4047 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034048 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514049 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074050 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:064051 scoped_refptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:504052 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:224053
4054 HttpRequestInfo request1;
4055 request1.method = "GET";
bncce36dca22015-04-21 22:11:234056 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:224057 request1.load_flags = 0;
4058
4059 HttpRequestInfo request2;
4060 request2.method = "GET";
bncce36dca22015-04-21 22:11:234061 request2.url = GURL("https://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:224062 request2.load_flags = 0;
4063
bncce36dca22015-04-21 22:11:234064 // CONNECT to www.example.org:443 via SPDY.
lgarrona91df87f2014-12-05 00:51:344065 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234066 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]23e482282013-06-14 16:08:024067 scoped_ptr<SpdyFrame> conn_resp1(
4068 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:224069
bncce36dca22015-04-21 22:11:234070 // Fetch https://www.example.org/ via HTTP.
4071 const char get1[] =
4072 "GET / HTTP/1.1\r\n"
4073 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:224074 "Connection: keep-alive\r\n\r\n";
4075 scoped_ptr<SpdyFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:024076 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:224077 const char resp1[] = "HTTP/1.1 200 OK\r\n"
4078 "Content-Length: 1\r\n\r\n";
4079 scoped_ptr<SpdyFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:024080 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
4081 scoped_ptr<SpdyFrame> wrapped_body1(
4082 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
[email protected]f6c63db52013-02-02 00:35:224083 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:204084 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:224085
bncce36dca22015-04-21 22:11:234086 // CONNECT to mail.example.org:443 via SPDY.
[email protected]745aa9c2014-06-27 02:21:294087 SpdyHeaderBlock connect2_block;
bnc7ecc1122015-09-28 13:22:494088 spdy_util_.MaybeAddVersionHeader(&connect2_block);
[email protected]745aa9c2014-06-27 02:21:294089 connect2_block[spdy_util_.GetMethodKey()] = "CONNECT";
bnc9b79a572015-09-02 12:25:034090 if (GetParam() == kProtoHTTP2) {
bnc6b996d532015-07-29 10:51:324091 connect2_block[spdy_util_.GetHostKey()] = "mail.example.org:443";
4092 } else {
bnc6b996d532015-07-29 10:51:324093 connect2_block[spdy_util_.GetHostKey()] = "mail.example.org";
bnc7ecc1122015-09-28 13:22:494094 connect2_block[spdy_util_.GetPathKey()] = "mail.example.org:443";
bnc6b996d532015-07-29 10:51:324095 }
[email protected]f6c63db52013-02-02 00:35:224096 scoped_ptr<SpdyFrame> connect2(
[email protected]745aa9c2014-06-27 02:21:294097 spdy_util_.ConstructSpdySyn(3, connect2_block, LOWEST, false, false));
[email protected]601e03f12014-04-06 16:26:394098
[email protected]23e482282013-06-14 16:08:024099 scoped_ptr<SpdyFrame> conn_resp2(
4100 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:224101
bncce36dca22015-04-21 22:11:234102 // Fetch https://mail.example.org/ via HTTP.
4103 const char get2[] =
4104 "GET / HTTP/1.1\r\n"
4105 "Host: mail.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:224106 "Connection: keep-alive\r\n\r\n";
4107 scoped_ptr<SpdyFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:024108 spdy_util_.ConstructSpdyBodyFrame(3, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:224109 const char resp2[] = "HTTP/1.1 200 OK\r\n"
4110 "Content-Length: 2\r\n\r\n";
4111 scoped_ptr<SpdyFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:024112 spdy_util_.ConstructSpdyBodyFrame(3, resp2, strlen(resp2), false));
[email protected]f6c63db52013-02-02 00:35:224113 scoped_ptr<SpdyFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:024114 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:224115
4116 MockWrite spdy_writes[] = {
4117 CreateMockWrite(*connect1, 0),
4118 CreateMockWrite(*wrapped_get1, 2),
4119 CreateMockWrite(*connect2, 5),
4120 CreateMockWrite(*wrapped_get2, 7),
4121 };
4122
4123 MockRead spdy_reads[] = {
4124 CreateMockRead(*conn_resp1, 1, ASYNC),
4125 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
4126 CreateMockRead(*wrapped_body1, 4, ASYNC),
4127 CreateMockRead(*conn_resp2, 6, ASYNC),
4128 CreateMockRead(*wrapped_get_resp2, 8, ASYNC),
4129 CreateMockRead(*wrapped_body2, 9, ASYNC),
4130 MockRead(ASYNC, 0, 10),
4131 };
4132
mmenke11eb5152015-06-09 14:50:504133 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4134 arraysize(spdy_writes));
4135 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:224136
4137 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:024138 ssl.SetNextProto(GetParam());
mmenke11eb5152015-06-09 14:50:504139 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:224140 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:504141 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:224142 SSLSocketDataProvider ssl3(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:504143 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:224144
4145 TestCompletionCallback callback;
4146
[email protected]262eec82013-03-19 21:01:364147 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504148 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224149 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:504150 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224151
4152 LoadTimingInfo load_timing_info;
4153 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4154 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
4155
4156 const HttpResponseInfo* response = trans->GetResponseInfo();
4157 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504158 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:224159 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4160
4161 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:294162 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
mmenke11eb5152015-06-09 14:50:504163 rv = trans->Read(buf.get(), 256, callback.callback());
4164 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224165
[email protected]262eec82013-03-19 21:01:364166 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:504167 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224168 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:504169 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224170
4171 LoadTimingInfo load_timing_info2;
4172 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4173 // Even though the SPDY connection is reused, a new tunnelled connection has
4174 // to be created, so the socket's load timing looks like a fresh connection.
4175 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
4176
4177 // The requests should have different IDs, since they each are using their own
4178 // separate stream.
4179 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
4180
mmenke11eb5152015-06-09 14:50:504181 rv = trans2->Read(buf.get(), 256, callback.callback());
4182 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224183}
4184
4185// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
4186// HTTPS Proxy to the same server.
[email protected]23e482282013-06-14 16:08:024187TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:224188 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
4189 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034190 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514191 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074192 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:064193 scoped_refptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:504194 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:224195
4196 HttpRequestInfo request1;
4197 request1.method = "GET";
bncce36dca22015-04-21 22:11:234198 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:224199 request1.load_flags = 0;
4200
4201 HttpRequestInfo request2;
4202 request2.method = "GET";
bncce36dca22015-04-21 22:11:234203 request2.url = GURL("https://www.example.org/2");
[email protected]f6c63db52013-02-02 00:35:224204 request2.load_flags = 0;
4205
bncce36dca22015-04-21 22:11:234206 // CONNECT to www.example.org:443 via SPDY.
lgarrona91df87f2014-12-05 00:51:344207 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234208 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]23e482282013-06-14 16:08:024209 scoped_ptr<SpdyFrame> conn_resp1(
4210 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:224211
bncce36dca22015-04-21 22:11:234212 // Fetch https://www.example.org/ via HTTP.
4213 const char get1[] =
4214 "GET / HTTP/1.1\r\n"
4215 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:224216 "Connection: keep-alive\r\n\r\n";
4217 scoped_ptr<SpdyFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:024218 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:224219 const char resp1[] = "HTTP/1.1 200 OK\r\n"
4220 "Content-Length: 1\r\n\r\n";
4221 scoped_ptr<SpdyFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:024222 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
4223 scoped_ptr<SpdyFrame> wrapped_body1(
4224 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
[email protected]f6c63db52013-02-02 00:35:224225 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:204226 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:224227
bncce36dca22015-04-21 22:11:234228 // Fetch https://www.example.org/2 via HTTP.
4229 const char get2[] =
4230 "GET /2 HTTP/1.1\r\n"
4231 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:224232 "Connection: keep-alive\r\n\r\n";
4233 scoped_ptr<SpdyFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:024234 spdy_util_.ConstructSpdyBodyFrame(1, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:224235 const char resp2[] = "HTTP/1.1 200 OK\r\n"
4236 "Content-Length: 2\r\n\r\n";
4237 scoped_ptr<SpdyFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:024238 spdy_util_.ConstructSpdyBodyFrame(1, resp2, strlen(resp2), false));
[email protected]f6c63db52013-02-02 00:35:224239 scoped_ptr<SpdyFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:024240 spdy_util_.ConstructSpdyBodyFrame(1, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:224241
4242 MockWrite spdy_writes[] = {
4243 CreateMockWrite(*connect1, 0),
4244 CreateMockWrite(*wrapped_get1, 2),
4245 CreateMockWrite(*wrapped_get2, 5),
4246 };
4247
4248 MockRead spdy_reads[] = {
4249 CreateMockRead(*conn_resp1, 1, ASYNC),
4250 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
4251 CreateMockRead(*wrapped_body1, 4, ASYNC),
4252 CreateMockRead(*wrapped_get_resp2, 6, ASYNC),
4253 CreateMockRead(*wrapped_body2, 7, ASYNC),
4254 MockRead(ASYNC, 0, 8),
4255 };
4256
mmenke11eb5152015-06-09 14:50:504257 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4258 arraysize(spdy_writes));
4259 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:224260
4261 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:024262 ssl.SetNextProto(GetParam());
mmenke11eb5152015-06-09 14:50:504263 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:224264 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:504265 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:224266
4267 TestCompletionCallback callback;
4268
[email protected]262eec82013-03-19 21:01:364269 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504270 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224271 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
4272 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f6c63db52013-02-02 00:35:224273
4274 rv = callback.WaitForResult();
4275 EXPECT_EQ(OK, rv);
4276
4277 LoadTimingInfo load_timing_info;
4278 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4279 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
4280
4281 const HttpResponseInfo* response = trans->GetResponseInfo();
4282 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504283 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:224284 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4285
4286 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:294287 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]90499482013-06-01 00:39:504288 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:224289 trans.reset();
4290
[email protected]262eec82013-03-19 21:01:364291 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:504292 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224293 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
4294 EXPECT_EQ(ERR_IO_PENDING, rv);
4295
[email protected]f6c63db52013-02-02 00:35:224296 rv = callback.WaitForResult();
4297 EXPECT_EQ(OK, rv);
4298
4299 LoadTimingInfo load_timing_info2;
4300 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4301 TestLoadTimingReused(load_timing_info2);
4302
4303 // The requests should have the same ID.
4304 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
4305
[email protected]90499482013-06-01 00:39:504306 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:224307}
4308
4309// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
4310// Proxy to different servers.
mmenke11eb5152015-06-09 14:50:504311TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) {
[email protected]f6c63db52013-02-02 00:35:224312 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034313 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514314 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074315 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:064316 scoped_refptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:504317 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:224318
4319 HttpRequestInfo request1;
4320 request1.method = "GET";
bncce36dca22015-04-21 22:11:234321 request1.url = GURL("http://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:224322 request1.load_flags = 0;
4323
4324 HttpRequestInfo request2;
4325 request2.method = "GET";
bncce36dca22015-04-21 22:11:234326 request2.url = GURL("http://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:224327 request2.load_flags = 0;
4328
bncce36dca22015-04-21 22:11:234329 // http://www.example.org/
[email protected]23e482282013-06-14 16:08:024330 scoped_ptr<SpdyHeaderBlock> headers(
bncce36dca22015-04-21 22:11:234331 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
[email protected]745aa9c2014-06-27 02:21:294332 scoped_ptr<SpdyFrame> get1(
4333 spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, false, true));
[email protected]23e482282013-06-14 16:08:024334 scoped_ptr<SpdyFrame> get_resp1(
4335 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
4336 scoped_ptr<SpdyFrame> body1(
4337 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, true));
[email protected]f6c63db52013-02-02 00:35:224338
bncce36dca22015-04-21 22:11:234339 // http://mail.example.org/
[email protected]23e482282013-06-14 16:08:024340 scoped_ptr<SpdyHeaderBlock> headers2(
bncce36dca22015-04-21 22:11:234341 spdy_util_.ConstructGetHeaderBlockForProxy("http://mail.example.org/"));
[email protected]745aa9c2014-06-27 02:21:294342 scoped_ptr<SpdyFrame> get2(
4343 spdy_util_.ConstructSpdySyn(3, *headers2, LOWEST, false, true));
[email protected]23e482282013-06-14 16:08:024344 scoped_ptr<SpdyFrame> get_resp2(
4345 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
4346 scoped_ptr<SpdyFrame> body2(
4347 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, true));
[email protected]f6c63db52013-02-02 00:35:224348
4349 MockWrite spdy_writes[] = {
4350 CreateMockWrite(*get1, 0),
4351 CreateMockWrite(*get2, 3),
4352 };
4353
4354 MockRead spdy_reads[] = {
4355 CreateMockRead(*get_resp1, 1, ASYNC),
4356 CreateMockRead(*body1, 2, ASYNC),
4357 CreateMockRead(*get_resp2, 4, ASYNC),
4358 CreateMockRead(*body2, 5, ASYNC),
4359 MockRead(ASYNC, 0, 6),
4360 };
4361
mmenke11eb5152015-06-09 14:50:504362 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4363 arraysize(spdy_writes));
4364 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:224365
4366 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:024367 ssl.SetNextProto(GetParam());
mmenke11eb5152015-06-09 14:50:504368 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:224369
4370 TestCompletionCallback callback;
4371
[email protected]262eec82013-03-19 21:01:364372 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504373 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224374 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:504375 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224376
4377 LoadTimingInfo load_timing_info;
4378 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4379 TestLoadTimingNotReused(load_timing_info,
4380 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4381
4382 const HttpResponseInfo* response = trans->GetResponseInfo();
4383 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504384 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:224385 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4386
4387 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:294388 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
mmenke11eb5152015-06-09 14:50:504389 rv = trans->Read(buf.get(), 256, callback.callback());
4390 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224391 // Delete the first request, so the second one can reuse the socket.
4392 trans.reset();
4393
[email protected]262eec82013-03-19 21:01:364394 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:504395 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224396 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:504397 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224398
4399 LoadTimingInfo load_timing_info2;
4400 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4401 TestLoadTimingReused(load_timing_info2);
4402
4403 // The requests should have the same ID.
4404 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
4405
mmenke11eb5152015-06-09 14:50:504406 rv = trans2->Read(buf.get(), 256, callback.callback());
4407 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224408}
4409
[email protected]2df19bb2010-08-25 20:13:464410// Test the challenge-response-retry sequence through an HTTPS Proxy
[email protected]23e482282013-06-14 16:08:024411TEST_P(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:464412 HttpRequestInfo request;
4413 request.method = "GET";
bncce36dca22015-04-21 22:11:234414 request.url = GURL("http://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:464415 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:294416 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]2df19bb2010-08-25 20:13:464417
[email protected]79cb5c12011-09-12 13:12:044418 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:034419 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:514420 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074421 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:064422 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274423
[email protected]2df19bb2010-08-25 20:13:464424 // Since we have proxy, should use full url
4425 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:234426 MockWrite(
4427 "GET http://www.example.org/ HTTP/1.1\r\n"
4428 "Host: www.example.org\r\n"
4429 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:464430
bncce36dca22015-04-21 22:11:234431 // After calling trans->RestartWithAuth(), this is the request we should
4432 // be issuing -- the final header line contains the credentials.
4433 MockWrite(
4434 "GET http://www.example.org/ HTTP/1.1\r\n"
4435 "Host: www.example.org\r\n"
4436 "Proxy-Connection: keep-alive\r\n"
4437 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:464438 };
4439
4440 // The proxy responds to the GET with a 407, using a persistent
4441 // connection.
4442 MockRead data_reads1[] = {
4443 // No credentials.
4444 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4445 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4446 MockRead("Proxy-Connection: keep-alive\r\n"),
4447 MockRead("Content-Length: 0\r\n\r\n"),
4448
4449 MockRead("HTTP/1.1 200 OK\r\n"),
4450 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4451 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064452 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:464453 };
4454
4455 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4456 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074457 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:064458 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074459 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:464460
[email protected]49639fa2011-12-20 23:22:414461 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:464462
[email protected]262eec82013-03-19 21:01:364463 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504464 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504465
[email protected]49639fa2011-12-20 23:22:414466 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:464467 EXPECT_EQ(ERR_IO_PENDING, rv);
4468
4469 rv = callback1.WaitForResult();
4470 EXPECT_EQ(OK, rv);
4471
[email protected]58e32bb2013-01-21 18:23:254472 LoadTimingInfo load_timing_info;
4473 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4474 TestLoadTimingNotReused(load_timing_info,
4475 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4476
[email protected]2df19bb2010-08-25 20:13:464477 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504478 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504479 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]2df19bb2010-08-25 20:13:464480 EXPECT_EQ(407, response->headers->response_code());
4481 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:044482 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:464483
[email protected]49639fa2011-12-20 23:22:414484 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:464485
[email protected]49639fa2011-12-20 23:22:414486 rv = trans->RestartWithAuth(
4487 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]2df19bb2010-08-25 20:13:464488 EXPECT_EQ(ERR_IO_PENDING, rv);
4489
4490 rv = callback2.WaitForResult();
4491 EXPECT_EQ(OK, rv);
4492
[email protected]58e32bb2013-01-21 18:23:254493 load_timing_info = LoadTimingInfo();
4494 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4495 // Retrying with HTTP AUTH is considered to be reusing a socket.
4496 TestLoadTimingReused(load_timing_info);
4497
[email protected]2df19bb2010-08-25 20:13:464498 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504499 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:464500
4501 EXPECT_TRUE(response->headers->IsKeepAlive());
4502 EXPECT_EQ(200, response->headers->response_code());
4503 EXPECT_EQ(100, response->headers->GetContentLength());
4504 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4505
4506 // The password prompt info should not be set.
4507 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4508}
4509
[email protected]23e482282013-06-14 16:08:024510void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:084511 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:424512 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:084513 request.method = "GET";
bncce36dca22015-04-21 22:11:234514 request.url = GURL("https://www.example.org/");
[email protected]c744cf22009-02-27 07:28:084515 request.load_flags = 0;
4516
[email protected]cb9bf6ca2011-01-28 13:15:274517 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:034518 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
mmenke6b3af6e2015-09-12 02:06:064519 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274520
[email protected]c744cf22009-02-27 07:28:084521 // Since we have proxy, should try to establish tunnel.
4522 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:234523 MockWrite(
4524 "CONNECT www.example.org:443 HTTP/1.1\r\n"
4525 "Host: www.example.org\r\n"
4526 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:084527 };
4528
4529 MockRead data_reads[] = {
4530 status,
4531 MockRead("Content-Length: 10\r\n\r\n"),
4532 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:064533 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]c744cf22009-02-27 07:28:084534 };
4535
[email protected]31a2bfe2010-02-09 08:03:394536 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
4537 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:074538 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:084539
[email protected]49639fa2011-12-20 23:22:414540 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:084541
[email protected]262eec82013-03-19 21:01:364542 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504543 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504544
[email protected]49639fa2011-12-20 23:22:414545 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424546 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]c744cf22009-02-27 07:28:084547
4548 rv = callback.WaitForResult();
4549 EXPECT_EQ(expected_status, rv);
4550}
4551
[email protected]23e482282013-06-14 16:08:024552void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:234553 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:084554 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:424555 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:084556}
4557
[email protected]23e482282013-06-14 16:08:024558TEST_P(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:084559 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
4560}
4561
[email protected]23e482282013-06-14 16:08:024562TEST_P(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:084563 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
4564}
4565
[email protected]23e482282013-06-14 16:08:024566TEST_P(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:084567 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
4568}
4569
[email protected]23e482282013-06-14 16:08:024570TEST_P(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:084571 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
4572}
4573
[email protected]23e482282013-06-14 16:08:024574TEST_P(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:084575 ConnectStatusHelper(
4576 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
4577}
4578
[email protected]23e482282013-06-14 16:08:024579TEST_P(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:084580 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
4581}
4582
[email protected]23e482282013-06-14 16:08:024583TEST_P(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:084584 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
4585}
4586
[email protected]23e482282013-06-14 16:08:024587TEST_P(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:084588 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
4589}
4590
[email protected]23e482282013-06-14 16:08:024591TEST_P(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:084592 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
4593}
4594
[email protected]23e482282013-06-14 16:08:024595TEST_P(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:084596 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
4597}
4598
[email protected]23e482282013-06-14 16:08:024599TEST_P(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:084600 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
4601}
4602
[email protected]23e482282013-06-14 16:08:024603TEST_P(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:084604 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
4605}
4606
[email protected]23e482282013-06-14 16:08:024607TEST_P(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:084608 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
4609}
4610
[email protected]23e482282013-06-14 16:08:024611TEST_P(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:084612 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
4613}
4614
[email protected]23e482282013-06-14 16:08:024615TEST_P(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:084616 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
4617}
4618
[email protected]23e482282013-06-14 16:08:024619TEST_P(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:084620 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
4621}
4622
[email protected]0a17aab32014-04-24 03:32:374623TEST_P(HttpNetworkTransactionTest, ConnectStatus308) {
4624 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
4625}
4626
[email protected]23e482282013-06-14 16:08:024627TEST_P(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:084628 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
4629}
4630
[email protected]23e482282013-06-14 16:08:024631TEST_P(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:084632 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
4633}
4634
[email protected]23e482282013-06-14 16:08:024635TEST_P(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:084636 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
4637}
4638
[email protected]23e482282013-06-14 16:08:024639TEST_P(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:084640 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
4641}
4642
[email protected]23e482282013-06-14 16:08:024643TEST_P(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:084644 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
4645}
4646
[email protected]23e482282013-06-14 16:08:024647TEST_P(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:084648 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
4649}
4650
[email protected]23e482282013-06-14 16:08:024651TEST_P(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:084652 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
4653}
4654
[email protected]23e482282013-06-14 16:08:024655TEST_P(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:084656 ConnectStatusHelperWithExpectedStatus(
4657 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:544658 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:084659}
4660
[email protected]23e482282013-06-14 16:08:024661TEST_P(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:084662 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
4663}
4664
[email protected]23e482282013-06-14 16:08:024665TEST_P(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:084666 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
4667}
4668
[email protected]23e482282013-06-14 16:08:024669TEST_P(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:084670 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
4671}
4672
[email protected]23e482282013-06-14 16:08:024673TEST_P(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:084674 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
4675}
4676
[email protected]23e482282013-06-14 16:08:024677TEST_P(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:084678 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
4679}
4680
[email protected]23e482282013-06-14 16:08:024681TEST_P(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:084682 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
4683}
4684
[email protected]23e482282013-06-14 16:08:024685TEST_P(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:084686 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
4687}
4688
[email protected]23e482282013-06-14 16:08:024689TEST_P(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:084690 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
4691}
4692
[email protected]23e482282013-06-14 16:08:024693TEST_P(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:084694 ConnectStatusHelper(
4695 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
4696}
4697
[email protected]23e482282013-06-14 16:08:024698TEST_P(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:084699 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
4700}
4701
[email protected]23e482282013-06-14 16:08:024702TEST_P(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:084703 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
4704}
4705
[email protected]23e482282013-06-14 16:08:024706TEST_P(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:084707 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
4708}
4709
[email protected]23e482282013-06-14 16:08:024710TEST_P(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:084711 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
4712}
4713
[email protected]23e482282013-06-14 16:08:024714TEST_P(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:084715 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
4716}
4717
[email protected]23e482282013-06-14 16:08:024718TEST_P(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:084719 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
4720}
4721
[email protected]23e482282013-06-14 16:08:024722TEST_P(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:084723 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
4724}
4725
[email protected]038e9a32008-10-08 22:40:164726// Test the flow when both the proxy server AND origin server require
4727// authentication. Again, this uses basic auth for both since that is
4728// the simplest to mock.
[email protected]23e482282013-06-14 16:08:024729TEST_P(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:274730 HttpRequestInfo request;
4731 request.method = "GET";
bncce36dca22015-04-21 22:11:234732 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274733 request.load_flags = 0;
4734
[email protected]038e9a32008-10-08 22:40:164735 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:034736 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
mmenke6b3af6e2015-09-12 02:06:064737 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:074738
4739 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:414740 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]038e9a32008-10-08 22:40:164741
[email protected]f9ee6b52008-11-08 06:46:234742 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:234743 MockWrite(
4744 "GET http://www.example.org/ HTTP/1.1\r\n"
4745 "Host: www.example.org\r\n"
4746 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:234747 };
4748
[email protected]038e9a32008-10-08 22:40:164749 MockRead data_reads1[] = {
4750 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
4751 // Give a couple authenticate options (only the middle one is actually
4752 // supported).
[email protected]22927ad2009-09-21 19:56:194753 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:164754 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4755 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
4756 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4757 // Large content-length -- won't matter, as connection will be reset.
4758 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064759 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:164760 };
4761
4762 // After calling trans->RestartWithAuth() the first time, this is the
4763 // request we should be issuing -- the final header line contains the
4764 // proxy's credentials.
4765 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:234766 MockWrite(
4767 "GET http://www.example.org/ HTTP/1.1\r\n"
4768 "Host: www.example.org\r\n"
4769 "Proxy-Connection: keep-alive\r\n"
4770 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:164771 };
4772
4773 // Now the proxy server lets the request pass through to origin server.
4774 // The origin server responds with a 401.
4775 MockRead data_reads2[] = {
4776 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4777 // Note: We are using the same realm-name as the proxy server. This is
4778 // completely valid, as realms are unique across hosts.
4779 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4780 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4781 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064782 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:164783 };
4784
4785 // After calling trans->RestartWithAuth() the second time, we should send
4786 // the credentials for both the proxy and origin server.
4787 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:234788 MockWrite(
4789 "GET http://www.example.org/ HTTP/1.1\r\n"
4790 "Host: www.example.org\r\n"
4791 "Proxy-Connection: keep-alive\r\n"
4792 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
4793 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:164794 };
4795
4796 // Lastly we get the desired content.
4797 MockRead data_reads3[] = {
4798 MockRead("HTTP/1.0 200 OK\r\n"),
4799 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4800 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064801 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:164802 };
4803
[email protected]31a2bfe2010-02-09 08:03:394804 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4805 data_writes1, arraysize(data_writes1));
4806 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4807 data_writes2, arraysize(data_writes2));
4808 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4809 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:074810 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4811 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4812 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:164813
[email protected]49639fa2011-12-20 23:22:414814 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:164815
[email protected]49639fa2011-12-20 23:22:414816 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424817 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:164818
4819 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424820 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:164821
[email protected]1c773ea12009-04-28 19:58:424822 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504823 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044824 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:164825
[email protected]49639fa2011-12-20 23:22:414826 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:164827
[email protected]49639fa2011-12-20 23:22:414828 rv = trans->RestartWithAuth(
4829 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:424830 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:164831
4832 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424833 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:164834
4835 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504836 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044837 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:164838
[email protected]49639fa2011-12-20 23:22:414839 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:164840
[email protected]49639fa2011-12-20 23:22:414841 rv = trans->RestartWithAuth(
4842 AuthCredentials(kFoo2, kBar2), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424843 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:164844
4845 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424846 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:164847
4848 response = trans->GetResponseInfo();
4849 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4850 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:164851}
[email protected]4ddaf2502008-10-23 18:26:194852
[email protected]ea9dc9a2009-09-05 00:43:324853// For the NTLM implementation using SSPI, we skip the NTLM tests since we
4854// can't hook into its internals to cause it to generate predictable NTLM
4855// authorization headers.
4856#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:294857// The NTLM authentication unit tests were generated by capturing the HTTP
4858// requests and responses using Fiddler 2 and inspecting the generated random
4859// bytes in the debugger.
4860
4861// Enter the correct password and authenticate successfully.
[email protected]23e482282013-06-14 16:08:024862TEST_P(HttpNetworkTransactionTest, NTLMAuth1) {
[email protected]1c773ea12009-04-28 19:58:424863 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:244864 request.method = "GET";
4865 request.url = GURL("http://172.22.68.17/kids/login.aspx");
[email protected]2217aa22013-10-11 03:03:544866
4867 // Ensure load is not disrupted by flags which suppress behaviour specific
4868 // to other auth schemes.
4869 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:244870
[email protected]cb9bf6ca2011-01-28 13:15:274871 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
4872 MockGetHostName);
mmenke6b3af6e2015-09-12 02:06:064873 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274874
[email protected]3f918782009-02-28 01:29:244875 MockWrite data_writes1[] = {
4876 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4877 "Host: 172.22.68.17\r\n"
4878 "Connection: keep-alive\r\n\r\n"),
4879 };
4880
4881 MockRead data_reads1[] = {
4882 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:044883 // Negotiate and NTLM are often requested together. However, we only want
4884 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
4885 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:244886 MockRead("WWW-Authenticate: NTLM\r\n"),
4887 MockRead("Connection: close\r\n"),
4888 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364889 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:244890 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064891 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]3f918782009-02-28 01:29:244892 };
4893
4894 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:224895 // After restarting with a null identity, this is the
[email protected]3f918782009-02-28 01:29:244896 // request we should be issuing -- the final header line contains a Type
4897 // 1 message.
4898 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4899 "Host: 172.22.68.17\r\n"
4900 "Connection: keep-alive\r\n"
4901 "Authorization: NTLM "
4902 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4903
4904 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4905 // (the credentials for the origin server). The second request continues
4906 // on the same connection.
4907 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4908 "Host: 172.22.68.17\r\n"
4909 "Connection: keep-alive\r\n"
[email protected]385a4672009-03-11 22:21:294910 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4911 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4912 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
4913 "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
4914 "ahlhx5I=\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:244915 };
4916
4917 MockRead data_reads2[] = {
4918 // The origin server responds with a Type 2 message.
4919 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4920 MockRead("WWW-Authenticate: NTLM "
[email protected]385a4672009-03-11 22:21:294921 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
[email protected]3f918782009-02-28 01:29:244922 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4923 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4924 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4925 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4926 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4927 "BtAAAAAAA=\r\n"),
4928 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364929 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:244930 MockRead("You are not authorized to view this page\r\n"),
4931
4932 // Lastly we get the desired content.
4933 MockRead("HTTP/1.1 200 OK\r\n"),
4934 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
4935 MockRead("Content-Length: 13\r\n\r\n"),
4936 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:064937 MockRead(SYNCHRONOUS, OK),
[email protected]3f918782009-02-28 01:29:244938 };
4939
[email protected]31a2bfe2010-02-09 08:03:394940 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4941 data_writes1, arraysize(data_writes1));
4942 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4943 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:074944 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4945 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:244946
[email protected]49639fa2011-12-20 23:22:414947 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:244948
[email protected]262eec82013-03-19 21:01:364949 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504950 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504951
[email protected]49639fa2011-12-20 23:22:414952 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424953 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:244954
4955 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424956 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:244957
[email protected]0757e7702009-03-27 04:00:224958 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4959
[email protected]1c773ea12009-04-28 19:58:424960 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:044961 ASSERT_FALSE(response == NULL);
4962 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:244963
[email protected]49639fa2011-12-20 23:22:414964 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:254965
[email protected]f3cf9802011-10-28 18:44:584966 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:414967 callback2.callback());
[email protected]10af5fe72011-01-31 16:17:254968 EXPECT_EQ(ERR_IO_PENDING, rv);
4969
4970 rv = callback2.WaitForResult();
4971 EXPECT_EQ(OK, rv);
4972
4973 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4974
4975 response = trans->GetResponseInfo();
4976 ASSERT_TRUE(response != NULL);
[email protected]10af5fe72011-01-31 16:17:254977 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4978
[email protected]49639fa2011-12-20 23:22:414979 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:244980
[email protected]49639fa2011-12-20 23:22:414981 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424982 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:244983
[email protected]0757e7702009-03-27 04:00:224984 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424985 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:244986
4987 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504988 ASSERT_TRUE(response != NULL);
[email protected]3f918782009-02-28 01:29:244989 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4990 EXPECT_EQ(13, response->headers->GetContentLength());
4991}
4992
[email protected]385a4672009-03-11 22:21:294993// Enter a wrong password, and then the correct one.
[email protected]23e482282013-06-14 16:08:024994TEST_P(HttpNetworkTransactionTest, NTLMAuth2) {
[email protected]1c773ea12009-04-28 19:58:424995 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:294996 request.method = "GET";
4997 request.url = GURL("http://172.22.68.17/kids/login.aspx");
4998 request.load_flags = 0;
4999
[email protected]cb9bf6ca2011-01-28 13:15:275000 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
5001 MockGetHostName);
mmenke6b3af6e2015-09-12 02:06:065002 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275003
[email protected]385a4672009-03-11 22:21:295004 MockWrite data_writes1[] = {
5005 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5006 "Host: 172.22.68.17\r\n"
5007 "Connection: keep-alive\r\n\r\n"),
5008 };
5009
5010 MockRead data_reads1[] = {
5011 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:045012 // Negotiate and NTLM are often requested together. However, we only want
5013 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
5014 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:295015 MockRead("WWW-Authenticate: NTLM\r\n"),
5016 MockRead("Connection: close\r\n"),
5017 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365018 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:295019 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:065020 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:295021 };
5022
5023 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:225024 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:295025 // request we should be issuing -- the final header line contains a Type
5026 // 1 message.
5027 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5028 "Host: 172.22.68.17\r\n"
5029 "Connection: keep-alive\r\n"
5030 "Authorization: NTLM "
5031 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
5032
5033 // After calling trans->RestartWithAuth(), we should send a Type 3 message
5034 // (the credentials for the origin server). The second request continues
5035 // on the same connection.
5036 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5037 "Host: 172.22.68.17\r\n"
5038 "Connection: keep-alive\r\n"
5039 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
5040 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
5041 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
5042 "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
5043 "4Ww7b7E=\r\n\r\n"),
5044 };
5045
5046 MockRead data_reads2[] = {
5047 // The origin server responds with a Type 2 message.
5048 MockRead("HTTP/1.1 401 Access Denied\r\n"),
5049 MockRead("WWW-Authenticate: NTLM "
5050 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
5051 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
5052 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
5053 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
5054 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
5055 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
5056 "BtAAAAAAA=\r\n"),
5057 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365058 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:295059 MockRead("You are not authorized to view this page\r\n"),
5060
5061 // Wrong password.
5062 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]385a4672009-03-11 22:21:295063 MockRead("WWW-Authenticate: NTLM\r\n"),
5064 MockRead("Connection: close\r\n"),
5065 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365066 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:295067 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:065068 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:295069 };
5070
5071 MockWrite data_writes3[] = {
[email protected]0757e7702009-03-27 04:00:225072 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:295073 // request we should be issuing -- the final header line contains a Type
5074 // 1 message.
5075 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5076 "Host: 172.22.68.17\r\n"
5077 "Connection: keep-alive\r\n"
5078 "Authorization: NTLM "
5079 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
5080
5081 // After calling trans->RestartWithAuth(), we should send a Type 3 message
5082 // (the credentials for the origin server). The second request continues
5083 // on the same connection.
5084 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5085 "Host: 172.22.68.17\r\n"
5086 "Connection: keep-alive\r\n"
5087 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
5088 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
5089 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
5090 "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
5091 "+4MUm7c=\r\n\r\n"),
5092 };
5093
5094 MockRead data_reads3[] = {
5095 // The origin server responds with a Type 2 message.
5096 MockRead("HTTP/1.1 401 Access Denied\r\n"),
5097 MockRead("WWW-Authenticate: NTLM "
5098 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
5099 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
5100 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
5101 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
5102 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
5103 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
5104 "BtAAAAAAA=\r\n"),
5105 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365106 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:295107 MockRead("You are not authorized to view this page\r\n"),
5108
5109 // Lastly we get the desired content.
5110 MockRead("HTTP/1.1 200 OK\r\n"),
5111 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
5112 MockRead("Content-Length: 13\r\n\r\n"),
5113 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:065114 MockRead(SYNCHRONOUS, OK),
[email protected]385a4672009-03-11 22:21:295115 };
5116
[email protected]31a2bfe2010-02-09 08:03:395117 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5118 data_writes1, arraysize(data_writes1));
5119 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5120 data_writes2, arraysize(data_writes2));
5121 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5122 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075123 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5124 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5125 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:295126
[email protected]49639fa2011-12-20 23:22:415127 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:295128
[email protected]262eec82013-03-19 21:01:365129 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505130 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:505131
[email protected]49639fa2011-12-20 23:22:415132 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425133 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:295134
5135 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425136 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:295137
[email protected]0757e7702009-03-27 04:00:225138 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:295139
[email protected]1c773ea12009-04-28 19:58:425140 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505141 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045142 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:295143
[email protected]49639fa2011-12-20 23:22:415144 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:295145
[email protected]0757e7702009-03-27 04:00:225146 // Enter the wrong password.
[email protected]f3cf9802011-10-28 18:44:585147 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword),
[email protected]49639fa2011-12-20 23:22:415148 callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425149 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:295150
[email protected]10af5fe72011-01-31 16:17:255151 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425152 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:295153
[email protected]0757e7702009-03-27 04:00:225154 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:415155 TestCompletionCallback callback3;
5156 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:425157 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]10af5fe72011-01-31 16:17:255158 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425159 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225160 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5161
5162 response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:045163 ASSERT_FALSE(response == NULL);
5164 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:225165
[email protected]49639fa2011-12-20 23:22:415166 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:225167
5168 // Now enter the right password.
[email protected]f3cf9802011-10-28 18:44:585169 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:415170 callback4.callback());
[email protected]10af5fe72011-01-31 16:17:255171 EXPECT_EQ(ERR_IO_PENDING, rv);
5172
5173 rv = callback4.WaitForResult();
5174 EXPECT_EQ(OK, rv);
5175
5176 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5177
[email protected]49639fa2011-12-20 23:22:415178 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:255179
5180 // One more roundtrip
[email protected]49639fa2011-12-20 23:22:415181 rv = trans->RestartWithAuth(AuthCredentials(), callback5.callback());
[email protected]1c773ea12009-04-28 19:58:425182 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:225183
5184 rv = callback5.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425185 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225186
[email protected]385a4672009-03-11 22:21:295187 response = trans->GetResponseInfo();
5188 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5189 EXPECT_EQ(13, response->headers->GetContentLength());
5190}
[email protected]ea9dc9a2009-09-05 00:43:325191#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:295192
[email protected]4ddaf2502008-10-23 18:26:195193// Test reading a server response which has only headers, and no body.
5194// After some maximum number of bytes is consumed, the transaction should
5195// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
[email protected]23e482282013-06-14 16:08:025196TEST_P(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:425197 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:195198 request.method = "GET";
bncce36dca22015-04-21 22:11:235199 request.url = GURL("http://www.example.org/");
[email protected]4ddaf2502008-10-23 18:26:195200 request.load_flags = 0;
5201
mmenke6b3af6e2015-09-12 02:06:065202 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275203 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415204 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275205
[email protected]b75b7b2f2009-10-06 00:54:535206 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:435207 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:535208 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:195209
5210 MockRead data_reads[] = {
5211 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:065212 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:195213 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:065214 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:195215 };
[email protected]31a2bfe2010-02-09 08:03:395216 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:075217 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:195218
[email protected]49639fa2011-12-20 23:22:415219 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:195220
[email protected]49639fa2011-12-20 23:22:415221 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425222 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]4ddaf2502008-10-23 18:26:195223
5224 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425225 EXPECT_EQ(ERR_RESPONSE_HEADERS_TOO_BIG, rv);
[email protected]4ddaf2502008-10-23 18:26:195226}
[email protected]f4e426b2008-11-05 00:24:495227
5228// Make sure that we don't try to reuse a TCPClientSocket when failing to
5229// establish tunnel.
5230// http://code.google.com/p/chromium/issues/detail?id=3772
[email protected]23e482282013-06-14 16:08:025231TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:235232 DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:275233 HttpRequestInfo request;
5234 request.method = "GET";
bncce36dca22015-04-21 22:11:235235 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275236 request.load_flags = 0;
5237
[email protected]f4e426b2008-11-05 00:24:495238 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035239 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]db8f44c2008-12-13 04:52:015240
mmenke6b3af6e2015-09-12 02:06:065241 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:495242
[email protected]262eec82013-03-19 21:01:365243 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505244 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f4e426b2008-11-05 00:24:495245
[email protected]f4e426b2008-11-05 00:24:495246 // Since we have proxy, should try to establish tunnel.
5247 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235248 MockWrite(
5249 "CONNECT www.example.org:443 HTTP/1.1\r\n"
5250 "Host: www.example.org\r\n"
5251 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:495252 };
5253
[email protected]77848d12008-11-14 00:00:225254 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:495255 // connection. Usually a proxy would return 501 (not implemented),
5256 // or 200 (tunnel established).
5257 MockRead data_reads1[] = {
5258 MockRead("HTTP/1.1 404 Not Found\r\n"),
5259 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065260 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]f4e426b2008-11-05 00:24:495261 };
5262
[email protected]31a2bfe2010-02-09 08:03:395263 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5264 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075265 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:495266
[email protected]49639fa2011-12-20 23:22:415267 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:495268
[email protected]49639fa2011-12-20 23:22:415269 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425270 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f4e426b2008-11-05 00:24:495271
5272 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425273 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]f4e426b2008-11-05 00:24:495274
[email protected]b4404c02009-04-10 16:38:525275 // Empty the current queue. This is necessary because idle sockets are
5276 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345277 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:525278
[email protected]f4e426b2008-11-05 00:24:495279 // We now check to make sure the TCPClientSocket was not added back to
5280 // the pool.
[email protected]90499482013-06-01 00:39:505281 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:495282 trans.reset();
[email protected]2da659e2013-05-23 20:51:345283 base::MessageLoop::current()->RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:495284 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:505285 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:495286}
[email protected]372d34a2008-11-05 21:30:515287
[email protected]1b157c02009-04-21 01:55:405288// Make sure that we recycle a socket after reading all of the response body.
[email protected]23e482282013-06-14 16:08:025289TEST_P(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:425290 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:405291 request.method = "GET";
bncce36dca22015-04-21 22:11:235292 request.url = GURL("http://www.example.org/");
[email protected]1b157c02009-04-21 01:55:405293 request.load_flags = 0;
5294
mmenke6b3af6e2015-09-12 02:06:065295 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275296
[email protected]262eec82013-03-19 21:01:365297 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505298 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275299
[email protected]1b157c02009-04-21 01:55:405300 MockRead data_reads[] = {
5301 // A part of the response body is received with the response headers.
5302 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
5303 // The rest of the response body is received in two parts.
5304 MockRead("lo"),
5305 MockRead(" world"),
5306 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:065307 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:405308 };
5309
[email protected]31a2bfe2010-02-09 08:03:395310 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:075311 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:405312
[email protected]49639fa2011-12-20 23:22:415313 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:405314
[email protected]49639fa2011-12-20 23:22:415315 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425316 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]1b157c02009-04-21 01:55:405317
5318 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425319 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:405320
[email protected]1c773ea12009-04-28 19:58:425321 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505322 ASSERT_TRUE(response != NULL);
[email protected]1b157c02009-04-21 01:55:405323
[email protected]90499482013-06-01 00:39:505324 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]1b157c02009-04-21 01:55:405325 std::string status_line = response->headers->GetStatusLine();
5326 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
5327
[email protected]90499482013-06-01 00:39:505328 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:405329
5330 std::string response_data;
5331 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:425332 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:405333 EXPECT_EQ("hello world", response_data);
5334
5335 // Empty the current queue. This is necessary because idle sockets are
5336 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345337 base::MessageLoop::current()->RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:405338
5339 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505340 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:405341}
5342
[email protected]76a505b2010-08-25 06:23:005343// Make sure that we recycle a SSL socket after reading all of the response
5344// body.
[email protected]23e482282013-06-14 16:08:025345TEST_P(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:005346 HttpRequestInfo request;
5347 request.method = "GET";
bncce36dca22015-04-21 22:11:235348 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:005349 request.load_flags = 0;
5350
5351 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:235352 MockWrite(
5353 "GET / HTTP/1.1\r\n"
5354 "Host: www.example.org\r\n"
5355 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:005356 };
5357
5358 MockRead data_reads[] = {
5359 MockRead("HTTP/1.1 200 OK\r\n"),
5360 MockRead("Content-Length: 11\r\n\r\n"),
5361 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:065362 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:005363 };
5364
[email protected]8ddf8322012-02-23 18:08:065365 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075366 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:005367
5368 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5369 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:075370 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:005371
[email protected]49639fa2011-12-20 23:22:415372 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:005373
mmenke6b3af6e2015-09-12 02:06:065374 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:365375 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505376 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:005377
[email protected]49639fa2011-12-20 23:22:415378 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:005379
5380 EXPECT_EQ(ERR_IO_PENDING, rv);
5381 EXPECT_EQ(OK, callback.WaitForResult());
5382
5383 const HttpResponseInfo* response = trans->GetResponseInfo();
5384 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:505385 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:005386 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5387
[email protected]90499482013-06-01 00:39:505388 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005389
5390 std::string response_data;
5391 rv = ReadTransaction(trans.get(), &response_data);
5392 EXPECT_EQ(OK, rv);
5393 EXPECT_EQ("hello world", response_data);
5394
5395 // Empty the current queue. This is necessary because idle sockets are
5396 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345397 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:005398
5399 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505400 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005401}
5402
5403// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
5404// from the pool and make sure that we recover okay.
[email protected]23e482282013-06-14 16:08:025405TEST_P(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:005406 HttpRequestInfo request;
5407 request.method = "GET";
bncce36dca22015-04-21 22:11:235408 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:005409 request.load_flags = 0;
5410
5411 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:235412 MockWrite(
5413 "GET / HTTP/1.1\r\n"
5414 "Host: www.example.org\r\n"
5415 "Connection: keep-alive\r\n\r\n"),
5416 MockWrite(
5417 "GET / HTTP/1.1\r\n"
5418 "Host: www.example.org\r\n"
5419 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:005420 };
5421
5422 MockRead data_reads[] = {
5423 MockRead("HTTP/1.1 200 OK\r\n"),
5424 MockRead("Content-Length: 11\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065425 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:005426 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:065427 MockRead(ASYNC, 0, 0) // EOF
[email protected]76a505b2010-08-25 06:23:005428 };
5429
[email protected]8ddf8322012-02-23 18:08:065430 SSLSocketDataProvider ssl(ASYNC, OK);
5431 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075432 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5433 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:005434
5435 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5436 data_writes, arraysize(data_writes));
5437 StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
5438 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:075439 session_deps_.socket_factory->AddSocketDataProvider(&data);
5440 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:005441
[email protected]49639fa2011-12-20 23:22:415442 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:005443
mmenke6b3af6e2015-09-12 02:06:065444 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:365445 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505446 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:005447
[email protected]49639fa2011-12-20 23:22:415448 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:005449
5450 EXPECT_EQ(ERR_IO_PENDING, rv);
5451 EXPECT_EQ(OK, callback.WaitForResult());
5452
5453 const HttpResponseInfo* response = trans->GetResponseInfo();
5454 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:505455 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:005456 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5457
[email protected]90499482013-06-01 00:39:505458 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005459
5460 std::string response_data;
5461 rv = ReadTransaction(trans.get(), &response_data);
5462 EXPECT_EQ(OK, rv);
5463 EXPECT_EQ("hello world", response_data);
5464
5465 // Empty the current queue. This is necessary because idle sockets are
5466 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345467 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:005468
5469 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505470 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005471
5472 // Now start the second transaction, which should reuse the previous socket.
5473
[email protected]90499482013-06-01 00:39:505474 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:005475
[email protected]49639fa2011-12-20 23:22:415476 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:005477
5478 EXPECT_EQ(ERR_IO_PENDING, rv);
5479 EXPECT_EQ(OK, callback.WaitForResult());
5480
5481 response = trans->GetResponseInfo();
5482 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:505483 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:005484 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5485
[email protected]90499482013-06-01 00:39:505486 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005487
5488 rv = ReadTransaction(trans.get(), &response_data);
5489 EXPECT_EQ(OK, rv);
5490 EXPECT_EQ("hello world", response_data);
5491
5492 // Empty the current queue. This is necessary because idle sockets are
5493 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345494 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:005495
5496 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505497 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005498}
5499
[email protected]b4404c02009-04-10 16:38:525500// Make sure that we recycle a socket after a zero-length response.
5501// http://crbug.com/9880
[email protected]23e482282013-06-14 16:08:025502TEST_P(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:425503 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:525504 request.method = "GET";
bncce36dca22015-04-21 22:11:235505 request.url = GURL(
5506 "http://www.example.org/csi?v=3&s=web&action=&"
5507 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
5508 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
5509 "rt=prt.2642,ol.2649,xjs.2951");
[email protected]b4404c02009-04-10 16:38:525510 request.load_flags = 0;
5511
mmenke6b3af6e2015-09-12 02:06:065512 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275513
[email protected]262eec82013-03-19 21:01:365514 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505515 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275516
[email protected]b4404c02009-04-10 16:38:525517 MockRead data_reads[] = {
5518 MockRead("HTTP/1.1 204 No Content\r\n"
5519 "Content-Length: 0\r\n"
5520 "Content-Type: text/html\r\n\r\n"),
5521 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:065522 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:525523 };
5524
[email protected]31a2bfe2010-02-09 08:03:395525 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:075526 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:525527
[email protected]49639fa2011-12-20 23:22:415528 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:525529
[email protected]49639fa2011-12-20 23:22:415530 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425531 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]b4404c02009-04-10 16:38:525532
5533 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425534 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:525535
[email protected]1c773ea12009-04-28 19:58:425536 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505537 ASSERT_TRUE(response != NULL);
[email protected]b4404c02009-04-10 16:38:525538
[email protected]90499482013-06-01 00:39:505539 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]b4404c02009-04-10 16:38:525540 std::string status_line = response->headers->GetStatusLine();
5541 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
5542
[email protected]90499482013-06-01 00:39:505543 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:525544
5545 std::string response_data;
5546 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:425547 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:525548 EXPECT_EQ("", response_data);
5549
5550 // Empty the current queue. This is necessary because idle sockets are
5551 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345552 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:525553
5554 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505555 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:525556}
5557
[email protected]23e482282013-06-14 16:08:025558TEST_P(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
[email protected]b2d26cfd2012-12-11 10:36:065559 ScopedVector<UploadElementReader> element_readers;
5560 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:075561 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:275562
[email protected]1c773ea12009-04-28 19:58:425563 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:515564 // Transaction 1: a GET request that succeeds. The socket is recycled
5565 // after use.
5566 request[0].method = "GET";
5567 request[0].url = GURL("http://www.google.com/");
5568 request[0].load_flags = 0;
5569 // Transaction 2: a POST request. Reuses the socket kept alive from
5570 // transaction 1. The first attempts fails when writing the POST data.
5571 // This causes the transaction to retry with a new socket. The second
5572 // attempt succeeds.
5573 request[1].method = "POST";
5574 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:275575 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:515576 request[1].load_flags = 0;
5577
mmenke6b3af6e2015-09-12 02:06:065578 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:515579
5580 // The first socket is used for transaction 1 and the first attempt of
5581 // transaction 2.
5582
5583 // The response of transaction 1.
5584 MockRead data_reads1[] = {
5585 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
5586 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:065587 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:515588 };
5589 // The mock write results of transaction 1 and the first attempt of
5590 // transaction 2.
5591 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:065592 MockWrite(SYNCHRONOUS, 64), // GET
5593 MockWrite(SYNCHRONOUS, 93), // POST
5594 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:515595 };
[email protected]31a2bfe2010-02-09 08:03:395596 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5597 data_writes1, arraysize(data_writes1));
[email protected]372d34a2008-11-05 21:30:515598
5599 // The second socket is used for the second attempt of transaction 2.
5600
5601 // The response of transaction 2.
5602 MockRead data_reads2[] = {
5603 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
5604 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:065605 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:515606 };
5607 // The mock write results of the second attempt of transaction 2.
5608 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:065609 MockWrite(SYNCHRONOUS, 93), // POST
5610 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:515611 };
[email protected]31a2bfe2010-02-09 08:03:395612 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5613 data_writes2, arraysize(data_writes2));
[email protected]372d34a2008-11-05 21:30:515614
[email protected]bb88e1d32013-05-03 23:11:075615 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5616 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:515617
thestig9d3bb0c2015-01-24 00:49:515618 const char* const kExpectedResponseData[] = {
[email protected]372d34a2008-11-05 21:30:515619 "hello world", "welcome"
5620 };
5621
5622 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:425623 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505624 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]372d34a2008-11-05 21:30:515625
[email protected]49639fa2011-12-20 23:22:415626 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:515627
[email protected]49639fa2011-12-20 23:22:415628 int rv = trans->Start(&request[i], callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425629 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]372d34a2008-11-05 21:30:515630
5631 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425632 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:515633
[email protected]1c773ea12009-04-28 19:58:425634 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505635 ASSERT_TRUE(response != NULL);
[email protected]372d34a2008-11-05 21:30:515636
[email protected]90499482013-06-01 00:39:505637 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]372d34a2008-11-05 21:30:515638 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5639
5640 std::string response_data;
5641 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:425642 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:515643 EXPECT_EQ(kExpectedResponseData[i], response_data);
5644 }
5645}
[email protected]f9ee6b52008-11-08 06:46:235646
5647// Test the request-challenge-retry sequence for basic auth when there is
5648// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:165649// it fails the identity from the URL is used to answer the challenge.
[email protected]23e482282013-06-14 16:08:025650TEST_P(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:425651 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235652 request.method = "GET";
bncce36dca22015-04-21 22:11:235653 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:415654 request.load_flags = LOAD_NORMAL;
[email protected]a97cca42009-08-14 01:00:295655
mmenke6b3af6e2015-09-12 02:06:065656 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275657 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415658 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275659
[email protected]a97cca42009-08-14 01:00:295660 // The password contains an escaped character -- for this test to pass it
5661 // will need to be unescaped by HttpNetworkTransaction.
5662 EXPECT_EQ("b%40r", request.url.password());
5663
[email protected]f9ee6b52008-11-08 06:46:235664 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235665 MockWrite(
5666 "GET / HTTP/1.1\r\n"
5667 "Host: www.example.org\r\n"
5668 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235669 };
5670
5671 MockRead data_reads1[] = {
5672 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5673 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5674 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065675 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235676 };
5677
[email protected]2262e3a2012-05-22 16:08:165678 // After the challenge above, the transaction will be restarted using the
5679 // identity from the url (foo, b@r) to answer the challenge.
5680 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235681 MockWrite(
5682 "GET / HTTP/1.1\r\n"
5683 "Host: www.example.org\r\n"
5684 "Connection: keep-alive\r\n"
5685 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:165686 };
5687
5688 MockRead data_reads2[] = {
5689 MockRead("HTTP/1.0 200 OK\r\n"),
5690 MockRead("Content-Length: 100\r\n\r\n"),
5691 MockRead(SYNCHRONOUS, OK),
5692 };
5693
[email protected]31a2bfe2010-02-09 08:03:395694 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5695 data_writes1, arraysize(data_writes1));
[email protected]2262e3a2012-05-22 16:08:165696 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5697 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075698 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5699 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235700
[email protected]49639fa2011-12-20 23:22:415701 TestCompletionCallback callback1;
[email protected]49639fa2011-12-20 23:22:415702 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425703 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235704 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425705 EXPECT_EQ(OK, rv);
[email protected]2262e3a2012-05-22 16:08:165706 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5707
5708 TestCompletionCallback callback2;
5709 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
5710 EXPECT_EQ(ERR_IO_PENDING, rv);
5711 rv = callback2.WaitForResult();
5712 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225713 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5714
[email protected]2262e3a2012-05-22 16:08:165715 const HttpResponseInfo* response = trans->GetResponseInfo();
5716 ASSERT_TRUE(response != NULL);
5717
5718 // There is no challenge info, since the identity in URL worked.
5719 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5720
5721 EXPECT_EQ(100, response->headers->GetContentLength());
5722
5723 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:345724 base::MessageLoop::current()->RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:165725}
5726
5727// Test the request-challenge-retry sequence for basic auth when there is an
5728// incorrect identity in the URL. The identity from the URL should be used only
5729// once.
[email protected]23e482282013-06-14 16:08:025730TEST_P(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:165731 HttpRequestInfo request;
5732 request.method = "GET";
5733 // Note: the URL has a username:password in it. The password "baz" is
5734 // wrong (should be "bar").
bncce36dca22015-04-21 22:11:235735 request.url = GURL("http://foo:[email protected]/");
[email protected]2262e3a2012-05-22 16:08:165736
5737 request.load_flags = LOAD_NORMAL;
5738
mmenke6b3af6e2015-09-12 02:06:065739 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2262e3a2012-05-22 16:08:165740 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415741 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2262e3a2012-05-22 16:08:165742
5743 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235744 MockWrite(
5745 "GET / HTTP/1.1\r\n"
5746 "Host: www.example.org\r\n"
5747 "Connection: keep-alive\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:165748 };
5749
5750 MockRead data_reads1[] = {
5751 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5752 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5753 MockRead("Content-Length: 10\r\n\r\n"),
5754 MockRead(SYNCHRONOUS, ERR_FAILED),
5755 };
5756
5757 // After the challenge above, the transaction will be restarted using the
5758 // identity from the url (foo, baz) to answer the challenge.
5759 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235760 MockWrite(
5761 "GET / HTTP/1.1\r\n"
5762 "Host: www.example.org\r\n"
5763 "Connection: keep-alive\r\n"
5764 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:165765 };
5766
5767 MockRead data_reads2[] = {
5768 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5769 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5770 MockRead("Content-Length: 10\r\n\r\n"),
5771 MockRead(SYNCHRONOUS, ERR_FAILED),
5772 };
5773
5774 // After the challenge above, the transaction will be restarted using the
5775 // identity supplied by the user (foo, bar) to answer the challenge.
5776 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:235777 MockWrite(
5778 "GET / HTTP/1.1\r\n"
5779 "Host: www.example.org\r\n"
5780 "Connection: keep-alive\r\n"
5781 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:165782 };
5783
5784 MockRead data_reads3[] = {
5785 MockRead("HTTP/1.0 200 OK\r\n"),
5786 MockRead("Content-Length: 100\r\n\r\n"),
5787 MockRead(SYNCHRONOUS, OK),
5788 };
5789
5790 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5791 data_writes1, arraysize(data_writes1));
5792 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5793 data_writes2, arraysize(data_writes2));
5794 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5795 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075796 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5797 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5798 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:165799
5800 TestCompletionCallback callback1;
5801
5802 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5803 EXPECT_EQ(ERR_IO_PENDING, rv);
5804
5805 rv = callback1.WaitForResult();
5806 EXPECT_EQ(OK, rv);
5807
5808 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5809 TestCompletionCallback callback2;
5810 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
5811 EXPECT_EQ(ERR_IO_PENDING, rv);
5812 rv = callback2.WaitForResult();
5813 EXPECT_EQ(OK, rv);
5814 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5815
5816 const HttpResponseInfo* response = trans->GetResponseInfo();
5817 ASSERT_TRUE(response != NULL);
5818 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
5819
5820 TestCompletionCallback callback3;
5821 rv = trans->RestartWithAuth(
5822 AuthCredentials(kFoo, kBar), callback3.callback());
5823 EXPECT_EQ(ERR_IO_PENDING, rv);
5824 rv = callback3.WaitForResult();
5825 EXPECT_EQ(OK, rv);
5826 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5827
5828 response = trans->GetResponseInfo();
5829 ASSERT_TRUE(response != NULL);
5830
5831 // There is no challenge info, since the identity worked.
5832 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5833
5834 EXPECT_EQ(100, response->headers->GetContentLength());
5835
[email protected]ea9dc9a2009-09-05 00:43:325836 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:345837 base::MessageLoop::current()->RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:325838}
5839
[email protected]2217aa22013-10-11 03:03:545840
5841// Test the request-challenge-retry sequence for basic auth when there is a
5842// correct identity in the URL, but its use is being suppressed. The identity
5843// from the URL should never be used.
5844TEST_P(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
5845 HttpRequestInfo request;
5846 request.method = "GET";
bncce36dca22015-04-21 22:11:235847 request.url = GURL("http://foo:[email protected]/");
[email protected]2217aa22013-10-11 03:03:545848 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
5849
mmenke6b3af6e2015-09-12 02:06:065850 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2217aa22013-10-11 03:03:545851 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415852 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2217aa22013-10-11 03:03:545853
5854 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235855 MockWrite(
5856 "GET / HTTP/1.1\r\n"
5857 "Host: www.example.org\r\n"
5858 "Connection: keep-alive\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:545859 };
5860
5861 MockRead data_reads1[] = {
5862 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5863 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5864 MockRead("Content-Length: 10\r\n\r\n"),
5865 MockRead(SYNCHRONOUS, ERR_FAILED),
5866 };
5867
5868 // After the challenge above, the transaction will be restarted using the
5869 // identity supplied by the user, not the one in the URL, to answer the
5870 // challenge.
5871 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:235872 MockWrite(
5873 "GET / HTTP/1.1\r\n"
5874 "Host: www.example.org\r\n"
5875 "Connection: keep-alive\r\n"
5876 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:545877 };
5878
5879 MockRead data_reads3[] = {
5880 MockRead("HTTP/1.0 200 OK\r\n"),
5881 MockRead("Content-Length: 100\r\n\r\n"),
5882 MockRead(SYNCHRONOUS, OK),
5883 };
5884
5885 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5886 data_writes1, arraysize(data_writes1));
5887 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5888 data_writes3, arraysize(data_writes3));
5889 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5890 session_deps_.socket_factory->AddSocketDataProvider(&data3);
5891
5892 TestCompletionCallback callback1;
5893 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5894 EXPECT_EQ(ERR_IO_PENDING, rv);
5895 rv = callback1.WaitForResult();
5896 EXPECT_EQ(OK, rv);
5897 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5898
5899 const HttpResponseInfo* response = trans->GetResponseInfo();
5900 ASSERT_TRUE(response != NULL);
5901 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
5902
5903 TestCompletionCallback callback3;
5904 rv = trans->RestartWithAuth(
5905 AuthCredentials(kFoo, kBar), callback3.callback());
5906 EXPECT_EQ(ERR_IO_PENDING, rv);
5907 rv = callback3.WaitForResult();
5908 EXPECT_EQ(OK, rv);
5909 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5910
5911 response = trans->GetResponseInfo();
5912 ASSERT_TRUE(response != NULL);
5913
5914 // There is no challenge info, since the identity worked.
5915 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5916 EXPECT_EQ(100, response->headers->GetContentLength());
5917
5918 // Empty the current queue.
5919 base::MessageLoop::current()->RunUntilIdle();
5920}
5921
[email protected]f9ee6b52008-11-08 06:46:235922// Test that previously tried username/passwords for a realm get re-used.
[email protected]23e482282013-06-14 16:08:025923TEST_P(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
mmenke6b3af6e2015-09-12 02:06:065924 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:235925
5926 // Transaction 1: authenticate (foo, bar) on MyRealm1
5927 {
[email protected]1c773ea12009-04-28 19:58:425928 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235929 request.method = "GET";
bncce36dca22015-04-21 22:11:235930 request.url = GURL("http://www.example.org/x/y/z");
[email protected]f9ee6b52008-11-08 06:46:235931 request.load_flags = 0;
5932
[email protected]262eec82013-03-19 21:01:365933 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505934 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275935
[email protected]f9ee6b52008-11-08 06:46:235936 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235937 MockWrite(
5938 "GET /x/y/z HTTP/1.1\r\n"
5939 "Host: www.example.org\r\n"
5940 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235941 };
5942
5943 MockRead data_reads1[] = {
5944 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5945 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5946 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065947 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235948 };
5949
5950 // Resend with authorization (username=foo, password=bar)
5951 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235952 MockWrite(
5953 "GET /x/y/z HTTP/1.1\r\n"
5954 "Host: www.example.org\r\n"
5955 "Connection: keep-alive\r\n"
5956 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235957 };
5958
5959 // Sever accepts the authorization.
5960 MockRead data_reads2[] = {
5961 MockRead("HTTP/1.0 200 OK\r\n"),
5962 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065963 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235964 };
5965
[email protected]31a2bfe2010-02-09 08:03:395966 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5967 data_writes1, arraysize(data_writes1));
5968 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5969 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075970 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5971 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235972
[email protected]49639fa2011-12-20 23:22:415973 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235974
[email protected]49639fa2011-12-20 23:22:415975 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425976 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235977
5978 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425979 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235980
[email protected]1c773ea12009-04-28 19:58:425981 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505982 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045983 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:235984
[email protected]49639fa2011-12-20 23:22:415985 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:235986
[email protected]49639fa2011-12-20 23:22:415987 rv = trans->RestartWithAuth(
5988 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425989 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235990
5991 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425992 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235993
5994 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505995 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235996 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5997 EXPECT_EQ(100, response->headers->GetContentLength());
5998 }
5999
6000 // ------------------------------------------------------------------------
6001
6002 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
6003 {
[email protected]1c773ea12009-04-28 19:58:426004 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236005 request.method = "GET";
6006 // Note that Transaction 1 was at /x/y/z, so this is in the same
6007 // protection space as MyRealm1.
bncce36dca22015-04-21 22:11:236008 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]f9ee6b52008-11-08 06:46:236009 request.load_flags = 0;
6010
[email protected]262eec82013-03-19 21:01:366011 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506012 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276013
[email protected]f9ee6b52008-11-08 06:46:236014 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236015 MockWrite(
6016 "GET /x/y/a/b HTTP/1.1\r\n"
6017 "Host: www.example.org\r\n"
6018 "Connection: keep-alive\r\n"
6019 // Send preemptive authorization for MyRealm1
6020 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236021 };
6022
6023 // The server didn't like the preemptive authorization, and
6024 // challenges us for a different realm (MyRealm2).
6025 MockRead data_reads1[] = {
6026 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6027 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
6028 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066029 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236030 };
6031
6032 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
6033 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236034 MockWrite(
6035 "GET /x/y/a/b HTTP/1.1\r\n"
6036 "Host: www.example.org\r\n"
6037 "Connection: keep-alive\r\n"
6038 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236039 };
6040
6041 // Sever accepts the authorization.
6042 MockRead data_reads2[] = {
6043 MockRead("HTTP/1.0 200 OK\r\n"),
6044 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066045 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:236046 };
6047
[email protected]31a2bfe2010-02-09 08:03:396048 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6049 data_writes1, arraysize(data_writes1));
6050 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6051 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076052 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6053 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:236054
[email protected]49639fa2011-12-20 23:22:416055 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:236056
[email protected]49639fa2011-12-20 23:22:416057 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426058 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236059
6060 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426061 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236062
[email protected]1c773ea12009-04-28 19:58:426063 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506064 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:046065 ASSERT_TRUE(response->auth_challenge.get());
6066 EXPECT_FALSE(response->auth_challenge->is_proxy);
bncce36dca22015-04-21 22:11:236067 EXPECT_EQ("www.example.org:80",
[email protected]79cb5c12011-09-12 13:12:046068 response->auth_challenge->challenger.ToString());
6069 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
6070 EXPECT_EQ("basic", response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:236071
[email protected]49639fa2011-12-20 23:22:416072 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:236073
[email protected]49639fa2011-12-20 23:22:416074 rv = trans->RestartWithAuth(
6075 AuthCredentials(kFoo2, kBar2), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:426076 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236077
6078 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426079 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236080
6081 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506082 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:236083 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6084 EXPECT_EQ(100, response->headers->GetContentLength());
6085 }
6086
6087 // ------------------------------------------------------------------------
6088
6089 // Transaction 3: Resend a request in MyRealm's protection space --
6090 // succeed with preemptive authorization.
6091 {
[email protected]1c773ea12009-04-28 19:58:426092 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236093 request.method = "GET";
bncce36dca22015-04-21 22:11:236094 request.url = GURL("http://www.example.org/x/y/z2");
[email protected]f9ee6b52008-11-08 06:46:236095 request.load_flags = 0;
6096
[email protected]262eec82013-03-19 21:01:366097 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506098 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276099
[email protected]f9ee6b52008-11-08 06:46:236100 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236101 MockWrite(
6102 "GET /x/y/z2 HTTP/1.1\r\n"
6103 "Host: www.example.org\r\n"
6104 "Connection: keep-alive\r\n"
6105 // The authorization for MyRealm1 gets sent preemptively
6106 // (since the url is in the same protection space)
6107 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236108 };
6109
6110 // Sever accepts the preemptive authorization
6111 MockRead data_reads1[] = {
6112 MockRead("HTTP/1.0 200 OK\r\n"),
6113 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066114 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:236115 };
6116
[email protected]31a2bfe2010-02-09 08:03:396117 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6118 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:076119 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:236120
[email protected]49639fa2011-12-20 23:22:416121 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:236122
[email protected]49639fa2011-12-20 23:22:416123 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426124 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236125
6126 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426127 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236128
[email protected]1c773ea12009-04-28 19:58:426129 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506130 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:236131
6132 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6133 EXPECT_EQ(100, response->headers->GetContentLength());
6134 }
6135
6136 // ------------------------------------------------------------------------
6137
6138 // Transaction 4: request another URL in MyRealm (however the
6139 // url is not known to belong to the protection space, so no pre-auth).
6140 {
[email protected]1c773ea12009-04-28 19:58:426141 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236142 request.method = "GET";
bncce36dca22015-04-21 22:11:236143 request.url = GURL("http://www.example.org/x/1");
[email protected]f9ee6b52008-11-08 06:46:236144 request.load_flags = 0;
6145
[email protected]262eec82013-03-19 21:01:366146 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506147 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276148
[email protected]f9ee6b52008-11-08 06:46:236149 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236150 MockWrite(
6151 "GET /x/1 HTTP/1.1\r\n"
6152 "Host: www.example.org\r\n"
6153 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236154 };
6155
6156 MockRead data_reads1[] = {
6157 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6158 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6159 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066160 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236161 };
6162
6163 // Resend with authorization from MyRealm's cache.
6164 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236165 MockWrite(
6166 "GET /x/1 HTTP/1.1\r\n"
6167 "Host: www.example.org\r\n"
6168 "Connection: keep-alive\r\n"
6169 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236170 };
6171
6172 // Sever accepts the authorization.
6173 MockRead data_reads2[] = {
6174 MockRead("HTTP/1.0 200 OK\r\n"),
6175 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066176 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:236177 };
6178
[email protected]31a2bfe2010-02-09 08:03:396179 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6180 data_writes1, arraysize(data_writes1));
6181 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6182 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076183 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6184 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:236185
[email protected]49639fa2011-12-20 23:22:416186 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:236187
[email protected]49639fa2011-12-20 23:22:416188 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426189 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236190
6191 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426192 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236193
[email protected]0757e7702009-03-27 04:00:226194 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:416195 TestCompletionCallback callback2;
6196 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:426197 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:226198 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426199 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:226200 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6201
[email protected]1c773ea12009-04-28 19:58:426202 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506203 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:236204 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6205 EXPECT_EQ(100, response->headers->GetContentLength());
6206 }
6207
6208 // ------------------------------------------------------------------------
6209
6210 // Transaction 5: request a URL in MyRealm, but the server rejects the
6211 // cached identity. Should invalidate and re-prompt.
6212 {
[email protected]1c773ea12009-04-28 19:58:426213 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236214 request.method = "GET";
bncce36dca22015-04-21 22:11:236215 request.url = GURL("http://www.example.org/p/q/t");
[email protected]f9ee6b52008-11-08 06:46:236216 request.load_flags = 0;
6217
[email protected]262eec82013-03-19 21:01:366218 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506219 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276220
[email protected]f9ee6b52008-11-08 06:46:236221 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236222 MockWrite(
6223 "GET /p/q/t HTTP/1.1\r\n"
6224 "Host: www.example.org\r\n"
6225 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236226 };
6227
6228 MockRead data_reads1[] = {
6229 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6230 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6231 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066232 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236233 };
6234
6235 // Resend with authorization from cache for MyRealm.
6236 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236237 MockWrite(
6238 "GET /p/q/t HTTP/1.1\r\n"
6239 "Host: www.example.org\r\n"
6240 "Connection: keep-alive\r\n"
6241 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236242 };
6243
6244 // Sever rejects the authorization.
6245 MockRead data_reads2[] = {
6246 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6247 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6248 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066249 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236250 };
6251
6252 // At this point we should prompt for new credentials for MyRealm.
6253 // Restart with username=foo3, password=foo4.
6254 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236255 MockWrite(
6256 "GET /p/q/t HTTP/1.1\r\n"
6257 "Host: www.example.org\r\n"
6258 "Connection: keep-alive\r\n"
6259 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236260 };
6261
6262 // Sever accepts the authorization.
6263 MockRead data_reads3[] = {
6264 MockRead("HTTP/1.0 200 OK\r\n"),
6265 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066266 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:236267 };
6268
[email protected]31a2bfe2010-02-09 08:03:396269 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6270 data_writes1, arraysize(data_writes1));
6271 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6272 data_writes2, arraysize(data_writes2));
6273 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6274 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076275 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6276 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6277 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:236278
[email protected]49639fa2011-12-20 23:22:416279 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:236280
[email protected]49639fa2011-12-20 23:22:416281 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426282 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236283
6284 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426285 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236286
[email protected]0757e7702009-03-27 04:00:226287 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:416288 TestCompletionCallback callback2;
6289 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:426290 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:226291 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426292 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:226293 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6294
[email protected]1c773ea12009-04-28 19:58:426295 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506296 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:046297 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:236298
[email protected]49639fa2011-12-20 23:22:416299 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:236300
[email protected]49639fa2011-12-20 23:22:416301 rv = trans->RestartWithAuth(
6302 AuthCredentials(kFoo3, kBar3), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:426303 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236304
[email protected]0757e7702009-03-27 04:00:226305 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426306 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236307
6308 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506309 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:236310 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6311 EXPECT_EQ(100, response->headers->GetContentLength());
6312 }
6313}
[email protected]89ceba9a2009-03-21 03:46:066314
[email protected]3c32c5f2010-05-18 15:18:126315// Tests that nonce count increments when multiple auth attempts
6316// are started with the same nonce.
[email protected]23e482282013-06-14 16:08:026317TEST_P(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:446318 HttpAuthHandlerDigest::Factory* digest_factory =
6319 new HttpAuthHandlerDigest::Factory();
6320 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
6321 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
6322 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:076323 session_deps_.http_auth_handler_factory.reset(digest_factory);
mmenke6b3af6e2015-09-12 02:06:066324 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:126325
6326 // Transaction 1: authenticate (foo, bar) on MyRealm1
6327 {
[email protected]3c32c5f2010-05-18 15:18:126328 HttpRequestInfo request;
6329 request.method = "GET";
bncce36dca22015-04-21 22:11:236330 request.url = GURL("http://www.example.org/x/y/z");
[email protected]3c32c5f2010-05-18 15:18:126331 request.load_flags = 0;
6332
[email protected]262eec82013-03-19 21:01:366333 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506334 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276335
[email protected]3c32c5f2010-05-18 15:18:126336 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236337 MockWrite(
6338 "GET /x/y/z HTTP/1.1\r\n"
6339 "Host: www.example.org\r\n"
6340 "Connection: keep-alive\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:126341 };
6342
6343 MockRead data_reads1[] = {
6344 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6345 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
6346 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066347 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:126348 };
6349
6350 // Resend with authorization (username=foo, password=bar)
6351 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236352 MockWrite(
6353 "GET /x/y/z HTTP/1.1\r\n"
6354 "Host: www.example.org\r\n"
6355 "Connection: keep-alive\r\n"
6356 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
6357 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
6358 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
6359 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:126360 };
6361
6362 // Sever accepts the authorization.
6363 MockRead data_reads2[] = {
zmo9528c9f42015-08-04 22:12:086364 MockRead("HTTP/1.0 200 OK\r\n"),
6365 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:126366 };
6367
6368 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6369 data_writes1, arraysize(data_writes1));
6370 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6371 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076372 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6373 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:126374
[email protected]49639fa2011-12-20 23:22:416375 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:126376
[email protected]49639fa2011-12-20 23:22:416377 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:126378 EXPECT_EQ(ERR_IO_PENDING, rv);
6379
6380 rv = callback1.WaitForResult();
6381 EXPECT_EQ(OK, rv);
6382
6383 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506384 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:046385 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:126386
[email protected]49639fa2011-12-20 23:22:416387 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:126388
[email protected]49639fa2011-12-20 23:22:416389 rv = trans->RestartWithAuth(
6390 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]3c32c5f2010-05-18 15:18:126391 EXPECT_EQ(ERR_IO_PENDING, rv);
6392
6393 rv = callback2.WaitForResult();
6394 EXPECT_EQ(OK, rv);
6395
6396 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506397 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:126398 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6399 }
6400
6401 // ------------------------------------------------------------------------
6402
6403 // Transaction 2: Request another resource in digestive's protection space.
6404 // This will preemptively add an Authorization header which should have an
6405 // "nc" value of 2 (as compared to 1 in the first use.
6406 {
[email protected]3c32c5f2010-05-18 15:18:126407 HttpRequestInfo request;
6408 request.method = "GET";
6409 // Note that Transaction 1 was at /x/y/z, so this is in the same
6410 // protection space as digest.
bncce36dca22015-04-21 22:11:236411 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]3c32c5f2010-05-18 15:18:126412 request.load_flags = 0;
6413
[email protected]262eec82013-03-19 21:01:366414 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506415 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276416
[email protected]3c32c5f2010-05-18 15:18:126417 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236418 MockWrite(
6419 "GET /x/y/a/b HTTP/1.1\r\n"
6420 "Host: www.example.org\r\n"
6421 "Connection: keep-alive\r\n"
6422 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
6423 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
6424 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
6425 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:126426 };
6427
6428 // Sever accepts the authorization.
6429 MockRead data_reads1[] = {
6430 MockRead("HTTP/1.0 200 OK\r\n"),
6431 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066432 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:126433 };
6434
6435 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6436 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:076437 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:126438
[email protected]49639fa2011-12-20 23:22:416439 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:126440
[email protected]49639fa2011-12-20 23:22:416441 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:126442 EXPECT_EQ(ERR_IO_PENDING, rv);
6443
6444 rv = callback1.WaitForResult();
6445 EXPECT_EQ(OK, rv);
6446
6447 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506448 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:126449 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6450 }
6451}
6452
[email protected]89ceba9a2009-03-21 03:46:066453// Test the ResetStateForRestart() private method.
[email protected]23e482282013-06-14 16:08:026454TEST_P(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:066455 // Create a transaction (the dependencies aren't important).
mmenke6b3af6e2015-09-12 02:06:066456 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:406457 scoped_ptr<HttpNetworkTransaction> trans(
dcheng48459ac22014-08-26 00:46:416458 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]89ceba9a2009-03-21 03:46:066459
6460 // Setup some state (which we expect ResetStateForRestart() will clear).
[email protected]89ceba9a2009-03-21 03:46:066461 trans->read_buf_ = new IOBuffer(15);
6462 trans->read_buf_len_ = 15;
[email protected]b94f92d2010-10-27 16:45:206463 trans->request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:066464
6465 // Setup state in response_
[email protected]a7e41312009-12-16 23:18:146466 HttpResponseInfo* response = &trans->response_;
[email protected]0877e3d2009-10-17 22:29:576467 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:086468 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:576469 response->response_time = base::Time::Now();
6470 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:066471
6472 { // Setup state for response_.vary_data
6473 HttpRequestInfo request;
6474 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
6475 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:276476 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:436477 request.extra_headers.SetHeader("Foo", "1");
6478 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:506479 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:066480 }
6481
6482 // Cause the above state to be reset.
6483 trans->ResetStateForRestart();
6484
6485 // Verify that the state that needed to be reset, has been reset.
[email protected]9b6fee12009-09-29 18:13:076486 EXPECT_TRUE(trans->read_buf_.get() == NULL);
[email protected]89ceba9a2009-03-21 03:46:066487 EXPECT_EQ(0, trans->read_buf_len_);
[email protected]b94f92d2010-10-27 16:45:206488 EXPECT_TRUE(trans->request_headers_.IsEmpty());
[email protected]0877e3d2009-10-17 22:29:576489 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6490 EXPECT_TRUE(response->headers.get() == NULL);
[email protected]34f40942010-10-04 00:34:046491 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:086492 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:576493 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:066494}
6495
[email protected]bacff652009-03-31 17:50:336496// Test HTTPS connections to a site with a bad certificate
[email protected]23e482282013-06-14 16:08:026497TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:336498 HttpRequestInfo request;
6499 request.method = "GET";
bncce36dca22015-04-21 22:11:236500 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:336501 request.load_flags = 0;
6502
mmenke6b3af6e2015-09-12 02:06:066503 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276504 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416505 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276506
[email protected]bacff652009-03-31 17:50:336507 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236508 MockWrite(
6509 "GET / HTTP/1.1\r\n"
6510 "Host: www.example.org\r\n"
6511 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:336512 };
6513
6514 MockRead data_reads[] = {
6515 MockRead("HTTP/1.0 200 OK\r\n"),
6516 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6517 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066518 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:336519 };
6520
[email protected]5ecc992a42009-11-11 01:41:596521 StaticSocketDataProvider ssl_bad_certificate;
[email protected]31a2bfe2010-02-09 08:03:396522 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6523 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066524 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
6525 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:336526
[email protected]bb88e1d32013-05-03 23:11:076527 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
6528 session_deps_.socket_factory->AddSocketDataProvider(&data);
6529 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
6530 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:336531
[email protected]49639fa2011-12-20 23:22:416532 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:336533
[email protected]49639fa2011-12-20 23:22:416534 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:336535 EXPECT_EQ(ERR_IO_PENDING, rv);
6536
6537 rv = callback.WaitForResult();
6538 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
6539
[email protected]49639fa2011-12-20 23:22:416540 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:336541 EXPECT_EQ(ERR_IO_PENDING, rv);
6542
6543 rv = callback.WaitForResult();
6544 EXPECT_EQ(OK, rv);
6545
6546 const HttpResponseInfo* response = trans->GetResponseInfo();
6547
[email protected]fe2255a2011-09-20 19:37:506548 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:336549 EXPECT_EQ(100, response->headers->GetContentLength());
6550}
6551
6552// Test HTTPS connections to a site with a bad certificate, going through a
6553// proxy
[email protected]23e482282013-06-14 16:08:026554TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
rdsmith82957ad2015-09-16 19:42:036555 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]bacff652009-03-31 17:50:336556
6557 HttpRequestInfo request;
6558 request.method = "GET";
bncce36dca22015-04-21 22:11:236559 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:336560 request.load_flags = 0;
6561
6562 MockWrite proxy_writes[] = {
bncce36dca22015-04-21 22:11:236563 MockWrite(
6564 "CONNECT www.example.org:443 HTTP/1.1\r\n"
6565 "Host: www.example.org\r\n"
6566 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:336567 };
6568
6569 MockRead proxy_reads[] = {
6570 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066571 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:336572 };
6573
6574 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236575 MockWrite(
6576 "CONNECT www.example.org:443 HTTP/1.1\r\n"
6577 "Host: www.example.org\r\n"
6578 "Proxy-Connection: keep-alive\r\n\r\n"),
6579 MockWrite(
6580 "GET / HTTP/1.1\r\n"
6581 "Host: www.example.org\r\n"
6582 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:336583 };
6584
6585 MockRead data_reads[] = {
6586 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
6587 MockRead("HTTP/1.0 200 OK\r\n"),
6588 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6589 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066590 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:336591 };
6592
[email protected]31a2bfe2010-02-09 08:03:396593 StaticSocketDataProvider ssl_bad_certificate(
6594 proxy_reads, arraysize(proxy_reads),
6595 proxy_writes, arraysize(proxy_writes));
6596 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6597 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066598 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
6599 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:336600
[email protected]bb88e1d32013-05-03 23:11:076601 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
6602 session_deps_.socket_factory->AddSocketDataProvider(&data);
6603 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
6604 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:336605
[email protected]49639fa2011-12-20 23:22:416606 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:336607
6608 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:076609 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:336610
mmenke6b3af6e2015-09-12 02:06:066611 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:406612 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416613 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bacff652009-03-31 17:50:336614
[email protected]49639fa2011-12-20 23:22:416615 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:336616 EXPECT_EQ(ERR_IO_PENDING, rv);
6617
6618 rv = callback.WaitForResult();
6619 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
6620
[email protected]49639fa2011-12-20 23:22:416621 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:336622 EXPECT_EQ(ERR_IO_PENDING, rv);
6623
6624 rv = callback.WaitForResult();
6625 EXPECT_EQ(OK, rv);
6626
6627 const HttpResponseInfo* response = trans->GetResponseInfo();
6628
[email protected]fe2255a2011-09-20 19:37:506629 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:336630 EXPECT_EQ(100, response->headers->GetContentLength());
6631 }
6632}
6633
[email protected]2df19bb2010-08-25 20:13:466634
6635// Test HTTPS connections to a site, going through an HTTPS proxy
[email protected]23e482282013-06-14 16:08:026636TEST_P(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:036637 session_deps_.proxy_service =
6638 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:516639 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076640 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:466641
6642 HttpRequestInfo request;
6643 request.method = "GET";
bncce36dca22015-04-21 22:11:236644 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:466645 request.load_flags = 0;
6646
6647 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236648 MockWrite(
6649 "CONNECT www.example.org:443 HTTP/1.1\r\n"
6650 "Host: www.example.org\r\n"
6651 "Proxy-Connection: keep-alive\r\n\r\n"),
6652 MockWrite(
6653 "GET / HTTP/1.1\r\n"
6654 "Host: www.example.org\r\n"
6655 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:466656 };
6657
6658 MockRead data_reads[] = {
6659 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
6660 MockRead("HTTP/1.1 200 OK\r\n"),
6661 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6662 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066663 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:466664 };
6665
6666 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6667 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066668 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
6669 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:466670
[email protected]bb88e1d32013-05-03 23:11:076671 session_deps_.socket_factory->AddSocketDataProvider(&data);
6672 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
6673 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:466674
[email protected]49639fa2011-12-20 23:22:416675 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:466676
mmenke6b3af6e2015-09-12 02:06:066677 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:466678 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416679 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2df19bb2010-08-25 20:13:466680
[email protected]49639fa2011-12-20 23:22:416681 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:466682 EXPECT_EQ(ERR_IO_PENDING, rv);
6683
6684 rv = callback.WaitForResult();
6685 EXPECT_EQ(OK, rv);
6686 const HttpResponseInfo* response = trans->GetResponseInfo();
6687
[email protected]fe2255a2011-09-20 19:37:506688 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:466689
6690 EXPECT_TRUE(response->headers->IsKeepAlive());
6691 EXPECT_EQ(200, response->headers->response_code());
6692 EXPECT_EQ(100, response->headers->GetContentLength());
6693 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:206694
6695 LoadTimingInfo load_timing_info;
6696 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6697 TestLoadTimingNotReusedWithPac(load_timing_info,
6698 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:466699}
6700
[email protected]511f6f52010-12-17 03:58:296701// Test an HTTPS Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:026702TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:036703 session_deps_.proxy_service =
6704 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:516705 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076706 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:296707
6708 HttpRequestInfo request;
6709 request.method = "GET";
bncce36dca22015-04-21 22:11:236710 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:296711 request.load_flags = 0;
6712
6713 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236714 MockWrite(
6715 "CONNECT www.example.org:443 HTTP/1.1\r\n"
6716 "Host: www.example.org\r\n"
6717 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:296718 };
6719
6720 MockRead data_reads[] = {
6721 MockRead("HTTP/1.1 302 Redirect\r\n"),
6722 MockRead("Location: http://login.example.com/\r\n"),
6723 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066724 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:296725 };
6726
6727 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6728 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066729 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:296730
[email protected]bb88e1d32013-05-03 23:11:076731 session_deps_.socket_factory->AddSocketDataProvider(&data);
6732 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296733
[email protected]49639fa2011-12-20 23:22:416734 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296735
mmenke6b3af6e2015-09-12 02:06:066736 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296737 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416738 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:296739
[email protected]49639fa2011-12-20 23:22:416740 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296741 EXPECT_EQ(ERR_IO_PENDING, rv);
6742
6743 rv = callback.WaitForResult();
6744 EXPECT_EQ(OK, rv);
6745 const HttpResponseInfo* response = trans->GetResponseInfo();
6746
[email protected]fe2255a2011-09-20 19:37:506747 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:296748
6749 EXPECT_EQ(302, response->headers->response_code());
6750 std::string url;
6751 EXPECT_TRUE(response->headers->IsRedirect(&url));
6752 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:206753
6754 // In the case of redirects from proxies, HttpNetworkTransaction returns
6755 // timing for the proxy connection instead of the connection to the host,
6756 // and no send / receive times.
6757 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
6758 LoadTimingInfo load_timing_info;
6759 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6760
6761 EXPECT_FALSE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:296762 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:206763
6764 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
6765 EXPECT_LE(load_timing_info.proxy_resolve_start,
6766 load_timing_info.proxy_resolve_end);
6767 EXPECT_LE(load_timing_info.proxy_resolve_end,
6768 load_timing_info.connect_timing.connect_start);
6769 ExpectConnectTimingHasTimes(
6770 load_timing_info.connect_timing,
6771 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
6772
6773 EXPECT_TRUE(load_timing_info.send_start.is_null());
6774 EXPECT_TRUE(load_timing_info.send_end.is_null());
6775 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:296776}
6777
6778// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:026779TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
rdsmith82957ad2015-09-16 19:42:036780 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:296781
6782 HttpRequestInfo request;
6783 request.method = "GET";
bncce36dca22015-04-21 22:11:236784 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:296785 request.load_flags = 0;
6786
lgarrona91df87f2014-12-05 00:51:346787 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:236788 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]c10b20852013-05-15 21:29:206789 scoped_ptr<SpdyFrame> goaway(
6790 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:296791 MockWrite data_writes[] = {
rch8e6c6c42015-05-01 14:05:136792 CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
6793 CreateMockWrite(*goaway.get(), 2, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:296794 };
6795
6796 static const char* const kExtraHeaders[] = {
6797 "location",
6798 "http://login.example.com/",
6799 };
[email protected]ff98d7f02012-03-22 21:44:196800 scoped_ptr<SpdyFrame> resp(
[email protected]23e482282013-06-14 16:08:026801 spdy_util_.ConstructSpdySynReplyError("302 Redirect", kExtraHeaders,
[email protected]511f6f52010-12-17 03:58:296802 arraysize(kExtraHeaders)/2, 1));
6803 MockRead data_reads[] = {
rch8e6c6c42015-05-01 14:05:136804 CreateMockRead(*resp.get(), 1), MockRead(ASYNC, 0, 3), // EOF
[email protected]511f6f52010-12-17 03:58:296805 };
6806
rch8e6c6c42015-05-01 14:05:136807 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
6808 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066809 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]23e482282013-06-14 16:08:026810 proxy_ssl.SetNextProto(GetParam());
[email protected]511f6f52010-12-17 03:58:296811
[email protected]bb88e1d32013-05-03 23:11:076812 session_deps_.socket_factory->AddSocketDataProvider(&data);
6813 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296814
[email protected]49639fa2011-12-20 23:22:416815 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296816
mmenke6b3af6e2015-09-12 02:06:066817 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296818 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416819 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:296820
[email protected]49639fa2011-12-20 23:22:416821 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296822 EXPECT_EQ(ERR_IO_PENDING, rv);
6823
6824 rv = callback.WaitForResult();
6825 EXPECT_EQ(OK, rv);
6826 const HttpResponseInfo* response = trans->GetResponseInfo();
6827
[email protected]fe2255a2011-09-20 19:37:506828 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:296829
6830 EXPECT_EQ(302, response->headers->response_code());
6831 std::string url;
6832 EXPECT_TRUE(response->headers->IsRedirect(&url));
6833 EXPECT_EQ("http://login.example.com/", url);
6834}
6835
[email protected]4eddbc732012-08-09 05:40:176836// Test that an HTTPS proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:026837TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:176838 ErrorResponseToHttpsConnectViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:036839 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:296840
6841 HttpRequestInfo request;
6842 request.method = "GET";
bncce36dca22015-04-21 22:11:236843 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:296844 request.load_flags = 0;
6845
6846 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236847 MockWrite(
6848 "CONNECT www.example.org:443 HTTP/1.1\r\n"
6849 "Host: www.example.org\r\n"
6850 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:296851 };
6852
6853 MockRead data_reads[] = {
6854 MockRead("HTTP/1.1 404 Not Found\r\n"),
6855 MockRead("Content-Length: 23\r\n\r\n"),
6856 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:066857 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:296858 };
6859
6860 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6861 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066862 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:296863
[email protected]bb88e1d32013-05-03 23:11:076864 session_deps_.socket_factory->AddSocketDataProvider(&data);
6865 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296866
[email protected]49639fa2011-12-20 23:22:416867 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296868
mmenke6b3af6e2015-09-12 02:06:066869 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296870 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416871 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:296872
[email protected]49639fa2011-12-20 23:22:416873 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296874 EXPECT_EQ(ERR_IO_PENDING, rv);
6875
6876 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:176877 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:296878
[email protected]4eddbc732012-08-09 05:40:176879 // TODO(ttuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:296880}
6881
[email protected]4eddbc732012-08-09 05:40:176882// Test that a SPDY proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:026883TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:176884 ErrorResponseToHttpsConnectViaSpdyProxy) {
rdsmith82957ad2015-09-16 19:42:036885 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:296886
6887 HttpRequestInfo request;
6888 request.method = "GET";
bncce36dca22015-04-21 22:11:236889 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:296890 request.load_flags = 0;
6891
lgarrona91df87f2014-12-05 00:51:346892 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:236893 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]c10b20852013-05-15 21:29:206894 scoped_ptr<SpdyFrame> rst(
6895 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:296896 MockWrite data_writes[] = {
rch8e6c6c42015-05-01 14:05:136897 CreateMockWrite(*conn.get(), 0), CreateMockWrite(*rst.get(), 3),
[email protected]511f6f52010-12-17 03:58:296898 };
6899
6900 static const char* const kExtraHeaders[] = {
6901 "location",
6902 "http://login.example.com/",
6903 };
[email protected]ff98d7f02012-03-22 21:44:196904 scoped_ptr<SpdyFrame> resp(
[email protected]23e482282013-06-14 16:08:026905 spdy_util_.ConstructSpdySynReplyError("404 Not Found", kExtraHeaders,
[email protected]511f6f52010-12-17 03:58:296906 arraysize(kExtraHeaders)/2, 1));
[email protected]ff98d7f02012-03-22 21:44:196907 scoped_ptr<SpdyFrame> body(
[email protected]23e482282013-06-14 16:08:026908 spdy_util_.ConstructSpdyBodyFrame(
6909 1, "The host does not exist", 23, true));
[email protected]511f6f52010-12-17 03:58:296910 MockRead data_reads[] = {
rch8e6c6c42015-05-01 14:05:136911 CreateMockRead(*resp.get(), 1),
6912 CreateMockRead(*body.get(), 2),
6913 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:296914 };
6915
rch8e6c6c42015-05-01 14:05:136916 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
6917 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066918 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]23e482282013-06-14 16:08:026919 proxy_ssl.SetNextProto(GetParam());
[email protected]511f6f52010-12-17 03:58:296920
[email protected]bb88e1d32013-05-03 23:11:076921 session_deps_.socket_factory->AddSocketDataProvider(&data);
6922 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296923
[email protected]49639fa2011-12-20 23:22:416924 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296925
mmenke6b3af6e2015-09-12 02:06:066926 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296927 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416928 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:296929
[email protected]49639fa2011-12-20 23:22:416930 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296931 EXPECT_EQ(ERR_IO_PENDING, rv);
6932
6933 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:176934 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:296935
[email protected]4eddbc732012-08-09 05:40:176936 // TODO(ttuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:296937}
6938
[email protected]0c5fb722012-02-28 11:50:356939// Test the request-challenge-retry sequence for basic auth, through
6940// a SPDY proxy over a single SPDY session.
[email protected]23e482282013-06-14 16:08:026941TEST_P(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:356942 HttpRequestInfo request;
6943 request.method = "GET";
bncce36dca22015-04-21 22:11:236944 request.url = GURL("https://www.example.org/");
[email protected]0c5fb722012-02-28 11:50:356945 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:296946 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]0c5fb722012-02-28 11:50:356947
6948 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:036949 session_deps_.proxy_service =
6950 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70");
vishal.b62985ca92015-04-17 08:45:516951 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076952 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:066953 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:356954
6955 // Since we have proxy, should try to establish tunnel.
lgarrona91df87f2014-12-05 00:51:346956 scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:236957 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]c10b20852013-05-15 21:29:206958 scoped_ptr<SpdyFrame> rst(
6959 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]0c5fb722012-02-28 11:50:356960
6961 // After calling trans->RestartWithAuth(), this is the request we should
6962 // be issuing -- the final header line contains the credentials.
6963 const char* const kAuthCredentials[] = {
6964 "proxy-authorization", "Basic Zm9vOmJhcg==",
6965 };
[email protected]fba2dbde2013-05-24 16:09:016966 scoped_ptr<SpdyFrame> connect2(spdy_util_.ConstructSpdyConnect(
lgarrona91df87f2014-12-05 00:51:346967 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST,
bncce36dca22015-04-21 22:11:236968 HostPortPair("www.example.org", 443)));
6969 // fetch https://www.example.org/ via HTTP
6970 const char get[] =
6971 "GET / HTTP/1.1\r\n"
6972 "Host: www.example.org\r\n"
6973 "Connection: keep-alive\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:196974 scoped_ptr<SpdyFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:026975 spdy_util_.ConstructSpdyBodyFrame(3, get, strlen(get), false));
[email protected]0c5fb722012-02-28 11:50:356976
6977 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:136978 CreateMockWrite(*req, 0, ASYNC),
6979 CreateMockWrite(*rst, 2, ASYNC),
6980 CreateMockWrite(*connect2, 3),
6981 CreateMockWrite(*wrapped_get, 5),
[email protected]0c5fb722012-02-28 11:50:356982 };
6983
6984 // The proxy responds to the connect with a 407, using a persistent
6985 // connection.
thestig9d3bb0c2015-01-24 00:49:516986 const char kAuthStatus[] = "407";
[email protected]0c5fb722012-02-28 11:50:356987 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:356988 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
6989 };
[email protected]745aa9c2014-06-27 02:21:296990 scoped_ptr<SpdyFrame> conn_auth_resp(spdy_util_.ConstructSpdySynReplyError(
6991 kAuthStatus, kAuthChallenge, arraysize(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:356992
[email protected]23e482282013-06-14 16:08:026993 scoped_ptr<SpdyFrame> conn_resp(
6994 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:356995 const char resp[] = "HTTP/1.1 200 OK\r\n"
6996 "Content-Length: 5\r\n\r\n";
6997
[email protected]ff98d7f02012-03-22 21:44:196998 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:026999 spdy_util_.ConstructSpdyBodyFrame(3, resp, strlen(resp), false));
[email protected]ff98d7f02012-03-22 21:44:197000 scoped_ptr<SpdyFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:027001 spdy_util_.ConstructSpdyBodyFrame(3, "hello", 5, false));
[email protected]0c5fb722012-02-28 11:50:357002 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:137003 CreateMockRead(*conn_auth_resp, 1, ASYNC),
7004 CreateMockRead(*conn_resp, 4, ASYNC),
7005 CreateMockRead(*wrapped_get_resp, 6, ASYNC),
7006 CreateMockRead(*wrapped_body, 7, ASYNC),
7007 MockRead(ASYNC, OK, 8), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:357008 };
7009
rch8e6c6c42015-05-01 14:05:137010 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
7011 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:077012 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:357013 // Negotiate SPDY to the proxy
7014 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:027015 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:077016 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:357017 // Vanilla SSL to the server
7018 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077019 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:357020
7021 TestCompletionCallback callback1;
7022
[email protected]262eec82013-03-19 21:01:367023 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507024 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0c5fb722012-02-28 11:50:357025
7026 int rv = trans->Start(&request, callback1.callback(), log.bound());
7027 EXPECT_EQ(ERR_IO_PENDING, rv);
7028
7029 rv = callback1.WaitForResult();
7030 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:467031 TestNetLogEntry::List entries;
[email protected]0c5fb722012-02-28 11:50:357032 log.GetEntries(&entries);
7033 size_t pos = ExpectLogContainsSomewhere(
7034 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
7035 NetLog::PHASE_NONE);
7036 ExpectLogContainsSomewhere(
7037 entries, pos,
7038 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
7039 NetLog::PHASE_NONE);
7040
7041 const HttpResponseInfo* response = trans->GetResponseInfo();
7042 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:507043 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]0c5fb722012-02-28 11:50:357044 EXPECT_EQ(407, response->headers->response_code());
7045 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
7046 EXPECT_TRUE(response->auth_challenge.get() != NULL);
7047 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
7048
7049 TestCompletionCallback callback2;
7050
7051 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
7052 callback2.callback());
7053 EXPECT_EQ(ERR_IO_PENDING, rv);
7054
7055 rv = callback2.WaitForResult();
7056 EXPECT_EQ(OK, rv);
7057
7058 response = trans->GetResponseInfo();
7059 ASSERT_TRUE(response != NULL);
7060
7061 EXPECT_TRUE(response->headers->IsKeepAlive());
7062 EXPECT_EQ(200, response->headers->response_code());
7063 EXPECT_EQ(5, response->headers->GetContentLength());
7064 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
7065
7066 // The password prompt info should not be set.
7067 EXPECT_TRUE(response->auth_challenge.get() == NULL);
7068
[email protected]029c83b62013-01-24 05:28:207069 LoadTimingInfo load_timing_info;
7070 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7071 TestLoadTimingNotReusedWithPac(load_timing_info,
7072 CONNECT_TIMING_HAS_SSL_TIMES);
7073
[email protected]0c5fb722012-02-28 11:50:357074 trans.reset();
7075 session->CloseAllConnections();
7076}
7077
[email protected]7c6f7ba2012-04-03 04:09:297078// Test that an explicitly trusted SPDY proxy can push a resource from an
7079// origin that is different from that of its associated resource.
[email protected]23e482282013-06-14 16:08:027080TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPush) {
[email protected]7c6f7ba2012-04-03 04:09:297081 HttpRequestInfo request;
7082 HttpRequestInfo push_request;
7083
[email protected]7c6f7ba2012-04-03 04:09:297084 request.method = "GET";
bncce36dca22015-04-21 22:11:237085 request.url = GURL("http://www.example.org/");
[email protected]7c6f7ba2012-04-03 04:09:297086 push_request.method = "GET";
7087 push_request.url = GURL("http://www.another-origin.com/foo.dat");
7088
[email protected]7c6f7ba2012-04-03 04:09:297089 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:037090 session_deps_.proxy_service =
7091 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70");
vishal.b62985ca92015-04-17 08:45:517092 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:077093 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:507094
7095 // Enable cross-origin push.
[email protected]bb88e1d32013-05-03 23:11:077096 session_deps_.trusted_spdy_proxy = "myproxy:70";
[email protected]61b4efc2012-04-27 18:12:507097
mmenke6b3af6e2015-09-12 02:06:067098 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:297099
[email protected]cdf8f7e72013-05-23 10:56:467100 scoped_ptr<SpdyFrame> stream1_syn(
7101 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]7c6f7ba2012-04-03 04:09:297102
7103 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:137104 CreateMockWrite(*stream1_syn, 0, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:297105 };
7106
7107 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:027108 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:297109
7110 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:027111 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:297112
7113 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:027114 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
[email protected]7c6f7ba2012-04-03 04:09:297115 0,
7116 2,
7117 1,
7118 "http://www.another-origin.com/foo.dat"));
[email protected]8a0fc822013-06-27 20:52:437119 const char kPushedData[] = "pushed";
7120 scoped_ptr<SpdyFrame> stream2_body(
7121 spdy_util_.ConstructSpdyBodyFrame(
7122 2, kPushedData, strlen(kPushedData), true));
[email protected]7c6f7ba2012-04-03 04:09:297123
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, 3, ASYNC),
7128 CreateMockRead(*stream2_body, 4, ASYNC),
7129 MockRead(ASYNC, ERR_IO_PENDING, 5), // Force a pause
[email protected]7c6f7ba2012-04-03 04:09:297130 };
7131
rch8e6c6c42015-05-01 14:05:137132 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
7133 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:077134 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:297135 // Negotiate SPDY to the proxy
7136 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:027137 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:077138 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:297139
[email protected]262eec82013-03-19 21:01:367140 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507141 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7c6f7ba2012-04-03 04:09:297142 TestCompletionCallback callback;
7143 int rv = trans->Start(&request, callback.callback(), log.bound());
7144 EXPECT_EQ(ERR_IO_PENDING, rv);
7145
7146 rv = callback.WaitForResult();
7147 EXPECT_EQ(OK, rv);
7148 const HttpResponseInfo* response = trans->GetResponseInfo();
7149
[email protected]262eec82013-03-19 21:01:367150 scoped_ptr<HttpTransaction> push_trans(
[email protected]90499482013-06-01 00:39:507151 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
7152 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
[email protected]7c6f7ba2012-04-03 04:09:297153 EXPECT_EQ(ERR_IO_PENDING, rv);
7154
7155 rv = callback.WaitForResult();
7156 EXPECT_EQ(OK, rv);
7157 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
7158
7159 ASSERT_TRUE(response != NULL);
7160 EXPECT_TRUE(response->headers->IsKeepAlive());
7161
7162 EXPECT_EQ(200, response->headers->response_code());
7163 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
7164
7165 std::string response_data;
7166 rv = ReadTransaction(trans.get(), &response_data);
7167 EXPECT_EQ(OK, rv);
7168 EXPECT_EQ("hello!", response_data);
7169
[email protected]029c83b62013-01-24 05:28:207170 LoadTimingInfo load_timing_info;
7171 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7172 TestLoadTimingNotReusedWithPac(load_timing_info,
7173 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7174
[email protected]7c6f7ba2012-04-03 04:09:297175 // Verify the pushed stream.
[email protected]90499482013-06-01 00:39:507176 EXPECT_TRUE(push_response->headers.get() != NULL);
[email protected]7c6f7ba2012-04-03 04:09:297177 EXPECT_EQ(200, push_response->headers->response_code());
7178
7179 rv = ReadTransaction(push_trans.get(), &response_data);
7180 EXPECT_EQ(OK, rv);
7181 EXPECT_EQ("pushed", response_data);
7182
[email protected]029c83b62013-01-24 05:28:207183 LoadTimingInfo push_load_timing_info;
7184 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
7185 TestLoadTimingReusedWithPac(push_load_timing_info);
7186 // The transactions should share a socket ID, despite being for different
7187 // origins.
7188 EXPECT_EQ(load_timing_info.socket_log_id,
7189 push_load_timing_info.socket_log_id);
7190
[email protected]7c6f7ba2012-04-03 04:09:297191 trans.reset();
7192 push_trans.reset();
7193 session->CloseAllConnections();
7194}
7195
[email protected]8c843192012-04-05 07:15:007196// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
[email protected]23e482282013-06-14 16:08:027197TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
[email protected]8c843192012-04-05 07:15:007198 HttpRequestInfo request;
7199
7200 request.method = "GET";
bncce36dca22015-04-21 22:11:237201 request.url = GURL("http://www.example.org/");
[email protected]8c843192012-04-05 07:15:007202
[email protected]8c843192012-04-05 07:15:007203 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:037204 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:517205 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:077206 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:507207
7208 // Enable cross-origin push.
[email protected]bb88e1d32013-05-03 23:11:077209 session_deps_.trusted_spdy_proxy = "myproxy:70";
[email protected]61b4efc2012-04-27 18:12:507210
mmenke6b3af6e2015-09-12 02:06:067211 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:007212
[email protected]cdf8f7e72013-05-23 10:56:467213 scoped_ptr<SpdyFrame> stream1_syn(
7214 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]8c843192012-04-05 07:15:007215
7216 scoped_ptr<SpdyFrame> push_rst(
[email protected]c10b20852013-05-15 21:29:207217 spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:007218
7219 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:137220 CreateMockWrite(*stream1_syn, 0, ASYNC), CreateMockWrite(*push_rst, 3),
[email protected]8c843192012-04-05 07:15:007221 };
7222
7223 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:027224 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:007225
7226 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:027227 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8c843192012-04-05 07:15:007228
7229 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:027230 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
[email protected]8c843192012-04-05 07:15:007231 0,
7232 2,
7233 1,
7234 "https://www.another-origin.com/foo.dat"));
7235
7236 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:137237 CreateMockRead(*stream1_reply, 1, ASYNC),
7238 CreateMockRead(*stream2_syn, 2, ASYNC),
7239 CreateMockRead(*stream1_body, 4, ASYNC),
7240 MockRead(ASYNC, ERR_IO_PENDING, 5), // Force a pause
[email protected]8c843192012-04-05 07:15:007241 };
7242
rch8e6c6c42015-05-01 14:05:137243 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
7244 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:077245 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:007246 // Negotiate SPDY to the proxy
7247 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:027248 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:077249 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:007250
[email protected]262eec82013-03-19 21:01:367251 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507252 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c843192012-04-05 07:15:007253 TestCompletionCallback callback;
7254 int rv = trans->Start(&request, callback.callback(), log.bound());
7255 EXPECT_EQ(ERR_IO_PENDING, rv);
7256
7257 rv = callback.WaitForResult();
7258 EXPECT_EQ(OK, rv);
7259 const HttpResponseInfo* response = trans->GetResponseInfo();
7260
7261 ASSERT_TRUE(response != NULL);
7262 EXPECT_TRUE(response->headers->IsKeepAlive());
7263
7264 EXPECT_EQ(200, response->headers->response_code());
7265 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
7266
7267 std::string response_data;
7268 rv = ReadTransaction(trans.get(), &response_data);
7269 EXPECT_EQ(OK, rv);
7270 EXPECT_EQ("hello!", response_data);
7271
7272 trans.reset();
7273 session->CloseAllConnections();
7274}
7275
[email protected]2df19bb2010-08-25 20:13:467276// Test HTTPS connections to a site with a bad certificate, going through an
7277// HTTPS proxy
[email protected]23e482282013-06-14 16:08:027278TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037279 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]2df19bb2010-08-25 20:13:467280
7281 HttpRequestInfo request;
7282 request.method = "GET";
bncce36dca22015-04-21 22:11:237283 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:467284 request.load_flags = 0;
7285
7286 // Attempt to fetch the URL from a server with a bad cert
7287 MockWrite bad_cert_writes[] = {
bncce36dca22015-04-21 22:11:237288 MockWrite(
7289 "CONNECT www.example.org:443 HTTP/1.1\r\n"
7290 "Host: www.example.org\r\n"
7291 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:467292 };
7293
7294 MockRead bad_cert_reads[] = {
7295 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067296 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:467297 };
7298
7299 // Attempt to fetch the URL with a good cert
7300 MockWrite good_data_writes[] = {
bncce36dca22015-04-21 22:11:237301 MockWrite(
7302 "CONNECT www.example.org:443 HTTP/1.1\r\n"
7303 "Host: www.example.org\r\n"
7304 "Proxy-Connection: keep-alive\r\n\r\n"),
7305 MockWrite(
7306 "GET / HTTP/1.1\r\n"
7307 "Host: www.example.org\r\n"
7308 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:467309 };
7310
7311 MockRead good_cert_reads[] = {
7312 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
7313 MockRead("HTTP/1.0 200 OK\r\n"),
7314 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7315 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067316 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:467317 };
7318
7319 StaticSocketDataProvider ssl_bad_certificate(
7320 bad_cert_reads, arraysize(bad_cert_reads),
7321 bad_cert_writes, arraysize(bad_cert_writes));
7322 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
7323 good_data_writes, arraysize(good_data_writes));
[email protected]8ddf8322012-02-23 18:08:067324 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
7325 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:467326
7327 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:077328 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7329 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
7330 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:467331
7332 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:077333 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7334 session_deps_.socket_factory->AddSocketDataProvider(&data);
7335 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:467336
[email protected]49639fa2011-12-20 23:22:417337 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:467338
mmenke6b3af6e2015-09-12 02:06:067339 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:467340 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417341 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2df19bb2010-08-25 20:13:467342
[email protected]49639fa2011-12-20 23:22:417343 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:467344 EXPECT_EQ(ERR_IO_PENDING, rv);
7345
7346 rv = callback.WaitForResult();
7347 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
7348
[email protected]49639fa2011-12-20 23:22:417349 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]2df19bb2010-08-25 20:13:467350 EXPECT_EQ(ERR_IO_PENDING, rv);
7351
7352 rv = callback.WaitForResult();
7353 EXPECT_EQ(OK, rv);
7354
7355 const HttpResponseInfo* response = trans->GetResponseInfo();
7356
[email protected]fe2255a2011-09-20 19:37:507357 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:467358 EXPECT_EQ(100, response->headers->GetContentLength());
7359}
7360
[email protected]23e482282013-06-14 16:08:027361TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:427362 HttpRequestInfo request;
7363 request.method = "GET";
bncce36dca22015-04-21 22:11:237364 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:437365 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
7366 "Chromium Ultra Awesome X Edition");
[email protected]1c773ea12009-04-28 19:58:427367
mmenke6b3af6e2015-09-12 02:06:067368 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277369 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417370 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277371
[email protected]1c773ea12009-04-28 19:58:427372 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237373 MockWrite(
7374 "GET / HTTP/1.1\r\n"
7375 "Host: www.example.org\r\n"
7376 "Connection: keep-alive\r\n"
7377 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427378 };
7379
7380 // Lastly, the server responds with the actual content.
7381 MockRead data_reads[] = {
7382 MockRead("HTTP/1.0 200 OK\r\n"),
7383 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7384 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067385 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427386 };
7387
[email protected]31a2bfe2010-02-09 08:03:397388 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7389 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077390 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427391
[email protected]49639fa2011-12-20 23:22:417392 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427393
[email protected]49639fa2011-12-20 23:22:417394 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427395 EXPECT_EQ(ERR_IO_PENDING, rv);
7396
7397 rv = callback.WaitForResult();
7398 EXPECT_EQ(OK, rv);
7399}
7400
[email protected]23e482282013-06-14 16:08:027401TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:297402 HttpRequestInfo request;
7403 request.method = "GET";
bncce36dca22015-04-21 22:11:237404 request.url = GURL("https://www.example.org/");
[email protected]da81f132010-08-18 23:39:297405 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
7406 "Chromium Ultra Awesome X Edition");
7407
rdsmith82957ad2015-09-16 19:42:037408 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
mmenke6b3af6e2015-09-12 02:06:067409 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277410 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417411 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277412
[email protected]da81f132010-08-18 23:39:297413 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237414 MockWrite(
7415 "CONNECT www.example.org:443 HTTP/1.1\r\n"
7416 "Host: www.example.org\r\n"
7417 "Proxy-Connection: keep-alive\r\n"
7418 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]da81f132010-08-18 23:39:297419 };
7420 MockRead data_reads[] = {
7421 // Return an error, so the transaction stops here (this test isn't
7422 // interested in the rest).
7423 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
7424 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7425 MockRead("Proxy-Connection: close\r\n\r\n"),
7426 };
7427
7428 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7429 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077430 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:297431
[email protected]49639fa2011-12-20 23:22:417432 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:297433
[email protected]49639fa2011-12-20 23:22:417434 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]da81f132010-08-18 23:39:297435 EXPECT_EQ(ERR_IO_PENDING, rv);
7436
7437 rv = callback.WaitForResult();
7438 EXPECT_EQ(OK, rv);
7439}
7440
[email protected]23e482282013-06-14 16:08:027441TEST_P(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:427442 HttpRequestInfo request;
7443 request.method = "GET";
bncce36dca22015-04-21 22:11:237444 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427445 request.load_flags = 0;
[email protected]c10450102011-06-27 09:06:167446 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
7447 "http://the.previous.site.com/");
[email protected]1c773ea12009-04-28 19:58:427448
mmenke6b3af6e2015-09-12 02:06:067449 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277450 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417451 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277452
[email protected]1c773ea12009-04-28 19:58:427453 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237454 MockWrite(
7455 "GET / HTTP/1.1\r\n"
7456 "Host: www.example.org\r\n"
7457 "Connection: keep-alive\r\n"
7458 "Referer: http://the.previous.site.com/\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427459 };
7460
7461 // Lastly, the server responds with the actual content.
7462 MockRead data_reads[] = {
7463 MockRead("HTTP/1.0 200 OK\r\n"),
7464 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7465 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067466 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427467 };
7468
[email protected]31a2bfe2010-02-09 08:03:397469 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7470 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077471 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427472
[email protected]49639fa2011-12-20 23:22:417473 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427474
[email protected]49639fa2011-12-20 23:22:417475 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427476 EXPECT_EQ(ERR_IO_PENDING, rv);
7477
7478 rv = callback.WaitForResult();
7479 EXPECT_EQ(OK, rv);
7480}
7481
[email protected]23e482282013-06-14 16:08:027482TEST_P(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:427483 HttpRequestInfo request;
7484 request.method = "POST";
bncce36dca22015-04-21 22:11:237485 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427486
mmenke6b3af6e2015-09-12 02:06:067487 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277488 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417489 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277490
[email protected]1c773ea12009-04-28 19:58:427491 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237492 MockWrite(
7493 "POST / HTTP/1.1\r\n"
7494 "Host: www.example.org\r\n"
7495 "Connection: keep-alive\r\n"
7496 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427497 };
7498
7499 // Lastly, the server responds with the actual content.
7500 MockRead data_reads[] = {
7501 MockRead("HTTP/1.0 200 OK\r\n"),
7502 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7503 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067504 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427505 };
7506
[email protected]31a2bfe2010-02-09 08:03:397507 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7508 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077509 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427510
[email protected]49639fa2011-12-20 23:22:417511 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427512
[email protected]49639fa2011-12-20 23:22:417513 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427514 EXPECT_EQ(ERR_IO_PENDING, rv);
7515
7516 rv = callback.WaitForResult();
7517 EXPECT_EQ(OK, rv);
7518}
7519
[email protected]23e482282013-06-14 16:08:027520TEST_P(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:427521 HttpRequestInfo request;
7522 request.method = "PUT";
bncce36dca22015-04-21 22:11:237523 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427524
mmenke6b3af6e2015-09-12 02:06:067525 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277526 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417527 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277528
[email protected]1c773ea12009-04-28 19:58:427529 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237530 MockWrite(
7531 "PUT / HTTP/1.1\r\n"
7532 "Host: www.example.org\r\n"
7533 "Connection: keep-alive\r\n"
7534 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427535 };
7536
7537 // Lastly, the server responds with the actual content.
7538 MockRead data_reads[] = {
7539 MockRead("HTTP/1.0 200 OK\r\n"),
7540 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7541 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067542 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427543 };
7544
[email protected]31a2bfe2010-02-09 08:03:397545 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7546 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077547 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427548
[email protected]49639fa2011-12-20 23:22:417549 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427550
[email protected]49639fa2011-12-20 23:22:417551 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427552 EXPECT_EQ(ERR_IO_PENDING, rv);
7553
7554 rv = callback.WaitForResult();
7555 EXPECT_EQ(OK, rv);
7556}
7557
[email protected]23e482282013-06-14 16:08:027558TEST_P(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:427559 HttpRequestInfo request;
7560 request.method = "HEAD";
bncce36dca22015-04-21 22:11:237561 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427562
mmenke6b3af6e2015-09-12 02:06:067563 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277564 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417565 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277566
[email protected]1c773ea12009-04-28 19:58:427567 MockWrite data_writes[] = {
csharrisonf473dd192015-08-18 13:54:137568 MockWrite("HEAD / HTTP/1.1\r\n"
7569 "Host: www.example.org\r\n"
7570 "Connection: keep-alive\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427571 };
7572
7573 // Lastly, the server responds with the actual content.
7574 MockRead data_reads[] = {
7575 MockRead("HTTP/1.0 200 OK\r\n"),
7576 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7577 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067578 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427579 };
7580
[email protected]31a2bfe2010-02-09 08:03:397581 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7582 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077583 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427584
[email protected]49639fa2011-12-20 23:22:417585 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427586
[email protected]49639fa2011-12-20 23:22:417587 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427588 EXPECT_EQ(ERR_IO_PENDING, rv);
7589
7590 rv = callback.WaitForResult();
7591 EXPECT_EQ(OK, rv);
7592}
7593
[email protected]23e482282013-06-14 16:08:027594TEST_P(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:427595 HttpRequestInfo request;
7596 request.method = "GET";
bncce36dca22015-04-21 22:11:237597 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427598 request.load_flags = LOAD_BYPASS_CACHE;
7599
mmenke6b3af6e2015-09-12 02:06:067600 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277601 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417602 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277603
[email protected]1c773ea12009-04-28 19:58:427604 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237605 MockWrite(
7606 "GET / HTTP/1.1\r\n"
7607 "Host: www.example.org\r\n"
7608 "Connection: keep-alive\r\n"
7609 "Pragma: no-cache\r\n"
7610 "Cache-Control: no-cache\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427611 };
7612
7613 // Lastly, the server responds with the actual content.
7614 MockRead data_reads[] = {
7615 MockRead("HTTP/1.0 200 OK\r\n"),
7616 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7617 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067618 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427619 };
7620
[email protected]31a2bfe2010-02-09 08:03:397621 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7622 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077623 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427624
[email protected]49639fa2011-12-20 23:22:417625 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427626
[email protected]49639fa2011-12-20 23:22:417627 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427628 EXPECT_EQ(ERR_IO_PENDING, rv);
7629
7630 rv = callback.WaitForResult();
7631 EXPECT_EQ(OK, rv);
7632}
7633
[email protected]23e482282013-06-14 16:08:027634TEST_P(HttpNetworkTransactionTest,
[email protected]1c773ea12009-04-28 19:58:427635 BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:427636 HttpRequestInfo request;
7637 request.method = "GET";
bncce36dca22015-04-21 22:11:237638 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427639 request.load_flags = LOAD_VALIDATE_CACHE;
7640
mmenke6b3af6e2015-09-12 02:06:067641 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277642 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417643 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277644
[email protected]1c773ea12009-04-28 19:58:427645 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237646 MockWrite(
7647 "GET / HTTP/1.1\r\n"
7648 "Host: www.example.org\r\n"
7649 "Connection: keep-alive\r\n"
7650 "Cache-Control: max-age=0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427651 };
7652
7653 // Lastly, the server responds with the actual content.
7654 MockRead data_reads[] = {
7655 MockRead("HTTP/1.0 200 OK\r\n"),
7656 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7657 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067658 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427659 };
7660
[email protected]31a2bfe2010-02-09 08:03:397661 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7662 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077663 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427664
[email protected]49639fa2011-12-20 23:22:417665 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427666
[email protected]49639fa2011-12-20 23:22:417667 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427668 EXPECT_EQ(ERR_IO_PENDING, rv);
7669
7670 rv = callback.WaitForResult();
7671 EXPECT_EQ(OK, rv);
7672}
7673
[email protected]23e482282013-06-14 16:08:027674TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:427675 HttpRequestInfo request;
7676 request.method = "GET";
bncce36dca22015-04-21 22:11:237677 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:437678 request.extra_headers.SetHeader("FooHeader", "Bar");
[email protected]1c773ea12009-04-28 19:58:427679
mmenke6b3af6e2015-09-12 02:06:067680 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277681 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417682 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277683
[email protected]1c773ea12009-04-28 19:58:427684 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237685 MockWrite(
7686 "GET / HTTP/1.1\r\n"
7687 "Host: www.example.org\r\n"
7688 "Connection: keep-alive\r\n"
7689 "FooHeader: Bar\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427690 };
7691
7692 // Lastly, the server responds with the actual content.
7693 MockRead data_reads[] = {
7694 MockRead("HTTP/1.0 200 OK\r\n"),
7695 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7696 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067697 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427698 };
7699
[email protected]31a2bfe2010-02-09 08:03:397700 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7701 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077702 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427703
[email protected]49639fa2011-12-20 23:22:417704 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427705
[email protected]49639fa2011-12-20 23:22:417706 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427707 EXPECT_EQ(ERR_IO_PENDING, rv);
7708
7709 rv = callback.WaitForResult();
7710 EXPECT_EQ(OK, rv);
7711}
7712
[email protected]23e482282013-06-14 16:08:027713TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:477714 HttpRequestInfo request;
7715 request.method = "GET";
bncce36dca22015-04-21 22:11:237716 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:437717 request.extra_headers.SetHeader("referer", "www.foo.com");
7718 request.extra_headers.SetHeader("hEllo", "Kitty");
7719 request.extra_headers.SetHeader("FoO", "bar");
[email protected]270c6412010-03-29 22:02:477720
mmenke6b3af6e2015-09-12 02:06:067721 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277722 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417723 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277724
[email protected]270c6412010-03-29 22:02:477725 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237726 MockWrite(
7727 "GET / HTTP/1.1\r\n"
7728 "Host: www.example.org\r\n"
7729 "Connection: keep-alive\r\n"
7730 "referer: www.foo.com\r\n"
7731 "hEllo: Kitty\r\n"
7732 "FoO: bar\r\n\r\n"),
[email protected]270c6412010-03-29 22:02:477733 };
7734
7735 // Lastly, the server responds with the actual content.
7736 MockRead data_reads[] = {
7737 MockRead("HTTP/1.0 200 OK\r\n"),
7738 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7739 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067740 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:477741 };
7742
7743 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7744 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077745 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:477746
[email protected]49639fa2011-12-20 23:22:417747 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:477748
[email protected]49639fa2011-12-20 23:22:417749 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]270c6412010-03-29 22:02:477750 EXPECT_EQ(ERR_IO_PENDING, rv);
7751
7752 rv = callback.WaitForResult();
7753 EXPECT_EQ(OK, rv);
7754}
7755
[email protected]23e482282013-06-14 16:08:027756TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277757 HttpRequestInfo request;
7758 request.method = "GET";
bncce36dca22015-04-21 22:11:237759 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:277760 request.load_flags = 0;
7761
rdsmith82957ad2015-09-16 19:42:037762 session_deps_.proxy_service =
7763 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080");
vishal.b62985ca92015-04-17 08:45:517764 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077765 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:027766
mmenke6b3af6e2015-09-12 02:06:067767 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3cd17242009-06-23 02:59:027768 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417769 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3cd17242009-06-23 02:59:027770
[email protected]3cd17242009-06-23 02:59:027771 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
7772 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7773
7774 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237775 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
7776 MockWrite(
7777 "GET / HTTP/1.1\r\n"
7778 "Host: www.example.org\r\n"
7779 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:027780
7781 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:067782 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:027783 MockRead("HTTP/1.0 200 OK\r\n"),
7784 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7785 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067786 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:027787 };
7788
[email protected]31a2bfe2010-02-09 08:03:397789 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7790 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077791 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:027792
[email protected]49639fa2011-12-20 23:22:417793 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:027794
[email protected]49639fa2011-12-20 23:22:417795 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:027796 EXPECT_EQ(ERR_IO_PENDING, rv);
7797
7798 rv = callback.WaitForResult();
7799 EXPECT_EQ(OK, rv);
7800
7801 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507802 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:027803
[email protected]029c83b62013-01-24 05:28:207804 LoadTimingInfo load_timing_info;
7805 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7806 TestLoadTimingNotReusedWithPac(load_timing_info,
7807 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7808
[email protected]3cd17242009-06-23 02:59:027809 std::string response_text;
7810 rv = ReadTransaction(trans.get(), &response_text);
7811 EXPECT_EQ(OK, rv);
7812 EXPECT_EQ("Payload", response_text);
7813}
7814
[email protected]23e482282013-06-14 16:08:027815TEST_P(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277816 HttpRequestInfo request;
7817 request.method = "GET";
bncce36dca22015-04-21 22:11:237818 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:277819 request.load_flags = 0;
7820
rdsmith82957ad2015-09-16 19:42:037821 session_deps_.proxy_service =
7822 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080");
vishal.b62985ca92015-04-17 08:45:517823 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077824 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:027825
mmenke6b3af6e2015-09-12 02:06:067826 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3cd17242009-06-23 02:59:027827 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417828 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3cd17242009-06-23 02:59:027829
[email protected]3cd17242009-06-23 02:59:027830 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
7831 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7832
7833 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237834 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
7835 arraysize(write_buffer)),
7836 MockWrite(
7837 "GET / HTTP/1.1\r\n"
7838 "Host: www.example.org\r\n"
7839 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:027840
7841 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:017842 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
7843 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:357844 MockRead("HTTP/1.0 200 OK\r\n"),
7845 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7846 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067847 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:357848 };
7849
[email protected]31a2bfe2010-02-09 08:03:397850 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7851 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077852 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:357853
[email protected]8ddf8322012-02-23 18:08:067854 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077855 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:357856
[email protected]49639fa2011-12-20 23:22:417857 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:357858
[email protected]49639fa2011-12-20 23:22:417859 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:357860 EXPECT_EQ(ERR_IO_PENDING, rv);
7861
7862 rv = callback.WaitForResult();
7863 EXPECT_EQ(OK, rv);
7864
[email protected]029c83b62013-01-24 05:28:207865 LoadTimingInfo load_timing_info;
7866 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7867 TestLoadTimingNotReusedWithPac(load_timing_info,
7868 CONNECT_TIMING_HAS_SSL_TIMES);
7869
[email protected]e0c27be2009-07-15 13:09:357870 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507871 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:357872
7873 std::string response_text;
7874 rv = ReadTransaction(trans.get(), &response_text);
7875 EXPECT_EQ(OK, rv);
7876 EXPECT_EQ("Payload", response_text);
7877}
7878
[email protected]23e482282013-06-14 16:08:027879TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:207880 HttpRequestInfo request;
7881 request.method = "GET";
bncce36dca22015-04-21 22:11:237882 request.url = GURL("http://www.example.org/");
[email protected]029c83b62013-01-24 05:28:207883 request.load_flags = 0;
7884
rdsmith82957ad2015-09-16 19:42:037885 session_deps_.proxy_service =
7886 ProxyService::CreateFixed("socks4://myproxy:1080");
vishal.b62985ca92015-04-17 08:45:517887 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077888 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:207889
mmenke6b3af6e2015-09-12 02:06:067890 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:207891 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417892 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:207893
7894 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
7895 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7896
7897 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237898 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
7899 MockWrite(
7900 "GET / HTTP/1.1\r\n"
7901 "Host: www.example.org\r\n"
7902 "Connection: keep-alive\r\n\r\n")};
[email protected]029c83b62013-01-24 05:28:207903
7904 MockRead data_reads[] = {
7905 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
7906 MockRead("HTTP/1.0 200 OK\r\n"),
7907 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7908 MockRead("Payload"),
7909 MockRead(SYNCHRONOUS, OK)
7910 };
7911
7912 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7913 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077914 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:207915
7916 TestCompletionCallback callback;
7917
7918 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7919 EXPECT_EQ(ERR_IO_PENDING, rv);
7920
7921 rv = callback.WaitForResult();
7922 EXPECT_EQ(OK, rv);
7923
7924 const HttpResponseInfo* response = trans->GetResponseInfo();
7925 ASSERT_TRUE(response != NULL);
7926
7927 LoadTimingInfo load_timing_info;
7928 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7929 TestLoadTimingNotReused(load_timing_info,
7930 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7931
7932 std::string response_text;
7933 rv = ReadTransaction(trans.get(), &response_text);
7934 EXPECT_EQ(OK, rv);
7935 EXPECT_EQ("Payload", response_text);
7936}
7937
[email protected]23e482282013-06-14 16:08:027938TEST_P(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277939 HttpRequestInfo request;
7940 request.method = "GET";
bncce36dca22015-04-21 22:11:237941 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:277942 request.load_flags = 0;
7943
rdsmith82957ad2015-09-16 19:42:037944 session_deps_.proxy_service =
7945 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:517946 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077947 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:357948
mmenke6b3af6e2015-09-12 02:06:067949 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e0c27be2009-07-15 13:09:357950 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417951 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]e0c27be2009-07-15 13:09:357952
[email protected]e0c27be2009-07-15 13:09:357953 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
7954 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:377955 const char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:237956 0x05, // Version
7957 0x01, // Command (CONNECT)
7958 0x00, // Reserved.
7959 0x03, // Address type (DOMAINNAME).
7960 0x0F, // Length of domain (15)
7961 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
7962 '.', 'o', 'r', 'g', 0x00, 0x50, // 16-bit port (80)
[email protected]f209dba2009-12-18 00:24:377963 };
[email protected]e0c27be2009-07-15 13:09:357964 const char kSOCKS5OkResponse[] =
7965 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
7966
7967 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237968 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
7969 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
7970 MockWrite(
7971 "GET / HTTP/1.1\r\n"
7972 "Host: www.example.org\r\n"
7973 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:357974
7975 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:017976 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
7977 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:357978 MockRead("HTTP/1.0 200 OK\r\n"),
7979 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7980 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067981 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:357982 };
7983
[email protected]31a2bfe2010-02-09 08:03:397984 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7985 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077986 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:357987
[email protected]49639fa2011-12-20 23:22:417988 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:357989
[email protected]49639fa2011-12-20 23:22:417990 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:357991 EXPECT_EQ(ERR_IO_PENDING, rv);
7992
7993 rv = callback.WaitForResult();
7994 EXPECT_EQ(OK, rv);
7995
7996 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507997 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:357998
[email protected]029c83b62013-01-24 05:28:207999 LoadTimingInfo load_timing_info;
8000 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8001 TestLoadTimingNotReusedWithPac(load_timing_info,
8002 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
8003
[email protected]e0c27be2009-07-15 13:09:358004 std::string response_text;
8005 rv = ReadTransaction(trans.get(), &response_text);
8006 EXPECT_EQ(OK, rv);
8007 EXPECT_EQ("Payload", response_text);
8008}
8009
[email protected]23e482282013-06-14 16:08:028010TEST_P(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:278011 HttpRequestInfo request;
8012 request.method = "GET";
bncce36dca22015-04-21 22:11:238013 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278014 request.load_flags = 0;
8015
rdsmith82957ad2015-09-16 19:42:038016 session_deps_.proxy_service =
8017 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:518018 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078019 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:358020
mmenke6b3af6e2015-09-12 02:06:068021 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e0c27be2009-07-15 13:09:358022 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418023 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]e0c27be2009-07-15 13:09:358024
[email protected]e0c27be2009-07-15 13:09:358025 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
8026 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:378027 const unsigned char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:238028 0x05, // Version
8029 0x01, // Command (CONNECT)
8030 0x00, // Reserved.
8031 0x03, // Address type (DOMAINNAME).
8032 0x0F, // Length of domain (15)
8033 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
8034 '.', 'o', 'r', 'g', 0x01, 0xBB, // 16-bit port (443)
[email protected]f209dba2009-12-18 00:24:378035 };
8036
[email protected]e0c27be2009-07-15 13:09:358037 const char kSOCKS5OkResponse[] =
8038 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
8039
8040 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238041 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
8042 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
8043 arraysize(kSOCKS5OkRequest)),
8044 MockWrite(
8045 "GET / HTTP/1.1\r\n"
8046 "Host: www.example.org\r\n"
8047 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:358048
8049 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:018050 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
8051 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:028052 MockRead("HTTP/1.0 200 OK\r\n"),
8053 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
8054 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:068055 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:028056 };
8057
[email protected]31a2bfe2010-02-09 08:03:398058 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8059 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078060 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:028061
[email protected]8ddf8322012-02-23 18:08:068062 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078063 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:028064
[email protected]49639fa2011-12-20 23:22:418065 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:028066
[email protected]49639fa2011-12-20 23:22:418067 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:028068 EXPECT_EQ(ERR_IO_PENDING, rv);
8069
8070 rv = callback.WaitForResult();
8071 EXPECT_EQ(OK, rv);
8072
8073 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508074 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:028075
[email protected]029c83b62013-01-24 05:28:208076 LoadTimingInfo load_timing_info;
8077 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8078 TestLoadTimingNotReusedWithPac(load_timing_info,
8079 CONNECT_TIMING_HAS_SSL_TIMES);
8080
[email protected]3cd17242009-06-23 02:59:028081 std::string response_text;
8082 rv = ReadTransaction(trans.get(), &response_text);
8083 EXPECT_EQ(OK, rv);
8084 EXPECT_EQ("Payload", response_text);
8085}
8086
[email protected]448d4ca52012-03-04 04:12:238087namespace {
8088
[email protected]04e5be32009-06-26 20:00:318089// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:068090
8091struct GroupNameTest {
8092 std::string proxy_server;
8093 std::string url;
8094 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:188095 bool ssl;
[email protected]2d731a32010-04-29 01:04:068096};
8097
mmenke6b3af6e2015-09-12 02:06:068098scoped_refptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]8a0fc822013-06-27 20:52:438099 NextProto next_proto,
[email protected]bb88e1d32013-05-03 23:11:078100 SpdySessionDependencies* session_deps_) {
mmenke6b3af6e2015-09-12 02:06:068101 scoped_refptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:068102
[email protected]30d4c022013-07-18 22:58:168103 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538104 session->http_server_properties();
bnccacc0992015-03-20 20:22:228105 AlternativeService alternative_service(
bnc4988e432015-03-31 03:06:258106 AlternateProtocolFromNextProto(next_proto), "", 443);
bnc7dc7e1b42015-07-28 14:43:128107 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:228108 http_server_properties->SetAlternativeService(
bnc7dc7e1b42015-07-28 14:43:128109 HostPortPair("host.with.alternate", 80), alternative_service, 1.0,
8110 expiration);
[email protected]2d731a32010-04-29 01:04:068111
8112 return session;
8113}
8114
mmenke6b3af6e2015-09-12 02:06:068115int GroupNameTransactionHelper(
8116 const std::string& url,
8117 const scoped_refptr<HttpNetworkSession>& session) {
[email protected]2d731a32010-04-29 01:04:068118 HttpRequestInfo request;
8119 request.method = "GET";
8120 request.url = GURL(url);
8121 request.load_flags = 0;
8122
[email protected]262eec82013-03-19 21:01:368123 scoped_ptr<HttpTransaction> trans(
mmenke6b3af6e2015-09-12 02:06:068124 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278125
[email protected]49639fa2011-12-20 23:22:418126 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:068127
8128 // We do not complete this request, the dtor will clean the transaction up.
[email protected]49639fa2011-12-20 23:22:418129 return trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d731a32010-04-29 01:04:068130}
8131
[email protected]448d4ca52012-03-04 04:12:238132} // namespace
8133
[email protected]23e482282013-06-14 16:08:028134TEST_P(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:068135 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:238136 {
8137 "", // unused
8138 "http://www.example.org/direct",
8139 "www.example.org:80",
8140 false,
8141 },
8142 {
8143 "", // unused
8144 "http://[2001:1418:13:1::25]/direct",
8145 "[2001:1418:13:1::25]:80",
8146 false,
8147 },
[email protected]04e5be32009-06-26 20:00:318148
bncce36dca22015-04-21 22:11:238149 // SSL Tests
8150 {
8151 "", // unused
8152 "https://www.example.org/direct_ssl",
8153 "ssl/www.example.org:443",
8154 true,
8155 },
8156 {
8157 "", // unused
8158 "https://[2001:1418:13:1::25]/direct",
8159 "ssl/[2001:1418:13:1::25]:443",
8160 true,
8161 },
8162 {
8163 "", // unused
8164 "http://host.with.alternate/direct",
8165 "ssl/host.with.alternate:443",
8166 true,
8167 },
[email protected]2d731a32010-04-29 01:04:068168 };
[email protected]2ff8b312010-04-26 22:20:548169
bnc55ff9da2015-08-19 18:42:358170 session_deps_.use_alternative_services = true;
[email protected]2d731a32010-04-29 01:04:068171
viettrungluue4a8b882014-10-16 06:17:388172 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:038173 session_deps_.proxy_service =
8174 ProxyService::CreateFixed(tests[i].proxy_server);
mmenke6b3af6e2015-09-12 02:06:068175 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:438176 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:068177
mmenke6b3af6e2015-09-12 02:06:068178 HttpNetworkSessionPeer peer(session);
[email protected]ab739042011-04-07 15:22:288179 CaptureGroupNameTransportSocketPool* transport_conn_pool =
8180 new CaptureGroupNameTransportSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:138181 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:348182 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]831e4a32013-11-14 02:14:448183 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
8184 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:028185 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
8186 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
dchenge3d1ddc2014-10-15 19:30:518187 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]2d731a32010-04-29 01:04:068188
8189 EXPECT_EQ(ERR_IO_PENDING,
mmenke6b3af6e2015-09-12 02:06:068190 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:188191 if (tests[i].ssl)
8192 EXPECT_EQ(tests[i].expected_group_name,
8193 ssl_conn_pool->last_group_name_received());
8194 else
8195 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:288196 transport_conn_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:068197 }
[email protected]2d731a32010-04-29 01:04:068198}
8199
[email protected]23e482282013-06-14 16:08:028200TEST_P(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:068201 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:238202 {
8203 "http_proxy",
8204 "http://www.example.org/http_proxy_normal",
8205 "www.example.org:80",
8206 false,
8207 },
[email protected]2d731a32010-04-29 01:04:068208
bncce36dca22015-04-21 22:11:238209 // SSL Tests
8210 {
8211 "http_proxy",
8212 "https://www.example.org/http_connect_ssl",
8213 "ssl/www.example.org:443",
8214 true,
8215 },
[email protected]af3490e2010-10-16 21:02:298216
bncce36dca22015-04-21 22:11:238217 {
8218 "http_proxy",
8219 "http://host.with.alternate/direct",
8220 "ssl/host.with.alternate:443",
8221 true,
8222 },
[email protected]45499252013-01-23 17:12:568223
bncce36dca22015-04-21 22:11:238224 {
8225 "http_proxy",
8226 "ftp://ftp.google.com/http_proxy_normal",
8227 "ftp/ftp.google.com:21",
8228 false,
8229 },
[email protected]2d731a32010-04-29 01:04:068230 };
8231
bnc55ff9da2015-08-19 18:42:358232 session_deps_.use_alternative_services = true;
[email protected]2d731a32010-04-29 01:04:068233
viettrungluue4a8b882014-10-16 06:17:388234 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:038235 session_deps_.proxy_service =
8236 ProxyService::CreateFixed(tests[i].proxy_server);
mmenke6b3af6e2015-09-12 02:06:068237 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:438238 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:068239
mmenke6b3af6e2015-09-12 02:06:068240 HttpNetworkSessionPeer peer(session);
[email protected]2d731a32010-04-29 01:04:068241
[email protected]e60e47a2010-07-14 03:37:188242 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:138243 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:348244 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:138245 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:348246 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:028247
[email protected]831e4a32013-11-14 02:14:448248 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
8249 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:028250 mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool);
8251 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
dchenge3d1ddc2014-10-15 19:30:518252 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]2d731a32010-04-29 01:04:068253
8254 EXPECT_EQ(ERR_IO_PENDING,
mmenke6b3af6e2015-09-12 02:06:068255 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:188256 if (tests[i].ssl)
8257 EXPECT_EQ(tests[i].expected_group_name,
8258 ssl_conn_pool->last_group_name_received());
8259 else
8260 EXPECT_EQ(tests[i].expected_group_name,
8261 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:068262 }
[email protected]2d731a32010-04-29 01:04:068263}
8264
[email protected]23e482282013-06-14 16:08:028265TEST_P(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:068266 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:238267 {
8268 "socks4://socks_proxy:1080",
8269 "http://www.example.org/socks4_direct",
8270 "socks4/www.example.org:80",
8271 false,
8272 },
8273 {
8274 "socks5://socks_proxy:1080",
8275 "http://www.example.org/socks5_direct",
8276 "socks5/www.example.org:80",
8277 false,
8278 },
[email protected]2d731a32010-04-29 01:04:068279
bncce36dca22015-04-21 22:11:238280 // SSL Tests
8281 {
8282 "socks4://socks_proxy:1080",
8283 "https://www.example.org/socks4_ssl",
8284 "socks4/ssl/www.example.org:443",
8285 true,
8286 },
8287 {
8288 "socks5://socks_proxy:1080",
8289 "https://www.example.org/socks5_ssl",
8290 "socks5/ssl/www.example.org:443",
8291 true,
8292 },
[email protected]af3490e2010-10-16 21:02:298293
bncce36dca22015-04-21 22:11:238294 {
8295 "socks4://socks_proxy:1080",
8296 "http://host.with.alternate/direct",
8297 "socks4/ssl/host.with.alternate:443",
8298 true,
8299 },
[email protected]04e5be32009-06-26 20:00:318300 };
8301
bnc55ff9da2015-08-19 18:42:358302 session_deps_.use_alternative_services = true;
[email protected]2ff8b312010-04-26 22:20:548303
viettrungluue4a8b882014-10-16 06:17:388304 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:038305 session_deps_.proxy_service =
8306 ProxyService::CreateFixed(tests[i].proxy_server);
mmenke6b3af6e2015-09-12 02:06:068307 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:438308 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]8b114dd72011-03-25 05:33:028309
mmenke6b3af6e2015-09-12 02:06:068310 HttpNetworkSessionPeer peer(session);
[email protected]04e5be32009-06-26 20:00:318311
[email protected]e60e47a2010-07-14 03:37:188312 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:138313 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:348314 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:138315 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:348316 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:028317
[email protected]831e4a32013-11-14 02:14:448318 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
8319 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:028320 mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_conn_pool);
8321 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
dchenge3d1ddc2014-10-15 19:30:518322 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]04e5be32009-06-26 20:00:318323
[email protected]262eec82013-03-19 21:01:368324 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508325 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]04e5be32009-06-26 20:00:318326
[email protected]2d731a32010-04-29 01:04:068327 EXPECT_EQ(ERR_IO_PENDING,
mmenke6b3af6e2015-09-12 02:06:068328 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:188329 if (tests[i].ssl)
8330 EXPECT_EQ(tests[i].expected_group_name,
8331 ssl_conn_pool->last_group_name_received());
8332 else
8333 EXPECT_EQ(tests[i].expected_group_name,
8334 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:318335 }
8336}
8337
[email protected]23e482282013-06-14 16:08:028338TEST_P(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:278339 HttpRequestInfo request;
8340 request.method = "GET";
bncce36dca22015-04-21 22:11:238341 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278342
rdsmith82957ad2015-09-16 19:42:038343 session_deps_.proxy_service =
8344 ProxyService::CreateFixed("myproxy:70;foobar:80");
[email protected]b59ff372009-07-15 22:04:328345
[email protected]69719062010-01-05 20:09:218346 // This simulates failure resolving all hostnames; that means we will fail
8347 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:078348 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:328349
mmenke6b3af6e2015-09-12 02:06:068350 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]9172a982009-06-06 00:30:258351 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418352 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]9172a982009-06-06 00:30:258353
[email protected]49639fa2011-12-20 23:22:418354 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:258355
[email protected]49639fa2011-12-20 23:22:418356 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9172a982009-06-06 00:30:258357 EXPECT_EQ(ERR_IO_PENDING, rv);
8358
[email protected]9172a982009-06-06 00:30:258359 rv = callback.WaitForResult();
[email protected]f7fccee2010-09-16 20:53:018360 EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
[email protected]9172a982009-06-06 00:30:258361}
8362
[email protected]685af592010-05-11 19:31:248363// Base test to make sure that when the load flags for a request specify to
8364// bypass the cache, the DNS cache is not used.
[email protected]23e482282013-06-14 16:08:028365void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
[email protected]bb88e1d32013-05-03 23:11:078366 int load_flags) {
[email protected]cb9bf6ca2011-01-28 13:15:278367 // Issue a request, asking to bypass the cache(s).
8368 HttpRequestInfo request;
8369 request.method = "GET";
8370 request.load_flags = load_flags;
bncce36dca22015-04-21 22:11:238371 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278372
[email protected]a2c2fb92009-07-18 07:31:048373 // Select a host resolver that does caching.
[email protected]bb88e1d32013-05-03 23:11:078374 session_deps_.host_resolver.reset(new MockCachingHostResolver);
[email protected]b59ff372009-07-15 22:04:328375
mmenke6b3af6e2015-09-12 02:06:068376 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:078377 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418378 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3b9cca42009-06-16 01:08:288379
bncce36dca22015-04-21 22:11:238380 // Warm up the host cache so it has an entry for "www.example.org".
[email protected]3b9cca42009-06-16 01:08:288381 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:298382 TestCompletionCallback callback;
[email protected]bb88e1d32013-05-03 23:11:078383 int rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:238384 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
8385 DEFAULT_PRIORITY, &addrlist, callback.callback(), NULL, BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:478386 EXPECT_EQ(ERR_IO_PENDING, rv);
8387 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:288388 EXPECT_EQ(OK, rv);
8389
8390 // Verify that it was added to host cache, by doing a subsequent async lookup
8391 // and confirming it completes synchronously.
[email protected]bb88e1d32013-05-03 23:11:078392 rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:238393 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
8394 DEFAULT_PRIORITY, &addrlist, callback.callback(), NULL, BoundNetLog());
[email protected]b59ff372009-07-15 22:04:328395 ASSERT_EQ(OK, rv);
[email protected]3b9cca42009-06-16 01:08:288396
bncce36dca22015-04-21 22:11:238397 // Inject a failure the next time that "www.example.org" is resolved. This way
[email protected]3b9cca42009-06-16 01:08:288398 // we can tell if the next lookup hit the cache, or the "network".
8399 // (cache --> success, "network" --> failure).
bncce36dca22015-04-21 22:11:238400 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.example.org");
[email protected]3b9cca42009-06-16 01:08:288401
8402 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
8403 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:068404 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
[email protected]31a2bfe2010-02-09 08:03:398405 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078406 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:288407
[email protected]3b9cca42009-06-16 01:08:288408 // Run the request.
[email protected]49639fa2011-12-20 23:22:418409 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3b9cca42009-06-16 01:08:288410 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:418411 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:288412
8413 // If we bypassed the cache, we would have gotten a failure while resolving
bncce36dca22015-04-21 22:11:238414 // "www.example.org".
[email protected]3b9cca42009-06-16 01:08:288415 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
8416}
8417
[email protected]685af592010-05-11 19:31:248418// There are multiple load flags that should trigger the host cache bypass.
8419// Test each in isolation:
[email protected]23e482282013-06-14 16:08:028420TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
[email protected]685af592010-05-11 19:31:248421 BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
8422}
8423
[email protected]23e482282013-06-14 16:08:028424TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
[email protected]685af592010-05-11 19:31:248425 BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
8426}
8427
[email protected]23e482282013-06-14 16:08:028428TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
[email protected]685af592010-05-11 19:31:248429 BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
8430}
8431
[email protected]0877e3d2009-10-17 22:29:578432// Make sure we can handle an error when writing the request.
[email protected]23e482282013-06-14 16:08:028433TEST_P(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:578434 HttpRequestInfo request;
8435 request.method = "GET";
8436 request.url = GURL("http://www.foo.com/");
8437 request.load_flags = 0;
8438
8439 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:068440 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:578441 };
[email protected]31a2bfe2010-02-09 08:03:398442 StaticSocketDataProvider data(NULL, 0,
8443 write_failure, arraysize(write_failure));
[email protected]bb88e1d32013-05-03 23:11:078444 session_deps_.socket_factory->AddSocketDataProvider(&data);
mmenke6b3af6e2015-09-12 02:06:068445 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578446
[email protected]49639fa2011-12-20 23:22:418447 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:578448
8449 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418450 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:578451
[email protected]49639fa2011-12-20 23:22:418452 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578453 EXPECT_EQ(ERR_IO_PENDING, rv);
8454
8455 rv = callback.WaitForResult();
8456 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
ttuttled9dbc652015-09-29 20:00:598457
8458 IPEndPoint endpoint;
8459 EXPECT_TRUE(trans->GetRemoteEndpoint(&endpoint));
8460 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:578461}
8462
zmo9528c9f42015-08-04 22:12:088463// Check that a connection closed after the start of the headers finishes ok.
8464TEST_P(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:578465 HttpRequestInfo request;
8466 request.method = "GET";
8467 request.url = GURL("http://www.foo.com/");
8468 request.load_flags = 0;
8469
8470 MockRead data_reads[] = {
8471 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:068472 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:578473 };
8474
[email protected]31a2bfe2010-02-09 08:03:398475 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078476 session_deps_.socket_factory->AddSocketDataProvider(&data);
mmenke6b3af6e2015-09-12 02:06:068477 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578478
[email protected]49639fa2011-12-20 23:22:418479 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:578480
8481 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418482 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:578483
[email protected]49639fa2011-12-20 23:22:418484 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578485 EXPECT_EQ(ERR_IO_PENDING, rv);
8486
8487 rv = callback.WaitForResult();
zmo9528c9f42015-08-04 22:12:088488 EXPECT_EQ(OK, rv);
8489
8490 const HttpResponseInfo* response = trans->GetResponseInfo();
8491 ASSERT_TRUE(response != NULL);
8492
8493 EXPECT_TRUE(response->headers.get() != NULL);
8494 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
8495
8496 std::string response_data;
8497 rv = ReadTransaction(trans.get(), &response_data);
8498 EXPECT_EQ(OK, rv);
8499 EXPECT_EQ("", response_data);
ttuttled9dbc652015-09-29 20:00:598500
8501 IPEndPoint endpoint;
8502 EXPECT_TRUE(trans->GetRemoteEndpoint(&endpoint));
8503 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:578504}
8505
8506// Make sure that a dropped connection while draining the body for auth
8507// restart does the right thing.
[email protected]23e482282013-06-14 16:08:028508TEST_P(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:578509 HttpRequestInfo request;
8510 request.method = "GET";
bncce36dca22015-04-21 22:11:238511 request.url = GURL("http://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:578512 request.load_flags = 0;
8513
8514 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238515 MockWrite(
8516 "GET / HTTP/1.1\r\n"
8517 "Host: www.example.org\r\n"
8518 "Connection: keep-alive\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:578519 };
8520
8521 MockRead data_reads1[] = {
8522 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
8523 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8524 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8525 MockRead("Content-Length: 14\r\n\r\n"),
8526 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:068527 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:578528 };
8529
[email protected]31a2bfe2010-02-09 08:03:398530 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8531 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:078532 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:578533
8534 // After calling trans->RestartWithAuth(), this is the request we should
8535 // be issuing -- the final header line contains the credentials.
8536 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238537 MockWrite(
8538 "GET / HTTP/1.1\r\n"
8539 "Host: www.example.org\r\n"
8540 "Connection: keep-alive\r\n"
8541 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:578542 };
8543
8544 // Lastly, the server responds with the actual content.
8545 MockRead data_reads2[] = {
8546 MockRead("HTTP/1.1 200 OK\r\n"),
8547 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8548 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068549 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:578550 };
8551
[email protected]31a2bfe2010-02-09 08:03:398552 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8553 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:078554 session_deps_.socket_factory->AddSocketDataProvider(&data2);
mmenke6b3af6e2015-09-12 02:06:068555 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578556
[email protected]49639fa2011-12-20 23:22:418557 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:578558
[email protected]262eec82013-03-19 21:01:368559 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508560 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:508561
[email protected]49639fa2011-12-20 23:22:418562 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578563 EXPECT_EQ(ERR_IO_PENDING, rv);
8564
8565 rv = callback1.WaitForResult();
8566 EXPECT_EQ(OK, rv);
8567
8568 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508569 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048570 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:578571
[email protected]49639fa2011-12-20 23:22:418572 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:578573
[email protected]49639fa2011-12-20 23:22:418574 rv = trans->RestartWithAuth(
8575 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]0877e3d2009-10-17 22:29:578576 EXPECT_EQ(ERR_IO_PENDING, rv);
8577
8578 rv = callback2.WaitForResult();
8579 EXPECT_EQ(OK, rv);
8580
8581 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508582 ASSERT_TRUE(response != NULL);
[email protected]0877e3d2009-10-17 22:29:578583 EXPECT_TRUE(response->auth_challenge.get() == NULL);
8584 EXPECT_EQ(100, response->headers->GetContentLength());
8585}
8586
8587// Test HTTPS connections going through a proxy that sends extra data.
[email protected]23e482282013-06-14 16:08:028588TEST_P(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
rdsmith82957ad2015-09-16 19:42:038589 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]0877e3d2009-10-17 22:29:578590
8591 HttpRequestInfo request;
8592 request.method = "GET";
bncce36dca22015-04-21 22:11:238593 request.url = GURL("https://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:578594 request.load_flags = 0;
8595
8596 MockRead proxy_reads[] = {
8597 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:068598 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:578599 };
8600
[email protected]31a2bfe2010-02-09 08:03:398601 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
[email protected]8ddf8322012-02-23 18:08:068602 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:578603
[email protected]bb88e1d32013-05-03 23:11:078604 session_deps_.socket_factory->AddSocketDataProvider(&data);
8605 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:578606
[email protected]49639fa2011-12-20 23:22:418607 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:578608
[email protected]bb88e1d32013-05-03 23:11:078609 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:578610
mmenke6b3af6e2015-09-12 02:06:068611 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578612 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418613 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:578614
[email protected]49639fa2011-12-20 23:22:418615 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578616 EXPECT_EQ(ERR_IO_PENDING, rv);
8617
8618 rv = callback.WaitForResult();
8619 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
8620}
8621
[email protected]23e482282013-06-14 16:08:028622TEST_P(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:468623 HttpRequestInfo request;
8624 request.method = "GET";
bncce36dca22015-04-21 22:11:238625 request.url = GURL("http://www.example.org/");
[email protected]9492e4a2010-02-24 00:58:468626 request.load_flags = 0;
8627
mmenke6b3af6e2015-09-12 02:06:068628 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:278629 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418630 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278631
[email protected]e22e1362009-11-23 21:31:128632 MockRead data_reads[] = {
8633 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068634 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:128635 };
[email protected]9492e4a2010-02-24 00:58:468636
8637 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078638 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:468639
[email protected]49639fa2011-12-20 23:22:418640 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:468641
[email protected]49639fa2011-12-20 23:22:418642 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9492e4a2010-02-24 00:58:468643 EXPECT_EQ(ERR_IO_PENDING, rv);
8644
8645 EXPECT_EQ(OK, callback.WaitForResult());
8646
8647 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508648 ASSERT_TRUE(response != NULL);
[email protected]9492e4a2010-02-24 00:58:468649
[email protected]90499482013-06-01 00:39:508650 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]9492e4a2010-02-24 00:58:468651 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
8652
8653 std::string response_data;
8654 rv = ReadTransaction(trans.get(), &response_data);
[email protected]5543cbb2012-04-20 16:35:238655 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
[email protected]e22e1362009-11-23 21:31:128656}
8657
[email protected]23e482282013-06-14 16:08:028658TEST_P(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:158659 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:528660 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
[email protected]95d88ffe2010-02-04 21:25:338661 const uint64 kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:218662 UploadFileElementReader::ScopedOverridingContentLengthForTests
8663 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:338664
[email protected]b2d26cfd2012-12-11 10:36:068665 ScopedVector<UploadElementReader> element_readers;
8666 element_readers.push_back(
skyostil4891b25b2015-06-11 11:43:458667 new UploadFileElementReader(base::ThreadTaskRunnerHandle::Get().get(),
8668 temp_file_path, 0, kuint64max, base::Time()));
mmenkecbc2b712014-10-09 20:29:078669 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:278670
8671 HttpRequestInfo request;
8672 request.method = "POST";
bncce36dca22015-04-21 22:11:238673 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:278674 request.upload_data_stream = &upload_data_stream;
8675 request.load_flags = 0;
8676
mmenke6b3af6e2015-09-12 02:06:068677 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]329b68b2012-11-14 17:54:278678 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418679 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]95d88ffe2010-02-04 21:25:338680
8681 MockRead data_reads[] = {
8682 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
8683 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068684 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:338685 };
[email protected]31a2bfe2010-02-09 08:03:398686 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078687 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:338688
[email protected]49639fa2011-12-20 23:22:418689 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:338690
[email protected]49639fa2011-12-20 23:22:418691 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]95d88ffe2010-02-04 21:25:338692 EXPECT_EQ(ERR_IO_PENDING, rv);
8693
8694 rv = callback.WaitForResult();
8695 EXPECT_EQ(OK, rv);
8696
8697 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508698 ASSERT_TRUE(response != NULL);
[email protected]95d88ffe2010-02-04 21:25:338699
[email protected]90499482013-06-01 00:39:508700 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]95d88ffe2010-02-04 21:25:338701 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
8702
8703 std::string response_data;
8704 rv = ReadTransaction(trans.get(), &response_data);
8705 EXPECT_EQ(OK, rv);
8706 EXPECT_EQ("hello world", response_data);
8707
[email protected]dd3aa792013-07-16 19:10:238708 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:338709}
8710
[email protected]23e482282013-06-14 16:08:028711TEST_P(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:158712 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:528713 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:368714 std::string temp_file_content("Unreadable file.");
[email protected]e5c2a22e2014-03-06 20:42:308715 ASSERT_TRUE(base::WriteFile(temp_file, temp_file_content.c_str(),
[email protected]6624b4622010-03-29 19:58:368716 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:118717 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:368718
[email protected]b2d26cfd2012-12-11 10:36:068719 ScopedVector<UploadElementReader> element_readers;
8720 element_readers.push_back(
skyostil4891b25b2015-06-11 11:43:458721 new UploadFileElementReader(base::ThreadTaskRunnerHandle::Get().get(),
8722 temp_file, 0, kuint64max, base::Time()));
mmenkecbc2b712014-10-09 20:29:078723 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:278724
8725 HttpRequestInfo request;
8726 request.method = "POST";
bncce36dca22015-04-21 22:11:238727 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:278728 request.upload_data_stream = &upload_data_stream;
8729 request.load_flags = 0;
8730
[email protected]999dd8c2013-11-12 06:45:548731 // If we try to upload an unreadable file, the transaction should fail.
mmenke6b3af6e2015-09-12 02:06:068732 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]329b68b2012-11-14 17:54:278733 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418734 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]6624b4622010-03-29 19:58:368735
[email protected]999dd8c2013-11-12 06:45:548736 StaticSocketDataProvider data(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078737 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:368738
[email protected]49639fa2011-12-20 23:22:418739 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:368740
[email protected]49639fa2011-12-20 23:22:418741 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]6624b4622010-03-29 19:58:368742 EXPECT_EQ(ERR_IO_PENDING, rv);
8743
8744 rv = callback.WaitForResult();
[email protected]999dd8c2013-11-12 06:45:548745 EXPECT_EQ(ERR_ACCESS_DENIED, rv);
[email protected]6624b4622010-03-29 19:58:368746
[email protected]dd3aa792013-07-16 19:10:238747 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:368748}
8749
[email protected]02cad5d2013-10-02 08:14:038750TEST_P(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
8751 class FakeUploadElementReader : public UploadElementReader {
8752 public:
8753 FakeUploadElementReader() {}
dchengb03027d2014-10-21 12:00:208754 ~FakeUploadElementReader() override {}
[email protected]02cad5d2013-10-02 08:14:038755
8756 const CompletionCallback& callback() const { return callback_; }
8757
8758 // UploadElementReader overrides:
dchengb03027d2014-10-21 12:00:208759 int Init(const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:038760 callback_ = callback;
8761 return ERR_IO_PENDING;
8762 }
dchengb03027d2014-10-21 12:00:208763 uint64 GetContentLength() const override { return 0; }
8764 uint64 BytesRemaining() const override { return 0; }
8765 int Read(IOBuffer* buf,
8766 int buf_length,
8767 const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:038768 return ERR_FAILED;
8769 }
8770
8771 private:
8772 CompletionCallback callback_;
8773 };
8774
8775 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
8776 ScopedVector<UploadElementReader> element_readers;
8777 element_readers.push_back(fake_reader);
mmenkecbc2b712014-10-09 20:29:078778 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02cad5d2013-10-02 08:14:038779
8780 HttpRequestInfo request;
8781 request.method = "POST";
bncce36dca22015-04-21 22:11:238782 request.url = GURL("http://www.example.org/upload");
[email protected]02cad5d2013-10-02 08:14:038783 request.upload_data_stream = &upload_data_stream;
8784 request.load_flags = 0;
8785
mmenke6b3af6e2015-09-12 02:06:068786 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02cad5d2013-10-02 08:14:038787 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418788 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02cad5d2013-10-02 08:14:038789
8790 StaticSocketDataProvider data;
8791 session_deps_.socket_factory->AddSocketDataProvider(&data);
8792
8793 TestCompletionCallback callback;
8794 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8795 EXPECT_EQ(ERR_IO_PENDING, rv);
8796 base::MessageLoop::current()->RunUntilIdle();
8797
8798 // Transaction is pending on request body initialization.
8799 ASSERT_FALSE(fake_reader->callback().is_null());
8800
8801 // Return Init()'s result after the transaction gets destroyed.
8802 trans.reset();
8803 fake_reader->callback().Run(OK); // Should not crash.
8804}
8805
[email protected]aeefc9e82010-02-19 16:18:278806// Tests that changes to Auth realms are treated like auth rejections.
[email protected]23e482282013-06-14 16:08:028807TEST_P(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:278808 HttpRequestInfo request;
8809 request.method = "GET";
bncce36dca22015-04-21 22:11:238810 request.url = GURL("http://www.example.org/");
[email protected]aeefc9e82010-02-19 16:18:278811 request.load_flags = 0;
8812
8813 // First transaction will request a resource and receive a Basic challenge
8814 // with realm="first_realm".
8815 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238816 MockWrite(
8817 "GET / HTTP/1.1\r\n"
8818 "Host: www.example.org\r\n"
8819 "Connection: keep-alive\r\n"
8820 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:278821 };
8822 MockRead data_reads1[] = {
8823 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8824 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
8825 "\r\n"),
8826 };
8827
8828 // After calling trans->RestartWithAuth(), provide an Authentication header
8829 // for first_realm. The server will reject and provide a challenge with
8830 // second_realm.
8831 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238832 MockWrite(
8833 "GET / HTTP/1.1\r\n"
8834 "Host: www.example.org\r\n"
8835 "Connection: keep-alive\r\n"
8836 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
8837 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:278838 };
8839 MockRead data_reads2[] = {
8840 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8841 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
8842 "\r\n"),
8843 };
8844
8845 // This again fails, and goes back to first_realm. Make sure that the
8846 // entry is removed from cache.
8847 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:238848 MockWrite(
8849 "GET / HTTP/1.1\r\n"
8850 "Host: www.example.org\r\n"
8851 "Connection: keep-alive\r\n"
8852 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
8853 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:278854 };
8855 MockRead data_reads3[] = {
8856 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8857 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
8858 "\r\n"),
8859 };
8860
8861 // Try one last time (with the correct password) and get the resource.
8862 MockWrite data_writes4[] = {
bncce36dca22015-04-21 22:11:238863 MockWrite(
8864 "GET / HTTP/1.1\r\n"
8865 "Host: www.example.org\r\n"
8866 "Connection: keep-alive\r\n"
8867 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
8868 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:278869 };
8870 MockRead data_reads4[] = {
8871 MockRead("HTTP/1.1 200 OK\r\n"
8872 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:508873 "Content-Length: 5\r\n"
8874 "\r\n"
8875 "hello"),
[email protected]aeefc9e82010-02-19 16:18:278876 };
8877
8878 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8879 data_writes1, arraysize(data_writes1));
8880 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8881 data_writes2, arraysize(data_writes2));
8882 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
8883 data_writes3, arraysize(data_writes3));
8884 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
8885 data_writes4, arraysize(data_writes4));
[email protected]bb88e1d32013-05-03 23:11:078886 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8887 session_deps_.socket_factory->AddSocketDataProvider(&data2);
8888 session_deps_.socket_factory->AddSocketDataProvider(&data3);
8889 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:278890
[email protected]49639fa2011-12-20 23:22:418891 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:278892
mmenke6b3af6e2015-09-12 02:06:068893 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0b0bf032010-09-21 18:08:508894 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418895 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:508896
[email protected]aeefc9e82010-02-19 16:18:278897 // Issue the first request with Authorize headers. There should be a
8898 // password prompt for first_realm waiting to be filled in after the
8899 // transaction completes.
[email protected]49639fa2011-12-20 23:22:418900 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]aeefc9e82010-02-19 16:18:278901 EXPECT_EQ(ERR_IO_PENDING, rv);
8902 rv = callback1.WaitForResult();
8903 EXPECT_EQ(OK, rv);
8904 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508905 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048906 const AuthChallengeInfo* challenge = response->auth_challenge.get();
8907 ASSERT_FALSE(challenge == NULL);
8908 EXPECT_FALSE(challenge->is_proxy);
bncce36dca22015-04-21 22:11:238909 EXPECT_EQ("www.example.org:80", challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:048910 EXPECT_EQ("first_realm", challenge->realm);
8911 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278912
8913 // Issue the second request with an incorrect password. There should be a
8914 // password prompt for second_realm waiting to be filled in after the
8915 // transaction completes.
[email protected]49639fa2011-12-20 23:22:418916 TestCompletionCallback callback2;
8917 rv = trans->RestartWithAuth(
8918 AuthCredentials(kFirst, kBaz), callback2.callback());
[email protected]aeefc9e82010-02-19 16:18:278919 EXPECT_EQ(ERR_IO_PENDING, rv);
8920 rv = callback2.WaitForResult();
8921 EXPECT_EQ(OK, rv);
8922 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508923 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048924 challenge = response->auth_challenge.get();
8925 ASSERT_FALSE(challenge == NULL);
8926 EXPECT_FALSE(challenge->is_proxy);
bncce36dca22015-04-21 22:11:238927 EXPECT_EQ("www.example.org:80", challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:048928 EXPECT_EQ("second_realm", challenge->realm);
8929 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278930
8931 // Issue the third request with another incorrect password. There should be
8932 // a password prompt for first_realm waiting to be filled in. If the password
8933 // prompt is not present, it indicates that the HttpAuthCacheEntry for
8934 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:418935 TestCompletionCallback callback3;
8936 rv = trans->RestartWithAuth(
8937 AuthCredentials(kSecond, kFou), callback3.callback());
[email protected]aeefc9e82010-02-19 16:18:278938 EXPECT_EQ(ERR_IO_PENDING, rv);
8939 rv = callback3.WaitForResult();
8940 EXPECT_EQ(OK, rv);
8941 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508942 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048943 challenge = response->auth_challenge.get();
8944 ASSERT_FALSE(challenge == NULL);
8945 EXPECT_FALSE(challenge->is_proxy);
bncce36dca22015-04-21 22:11:238946 EXPECT_EQ("www.example.org:80", challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:048947 EXPECT_EQ("first_realm", challenge->realm);
8948 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278949
8950 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:418951 TestCompletionCallback callback4;
8952 rv = trans->RestartWithAuth(
8953 AuthCredentials(kFirst, kBar), callback4.callback());
[email protected]aeefc9e82010-02-19 16:18:278954 EXPECT_EQ(ERR_IO_PENDING, rv);
8955 rv = callback4.WaitForResult();
8956 EXPECT_EQ(OK, rv);
8957 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508958 ASSERT_TRUE(response != NULL);
[email protected]aeefc9e82010-02-19 16:18:278959 EXPECT_TRUE(response->auth_challenge.get() == NULL);
8960}
8961
bncc958faa2015-07-31 18:14:528962TEST_P(HttpNetworkTransactionTest, HonorAlternativeServiceHeader) {
8963 session_deps_.next_protos = SpdyNextProtos();
bnc55ff9da2015-08-19 18:42:358964 session_deps_.use_alternative_services = true;
bncc958faa2015-07-31 18:14:528965
8966 std::string alternative_service_http_header =
8967 GetAlternativeServiceHttpHeader();
8968
8969 MockRead data_reads[] = {
8970 MockRead("HTTP/1.1 200 OK\r\n"),
8971 MockRead(alternative_service_http_header.c_str()),
8972 MockRead("\r\n"),
8973 MockRead("hello world"),
8974 MockRead(SYNCHRONOUS, OK),
8975 };
8976
8977 HttpRequestInfo request;
8978 request.method = "GET";
8979 request.url = GURL("http://www.example.org/");
8980 request.load_flags = 0;
8981
8982 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
8983
8984 session_deps_.socket_factory->AddSocketDataProvider(&data);
8985
8986 TestCompletionCallback callback;
8987
mmenke6b3af6e2015-09-12 02:06:068988 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bncc958faa2015-07-31 18:14:528989 scoped_ptr<HttpTransaction> trans(
8990 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8991
8992 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8993 EXPECT_EQ(ERR_IO_PENDING, rv);
8994
8995 HostPortPair http_host_port_pair("www.example.org", 80);
8996 HttpServerProperties& http_server_properties =
8997 *session->http_server_properties();
8998 AlternativeServiceVector alternative_service_vector =
8999 http_server_properties.GetAlternativeServices(http_host_port_pair);
9000 EXPECT_TRUE(alternative_service_vector.empty());
9001
9002 EXPECT_EQ(OK, callback.WaitForResult());
9003
9004 const HttpResponseInfo* response = trans->GetResponseInfo();
9005 ASSERT_TRUE(response != NULL);
9006 ASSERT_TRUE(response->headers.get() != NULL);
9007 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9008 EXPECT_FALSE(response->was_fetched_via_spdy);
9009 EXPECT_FALSE(response->was_npn_negotiated);
9010
9011 std::string response_data;
9012 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9013 EXPECT_EQ("hello world", response_data);
9014
9015 alternative_service_vector =
9016 http_server_properties.GetAlternativeServices(http_host_port_pair);
9017 ASSERT_EQ(1u, alternative_service_vector.size());
9018 EXPECT_EQ(AlternateProtocolFromNextProto(GetParam()),
9019 alternative_service_vector[0].protocol);
9020 EXPECT_EQ("www.example.com", alternative_service_vector[0].host);
9021 EXPECT_EQ(443, alternative_service_vector[0].port);
9022}
9023
bnc54ec34b72015-08-26 19:34:569024// Alternative Service headers must be ignored when |use_alternative_services|
9025// is false.
9026TEST_P(HttpNetworkTransactionTest, DoNotHonorAlternativeServiceHeader) {
9027 session_deps_.next_protos = SpdyNextProtos();
9028 session_deps_.use_alternative_services = false;
9029
9030 std::string alternative_service_http_header =
9031 GetAlternativeServiceHttpHeader();
9032
9033 MockRead data_reads[] = {
9034 MockRead("HTTP/1.1 200 OK\r\n"),
9035 MockRead(alternative_service_http_header.c_str()),
9036 MockRead("\r\n"),
9037 MockRead("hello world"),
9038 MockRead(SYNCHRONOUS, OK),
9039 };
9040
9041 HttpRequestInfo request;
9042 request.method = "GET";
9043 request.url = GURL("http://www.example.org/");
9044 request.load_flags = 0;
9045
9046 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
9047
9048 session_deps_.socket_factory->AddSocketDataProvider(&data);
9049
9050 TestCompletionCallback callback;
9051
mmenke6b3af6e2015-09-12 02:06:069052 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc54ec34b72015-08-26 19:34:569053 scoped_ptr<HttpTransaction> trans(
9054 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9055
9056 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9057 EXPECT_EQ(ERR_IO_PENDING, rv);
9058
9059 HostPortPair http_host_port_pair("www.example.org", 80);
9060 HttpServerProperties& http_server_properties =
9061 *session->http_server_properties();
9062 AlternativeServiceVector alternative_service_vector =
9063 http_server_properties.GetAlternativeServices(http_host_port_pair);
9064 EXPECT_TRUE(alternative_service_vector.empty());
9065
9066 EXPECT_EQ(OK, callback.WaitForResult());
9067
9068 const HttpResponseInfo* response = trans->GetResponseInfo();
9069 ASSERT_TRUE(response != nullptr);
9070 ASSERT_TRUE(response->headers.get() != nullptr);
9071 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9072 EXPECT_FALSE(response->was_fetched_via_spdy);
9073 EXPECT_FALSE(response->was_npn_negotiated);
9074
9075 std::string response_data;
9076 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9077 EXPECT_EQ("hello world", response_data);
9078
9079 alternative_service_vector =
9080 http_server_properties.GetAlternativeServices(http_host_port_pair);
9081 EXPECT_TRUE(alternative_service_vector.empty());
9082}
9083
bncc958faa2015-07-31 18:14:529084TEST_P(HttpNetworkTransactionTest, HonorMultipleAlternativeServiceHeader) {
9085 session_deps_.next_protos = SpdyNextProtos();
bnc55ff9da2015-08-19 18:42:359086 session_deps_.use_alternative_services = true;
bncc958faa2015-07-31 18:14:529087
9088 MockRead data_reads[] = {
9089 MockRead("HTTP/1.1 200 OK\r\n"),
9090 MockRead("Alt-Svc: "),
9091 MockRead(GetAlternateProtocolFromParam()),
9092 MockRead("=\"www.example.com:443\";p=1.0,"),
9093 MockRead("quic=\":1234\"\r\n\r\n"),
9094 MockRead("hello world"),
9095 MockRead(SYNCHRONOUS, OK),
9096 };
9097
9098 HttpRequestInfo request;
9099 request.method = "GET";
9100 request.url = GURL("http://www.example.org/");
9101 request.load_flags = 0;
9102
9103 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
9104
9105 session_deps_.socket_factory->AddSocketDataProvider(&data);
9106
9107 TestCompletionCallback callback;
9108
mmenke6b3af6e2015-09-12 02:06:069109 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bncc958faa2015-07-31 18:14:529110 scoped_ptr<HttpTransaction> trans(
9111 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9112
9113 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9114 EXPECT_EQ(ERR_IO_PENDING, rv);
9115
9116 HostPortPair http_host_port_pair("www.example.org", 80);
9117 HttpServerProperties& http_server_properties =
9118 *session->http_server_properties();
9119 AlternativeServiceVector alternative_service_vector =
9120 http_server_properties.GetAlternativeServices(http_host_port_pair);
9121 EXPECT_TRUE(alternative_service_vector.empty());
9122
9123 EXPECT_EQ(OK, callback.WaitForResult());
9124
9125 const HttpResponseInfo* response = trans->GetResponseInfo();
9126 ASSERT_TRUE(response != NULL);
9127 ASSERT_TRUE(response->headers.get() != NULL);
9128 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9129 EXPECT_FALSE(response->was_fetched_via_spdy);
9130 EXPECT_FALSE(response->was_npn_negotiated);
9131
9132 std::string response_data;
9133 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9134 EXPECT_EQ("hello world", response_data);
9135
9136 alternative_service_vector =
9137 http_server_properties.GetAlternativeServices(http_host_port_pair);
9138 ASSERT_EQ(2u, alternative_service_vector.size());
9139 EXPECT_EQ(AlternateProtocolFromNextProto(GetParam()),
9140 alternative_service_vector[0].protocol);
9141 EXPECT_EQ("www.example.com", alternative_service_vector[0].host);
9142 EXPECT_EQ(443, alternative_service_vector[0].port);
9143 EXPECT_EQ(QUIC, alternative_service_vector[1].protocol);
9144 EXPECT_EQ("www.example.org", alternative_service_vector[1].host);
9145 EXPECT_EQ(1234, alternative_service_vector[1].port);
9146}
9147
bnc54ec34b72015-08-26 19:34:569148// Alternate Protocol headers must be honored even if |use_alternative_services|
9149// is false.
[email protected]23e482282013-06-14 16:08:029150TEST_P(HttpNetworkTransactionTest, HonorAlternateProtocolHeader) {
[email protected]d7599122014-05-24 03:37:239151 session_deps_.next_protos = SpdyNextProtos();
bnc54ec34b72015-08-26 19:34:569152 session_deps_.use_alternative_services = false;
[email protected]a2cb8122010-03-10 17:22:429153
[email protected]8a0fc822013-06-27 20:52:439154 std::string alternate_protocol_http_header =
9155 GetAlternateProtocolHttpHeader();
9156
[email protected]564b4912010-03-09 16:30:429157 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:529158 MockRead("HTTP/1.1 200 OK\r\n"),
9159 MockRead(alternate_protocol_http_header.c_str()),
9160 MockRead("\r\n"),
9161 MockRead("hello world"),
9162 MockRead(SYNCHRONOUS, OK),
[email protected]564b4912010-03-09 16:30:429163 };
9164
9165 HttpRequestInfo request;
9166 request.method = "GET";
bncce36dca22015-04-21 22:11:239167 request.url = GURL("http://www.example.org/");
[email protected]564b4912010-03-09 16:30:429168 request.load_flags = 0;
9169
9170 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
9171
[email protected]bb88e1d32013-05-03 23:11:079172 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]564b4912010-03-09 16:30:429173
[email protected]49639fa2011-12-20 23:22:419174 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:429175
mmenke6b3af6e2015-09-12 02:06:069176 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369177 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509178 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]564b4912010-03-09 16:30:429179
[email protected]49639fa2011-12-20 23:22:419180 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:429181 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]9e743cd2010-03-16 07:03:539182
bncce36dca22015-04-21 22:11:239183 HostPortPair http_host_port_pair("www.example.org", 80);
[email protected]9801e3702014-03-07 09:33:559184 HttpServerProperties& http_server_properties =
[email protected]17291a022011-10-10 07:32:539185 *session->http_server_properties();
bncd9b132e2015-07-08 05:16:109186 AlternativeServiceVector alternative_service_vector =
9187 http_server_properties.GetAlternativeServices(http_host_port_pair);
9188 EXPECT_TRUE(alternative_service_vector.empty());
[email protected]564b4912010-03-09 16:30:429189
9190 EXPECT_EQ(OK, callback.WaitForResult());
9191
9192 const HttpResponseInfo* response = trans->GetResponseInfo();
9193 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509194 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:429195 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539196 EXPECT_FALSE(response->was_fetched_via_spdy);
9197 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]564b4912010-03-09 16:30:429198
9199 std::string response_data;
9200 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9201 EXPECT_EQ("hello world", response_data);
9202
bncd9b132e2015-07-08 05:16:109203 alternative_service_vector =
9204 http_server_properties.GetAlternativeServices(http_host_port_pair);
9205 ASSERT_EQ(1u, alternative_service_vector.size());
9206 EXPECT_EQ(443, alternative_service_vector[0].port);
bnc181b39a2015-03-17 21:36:479207 EXPECT_EQ(AlternateProtocolFromNextProto(GetParam()),
bncd9b132e2015-07-08 05:16:109208 alternative_service_vector[0].protocol);
[email protected]564b4912010-03-09 16:30:429209}
9210
rch89c6e102015-03-18 18:56:529211TEST_P(HttpNetworkTransactionTest, EmptyAlternateProtocolHeader) {
9212 session_deps_.next_protos = SpdyNextProtos();
bnc55ff9da2015-08-19 18:42:359213 session_deps_.use_alternative_services = true;
rch89c6e102015-03-18 18:56:529214
9215 MockRead data_reads[] = {
9216 MockRead("HTTP/1.1 200 OK\r\n"),
9217 MockRead("Alternate-Protocol: \r\n\r\n"),
9218 MockRead("hello world"),
9219 MockRead(SYNCHRONOUS, OK),
9220 };
9221
9222 HttpRequestInfo request;
9223 request.method = "GET";
bncce36dca22015-04-21 22:11:239224 request.url = GURL("http://www.example.org/");
rch89c6e102015-03-18 18:56:529225 request.load_flags = 0;
9226
9227 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
9228
9229 session_deps_.socket_factory->AddSocketDataProvider(&data);
9230
9231 TestCompletionCallback callback;
9232
mmenke6b3af6e2015-09-12 02:06:069233 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
rch89c6e102015-03-18 18:56:529234
bncce36dca22015-04-21 22:11:239235 HostPortPair http_host_port_pair("www.example.org", 80);
rch89c6e102015-03-18 18:56:529236 HttpServerProperties& http_server_properties =
9237 *session->http_server_properties();
bnccacc0992015-03-20 20:22:229238 AlternativeService alternative_service(QUIC, "", 80);
bnc7dc7e1b42015-07-28 14:43:129239 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
9240 http_server_properties.SetAlternativeService(
9241 http_host_port_pair, alternative_service, 1.0, expiration);
bnccacc0992015-03-20 20:22:229242
bncd9b132e2015-07-08 05:16:109243 AlternativeServiceVector alternative_service_vector =
9244 http_server_properties.GetAlternativeServices(http_host_port_pair);
9245 ASSERT_EQ(1u, alternative_service_vector.size());
9246 EXPECT_EQ(QUIC, alternative_service_vector[0].protocol);
rch89c6e102015-03-18 18:56:529247
9248 scoped_ptr<HttpTransaction> trans(
9249 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9250
9251 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9252 EXPECT_EQ(ERR_IO_PENDING, rv);
9253
9254 EXPECT_EQ(OK, callback.WaitForResult());
9255
9256 const HttpResponseInfo* response = trans->GetResponseInfo();
9257 ASSERT_TRUE(response != NULL);
9258 ASSERT_TRUE(response->headers.get() != NULL);
9259 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9260 EXPECT_FALSE(response->was_fetched_via_spdy);
9261 EXPECT_FALSE(response->was_npn_negotiated);
9262
9263 std::string response_data;
9264 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9265 EXPECT_EQ("hello world", response_data);
9266
bncd9b132e2015-07-08 05:16:109267 alternative_service_vector =
9268 http_server_properties.GetAlternativeServices(http_host_port_pair);
9269 EXPECT_TRUE(alternative_service_vector.empty());
rch89c6e102015-03-18 18:56:529270}
9271
bncc958faa2015-07-31 18:14:529272TEST_P(HttpNetworkTransactionTest, AltSvcOverwritesAlternateProtocol) {
9273 session_deps_.next_protos = SpdyNextProtos();
bnc55ff9da2015-08-19 18:42:359274 session_deps_.use_alternative_services = true;
bncc958faa2015-07-31 18:14:529275
9276 std::string alternative_service_http_header =
9277 GetAlternativeServiceHttpHeader();
9278 std::string alternate_protocol_http_header = GetAlternateProtocolHttpHeader();
9279
9280 MockRead data_reads[] = {
9281 MockRead("HTTP/1.1 200 OK\r\n"),
9282 MockRead(alternative_service_http_header.c_str()),
9283 MockRead(alternate_protocol_http_header.c_str()),
9284 MockRead("\r\n"),
9285 MockRead("hello world"),
9286 MockRead(SYNCHRONOUS, OK),
9287 };
9288
9289 HttpRequestInfo request;
9290 request.method = "GET";
9291 request.url = GURL("http://www.example.org/");
9292 request.load_flags = 0;
9293
9294 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
9295
9296 session_deps_.socket_factory->AddSocketDataProvider(&data);
9297
9298 TestCompletionCallback callback;
9299
mmenke6b3af6e2015-09-12 02:06:069300 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bncc958faa2015-07-31 18:14:529301 scoped_ptr<HttpTransaction> trans(
9302 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9303
9304 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9305 EXPECT_EQ(ERR_IO_PENDING, rv);
9306
9307 HostPortPair http_host_port_pair("www.example.org", 80);
9308 HttpServerProperties& http_server_properties =
9309 *session->http_server_properties();
9310 AlternativeServiceVector alternative_service_vector =
9311 http_server_properties.GetAlternativeServices(http_host_port_pair);
9312 EXPECT_TRUE(alternative_service_vector.empty());
9313
9314 EXPECT_EQ(OK, callback.WaitForResult());
9315
9316 const HttpResponseInfo* response = trans->GetResponseInfo();
9317 ASSERT_TRUE(response != NULL);
9318 ASSERT_TRUE(response->headers.get() != NULL);
9319 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9320 EXPECT_FALSE(response->was_fetched_via_spdy);
9321 EXPECT_FALSE(response->was_npn_negotiated);
9322
9323 std::string response_data;
9324 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9325 EXPECT_EQ("hello world", response_data);
9326
9327 alternative_service_vector =
9328 http_server_properties.GetAlternativeServices(http_host_port_pair);
9329 ASSERT_EQ(1u, alternative_service_vector.size());
9330 EXPECT_EQ(AlternateProtocolFromNextProto(GetParam()),
9331 alternative_service_vector[0].protocol);
9332 EXPECT_EQ("www.example.com", alternative_service_vector[0].host);
9333 EXPECT_EQ(443, alternative_service_vector[0].port);
9334}
9335
bnc54ec34b72015-08-26 19:34:569336// When |use_alternative_services| is false, do not observe alternative service
9337// entries that point to a different host.
9338TEST_P(HttpNetworkTransactionTest, DisableAlternativeServiceToDifferentHost) {
9339 session_deps_.use_alternative_services = false;
9340
9341 HttpRequestInfo request;
9342 request.method = "GET";
9343 request.url = GURL("http://www.example.org/");
9344 request.load_flags = 0;
9345
9346 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
9347 StaticSocketDataProvider first_data;
9348 first_data.set_connect_data(mock_connect);
9349 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
9350
9351 MockRead data_reads[] = {
9352 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
9353 MockRead(ASYNC, OK),
9354 };
9355 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads),
9356 nullptr, 0);
9357 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
9358
mmenke6b3af6e2015-09-12 02:06:069359 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc54ec34b72015-08-26 19:34:569360
9361 base::WeakPtr<HttpServerProperties> http_server_properties =
9362 session->http_server_properties();
9363 AlternativeService alternative_service(
9364 AlternateProtocolFromNextProto(GetParam()), "different.example.org", 80);
9365 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
9366 http_server_properties->SetAlternativeService(
9367 HostPortPair::FromURL(request.url), alternative_service, 1.0, expiration);
9368
9369 scoped_ptr<HttpTransaction> trans(
9370 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9371 TestCompletionCallback callback;
9372
9373 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9374 // The connetion to origin was refused, and the alternative service should not
9375 // be used (even though mock data are there), therefore the request should
9376 // fail.
9377 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.GetResult(rv));
9378}
9379
[email protected]23e482282013-06-14 16:08:029380TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239381 MarkBrokenAlternateProtocolAndFallback) {
bnc55ff9da2015-08-19 18:42:359382 session_deps_.use_alternative_services = true;
[email protected]564b4912010-03-09 16:30:429383
9384 HttpRequestInfo request;
9385 request.method = "GET";
bncce36dca22015-04-21 22:11:239386 request.url = GURL("http://www.example.org/");
[email protected]564b4912010-03-09 16:30:429387 request.load_flags = 0;
9388
[email protected]d973e99a2012-02-17 21:02:369389 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:429390 StaticSocketDataProvider first_data;
9391 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079392 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]564b4912010-03-09 16:30:429393
9394 MockRead data_reads[] = {
9395 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9396 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069397 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:429398 };
9399 StaticSocketDataProvider second_data(
9400 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079401 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:429402
mmenke6b3af6e2015-09-12 02:06:069403 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:429404
[email protected]30d4c022013-07-18 22:58:169405 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:539406 session->http_server_properties();
bnc8445b3002015-03-13 01:57:099407 const HostPortPair host_port_pair = HostPortPair::FromURL(request.url);
[email protected]3912662a32011-10-04 00:51:119408 // Port must be < 1024, or the header will be ignored (since initial port was
9409 // port 80 (another restricted port).
bncd9b132e2015-07-08 05:16:109410 const AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239411 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bncd9b132e2015-07-08 05:16:109412 666); // Port is ignored by MockConnect anyway.
bnc7dc7e1b42015-07-28 14:43:129413 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
9414 http_server_properties->SetAlternativeService(
9415 host_port_pair, alternative_service, 1.0, expiration);
[email protected]564b4912010-03-09 16:30:429416
[email protected]262eec82013-03-19 21:01:369417 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509418 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419419 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:429420
[email protected]49639fa2011-12-20 23:22:419421 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:429422 EXPECT_EQ(ERR_IO_PENDING, rv);
9423 EXPECT_EQ(OK, callback.WaitForResult());
9424
9425 const HttpResponseInfo* response = trans->GetResponseInfo();
9426 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509427 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:429428 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9429
9430 std::string response_data;
9431 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9432 EXPECT_EQ("hello world", response_data);
9433
bncd9b132e2015-07-08 05:16:109434 const AlternativeServiceVector alternative_service_vector =
9435 http_server_properties->GetAlternativeServices(host_port_pair);
9436 ASSERT_EQ(1u, alternative_service_vector.size());
9437 EXPECT_EQ(alternative_service, alternative_service_vector[0]);
9438 EXPECT_TRUE(http_server_properties->IsAlternativeServiceBroken(
9439 alternative_service_vector[0]));
[email protected]564b4912010-03-09 16:30:429440}
9441
bnc55ff9da2015-08-19 18:42:359442// Ensure that we are not allowed to redirect traffic via an alternate protocol
9443// to an unrestricted (port >= 1024) when the original traffic was on a
9444// restricted port (port < 1024). Ensure that we can redirect in all other
9445// cases.
[email protected]23e482282013-06-14 16:08:029446TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239447 AlternateProtocolPortRestrictedBlocked) {
bnc55ff9da2015-08-19 18:42:359448 session_deps_.use_alternative_services = true;
[email protected]3912662a32011-10-04 00:51:119449
9450 HttpRequestInfo restricted_port_request;
9451 restricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:239452 restricted_port_request.url = GURL("http://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:119453 restricted_port_request.load_flags = 0;
9454
[email protected]d973e99a2012-02-17 21:02:369455 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:119456 StaticSocketDataProvider first_data;
9457 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079458 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:119459
9460 MockRead data_reads[] = {
9461 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9462 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069463 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:119464 };
9465 StaticSocketDataProvider second_data(
9466 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079467 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:119468
mmenke6b3af6e2015-09-12 02:06:069469 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:119470
[email protected]30d4c022013-07-18 22:58:169471 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:539472 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:119473 const int kUnrestrictedAlternatePort = 1024;
bnccacc0992015-03-20 20:22:229474 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239475 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229476 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:129477 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:229478 http_server_properties->SetAlternativeService(
9479 HostPortPair::FromURL(restricted_port_request.url), alternative_service,
bnc7dc7e1b42015-07-28 14:43:129480 1.0, expiration);
[email protected]3912662a32011-10-04 00:51:119481
[email protected]262eec82013-03-19 21:01:369482 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509483 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419484 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:119485
[email protected]49639fa2011-12-20 23:22:419486 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:369487 &restricted_port_request,
9488 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:119489 EXPECT_EQ(ERR_IO_PENDING, rv);
9490 // Invalid change to unrestricted port should fail.
9491 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.WaitForResult());
[email protected]c54c6962013-02-01 04:53:199492}
[email protected]3912662a32011-10-04 00:51:119493
bnc55ff9da2015-08-19 18:42:359494// Ensure that we are allowed to redirect traffic via an alternate protocol to
9495// an unrestricted (port >= 1024) when the original traffic was on a restricted
9496// port (port < 1024) if we set |enable_user_alternate_protocol_ports|.
[email protected]23e482282013-06-14 16:08:029497TEST_P(HttpNetworkTransactionTest,
[email protected]c54c6962013-02-01 04:53:199498 AlternateProtocolPortRestrictedPermitted) {
bnc55ff9da2015-08-19 18:42:359499 session_deps_.use_alternative_services = true;
[email protected]bb88e1d32013-05-03 23:11:079500 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:199501
9502 HttpRequestInfo restricted_port_request;
9503 restricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:239504 restricted_port_request.url = GURL("http://www.example.org:1023/");
[email protected]c54c6962013-02-01 04:53:199505 restricted_port_request.load_flags = 0;
9506
9507 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
9508 StaticSocketDataProvider first_data;
9509 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079510 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:199511
9512 MockRead data_reads[] = {
9513 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9514 MockRead("hello world"),
9515 MockRead(ASYNC, OK),
9516 };
9517 StaticSocketDataProvider second_data(
9518 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079519 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]c54c6962013-02-01 04:53:199520
mmenke6b3af6e2015-09-12 02:06:069521 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:199522
[email protected]30d4c022013-07-18 22:58:169523 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]c54c6962013-02-01 04:53:199524 session->http_server_properties();
9525 const int kUnrestrictedAlternatePort = 1024;
bnccacc0992015-03-20 20:22:229526 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239527 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229528 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:129529 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:229530 http_server_properties->SetAlternativeService(
9531 HostPortPair::FromURL(restricted_port_request.url), alternative_service,
bnc7dc7e1b42015-07-28 14:43:129532 1.0, expiration);
[email protected]c54c6962013-02-01 04:53:199533
[email protected]262eec82013-03-19 21:01:369534 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509535 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]c54c6962013-02-01 04:53:199536 TestCompletionCallback callback;
9537
9538 EXPECT_EQ(ERR_IO_PENDING, trans->Start(
[email protected]262eec82013-03-19 21:01:369539 &restricted_port_request,
9540 callback.callback(), BoundNetLog()));
[email protected]c54c6962013-02-01 04:53:199541 // Change to unrestricted port should succeed.
9542 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:119543}
9544
bnc55ff9da2015-08-19 18:42:359545// Ensure that we are not allowed to redirect traffic via an alternate protocol
9546// to an unrestricted (port >= 1024) when the original traffic was on a
9547// restricted port (port < 1024). Ensure that we can redirect in all other
9548// cases.
[email protected]23e482282013-06-14 16:08:029549TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239550 AlternateProtocolPortRestrictedAllowed) {
bnc55ff9da2015-08-19 18:42:359551 session_deps_.use_alternative_services = true;
[email protected]3912662a32011-10-04 00:51:119552
9553 HttpRequestInfo restricted_port_request;
9554 restricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:239555 restricted_port_request.url = GURL("http://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:119556 restricted_port_request.load_flags = 0;
9557
[email protected]d973e99a2012-02-17 21:02:369558 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:119559 StaticSocketDataProvider first_data;
9560 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079561 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:119562
9563 MockRead data_reads[] = {
9564 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9565 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069566 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:119567 };
9568 StaticSocketDataProvider second_data(
9569 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079570 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:119571
mmenke6b3af6e2015-09-12 02:06:069572 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:119573
[email protected]30d4c022013-07-18 22:58:169574 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:539575 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:119576 const int kRestrictedAlternatePort = 80;
bnccacc0992015-03-20 20:22:229577 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239578 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229579 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:129580 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:229581 http_server_properties->SetAlternativeService(
9582 HostPortPair::FromURL(restricted_port_request.url), alternative_service,
bnc7dc7e1b42015-07-28 14:43:129583 1.0, expiration);
[email protected]3912662a32011-10-04 00:51:119584
[email protected]262eec82013-03-19 21:01:369585 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509586 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419587 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:119588
[email protected]49639fa2011-12-20 23:22:419589 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:369590 &restricted_port_request,
9591 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:119592 EXPECT_EQ(ERR_IO_PENDING, rv);
9593 // Valid change to restricted port should pass.
9594 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:119595}
9596
bnc55ff9da2015-08-19 18:42:359597// Ensure that we are not allowed to redirect traffic via an alternate protocol
9598// to an unrestricted (port >= 1024) when the original traffic was on a
9599// restricted port (port < 1024). Ensure that we can redirect in all other
9600// cases.
[email protected]23e482282013-06-14 16:08:029601TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239602 AlternateProtocolPortUnrestrictedAllowed1) {
bnc55ff9da2015-08-19 18:42:359603 session_deps_.use_alternative_services = true;
[email protected]3912662a32011-10-04 00:51:119604
9605 HttpRequestInfo unrestricted_port_request;
9606 unrestricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:239607 unrestricted_port_request.url = GURL("http://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:119608 unrestricted_port_request.load_flags = 0;
9609
[email protected]d973e99a2012-02-17 21:02:369610 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:119611 StaticSocketDataProvider first_data;
9612 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079613 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:119614
9615 MockRead data_reads[] = {
9616 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9617 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069618 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:119619 };
9620 StaticSocketDataProvider second_data(
9621 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079622 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:119623
mmenke6b3af6e2015-09-12 02:06:069624 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:119625
[email protected]30d4c022013-07-18 22:58:169626 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:539627 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:119628 const int kRestrictedAlternatePort = 80;
bnccacc0992015-03-20 20:22:229629 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239630 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229631 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:129632 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:229633 http_server_properties->SetAlternativeService(
9634 HostPortPair::FromURL(unrestricted_port_request.url), alternative_service,
bnc7dc7e1b42015-07-28 14:43:129635 1.0, expiration);
[email protected]3912662a32011-10-04 00:51:119636
[email protected]262eec82013-03-19 21:01:369637 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509638 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419639 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:119640
[email protected]49639fa2011-12-20 23:22:419641 int rv = trans->Start(
9642 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:119643 EXPECT_EQ(ERR_IO_PENDING, rv);
9644 // Valid change to restricted port should pass.
9645 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:119646}
9647
bnc55ff9da2015-08-19 18:42:359648// Ensure that we are not allowed to redirect traffic via an alternate protocol
9649// to an unrestricted (port >= 1024) when the original traffic was on a
9650// restricted port (port < 1024). Ensure that we can redirect in all other
9651// cases.
[email protected]23e482282013-06-14 16:08:029652TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239653 AlternateProtocolPortUnrestrictedAllowed2) {
bnc55ff9da2015-08-19 18:42:359654 session_deps_.use_alternative_services = true;
[email protected]3912662a32011-10-04 00:51:119655
9656 HttpRequestInfo unrestricted_port_request;
9657 unrestricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:239658 unrestricted_port_request.url = GURL("http://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:119659 unrestricted_port_request.load_flags = 0;
9660
[email protected]d973e99a2012-02-17 21:02:369661 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:119662 StaticSocketDataProvider first_data;
9663 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079664 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:119665
9666 MockRead data_reads[] = {
9667 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9668 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069669 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:119670 };
9671 StaticSocketDataProvider second_data(
9672 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079673 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:119674
mmenke6b3af6e2015-09-12 02:06:069675 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:119676
[email protected]30d4c022013-07-18 22:58:169677 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:539678 session->http_server_properties();
bnc0bbb02622015-07-23 10:06:229679 const int kUnrestrictedAlternatePort = 1025;
bnccacc0992015-03-20 20:22:229680 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239681 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229682 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:129683 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:229684 http_server_properties->SetAlternativeService(
9685 HostPortPair::FromURL(unrestricted_port_request.url), alternative_service,
bnc7dc7e1b42015-07-28 14:43:129686 1.0, expiration);
[email protected]3912662a32011-10-04 00:51:119687
[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]49639fa2011-12-20 23:22:419690 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:119691
[email protected]49639fa2011-12-20 23:22:419692 int rv = trans->Start(
9693 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:119694 EXPECT_EQ(ERR_IO_PENDING, rv);
9695 // Valid change to an unrestricted port should pass.
9696 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:119697}
9698
bnc55ff9da2015-08-19 18:42:359699// Ensure that we are not allowed to redirect traffic via an alternate protocol
9700// to an unsafe port, and that we resume the second HttpStreamFactoryImpl::Job
9701// once the alternate protocol request fails.
[email protected]d7599122014-05-24 03:37:239702TEST_P(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
bnc55ff9da2015-08-19 18:42:359703 session_deps_.use_alternative_services = true;
[email protected]eb6234e2012-01-19 01:50:029704
9705 HttpRequestInfo request;
9706 request.method = "GET";
bncce36dca22015-04-21 22:11:239707 request.url = GURL("http://www.example.org/");
[email protected]eb6234e2012-01-19 01:50:029708 request.load_flags = 0;
9709
9710 // The alternate protocol request will error out before we attempt to connect,
9711 // so only the standard HTTP request will try to connect.
9712 MockRead data_reads[] = {
9713 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9714 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069715 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:029716 };
9717 StaticSocketDataProvider data(
9718 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079719 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:029720
mmenke6b3af6e2015-09-12 02:06:069721 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:029722
[email protected]30d4c022013-07-18 22:58:169723 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]eb6234e2012-01-19 01:50:029724 session->http_server_properties();
9725 const int kUnsafePort = 7;
bnccacc0992015-03-20 20:22:229726 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239727 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229728 kUnsafePort);
bnc7dc7e1b42015-07-28 14:43:129729 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:229730 http_server_properties->SetAlternativeService(
bnc7dc7e1b42015-07-28 14:43:129731 HostPortPair::FromURL(request.url), alternative_service, 1.0, expiration);
[email protected]eb6234e2012-01-19 01:50:029732
[email protected]262eec82013-03-19 21:01:369733 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509734 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]eb6234e2012-01-19 01:50:029735 TestCompletionCallback callback;
9736
9737 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9738 EXPECT_EQ(ERR_IO_PENDING, rv);
9739 // The HTTP request should succeed.
9740 EXPECT_EQ(OK, callback.WaitForResult());
9741
[email protected]eb6234e2012-01-19 01:50:029742 const HttpResponseInfo* response = trans->GetResponseInfo();
9743 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509744 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]eb6234e2012-01-19 01:50:029745 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9746
9747 std::string response_data;
9748 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9749 EXPECT_EQ("hello world", response_data);
9750}
9751
[email protected]23e482282013-06-14 16:08:029752TEST_P(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
bnc55ff9da2015-08-19 18:42:359753 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:239754 session_deps_.next_protos = SpdyNextProtos();
[email protected]2ff8b312010-04-26 22:20:549755
9756 HttpRequestInfo request;
9757 request.method = "GET";
bncce36dca22015-04-21 22:11:239758 request.url = GURL("http://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:549759 request.load_flags = 0;
9760
[email protected]8a0fc822013-06-27 20:52:439761 std::string alternate_protocol_http_header =
9762 GetAlternateProtocolHttpHeader();
9763
[email protected]2ff8b312010-04-26 22:20:549764 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:529765 MockRead("HTTP/1.1 200 OK\r\n"),
9766 MockRead(alternate_protocol_http_header.c_str()),
9767 MockRead("\r\n"),
9768 MockRead("hello world"),
9769 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
9770 MockRead(ASYNC, OK)};
[email protected]2ff8b312010-04-26 22:20:549771
9772 StaticSocketDataProvider first_transaction(
9773 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079774 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:549775
[email protected]8ddf8322012-02-23 18:08:069776 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029777 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:239778 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
9779 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:079780 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:549781
[email protected]cdf8f7e72013-05-23 10:56:469782 scoped_ptr<SpdyFrame> req(
9783 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
rch8e6c6c42015-05-01 14:05:139784 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]2ff8b312010-04-26 22:20:549785
[email protected]23e482282013-06-14 16:08:029786 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9787 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:549788 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:139789 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:549790 };
9791
rch8e6c6c42015-05-01 14:05:139792 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9793 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079794 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:549795
[email protected]d973e99a2012-02-17 21:02:369796 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559797 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
9798 NULL, 0, NULL, 0);
9799 hanging_non_alternate_protocol_socket.set_connect_data(
9800 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:079801 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:559802 &hanging_non_alternate_protocol_socket);
9803
[email protected]49639fa2011-12-20 23:22:419804 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:549805
mmenke6b3af6e2015-09-12 02:06:069806 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369807 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509808 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:549809
[email protected]49639fa2011-12-20 23:22:419810 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:549811 EXPECT_EQ(ERR_IO_PENDING, rv);
9812 EXPECT_EQ(OK, callback.WaitForResult());
9813
9814 const HttpResponseInfo* response = trans->GetResponseInfo();
9815 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509816 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:549817 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9818
9819 std::string response_data;
9820 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9821 EXPECT_EQ("hello world", response_data);
9822
[email protected]90499482013-06-01 00:39:509823 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:549824
[email protected]49639fa2011-12-20 23:22:419825 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:549826 EXPECT_EQ(ERR_IO_PENDING, rv);
9827 EXPECT_EQ(OK, callback.WaitForResult());
9828
9829 response = trans->GetResponseInfo();
9830 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509831 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:549832 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539833 EXPECT_TRUE(response->was_fetched_via_spdy);
9834 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:549835
9836 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9837 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:549838}
9839
[email protected]23e482282013-06-14 16:08:029840TEST_P(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
bnc55ff9da2015-08-19 18:42:359841 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:239842 session_deps_.next_protos = SpdyNextProtos();
[email protected]2d6728692011-03-12 01:39:559843
9844 HttpRequestInfo request;
9845 request.method = "GET";
bncce36dca22015-04-21 22:11:239846 request.url = GURL("http://www.example.org/");
[email protected]2d6728692011-03-12 01:39:559847 request.load_flags = 0;
9848
[email protected]8a0fc822013-06-27 20:52:439849 std::string alternate_protocol_http_header =
9850 GetAlternateProtocolHttpHeader();
9851
[email protected]2d6728692011-03-12 01:39:559852 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:529853 MockRead("HTTP/1.1 200 OK\r\n"),
9854 MockRead(alternate_protocol_http_header.c_str()),
9855 MockRead("\r\n"),
9856 MockRead("hello world"),
9857 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
9858 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:559859 };
9860
9861 StaticSocketDataProvider first_transaction(
9862 data_reads, arraysize(data_reads), NULL, 0);
9863 // Socket 1 is the HTTP transaction with the Alternate-Protocol header.
[email protected]bb88e1d32013-05-03 23:11:079864 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:559865
[email protected]d973e99a2012-02-17 21:02:369866 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559867 StaticSocketDataProvider hanging_socket(
9868 NULL, 0, NULL, 0);
9869 hanging_socket.set_connect_data(never_finishing_connect);
9870 // Socket 2 and 3 are the hanging Alternate-Protocol and
9871 // non-Alternate-Protocol jobs from the 2nd transaction.
[email protected]bb88e1d32013-05-03 23:11:079872 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
9873 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
[email protected]2d6728692011-03-12 01:39:559874
[email protected]8ddf8322012-02-23 18:08:069875 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029876 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:239877 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
9878 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:079879 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:559880
[email protected]cdf8f7e72013-05-23 10:56:469881 scoped_ptr<SpdyFrame> req1(
9882 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
9883 scoped_ptr<SpdyFrame> req2(
9884 spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
[email protected]2d6728692011-03-12 01:39:559885 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:139886 CreateMockWrite(*req1, 0), CreateMockWrite(*req2, 1),
[email protected]2d6728692011-03-12 01:39:559887 };
[email protected]23e482282013-06-14 16:08:029888 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9889 scoped_ptr<SpdyFrame> data1(spdy_util_.ConstructSpdyBodyFrame(1, true));
9890 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
9891 scoped_ptr<SpdyFrame> data2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]2d6728692011-03-12 01:39:559892 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:139893 CreateMockRead(*resp1, 2),
9894 CreateMockRead(*data1, 3),
9895 CreateMockRead(*resp2, 4),
9896 CreateMockRead(*data2, 5),
9897 MockRead(ASYNC, 0, 6),
[email protected]2d6728692011-03-12 01:39:559898 };
9899
rch8e6c6c42015-05-01 14:05:139900 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9901 arraysize(spdy_writes));
[email protected]2d6728692011-03-12 01:39:559902 // Socket 4 is the successful Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:079903 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:559904
9905 // Socket 5 is the unsuccessful non-Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:079906 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
[email protected]2d6728692011-03-12 01:39:559907
mmenke6b3af6e2015-09-12 02:06:069908 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:419909 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:509910 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:559911
[email protected]49639fa2011-12-20 23:22:419912 int rv = trans1.Start(&request, callback1.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559913 EXPECT_EQ(ERR_IO_PENDING, rv);
9914 EXPECT_EQ(OK, callback1.WaitForResult());
9915
9916 const HttpResponseInfo* response = trans1.GetResponseInfo();
9917 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509918 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559919 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9920
9921 std::string response_data;
9922 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
9923 EXPECT_EQ("hello world", response_data);
9924
[email protected]49639fa2011-12-20 23:22:419925 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:509926 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:419927 rv = trans2.Start(&request, callback2.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559928 EXPECT_EQ(ERR_IO_PENDING, rv);
9929
[email protected]49639fa2011-12-20 23:22:419930 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:509931 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:419932 rv = trans3.Start(&request, callback3.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559933 EXPECT_EQ(ERR_IO_PENDING, rv);
9934
9935 EXPECT_EQ(OK, callback2.WaitForResult());
9936 EXPECT_EQ(OK, callback3.WaitForResult());
9937
9938 response = trans2.GetResponseInfo();
9939 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509940 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559941 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9942 EXPECT_TRUE(response->was_fetched_via_spdy);
9943 EXPECT_TRUE(response->was_npn_negotiated);
9944 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
9945 EXPECT_EQ("hello!", response_data);
9946
9947 response = trans3.GetResponseInfo();
9948 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509949 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559950 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9951 EXPECT_TRUE(response->was_fetched_via_spdy);
9952 EXPECT_TRUE(response->was_npn_negotiated);
9953 ASSERT_EQ(OK, ReadTransaction(&trans3, &response_data));
9954 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:559955}
9956
[email protected]23e482282013-06-14 16:08:029957TEST_P(HttpNetworkTransactionTest, StallAlternateProtocolForNpnSpdy) {
bnc55ff9da2015-08-19 18:42:359958 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:239959 session_deps_.next_protos = SpdyNextProtos();
[email protected]2d6728692011-03-12 01:39:559960
9961 HttpRequestInfo request;
9962 request.method = "GET";
bncce36dca22015-04-21 22:11:239963 request.url = GURL("http://www.example.org/");
[email protected]2d6728692011-03-12 01:39:559964 request.load_flags = 0;
9965
[email protected]8a0fc822013-06-27 20:52:439966 std::string alternate_protocol_http_header =
9967 GetAlternateProtocolHttpHeader();
9968
[email protected]2d6728692011-03-12 01:39:559969 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:529970 MockRead("HTTP/1.1 200 OK\r\n"),
9971 MockRead(alternate_protocol_http_header.c_str()),
9972 MockRead("\r\n"),
9973 MockRead("hello world"),
9974 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
9975 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:559976 };
9977
9978 StaticSocketDataProvider first_transaction(
9979 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079980 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:559981
[email protected]8ddf8322012-02-23 18:08:069982 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029983 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:079984 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:559985
[email protected]d973e99a2012-02-17 21:02:369986 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559987 StaticSocketDataProvider hanging_alternate_protocol_socket(
9988 NULL, 0, NULL, 0);
9989 hanging_alternate_protocol_socket.set_connect_data(
9990 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:079991 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:559992 &hanging_alternate_protocol_socket);
9993
9994 // 2nd request is just a copy of the first one, over HTTP again.
[email protected]bb88e1d32013-05-03 23:11:079995 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:559996
[email protected]49639fa2011-12-20 23:22:419997 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:559998
mmenke6b3af6e2015-09-12 02:06:069999 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610000 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010001 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:5510002
[email protected]49639fa2011-12-20 23:22:4110003 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:5510004 EXPECT_EQ(ERR_IO_PENDING, rv);
10005 EXPECT_EQ(OK, callback.WaitForResult());
10006
10007 const HttpResponseInfo* response = trans->GetResponseInfo();
10008 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010009 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:5510010 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10011
10012 std::string response_data;
10013 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10014 EXPECT_EQ("hello world", response_data);
10015
[email protected]90499482013-06-01 00:39:5010016 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:5510017
[email protected]49639fa2011-12-20 23:22:4110018 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:5510019 EXPECT_EQ(ERR_IO_PENDING, rv);
10020 EXPECT_EQ(OK, callback.WaitForResult());
10021
10022 response = trans->GetResponseInfo();
10023 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010024 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:5510025 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10026 EXPECT_FALSE(response->was_fetched_via_spdy);
10027 EXPECT_FALSE(response->was_npn_negotiated);
10028
10029 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10030 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:5510031}
10032
[email protected]631f1322010-04-30 17:59:1110033class CapturingProxyResolver : public ProxyResolver {
10034 public:
sammce90c9212015-05-27 23:43:3510035 CapturingProxyResolver() {}
dchengb03027d2014-10-21 12:00:2010036 ~CapturingProxyResolver() override {}
[email protected]631f1322010-04-30 17:59:1110037
dchengb03027d2014-10-21 12:00:2010038 int GetProxyForURL(const GURL& url,
10039 ProxyInfo* results,
10040 const CompletionCallback& callback,
10041 RequestHandle* request,
10042 const BoundNetLog& net_log) override {
[email protected]fae7669f2010-08-02 21:49:4010043 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
10044 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:4210045 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:1110046 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:4210047 return OK;
[email protected]631f1322010-04-30 17:59:1110048 }
10049
dchengb03027d2014-10-21 12:00:2010050 void CancelRequest(RequestHandle request) override { NOTREACHED(); }
[email protected]631f1322010-04-30 17:59:1110051
dchengb03027d2014-10-21 12:00:2010052 LoadState GetLoadState(RequestHandle request) const override {
[email protected]f2c971f2011-11-08 00:33:1710053 NOTREACHED();
10054 return LOAD_STATE_IDLE;
10055 }
10056
[email protected]24476402010-07-20 20:55:1710057 const std::vector<GURL>& resolved() const { return resolved_; }
10058
10059 private:
[email protected]631f1322010-04-30 17:59:1110060 std::vector<GURL> resolved_;
10061
10062 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
10063};
10064
sammce64b2362015-04-29 03:50:2310065class CapturingProxyResolverFactory : public ProxyResolverFactory {
10066 public:
10067 explicit CapturingProxyResolverFactory(CapturingProxyResolver* resolver)
10068 : ProxyResolverFactory(false), resolver_(resolver) {}
10069
10070 int CreateProxyResolver(
10071 const scoped_refptr<ProxyResolverScriptData>& pac_script,
10072 scoped_ptr<ProxyResolver>* resolver,
10073 const net::CompletionCallback& callback,
10074 scoped_ptr<Request>* request) override {
10075 resolver->reset(new ForwardingProxyResolver(resolver_));
10076 return OK;
10077 }
10078
10079 private:
10080 ProxyResolver* resolver_;
10081};
10082
[email protected]23e482282013-06-14 16:08:0210083TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310084 UseAlternateProtocolForTunneledNpnSpdy) {
bnc55ff9da2015-08-19 18:42:3510085 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2310086 session_deps_.next_protos = SpdyNextProtos();
[email protected]631f1322010-04-30 17:59:1110087
10088 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:4210089 proxy_config.set_auto_detect(true);
10090 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:1110091
sammc5dd160c2015-04-02 02:43:1310092 CapturingProxyResolver capturing_proxy_resolver;
[email protected]bb88e1d32013-05-03 23:11:0710093 session_deps_.proxy_service.reset(new ProxyService(
csharrisonb7e3a082015-09-22 19:13:0410094 make_scoped_ptr(new ProxyConfigServiceFixed(proxy_config)),
sammc5dd160c2015-04-02 02:43:1310095 make_scoped_ptr(
sammce64b2362015-04-29 03:50:2310096 new CapturingProxyResolverFactory(&capturing_proxy_resolver)),
[email protected]66761b952010-06-25 21:30:3810097 NULL));
vishal.b62985ca92015-04-17 08:45:5110098 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710099 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:1110100
10101 HttpRequestInfo request;
10102 request.method = "GET";
bncce36dca22015-04-21 22:11:2310103 request.url = GURL("http://www.example.org/");
[email protected]631f1322010-04-30 17:59:1110104 request.load_flags = 0;
10105
[email protected]8a0fc822013-06-27 20:52:4310106 std::string alternate_protocol_http_header =
10107 GetAlternateProtocolHttpHeader();
10108
[email protected]631f1322010-04-30 17:59:1110109 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210110 MockRead("HTTP/1.1 200 OK\r\n"),
10111 MockRead(alternate_protocol_http_header.c_str()),
10112 MockRead("\r\n"),
10113 MockRead("hello world"),
10114 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
10115 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:1110116 };
10117
10118 StaticSocketDataProvider first_transaction(
10119 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710120 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]631f1322010-04-30 17:59:1110121
[email protected]8ddf8322012-02-23 18:08:0610122 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210123 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:2310124 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
10125 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:0710126 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]631f1322010-04-30 17:59:1110127
[email protected]cdf8f7e72013-05-23 10:56:4610128 scoped_ptr<SpdyFrame> req(
10129 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]631f1322010-04-30 17:59:1110130 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1310131 MockWrite(ASYNC, 0,
10132 "CONNECT www.example.org:443 HTTP/1.1\r\n"
10133 "Host: www.example.org\r\n"
10134 "Proxy-Connection: keep-alive\r\n\r\n"),
10135 CreateMockWrite(*req, 2),
[email protected]631f1322010-04-30 17:59:1110136 };
10137
[email protected]d911f1b2010-05-05 22:39:4210138 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
10139
[email protected]23e482282013-06-14 16:08:0210140 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10141 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]631f1322010-04-30 17:59:1110142 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1310143 MockRead(ASYNC, 1, kCONNECTResponse),
10144 CreateMockRead(*resp.get(), 3),
10145 CreateMockRead(*data.get(), 4),
10146 MockRead(ASYNC, ERR_IO_PENDING, 5),
[email protected]631f1322010-04-30 17:59:1110147 };
10148
rch8e6c6c42015-05-01 14:05:1310149 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10150 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710151 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:1110152
[email protected]d973e99a2012-02-17 21:02:3610153 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5510154 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
10155 NULL, 0, NULL, 0);
10156 hanging_non_alternate_protocol_socket.set_connect_data(
10157 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0710158 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5510159 &hanging_non_alternate_protocol_socket);
10160
[email protected]49639fa2011-12-20 23:22:4110161 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:1110162
mmenke6b3af6e2015-09-12 02:06:0610163 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610164 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010165 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:1110166
[email protected]49639fa2011-12-20 23:22:4110167 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:1110168 EXPECT_EQ(ERR_IO_PENDING, rv);
10169 EXPECT_EQ(OK, callback.WaitForResult());
10170
10171 const HttpResponseInfo* response = trans->GetResponseInfo();
10172 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010173 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]631f1322010-04-30 17:59:1110174 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5310175 EXPECT_FALSE(response->was_fetched_via_spdy);
10176 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:1110177
10178 std::string response_data;
10179 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10180 EXPECT_EQ("hello world", response_data);
10181
[email protected]90499482013-06-01 00:39:5010182 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:1110183
[email protected]49639fa2011-12-20 23:22:4110184 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:1110185 EXPECT_EQ(ERR_IO_PENDING, rv);
10186 EXPECT_EQ(OK, callback.WaitForResult());
10187
10188 response = trans->GetResponseInfo();
10189 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010190 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]631f1322010-04-30 17:59:1110191 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5310192 EXPECT_TRUE(response->was_fetched_via_spdy);
10193 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:1110194
10195 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10196 EXPECT_EQ("hello!", response_data);
sammc5dd160c2015-04-02 02:43:1310197 ASSERT_EQ(3u, capturing_proxy_resolver.resolved().size());
bncce36dca22015-04-21 22:11:2310198 EXPECT_EQ("http://www.example.org/",
sammc5dd160c2015-04-02 02:43:1310199 capturing_proxy_resolver.resolved()[0].spec());
bncce36dca22015-04-21 22:11:2310200 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1310201 capturing_proxy_resolver.resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:1110202
[email protected]029c83b62013-01-24 05:28:2010203 LoadTimingInfo load_timing_info;
10204 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10205 TestLoadTimingNotReusedWithPac(load_timing_info,
10206 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:1110207}
[email protected]631f1322010-04-30 17:59:1110208
[email protected]23e482282013-06-14 16:08:0210209TEST_P(HttpNetworkTransactionTest,
[email protected]2ff8b312010-04-26 22:20:5410210 UseAlternateProtocolForNpnSpdyWithExistingSpdySession) {
bnc55ff9da2015-08-19 18:42:3510211 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2310212 session_deps_.next_protos = SpdyNextProtos();
[email protected]2ff8b312010-04-26 22:20:5410213
10214 HttpRequestInfo request;
10215 request.method = "GET";
bncce36dca22015-04-21 22:11:2310216 request.url = GURL("http://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5410217 request.load_flags = 0;
10218
[email protected]8a0fc822013-06-27 20:52:4310219 std::string alternate_protocol_http_header =
10220 GetAlternateProtocolHttpHeader();
10221
[email protected]2ff8b312010-04-26 22:20:5410222 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210223 MockRead("HTTP/1.1 200 OK\r\n"),
10224 MockRead(alternate_protocol_http_header.c_str()),
10225 MockRead("\r\n"),
10226 MockRead("hello world"),
10227 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:5410228 };
10229
10230 StaticSocketDataProvider first_transaction(
10231 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710232 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:5410233
[email protected]8ddf8322012-02-23 18:08:0610234 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210235 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:2310236 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
10237 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:0710238 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:5410239
[email protected]cdf8f7e72013-05-23 10:56:4610240 scoped_ptr<SpdyFrame> req(
10241 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
rch8e6c6c42015-05-01 14:05:1310242 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]2ff8b312010-04-26 22:20:5410243
[email protected]23e482282013-06-14 16:08:0210244 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10245 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5410246 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1310247 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5410248 };
10249
rch8e6c6c42015-05-01 14:05:1310250 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10251 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710252 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5410253
[email protected]83039bb2011-12-09 18:43:5510254 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5410255
mmenke6b3af6e2015-09-12 02:06:0610256 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:5410257
[email protected]262eec82013-03-19 21:01:3610258 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010259 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5410260
[email protected]49639fa2011-12-20 23:22:4110261 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:5410262 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110263 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:5410264
10265 const HttpResponseInfo* response = trans->GetResponseInfo();
10266 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010267 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:5410268 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10269
10270 std::string response_data;
10271 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10272 EXPECT_EQ("hello world", response_data);
10273
10274 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2310275 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4010276 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5310277 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2710278 base::WeakPtr<SpdySession> spdy_session =
mmenke6b3af6e2015-09-12 02:06:0610279 CreateSecureSpdySession(session, key, BoundNetLog());
[email protected]02b0c342010-09-25 21:09:3810280
[email protected]90499482013-06-01 00:39:5010281 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5410282
[email protected]49639fa2011-12-20 23:22:4110283 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:5410284 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110285 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:5410286
10287 response = trans->GetResponseInfo();
10288 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010289 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:5410290 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5310291 EXPECT_TRUE(response->was_fetched_via_spdy);
10292 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5410293
10294 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10295 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:4210296}
10297
[email protected]044de0642010-06-17 10:42:1510298// GenerateAuthToken is a mighty big test.
10299// It tests all permutation of GenerateAuthToken behavior:
10300// - Synchronous and Asynchronous completion.
10301// - OK or error on completion.
10302// - Direct connection, non-authenticating proxy, and authenticating proxy.
10303// - HTTP or HTTPS backend (to include proxy tunneling).
10304// - Non-authenticating and authenticating backend.
10305//
[email protected]fe3b7dc2012-02-03 19:52:0910306// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:1510307// problems generating an auth token for an authenticating proxy, we don't
10308// need to test all permutations of the backend server).
10309//
10310// The test proceeds by going over each of the configuration cases, and
10311// potentially running up to three rounds in each of the tests. The TestConfig
10312// specifies both the configuration for the test as well as the expectations
10313// for the results.
[email protected]23e482282013-06-14 16:08:0210314TEST_P(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:5010315 static const char kServer[] = "http://www.example.com";
10316 static const char kSecureServer[] = "https://www.example.com";
10317 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:1510318 const int kAuthErr = ERR_INVALID_AUTH_CREDENTIALS;
10319
10320 enum AuthTiming {
10321 AUTH_NONE,
10322 AUTH_SYNC,
10323 AUTH_ASYNC,
10324 };
10325
10326 const MockWrite kGet(
10327 "GET / HTTP/1.1\r\n"
10328 "Host: www.example.com\r\n"
10329 "Connection: keep-alive\r\n\r\n");
10330 const MockWrite kGetProxy(
10331 "GET http://www.example.com/ HTTP/1.1\r\n"
10332 "Host: www.example.com\r\n"
10333 "Proxy-Connection: keep-alive\r\n\r\n");
10334 const MockWrite kGetAuth(
10335 "GET / HTTP/1.1\r\n"
10336 "Host: www.example.com\r\n"
10337 "Connection: keep-alive\r\n"
10338 "Authorization: auth_token\r\n\r\n");
10339 const MockWrite kGetProxyAuth(
10340 "GET http://www.example.com/ HTTP/1.1\r\n"
10341 "Host: www.example.com\r\n"
10342 "Proxy-Connection: keep-alive\r\n"
10343 "Proxy-Authorization: auth_token\r\n\r\n");
10344 const MockWrite kGetAuthThroughProxy(
10345 "GET http://www.example.com/ HTTP/1.1\r\n"
10346 "Host: www.example.com\r\n"
10347 "Proxy-Connection: keep-alive\r\n"
10348 "Authorization: auth_token\r\n\r\n");
10349 const MockWrite kGetAuthWithProxyAuth(
10350 "GET http://www.example.com/ HTTP/1.1\r\n"
10351 "Host: www.example.com\r\n"
10352 "Proxy-Connection: keep-alive\r\n"
10353 "Proxy-Authorization: auth_token\r\n"
10354 "Authorization: auth_token\r\n\r\n");
10355 const MockWrite kConnect(
10356 "CONNECT www.example.com:443 HTTP/1.1\r\n"
10357 "Host: www.example.com\r\n"
10358 "Proxy-Connection: keep-alive\r\n\r\n");
10359 const MockWrite kConnectProxyAuth(
10360 "CONNECT www.example.com:443 HTTP/1.1\r\n"
10361 "Host: www.example.com\r\n"
10362 "Proxy-Connection: keep-alive\r\n"
10363 "Proxy-Authorization: auth_token\r\n\r\n");
10364
10365 const MockRead kSuccess(
10366 "HTTP/1.1 200 OK\r\n"
10367 "Content-Type: text/html; charset=iso-8859-1\r\n"
10368 "Content-Length: 3\r\n\r\n"
10369 "Yes");
10370 const MockRead kFailure(
10371 "Should not be called.");
10372 const MockRead kServerChallenge(
10373 "HTTP/1.1 401 Unauthorized\r\n"
10374 "WWW-Authenticate: Mock realm=server\r\n"
10375 "Content-Type: text/html; charset=iso-8859-1\r\n"
10376 "Content-Length: 14\r\n\r\n"
10377 "Unauthorized\r\n");
10378 const MockRead kProxyChallenge(
10379 "HTTP/1.1 407 Unauthorized\r\n"
10380 "Proxy-Authenticate: Mock realm=proxy\r\n"
10381 "Proxy-Connection: close\r\n"
10382 "Content-Type: text/html; charset=iso-8859-1\r\n"
10383 "Content-Length: 14\r\n\r\n"
10384 "Unauthorized\r\n");
10385 const MockRead kProxyConnected(
10386 "HTTP/1.1 200 Connection Established\r\n\r\n");
10387
10388 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
10389 // no constructors, but the C++ compiler on Windows warns about
10390 // unspecified data in compound literals. So, moved to using constructors,
10391 // and TestRound's created with the default constructor should not be used.
10392 struct TestRound {
10393 TestRound()
10394 : expected_rv(ERR_UNEXPECTED),
10395 extra_write(NULL),
10396 extra_read(NULL) {
10397 }
10398 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
10399 int expected_rv_arg)
10400 : write(write_arg),
10401 read(read_arg),
10402 expected_rv(expected_rv_arg),
10403 extra_write(NULL),
10404 extra_read(NULL) {
10405 }
10406 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
10407 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:0110408 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:1510409 : write(write_arg),
10410 read(read_arg),
10411 expected_rv(expected_rv_arg),
10412 extra_write(extra_write_arg),
10413 extra_read(extra_read_arg) {
10414 }
10415 MockWrite write;
10416 MockRead read;
10417 int expected_rv;
10418 const MockWrite* extra_write;
10419 const MockRead* extra_read;
10420 };
10421
10422 static const int kNoSSL = 500;
10423
10424 struct TestConfig {
thestig9d3bb0c2015-01-24 00:49:5110425 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:1510426 AuthTiming proxy_auth_timing;
10427 int proxy_auth_rv;
thestig9d3bb0c2015-01-24 00:49:5110428 const char* const server_url;
[email protected]044de0642010-06-17 10:42:1510429 AuthTiming server_auth_timing;
10430 int server_auth_rv;
10431 int num_auth_rounds;
10432 int first_ssl_round;
10433 TestRound rounds[3];
10434 } test_configs[] = {
10435 // Non-authenticating HTTP server with a direct connection.
10436 { NULL, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
10437 { TestRound(kGet, kSuccess, OK)}},
10438 // Authenticating HTTP server with a direct connection.
10439 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
10440 { TestRound(kGet, kServerChallenge, OK),
10441 TestRound(kGetAuth, kSuccess, OK)}},
10442 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
10443 { TestRound(kGet, kServerChallenge, OK),
10444 TestRound(kGetAuth, kFailure, kAuthErr)}},
10445 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
10446 { TestRound(kGet, kServerChallenge, OK),
10447 TestRound(kGetAuth, kSuccess, OK)}},
10448 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
10449 { TestRound(kGet, kServerChallenge, OK),
10450 TestRound(kGetAuth, kFailure, kAuthErr)}},
10451 // Non-authenticating HTTP server through a non-authenticating proxy.
10452 { kProxy, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
10453 { TestRound(kGetProxy, kSuccess, OK)}},
10454 // Authenticating HTTP server through a non-authenticating proxy.
10455 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
10456 { TestRound(kGetProxy, kServerChallenge, OK),
10457 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
10458 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
10459 { TestRound(kGetProxy, kServerChallenge, OK),
10460 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
10461 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
10462 { TestRound(kGetProxy, kServerChallenge, OK),
10463 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
10464 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
10465 { TestRound(kGetProxy, kServerChallenge, OK),
10466 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
10467 // Non-authenticating HTTP server through an authenticating proxy.
10468 { kProxy, AUTH_SYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
10469 { TestRound(kGetProxy, kProxyChallenge, OK),
10470 TestRound(kGetProxyAuth, kSuccess, OK)}},
10471 { kProxy, AUTH_SYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
10472 { TestRound(kGetProxy, kProxyChallenge, OK),
10473 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
10474 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
10475 { TestRound(kGetProxy, kProxyChallenge, OK),
10476 TestRound(kGetProxyAuth, kSuccess, OK)}},
10477 { kProxy, AUTH_ASYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
10478 { TestRound(kGetProxy, kProxyChallenge, OK),
10479 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
10480 // Authenticating HTTP server through an authenticating proxy.
10481 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
10482 { TestRound(kGetProxy, kProxyChallenge, OK),
10483 TestRound(kGetProxyAuth, kServerChallenge, OK),
10484 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
10485 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
10486 { TestRound(kGetProxy, kProxyChallenge, OK),
10487 TestRound(kGetProxyAuth, kServerChallenge, OK),
10488 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
10489 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
10490 { TestRound(kGetProxy, kProxyChallenge, OK),
10491 TestRound(kGetProxyAuth, kServerChallenge, OK),
10492 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
10493 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
10494 { TestRound(kGetProxy, kProxyChallenge, OK),
10495 TestRound(kGetProxyAuth, kServerChallenge, OK),
10496 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
10497 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
10498 { TestRound(kGetProxy, kProxyChallenge, OK),
10499 TestRound(kGetProxyAuth, kServerChallenge, OK),
10500 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
10501 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
10502 { TestRound(kGetProxy, kProxyChallenge, OK),
10503 TestRound(kGetProxyAuth, kServerChallenge, OK),
10504 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
10505 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
10506 { TestRound(kGetProxy, kProxyChallenge, OK),
10507 TestRound(kGetProxyAuth, kServerChallenge, OK),
10508 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
10509 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
10510 { TestRound(kGetProxy, kProxyChallenge, OK),
10511 TestRound(kGetProxyAuth, kServerChallenge, OK),
10512 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
10513 // Non-authenticating HTTPS server with a direct connection.
10514 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
10515 { TestRound(kGet, kSuccess, OK)}},
10516 // Authenticating HTTPS server with a direct connection.
10517 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
10518 { TestRound(kGet, kServerChallenge, OK),
10519 TestRound(kGetAuth, kSuccess, OK)}},
10520 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
10521 { TestRound(kGet, kServerChallenge, OK),
10522 TestRound(kGetAuth, kFailure, kAuthErr)}},
10523 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
10524 { TestRound(kGet, kServerChallenge, OK),
10525 TestRound(kGetAuth, kSuccess, OK)}},
10526 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
10527 { TestRound(kGet, kServerChallenge, OK),
10528 TestRound(kGetAuth, kFailure, kAuthErr)}},
10529 // Non-authenticating HTTPS server with a non-authenticating proxy.
10530 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
10531 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
10532 // Authenticating HTTPS server through a non-authenticating proxy.
10533 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
10534 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
10535 TestRound(kGetAuth, kSuccess, OK)}},
10536 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
10537 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
10538 TestRound(kGetAuth, kFailure, kAuthErr)}},
10539 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
10540 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
10541 TestRound(kGetAuth, kSuccess, OK)}},
10542 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
10543 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
10544 TestRound(kGetAuth, kFailure, kAuthErr)}},
10545 // Non-Authenticating HTTPS server through an authenticating proxy.
10546 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
10547 { TestRound(kConnect, kProxyChallenge, OK),
10548 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
10549 { kProxy, AUTH_SYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
10550 { TestRound(kConnect, kProxyChallenge, OK),
10551 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
10552 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
10553 { TestRound(kConnect, kProxyChallenge, OK),
10554 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
10555 { kProxy, AUTH_ASYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
10556 { TestRound(kConnect, kProxyChallenge, OK),
10557 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
10558 // Authenticating HTTPS server through an authenticating proxy.
10559 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
10560 { TestRound(kConnect, kProxyChallenge, OK),
10561 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10562 &kGet, &kServerChallenge),
10563 TestRound(kGetAuth, kSuccess, OK)}},
10564 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
10565 { TestRound(kConnect, kProxyChallenge, OK),
10566 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10567 &kGet, &kServerChallenge),
10568 TestRound(kGetAuth, kFailure, kAuthErr)}},
10569 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
10570 { TestRound(kConnect, kProxyChallenge, OK),
10571 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10572 &kGet, &kServerChallenge),
10573 TestRound(kGetAuth, kSuccess, OK)}},
10574 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
10575 { TestRound(kConnect, kProxyChallenge, OK),
10576 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10577 &kGet, &kServerChallenge),
10578 TestRound(kGetAuth, kFailure, kAuthErr)}},
10579 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
10580 { TestRound(kConnect, kProxyChallenge, OK),
10581 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10582 &kGet, &kServerChallenge),
10583 TestRound(kGetAuth, kSuccess, OK)}},
10584 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
10585 { TestRound(kConnect, kProxyChallenge, OK),
10586 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10587 &kGet, &kServerChallenge),
10588 TestRound(kGetAuth, kFailure, kAuthErr)}},
10589 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
10590 { TestRound(kConnect, kProxyChallenge, OK),
10591 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10592 &kGet, &kServerChallenge),
10593 TestRound(kGetAuth, kSuccess, OK)}},
10594 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
10595 { TestRound(kConnect, kProxyChallenge, OK),
10596 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10597 &kGet, &kServerChallenge),
10598 TestRound(kGetAuth, kFailure, kAuthErr)}},
10599 };
10600
viettrungluue4a8b882014-10-16 06:17:3810601 for (size_t i = 0; i < arraysize(test_configs); ++i) {
[email protected]2d01c262011-08-11 23:07:0810602 HttpAuthHandlerMock::Factory* auth_factory(
10603 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0710604 session_deps_.http_auth_handler_factory.reset(auth_factory);
[email protected]044de0642010-06-17 10:42:1510605 const TestConfig& test_config = test_configs[i];
[email protected]65d34382010-07-01 18:12:2610606
10607 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:1510608 if (test_config.proxy_auth_timing != AUTH_NONE) {
[email protected]2d01c262011-08-11 23:07:0810609 for (int n = 0; n < 2; n++) {
10610 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
10611 std::string auth_challenge = "Mock realm=proxy";
10612 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:2410613 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
10614 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:0810615 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
10616 origin, BoundNetLog());
10617 auth_handler->SetGenerateExpectation(
10618 test_config.proxy_auth_timing == AUTH_ASYNC,
10619 test_config.proxy_auth_rv);
10620 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
10621 }
[email protected]044de0642010-06-17 10:42:1510622 }
10623 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:0010624 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:1510625 std::string auth_challenge = "Mock realm=server";
10626 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:2410627 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
10628 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:1510629 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
10630 origin, BoundNetLog());
10631 auth_handler->SetGenerateExpectation(
10632 test_config.server_auth_timing == AUTH_ASYNC,
10633 test_config.server_auth_rv);
[email protected]2d01c262011-08-11 23:07:0810634 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:1510635 }
10636 if (test_config.proxy_url) {
rdsmith82957ad2015-09-16 19:42:0310637 session_deps_.proxy_service =
10638 ProxyService::CreateFixed(test_config.proxy_url);
[email protected]044de0642010-06-17 10:42:1510639 } else {
rdsmith82957ad2015-09-16 19:42:0310640 session_deps_.proxy_service = ProxyService::CreateDirect();
[email protected]044de0642010-06-17 10:42:1510641 }
10642
10643 HttpRequestInfo request;
10644 request.method = "GET";
10645 request.url = GURL(test_config.server_url);
10646 request.load_flags = 0;
10647
mmenke6b3af6e2015-09-12 02:06:0610648 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
dcheng48459ac22014-08-26 00:46:4110649 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]044de0642010-06-17 10:42:1510650
rchcb68dc62015-05-21 04:45:3610651 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
10652
10653 std::vector<std::vector<MockRead>> mock_reads(1);
10654 std::vector<std::vector<MockWrite>> mock_writes(1);
[email protected]044de0642010-06-17 10:42:1510655 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
10656 const TestRound& read_write_round = test_config.rounds[round];
10657
10658 // Set up expected reads and writes.
rchcb68dc62015-05-21 04:45:3610659 mock_reads.back().push_back(read_write_round.read);
10660 mock_writes.back().push_back(read_write_round.write);
10661
10662 // kProxyChallenge uses Proxy-Connection: close which means that the
10663 // socket is closed and a new one will be created for the next request.
mmenkee0b5c882015-08-26 20:29:1110664 if (read_write_round.read.data == kProxyChallenge.data) {
rchcb68dc62015-05-21 04:45:3610665 mock_reads.push_back(std::vector<MockRead>());
10666 mock_writes.push_back(std::vector<MockWrite>());
[email protected]044de0642010-06-17 10:42:1510667 }
10668
rchcb68dc62015-05-21 04:45:3610669 if (read_write_round.extra_read) {
10670 mock_reads.back().push_back(*read_write_round.extra_read);
[email protected]044de0642010-06-17 10:42:1510671 }
rchcb68dc62015-05-21 04:45:3610672 if (read_write_round.extra_write) {
10673 mock_writes.back().push_back(*read_write_round.extra_write);
10674 }
[email protected]044de0642010-06-17 10:42:1510675
10676 // Add an SSL sequence if necessary.
[email protected]044de0642010-06-17 10:42:1510677 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0710678 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1510679 &ssl_socket_data_provider);
rchcb68dc62015-05-21 04:45:3610680 }
[email protected]044de0642010-06-17 10:42:1510681
rchcb68dc62015-05-21 04:45:3610682 ScopedVector<StaticSocketDataProvider> data_providers;
10683 for (size_t i = 0; i < mock_reads.size(); ++i) {
10684 data_providers.push_back(new StaticSocketDataProvider(
10685 vector_as_array(&mock_reads[i]), mock_reads[i].size(),
10686 vector_as_array(&mock_writes[i]), mock_writes[i].size()));
10687 session_deps_.socket_factory->AddSocketDataProvider(
10688 data_providers.back());
10689 }
10690
10691 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
10692 const TestRound& read_write_round = test_config.rounds[round];
[email protected]044de0642010-06-17 10:42:1510693 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4110694 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1510695 int rv;
10696 if (round == 0) {
[email protected]49639fa2011-12-20 23:22:4110697 rv = trans.Start(&request, callback.callback(), BoundNetLog());
[email protected]044de0642010-06-17 10:42:1510698 } else {
[email protected]49639fa2011-12-20 23:22:4110699 rv = trans.RestartWithAuth(
10700 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1510701 }
10702 if (rv == ERR_IO_PENDING)
10703 rv = callback.WaitForResult();
10704
10705 // Compare results with expected data.
10706 EXPECT_EQ(read_write_round.expected_rv, rv);
[email protected]0b0bf032010-09-21 18:08:5010707 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttlec0c828492015-05-15 01:25:5510708 if (read_write_round.expected_rv != OK) {
[email protected]044de0642010-06-17 10:42:1510709 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
10710 continue;
10711 }
10712 if (round + 1 < test_config.num_auth_rounds) {
10713 EXPECT_FALSE(response->auth_challenge.get() == NULL);
10714 } else {
10715 EXPECT_TRUE(response->auth_challenge.get() == NULL);
10716 }
10717 }
[email protected]e5ae96a2010-04-14 20:12:4510718 }
10719}
10720
[email protected]23e482282013-06-14 16:08:0210721TEST_P(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1410722 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1410723 HttpAuthHandlerMock::Factory* auth_factory(
10724 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0710725 session_deps_.http_auth_handler_factory.reset(auth_factory);
rdsmith82957ad2015-09-16 19:42:0310726 session_deps_.proxy_service = ProxyService::CreateDirect();
[email protected]bb88e1d32013-05-03 23:11:0710727 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
10728 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:1410729
10730 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
10731 auth_handler->set_connection_based(true);
10732 std::string auth_challenge = "Mock realm=server";
10733 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2410734 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
10735 auth_challenge.end());
[email protected]c871bce92010-07-15 21:51:1410736 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
10737 origin, BoundNetLog());
[email protected]2d01c262011-08-11 23:07:0810738 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1410739
[email protected]c871bce92010-07-15 21:51:1410740 int rv = OK;
10741 const HttpResponseInfo* response = NULL;
10742 HttpRequestInfo request;
10743 request.method = "GET";
10744 request.url = origin;
10745 request.load_flags = 0;
[email protected]cb9bf6ca2011-01-28 13:15:2710746
mmenke6b3af6e2015-09-12 02:06:0610747 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1010748
10749 // Use a TCP Socket Pool with only one connection per group. This is used
10750 // to validate that the TCP socket is not released to the pool between
10751 // each round of multi-round authentication.
mmenke6b3af6e2015-09-12 02:06:0610752 HttpNetworkSessionPeer session_peer(session);
[email protected]ab739042011-04-07 15:22:2810753 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:1010754 50, // Max sockets for pool
10755 1, // Max sockets per group
[email protected]bb88e1d32013-05-03 23:11:0710756 session_deps_.host_resolver.get(),
10757 session_deps_.socket_factory.get(),
10758 session_deps_.net_log);
[email protected]831e4a32013-11-14 02:14:4410759 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
10760 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:0210761 mock_pool_manager->SetTransportSocketPool(transport_pool);
dchenge3d1ddc2014-10-15 19:30:5110762 session_peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]7ef4cbbb2011-02-06 11:19:1010763
[email protected]262eec82013-03-19 21:01:3610764 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010765 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110766 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1410767
10768 const MockWrite kGet(
10769 "GET / HTTP/1.1\r\n"
10770 "Host: www.example.com\r\n"
10771 "Connection: keep-alive\r\n\r\n");
10772 const MockWrite kGetAuth(
10773 "GET / HTTP/1.1\r\n"
10774 "Host: www.example.com\r\n"
10775 "Connection: keep-alive\r\n"
10776 "Authorization: auth_token\r\n\r\n");
10777
10778 const MockRead kServerChallenge(
10779 "HTTP/1.1 401 Unauthorized\r\n"
10780 "WWW-Authenticate: Mock realm=server\r\n"
10781 "Content-Type: text/html; charset=iso-8859-1\r\n"
10782 "Content-Length: 14\r\n\r\n"
10783 "Unauthorized\r\n");
10784 const MockRead kSuccess(
10785 "HTTP/1.1 200 OK\r\n"
10786 "Content-Type: text/html; charset=iso-8859-1\r\n"
10787 "Content-Length: 3\r\n\r\n"
10788 "Yes");
10789
10790 MockWrite writes[] = {
10791 // First round
10792 kGet,
10793 // Second round
10794 kGetAuth,
10795 // Third round
10796 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3010797 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1010798 kGetAuth,
10799 // Competing request
10800 kGet,
[email protected]c871bce92010-07-15 21:51:1410801 };
10802 MockRead reads[] = {
10803 // First round
10804 kServerChallenge,
10805 // Second round
10806 kServerChallenge,
10807 // Third round
[email protected]eca50e122010-09-11 14:03:3010808 kServerChallenge,
10809 // Fourth round
[email protected]c871bce92010-07-15 21:51:1410810 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1010811 // Competing response
10812 kSuccess,
[email protected]c871bce92010-07-15 21:51:1410813 };
10814 StaticSocketDataProvider data_provider(reads, arraysize(reads),
10815 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:0710816 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1410817
thestig9d3bb0c2015-01-24 00:49:5110818 const char kSocketGroup[] = "www.example.com:80";
[email protected]7ef4cbbb2011-02-06 11:19:1010819
10820 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1410821 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4110822 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]c871bce92010-07-15 21:51:1410823 if (rv == ERR_IO_PENDING)
10824 rv = callback.WaitForResult();
10825 EXPECT_EQ(OK, rv);
10826 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010827 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:1410828 EXPECT_FALSE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2810829 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1410830
[email protected]7ef4cbbb2011-02-06 11:19:1010831 // In between rounds, another request comes in for the same domain.
10832 // It should not be able to grab the TCP socket that trans has already
10833 // claimed.
10834 scoped_ptr<HttpTransaction> trans_compete(
[email protected]90499482013-06-01 00:39:5010835 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110836 TestCompletionCallback callback_compete;
10837 rv = trans_compete->Start(
10838 &request, callback_compete.callback(), BoundNetLog());
[email protected]7ef4cbbb2011-02-06 11:19:1010839 EXPECT_EQ(ERR_IO_PENDING, rv);
10840 // callback_compete.WaitForResult at this point would stall forever,
10841 // since the HttpNetworkTransaction does not release the request back to
10842 // the pool until after authentication completes.
10843
10844 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1410845 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4110846 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1410847 if (rv == ERR_IO_PENDING)
10848 rv = callback.WaitForResult();
10849 EXPECT_EQ(OK, rv);
10850 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010851 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:1410852 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2810853 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1410854
[email protected]7ef4cbbb2011-02-06 11:19:1010855 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1410856 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4110857 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1410858 if (rv == ERR_IO_PENDING)
10859 rv = callback.WaitForResult();
10860 EXPECT_EQ(OK, rv);
10861 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010862 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:1410863 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2810864 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]eca50e122010-09-11 14:03:3010865
[email protected]7ef4cbbb2011-02-06 11:19:1010866 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3010867 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4110868 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3010869 if (rv == ERR_IO_PENDING)
10870 rv = callback.WaitForResult();
10871 EXPECT_EQ(OK, rv);
10872 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010873 ASSERT_TRUE(response != NULL);
[email protected]eca50e122010-09-11 14:03:3010874 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2810875 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1010876
10877 // Read the body since the fourth round was successful. This will also
10878 // release the socket back to the pool.
10879 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
[email protected]90499482013-06-01 00:39:5010880 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1010881 if (rv == ERR_IO_PENDING)
10882 rv = callback.WaitForResult();
10883 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:5010884 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1010885 EXPECT_EQ(0, rv);
10886 // There are still 0 idle sockets, since the trans_compete transaction
10887 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:2810888 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1010889
10890 // The competing request can now finish. Wait for the headers and then
10891 // read the body.
10892 rv = callback_compete.WaitForResult();
10893 EXPECT_EQ(OK, rv);
[email protected]90499482013-06-01 00:39:5010894 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1010895 if (rv == ERR_IO_PENDING)
10896 rv = callback.WaitForResult();
10897 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:5010898 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1010899 EXPECT_EQ(0, rv);
10900
10901 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:2810902 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1410903}
10904
[email protected]65041fa2010-05-21 06:56:5310905// This tests the case that a request is issued via http instead of spdy after
10906// npn is negotiated.
[email protected]23e482282013-06-14 16:08:0210907TEST_P(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
bnc55ff9da2015-08-19 18:42:3510908 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2310909 NextProtoVector next_protos;
[email protected]0ce3af82013-07-22 16:17:1610910 next_protos.push_back(kProtoHTTP11);
[email protected]d7599122014-05-24 03:37:2310911 session_deps_.next_protos = next_protos;
10912
[email protected]65041fa2010-05-21 06:56:5310913 HttpRequestInfo request;
10914 request.method = "GET";
bncce36dca22015-04-21 22:11:2310915 request.url = GURL("https://www.example.org/");
[email protected]65041fa2010-05-21 06:56:5310916 request.load_flags = 0;
10917
10918 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310919 MockWrite(
10920 "GET / HTTP/1.1\r\n"
10921 "Host: www.example.org\r\n"
10922 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5310923 };
10924
[email protected]8a0fc822013-06-27 20:52:4310925 std::string alternate_protocol_http_header =
10926 GetAlternateProtocolHttpHeader();
10927
[email protected]65041fa2010-05-21 06:56:5310928 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210929 MockRead("HTTP/1.1 200 OK\r\n"),
10930 MockRead(alternate_protocol_http_header.c_str()),
10931 MockRead("\r\n"),
10932 MockRead("hello world"),
10933 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5310934 };
10935
[email protected]8ddf8322012-02-23 18:08:0610936 SSLSocketDataProvider ssl(ASYNC, OK);
davidben6974bf72015-04-27 17:52:4810937 ssl.SetNextProto(kProtoHTTP11);
[email protected]65041fa2010-05-21 06:56:5310938
[email protected]bb88e1d32013-05-03 23:11:0710939 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5310940
10941 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
10942 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0710943 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5310944
[email protected]49639fa2011-12-20 23:22:4110945 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5310946
mmenke6b3af6e2015-09-12 02:06:0610947 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610948 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010949 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]65041fa2010-05-21 06:56:5310950
[email protected]49639fa2011-12-20 23:22:4110951 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]65041fa2010-05-21 06:56:5310952
10953 EXPECT_EQ(ERR_IO_PENDING, rv);
10954 EXPECT_EQ(OK, callback.WaitForResult());
10955
10956 const HttpResponseInfo* response = trans->GetResponseInfo();
10957 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010958 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]65041fa2010-05-21 06:56:5310959 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10960
10961 std::string response_data;
10962 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10963 EXPECT_EQ("hello world", response_data);
10964
10965 EXPECT_FALSE(response->was_fetched_via_spdy);
10966 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]65041fa2010-05-21 06:56:5310967}
[email protected]26ef6582010-06-24 02:30:4710968
bnc55ff9da2015-08-19 18:42:3510969// Simulate the SSL handshake completing with an NPN negotiation followed by an
10970// immediate server closing of the socket.
10971// Regression test for https://crbug.com/46369.
[email protected]23e482282013-06-14 16:08:0210972TEST_P(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
bnc55ff9da2015-08-19 18:42:3510973 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2310974 session_deps_.next_protos = SpdyNextProtos();
[email protected]26ef6582010-06-24 02:30:4710975
10976 HttpRequestInfo request;
10977 request.method = "GET";
bncce36dca22015-04-21 22:11:2310978 request.url = GURL("https://www.example.org/");
[email protected]26ef6582010-06-24 02:30:4710979 request.load_flags = 0;
10980
[email protected]8ddf8322012-02-23 18:08:0610981 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210982 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710983 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4710984
[email protected]cdf8f7e72013-05-23 10:56:4610985 scoped_ptr<SpdyFrame> req(
10986 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
rch8e6c6c42015-05-01 14:05:1310987 MockWrite spdy_writes[] = {CreateMockWrite(*req, 1)};
[email protected]26ef6582010-06-24 02:30:4710988
10989 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0610990 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4710991 };
10992
rch8e6c6c42015-05-01 14:05:1310993 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10994 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710995 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4710996
[email protected]49639fa2011-12-20 23:22:4110997 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4710998
mmenke6b3af6e2015-09-12 02:06:0610999 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3611000 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011001 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]26ef6582010-06-24 02:30:4711002
[email protected]49639fa2011-12-20 23:22:4111003 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]26ef6582010-06-24 02:30:4711004 EXPECT_EQ(ERR_IO_PENDING, rv);
11005 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult());
[email protected]26ef6582010-06-24 02:30:4711006}
[email protected]65d34382010-07-01 18:12:2611007
[email protected]795cbf82013-07-22 09:37:2711008// A subclass of HttpAuthHandlerMock that records the request URL when
11009// it gets it. This is needed since the auth handler may get destroyed
11010// before we get a chance to query it.
11011class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
11012 public:
11013 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
11014
dchengb03027d2014-10-21 12:00:2011015 ~UrlRecordingHttpAuthHandlerMock() override {}
[email protected]795cbf82013-07-22 09:37:2711016
11017 protected:
dchengb03027d2014-10-21 12:00:2011018 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
11019 const HttpRequestInfo* request,
11020 const CompletionCallback& callback,
11021 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2711022 *url_ = request->url;
11023 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
11024 credentials, request, callback, auth_token);
11025 }
11026
11027 private:
11028 GURL* url_;
11029};
11030
bnc55ff9da2015-08-19 18:42:3511031// This test ensures that the URL passed into the proxy is upgraded to https
11032// when doing an Alternate Protocol upgrade.
[email protected]23e482282013-06-14 16:08:0211033TEST_P(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) {
bnc55ff9da2015-08-19 18:42:3511034 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2311035 session_deps_.next_protos = SpdyNextProtos();
[email protected]f45c1ee2010-08-03 00:54:3011036
rdsmith82957ad2015-09-16 19:42:0311037 session_deps_.proxy_service =
11038 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5111039 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0711040 session_deps_.net_log = &net_log;
[email protected]795cbf82013-07-22 09:37:2711041 GURL request_url;
11042 {
11043 HttpAuthHandlerMock::Factory* auth_factory =
11044 new HttpAuthHandlerMock::Factory();
11045 UrlRecordingHttpAuthHandlerMock* auth_handler =
11046 new UrlRecordingHttpAuthHandlerMock(&request_url);
11047 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
11048 auth_factory->set_do_init_from_challenge(true);
11049 session_deps_.http_auth_handler_factory.reset(auth_factory);
11050 }
[email protected]f45c1ee2010-08-03 00:54:3011051
11052 HttpRequestInfo request;
11053 request.method = "GET";
bncce36dca22015-04-21 22:11:2311054 request.url = GURL("http://www.example.org");
[email protected]f45c1ee2010-08-03 00:54:3011055 request.load_flags = 0;
11056
11057 // First round goes unauthenticated through the proxy.
11058 MockWrite data_writes_1[] = {
bncce36dca22015-04-21 22:11:2311059 MockWrite(
11060 "GET http://www.example.org/ HTTP/1.1\r\n"
11061 "Host: www.example.org\r\n"
11062 "Proxy-Connection: keep-alive\r\n"
11063 "\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3011064 };
11065 MockRead data_reads_1[] = {
[email protected]8ddf8322012-02-23 18:08:0611066 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
bnc33b8cef42014-11-19 17:30:3811067 MockRead("HTTP/1.1 200 OK\r\n"),
11068 MockRead("Alternate-Protocol: 443:"),
11069 MockRead(GetAlternateProtocolFromParam()),
11070 MockRead("\r\n"),
11071 MockRead("Proxy-Connection: close\r\n"),
11072 MockRead("\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3011073 };
11074 StaticSocketDataProvider data_1(data_reads_1, arraysize(data_reads_1),
11075 data_writes_1, arraysize(data_writes_1));
11076
bncce36dca22015-04-21 22:11:2311077 // Second round tries to tunnel to www.example.org due to the
[email protected]f45c1ee2010-08-03 00:54:3011078 // Alternate-Protocol announcement in the first round. It fails due
11079 // to a proxy authentication challenge.
bncce36dca22015-04-21 22:11:2311080 // After the failure, a tunnel is established to www.example.org using
[email protected]394816e92010-08-03 07:38:5911081 // Proxy-Authorization headers. There is then a SPDY request round.
11082 //
[email protected]fe3b7dc2012-02-03 19:52:0911083 // NOTE: Despite the "Proxy-Connection: Close", these are done on the
11084 // same MockTCPClientSocket since the underlying HttpNetworkClientSocket
11085 // does a Disconnect and Connect on the same socket, rather than trying
11086 // to obtain a new one.
11087 //
[email protected]394816e92010-08-03 07:38:5911088 // NOTE: Originally, the proxy response to the second CONNECT request
11089 // simply returned another 407 so the unit test could skip the SSL connection
11090 // establishment and SPDY framing issues. Alas, the
11091 // retry-http-when-alternate-protocol fails logic kicks in, which was more
[email protected]f45c1ee2010-08-03 00:54:3011092 // complicated to set up expectations for than the SPDY session.
[email protected]394816e92010-08-03 07:38:5911093
[email protected]cdf8f7e72013-05-23 10:56:4611094 scoped_ptr<SpdyFrame> req(
11095 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]23e482282013-06-14 16:08:0211096 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11097 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]f45c1ee2010-08-03 00:54:3011098
[email protected]394816e92010-08-03 07:38:5911099 MockWrite data_writes_2[] = {
bncce36dca22015-04-21 22:11:2311100 // First connection attempt without Proxy-Authorization.
rch8e6c6c42015-05-01 14:05:1311101 MockWrite(ASYNC, 0,
11102 "CONNECT www.example.org:443 HTTP/1.1\r\n"
11103 "Host: www.example.org\r\n"
11104 "Proxy-Connection: keep-alive\r\n"
11105 "\r\n"),
[email protected]394816e92010-08-03 07:38:5911106
bncce36dca22015-04-21 22:11:2311107 // Second connection attempt with Proxy-Authorization.
rch8e6c6c42015-05-01 14:05:1311108 MockWrite(ASYNC, 2,
11109 "CONNECT www.example.org:443 HTTP/1.1\r\n"
11110 "Host: www.example.org\r\n"
11111 "Proxy-Connection: keep-alive\r\n"
11112 "Proxy-Authorization: auth_token\r\n"
11113 "\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3011114
bncce36dca22015-04-21 22:11:2311115 // SPDY request
rch8e6c6c42015-05-01 14:05:1311116 CreateMockWrite(*req, 4),
[email protected]f45c1ee2010-08-03 00:54:3011117 };
[email protected]394816e92010-08-03 07:38:5911118 MockRead data_reads_2[] = {
rch8e6c6c42015-05-01 14:05:1311119 // First connection attempt fails
mmenkee0b5c882015-08-26 20:29:1111120 MockRead(ASYNC, 1,
11121 "HTTP/1.1 407 Unauthorized\r\n"
11122 "Proxy-Authenticate: Mock\r\n"
11123 "Content-Length: 0\r\n"
11124 "Proxy-Connection: keep-alive\r\n"
11125 "\r\n"),
[email protected]394816e92010-08-03 07:38:5911126
rch8e6c6c42015-05-01 14:05:1311127 // Second connection attempt passes
mmenkee0b5c882015-08-26 20:29:1111128 MockRead(ASYNC, 3, "HTTP/1.1 200 Connected\r\n\r\n"),
[email protected]394816e92010-08-03 07:38:5911129
rch8e6c6c42015-05-01 14:05:1311130 // SPDY response
mmenkee0b5c882015-08-26 20:29:1111131 CreateMockRead(*resp.get(), 5), CreateMockRead(*data.get(), 6),
rch8e6c6c42015-05-01 14:05:1311132 MockRead(ASYNC, 0, 0, 7),
[email protected]394816e92010-08-03 07:38:5911133 };
rch8e6c6c42015-05-01 14:05:1311134 SequencedSocketData data_2(data_reads_2, arraysize(data_reads_2),
11135 data_writes_2, arraysize(data_writes_2));
[email protected]f45c1ee2010-08-03 00:54:3011136
[email protected]8ddf8322012-02-23 18:08:0611137 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211138 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:2311139 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
11140 ASSERT_TRUE(ssl.cert.get());
[email protected]f45c1ee2010-08-03 00:54:3011141
[email protected]d973e99a2012-02-17 21:02:3611142 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511143 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
11144 NULL, 0, NULL, 0);
11145 hanging_non_alternate_protocol_socket.set_connect_data(
11146 never_finishing_connect);
11147
[email protected]bb88e1d32013-05-03 23:11:0711148 session_deps_.socket_factory->AddSocketDataProvider(&data_1);
11149 session_deps_.socket_factory->AddSocketDataProvider(&data_2);
11150 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11151 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511152 &hanging_non_alternate_protocol_socket);
mmenke6b3af6e2015-09-12 02:06:0611153 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f45c1ee2010-08-03 00:54:3011154
11155 // First round should work and provide the Alternate-Protocol state.
[email protected]49639fa2011-12-20 23:22:4111156 TestCompletionCallback callback_1;
[email protected]262eec82013-03-19 21:01:3611157 scoped_ptr<HttpTransaction> trans_1(
[email protected]90499482013-06-01 00:39:5011158 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4111159 int rv = trans_1->Start(&request, callback_1.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:3011160 EXPECT_EQ(ERR_IO_PENDING, rv);
11161 EXPECT_EQ(OK, callback_1.WaitForResult());
11162
11163 // Second round should attempt a tunnel connect and get an auth challenge.
[email protected]49639fa2011-12-20 23:22:4111164 TestCompletionCallback callback_2;
[email protected]262eec82013-03-19 21:01:3611165 scoped_ptr<HttpTransaction> trans_2(
[email protected]90499482013-06-01 00:39:5011166 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4111167 rv = trans_2->Start(&request, callback_2.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:3011168 EXPECT_EQ(ERR_IO_PENDING, rv);
11169 EXPECT_EQ(OK, callback_2.WaitForResult());
11170 const HttpResponseInfo* response = trans_2->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5011171 ASSERT_TRUE(response != NULL);
[email protected]f45c1ee2010-08-03 00:54:3011172 ASSERT_FALSE(response->auth_challenge.get() == NULL);
11173
11174 // Restart with auth. Tunnel should work and response received.
[email protected]49639fa2011-12-20 23:22:4111175 TestCompletionCallback callback_3;
11176 rv = trans_2->RestartWithAuth(
11177 AuthCredentials(kFoo, kBar), callback_3.callback());
[email protected]f45c1ee2010-08-03 00:54:3011178 EXPECT_EQ(ERR_IO_PENDING, rv);
11179 EXPECT_EQ(OK, callback_3.WaitForResult());
11180
11181 // After all that work, these two lines (or actually, just the scheme) are
11182 // what this test is all about. Make sure it happens correctly.
[email protected]f45c1ee2010-08-03 00:54:3011183 EXPECT_EQ("https", request_url.scheme());
bncce36dca22015-04-21 22:11:2311184 EXPECT_EQ("www.example.org", request_url.host());
[email protected]f45c1ee2010-08-03 00:54:3011185
[email protected]029c83b62013-01-24 05:28:2011186 LoadTimingInfo load_timing_info;
11187 EXPECT_TRUE(trans_2->GetLoadTimingInfo(&load_timing_info));
11188 TestLoadTimingNotReusedWithPac(load_timing_info,
11189 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]8e6441ca2010-08-19 05:56:3811190}
11191
11192// Test that if we cancel the transaction as the connection is completing, that
11193// everything tears down correctly.
[email protected]23e482282013-06-14 16:08:0211194TEST_P(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3811195 // Setup everything about the connection to complete synchronously, so that
11196 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
11197 // for is the callback from the HttpStreamRequest.
11198 // Then cancel the transaction.
11199 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3611200 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3811201 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0611202 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
11203 MockRead(SYNCHRONOUS, "hello world"),
11204 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3811205 };
11206
[email protected]8e6441ca2010-08-19 05:56:3811207 HttpRequestInfo request;
11208 request.method = "GET";
bncce36dca22015-04-21 22:11:2311209 request.url = GURL("http://www.example.org/");
[email protected]8e6441ca2010-08-19 05:56:3811210 request.load_flags = 0;
11211
[email protected]bb88e1d32013-05-03 23:11:0711212 session_deps_.host_resolver->set_synchronous_mode(true);
mmenke6b3af6e2015-09-12 02:06:0611213 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:2711214 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4111215 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:2711216
[email protected]8e6441ca2010-08-19 05:56:3811217 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
11218 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711219 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3811220
[email protected]49639fa2011-12-20 23:22:4111221 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3811222
vishal.b62985ca92015-04-17 08:45:5111223 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4111224 int rv = trans->Start(&request, callback.callback(), log.bound());
[email protected]8e6441ca2010-08-19 05:56:3811225 EXPECT_EQ(ERR_IO_PENDING, rv);
11226 trans.reset(); // Cancel the transaction here.
11227
[email protected]2da659e2013-05-23 20:51:3411228 base::MessageLoop::current()->RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3011229}
11230
[email protected]ecab6e052014-05-16 14:58:1211231// Test that if a transaction is cancelled after receiving the headers, the
11232// stream is drained properly and added back to the socket pool. The main
11233// purpose of this test is to make sure that an HttpStreamParser can be read
11234// from after the HttpNetworkTransaction and the objects it owns have been
11235// deleted.
11236// See http://crbug.com/368418
11237TEST_P(HttpNetworkTransactionTest, CancelAfterHeaders) {
11238 MockRead data_reads[] = {
11239 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
11240 MockRead(ASYNC, "Content-Length: 2\r\n"),
11241 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
11242 MockRead(ASYNC, "1"),
11243 // 2 async reads are necessary to trigger a ReadResponseBody call after the
11244 // HttpNetworkTransaction has been deleted.
11245 MockRead(ASYNC, "2"),
11246 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
11247 };
11248 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
11249 session_deps_.socket_factory->AddSocketDataProvider(&data);
11250
mmenke6b3af6e2015-09-12 02:06:0611251 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]ecab6e052014-05-16 14:58:1211252
11253 {
11254 HttpRequestInfo request;
11255 request.method = "GET";
bncce36dca22015-04-21 22:11:2311256 request.url = GURL("http://www.example.org/");
[email protected]ecab6e052014-05-16 14:58:1211257 request.load_flags = 0;
11258
dcheng48459ac22014-08-26 00:46:4111259 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1211260 TestCompletionCallback callback;
11261
11262 int rv = trans.Start(&request, callback.callback(), BoundNetLog());
11263 EXPECT_EQ(ERR_IO_PENDING, rv);
11264 callback.WaitForResult();
11265
11266 const HttpResponseInfo* response = trans.GetResponseInfo();
11267 ASSERT_TRUE(response != NULL);
11268 EXPECT_TRUE(response->headers.get() != NULL);
11269 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11270
11271 // The transaction and HttpRequestInfo are deleted.
11272 }
11273
11274 // Let the HttpResponseBodyDrainer drain the socket.
11275 base::MessageLoop::current()->RunUntilIdle();
11276
11277 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4111278 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1211279}
11280
[email protected]76a505b2010-08-25 06:23:0011281// Test a basic GET request through a proxy.
[email protected]23e482282013-06-14 16:08:0211282TEST_P(HttpNetworkTransactionTest, ProxyGet) {
rdsmith82957ad2015-09-16 19:42:0311283 session_deps_.proxy_service =
11284 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5111285 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0711286 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:0611287 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0011288
[email protected]76a505b2010-08-25 06:23:0011289 HttpRequestInfo request;
11290 request.method = "GET";
bncce36dca22015-04-21 22:11:2311291 request.url = GURL("http://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0011292
11293 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2311294 MockWrite(
11295 "GET http://www.example.org/ HTTP/1.1\r\n"
11296 "Host: www.example.org\r\n"
11297 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0011298 };
11299
11300 MockRead data_reads1[] = {
11301 MockRead("HTTP/1.1 200 OK\r\n"),
11302 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11303 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0611304 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0011305 };
11306
11307 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
11308 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0711309 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0011310
[email protected]49639fa2011-12-20 23:22:4111311 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0011312
[email protected]262eec82013-03-19 21:01:3611313 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011314 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]597a1ab2014-06-26 08:12:2711315 BeforeProxyHeadersSentHandler proxy_headers_handler;
11316 trans->SetBeforeProxyHeadersSentCallback(
11317 base::Bind(&BeforeProxyHeadersSentHandler::OnBeforeProxyHeadersSent,
11318 base::Unretained(&proxy_headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5011319
[email protected]49639fa2011-12-20 23:22:4111320 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0011321 EXPECT_EQ(ERR_IO_PENDING, rv);
11322
11323 rv = callback1.WaitForResult();
11324 EXPECT_EQ(OK, rv);
11325
11326 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5011327 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:0011328
11329 EXPECT_TRUE(response->headers->IsKeepAlive());
11330 EXPECT_EQ(200, response->headers->response_code());
11331 EXPECT_EQ(100, response->headers->GetContentLength());
11332 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]d8fc4722014-06-13 13:17:1511333 EXPECT_TRUE(
11334 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
[email protected]597a1ab2014-06-26 08:12:2711335 EXPECT_TRUE(proxy_headers_handler.observed_before_proxy_headers_sent());
11336 EXPECT_EQ("myproxy:70", proxy_headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0011337 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2011338
11339 LoadTimingInfo load_timing_info;
11340 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
11341 TestLoadTimingNotReusedWithPac(load_timing_info,
11342 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0011343}
11344
11345// Test a basic HTTPS GET request through a proxy.
[email protected]23e482282013-06-14 16:08:0211346TEST_P(HttpNetworkTransactionTest, ProxyTunnelGet) {
rdsmith82957ad2015-09-16 19:42:0311347 session_deps_.proxy_service =
11348 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5111349 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0711350 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:0611351 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0011352
[email protected]76a505b2010-08-25 06:23:0011353 HttpRequestInfo request;
11354 request.method = "GET";
bncce36dca22015-04-21 22:11:2311355 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0011356
11357 // Since we have proxy, should try to establish tunnel.
11358 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2311359 MockWrite(
11360 "CONNECT www.example.org:443 HTTP/1.1\r\n"
11361 "Host: www.example.org\r\n"
11362 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0011363
bncce36dca22015-04-21 22:11:2311364 MockWrite(
11365 "GET / HTTP/1.1\r\n"
11366 "Host: www.example.org\r\n"
11367 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0011368 };
11369
11370 MockRead data_reads1[] = {
11371 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
11372
11373 MockRead("HTTP/1.1 200 OK\r\n"),
11374 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11375 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0611376 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0011377 };
11378
11379 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
11380 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0711381 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0611382 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0711383 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0011384
[email protected]49639fa2011-12-20 23:22:4111385 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0011386
[email protected]262eec82013-03-19 21:01:3611387 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011388 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5011389
[email protected]49639fa2011-12-20 23:22:4111390 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0011391 EXPECT_EQ(ERR_IO_PENDING, rv);
11392
11393 rv = callback1.WaitForResult();
11394 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:4611395 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4011396 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0011397 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4011398 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0011399 NetLog::PHASE_NONE);
11400 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4011401 entries, pos,
[email protected]76a505b2010-08-25 06:23:0011402 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
11403 NetLog::PHASE_NONE);
11404
11405 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5011406 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:0011407
11408 EXPECT_TRUE(response->headers->IsKeepAlive());
11409 EXPECT_EQ(200, response->headers->response_code());
11410 EXPECT_EQ(100, response->headers->GetContentLength());
11411 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
11412 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]d8fc4722014-06-13 13:17:1511413 EXPECT_TRUE(
11414 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
[email protected]029c83b62013-01-24 05:28:2011415
11416 LoadTimingInfo load_timing_info;
11417 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
11418 TestLoadTimingNotReusedWithPac(load_timing_info,
11419 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0011420}
11421
11422// Test a basic HTTPS GET request through a proxy, but the server hangs up
11423// while establishing the tunnel.
[email protected]23e482282013-06-14 16:08:0211424TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
rdsmith82957ad2015-09-16 19:42:0311425 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:5111426 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0711427 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:0611428 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0011429
[email protected]76a505b2010-08-25 06:23:0011430 HttpRequestInfo request;
11431 request.method = "GET";
bncce36dca22015-04-21 22:11:2311432 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0011433
11434 // Since we have proxy, should try to establish tunnel.
11435 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2311436 MockWrite(
11437 "CONNECT www.example.org:443 HTTP/1.1\r\n"
11438 "Host: www.example.org\r\n"
11439 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0011440
bncce36dca22015-04-21 22:11:2311441 MockWrite(
11442 "GET / HTTP/1.1\r\n"
11443 "Host: www.example.org\r\n"
11444 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0011445 };
11446
11447 MockRead data_reads1[] = {
[email protected]8ddf8322012-02-23 18:08:0611448 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:0011449 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0611450 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0011451 };
11452
11453 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
11454 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0711455 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0611456 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0711457 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0011458
[email protected]49639fa2011-12-20 23:22:4111459 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0011460
[email protected]262eec82013-03-19 21:01:3611461 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011462 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5011463
[email protected]49639fa2011-12-20 23:22:4111464 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0011465 EXPECT_EQ(ERR_IO_PENDING, rv);
11466
11467 rv = callback1.WaitForResult();
11468 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
mmenke43758e62015-05-04 21:09:4611469 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4011470 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0011471 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4011472 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0011473 NetLog::PHASE_NONE);
11474 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4011475 entries, pos,
[email protected]76a505b2010-08-25 06:23:0011476 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
11477 NetLog::PHASE_NONE);
11478}
11479
[email protected]749eefa82010-09-13 22:14:0311480// Test for crbug.com/55424.
[email protected]23e482282013-06-14 16:08:0211481TEST_P(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
[email protected]cdf8f7e72013-05-23 10:56:4611482 scoped_ptr<SpdyFrame> req(
bncce36dca22015-04-21 22:11:2311483 spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
rch8e6c6c42015-05-01 14:05:1311484 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]749eefa82010-09-13 22:14:0311485
[email protected]23e482282013-06-14 16:08:0211486 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11487 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0311488 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1311489 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0311490 };
11491
rch8e6c6c42015-05-01 14:05:1311492 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11493 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711494 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0311495
[email protected]8ddf8322012-02-23 18:08:0611496 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211497 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711498 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0311499
mmenke6b3af6e2015-09-12 02:06:0611500 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0311501
11502 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2311503 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4011504 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5311505 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2711506 base::WeakPtr<SpdySession> spdy_session =
mmenke6b3af6e2015-09-12 02:06:0611507 CreateInsecureSpdySession(session, key, BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0311508
11509 HttpRequestInfo request;
11510 request.method = "GET";
bncce36dca22015-04-21 22:11:2311511 request.url = GURL("https://www.example.org/");
[email protected]749eefa82010-09-13 22:14:0311512 request.load_flags = 0;
11513
11514 // This is the important line that marks this as a preconnect.
11515 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
11516
[email protected]262eec82013-03-19 21:01:3611517 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011518 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]749eefa82010-09-13 22:14:0311519
[email protected]41d64e82013-07-03 22:44:2611520 TestCompletionCallback callback;
[email protected]49639fa2011-12-20 23:22:4111521 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0311522 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111523 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]749eefa82010-09-13 22:14:0311524}
11525
[email protected]73b8dd222010-11-11 19:55:2411526// Given a net error, cause that error to be returned from the first Write()
11527// call and verify that the HttpTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0211528void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0711529 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2911530 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2711531 request_info.url = GURL("https://www.example.com/");
11532 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2911533 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2711534
[email protected]8ddf8322012-02-23 18:08:0611535 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2911536 MockWrite data_writes[] = {
11537 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2411538 };
ttuttle859dc7a2015-04-23 19:42:2911539 StaticSocketDataProvider data(NULL, 0, data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0711540 session_deps_.socket_factory->AddSocketDataProvider(&data);
11541 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2411542
mmenke6b3af6e2015-09-12 02:06:0611543 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3611544 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011545 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]73b8dd222010-11-11 19:55:2411546
[email protected]49639fa2011-12-20 23:22:4111547 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2911548 int rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
11549 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2411550 rv = callback.WaitForResult();
11551 ASSERT_EQ(error, rv);
11552}
11553
[email protected]23e482282013-06-14 16:08:0211554TEST_P(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2411555 // Just check a grab bag of cert errors.
11556 static const int kErrors[] = {
11557 ERR_CERT_COMMON_NAME_INVALID,
11558 ERR_CERT_AUTHORITY_INVALID,
11559 ERR_CERT_DATE_INVALID,
11560 };
11561 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0611562 CheckErrorIsPassedBack(kErrors[i], ASYNC);
11563 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2411564 }
11565}
11566
[email protected]bd0b6772011-01-11 19:59:3011567// Ensure that a client certificate is removed from the SSL client auth
11568// cache when:
11569// 1) No proxy is involved.
11570// 2) TLS False Start is disabled.
11571// 3) The initial TLS handshake requests a client certificate.
11572// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0211573TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2311574 ClientAuthCertCache_Direct_NoFalseStart) {
ttuttle859dc7a2015-04-23 19:42:2911575 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2711576 request_info.url = GURL("https://www.example.com/");
11577 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2911578 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2711579
[email protected]bd0b6772011-01-11 19:59:3011580 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4111581 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3011582
11583 // [ssl_]data1 contains the data for the first SSL handshake. When a
11584 // CertificateRequest is received for the first time, the handshake will
11585 // be aborted to allow the caller to provide a certificate.
ttuttle859dc7a2015-04-23 19:42:2911586 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3011587 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711588 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2911589 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711590 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3011591
11592 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
11593 // False Start is not being used, the result of the SSL handshake will be
11594 // returned as part of the SSLClientSocket::Connect() call. This test
11595 // matches the result of a server sending a handshake_failure alert,
11596 // rather than a Finished message, because it requires a client
11597 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2911598 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3011599 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711600 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2911601 StaticSocketDataProvider data2(NULL, 0, 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 // [ssl_]data3 contains the data for the third SSL handshake. When a
11605 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4211606 // HttpNetworkTransaction will attempt to fallback to TLSv1.1 if the previous
11607 // connection was attempted with TLSv1.2. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3011608 // of the HttpNetworkTransaction. Because this test failure is due to
11609 // requiring a client certificate, this fallback handshake should also
11610 // fail.
ttuttle859dc7a2015-04-23 19:42:2911611 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3011612 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711613 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2911614 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711615 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3011616
[email protected]80c75f682012-05-26 16:22:1711617 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
11618 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4211619 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
11620 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]80c75f682012-05-26 16:22:1711621 // of the HttpNetworkTransaction. Because this test failure is due to
11622 // requiring a client certificate, this fallback handshake should also
11623 // fail.
ttuttle859dc7a2015-04-23 19:42:2911624 SSLSocketDataProvider ssl_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1711625 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711626 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2911627 StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711628 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1711629
mmenke6b3af6e2015-09-12 02:06:0611630 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3611631 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011632 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3011633
[email protected]bd0b6772011-01-11 19:59:3011634 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4111635 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2911636 int rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
11637 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3011638
11639 // Complete the SSL handshake, which should abort due to requiring a
11640 // client certificate.
11641 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911642 ASSERT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
[email protected]bd0b6772011-01-11 19:59:3011643
11644 // Indicate that no certificate should be supplied. From the perspective
11645 // of SSLClientCertCache, NULL is just as meaningful as a real
11646 // certificate, so this is the same as supply a
11647 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4111648 rv = trans->RestartWithCertificate(NULL, callback.callback());
ttuttle859dc7a2015-04-23 19:42:2911649 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3011650
11651 // Ensure the certificate was added to the client auth cache before
11652 // allowing the connection to continue restarting.
11653 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4111654 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
11655 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3011656 ASSERT_EQ(NULL, client_cert.get());
11657
11658 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1711659 // then consume ssl_data3 and ssl_data4, both of which should also fail.
11660 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3011661 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911662 ASSERT_EQ(ERR_SSL_PROTOCOL_ERROR, rv);
[email protected]bd0b6772011-01-11 19:59:3011663
11664 // Ensure that the client certificate is removed from the cache on a
11665 // handshake failure.
[email protected]791879c2013-12-17 07:22:4111666 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11667 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3011668}
11669
11670// Ensure that a client certificate is removed from the SSL client auth
11671// cache when:
11672// 1) No proxy is involved.
11673// 2) TLS False Start is enabled.
11674// 3) The initial TLS handshake requests a client certificate.
11675// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0211676TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2311677 ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2911678 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2711679 request_info.url = GURL("https://www.example.com/");
11680 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2911681 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2711682
[email protected]bd0b6772011-01-11 19:59:3011683 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4111684 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3011685
11686 // When TLS False Start is used, SSLClientSocket::Connect() calls will
11687 // return successfully after reading up to the peer's Certificate message.
11688 // This is to allow the caller to call SSLClientSocket::Write(), which can
11689 // enqueue application data to be sent in the same packet as the
11690 // ChangeCipherSpec and Finished messages.
11691 // The actual handshake will be finished when SSLClientSocket::Read() is
11692 // called, which expects to process the peer's ChangeCipherSpec and
11693 // Finished messages. If there was an error negotiating with the peer,
11694 // such as due to the peer requiring a client certificate when none was
11695 // supplied, the alert sent by the peer won't be processed until Read() is
11696 // called.
11697
11698 // Like the non-False Start case, when a client certificate is requested by
11699 // the peer, the handshake is aborted during the Connect() call.
11700 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2911701 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3011702 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711703 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2911704 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711705 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3011706
11707 // When a client certificate is supplied, Connect() will not be aborted
11708 // when the peer requests the certificate. Instead, the handshake will
11709 // artificially succeed, allowing the caller to write the HTTP request to
11710 // the socket. The handshake messages are not processed until Read() is
11711 // called, which then detects that the handshake was aborted, due to the
11712 // peer sending a handshake_failure because it requires a client
11713 // certificate.
ttuttle859dc7a2015-04-23 19:42:2911714 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3011715 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711716 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2911717 MockRead data2_reads[] = {
11718 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3011719 };
ttuttle859dc7a2015-04-23 19:42:2911720 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711721 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3011722
11723 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1711724 // the data for the SSL handshake once the TLSv1.1 connection falls back to
11725 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2911726 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3011727 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711728 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2911729 StaticSocketDataProvider data3(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711730 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3011731
[email protected]80c75f682012-05-26 16:22:1711732 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
11733 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2911734 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1711735 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711736 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2911737 StaticSocketDataProvider data4(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711738 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1711739
[email protected]7799de12013-05-30 05:52:5111740 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2911741 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5111742 ssl_data5.cert_request_info = cert_request.get();
11743 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
ttuttle859dc7a2015-04-23 19:42:2911744 StaticSocketDataProvider data5(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]7799de12013-05-30 05:52:5111745 session_deps_.socket_factory->AddSocketDataProvider(&data5);
11746
mmenke6b3af6e2015-09-12 02:06:0611747 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3611748 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011749 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3011750
[email protected]bd0b6772011-01-11 19:59:3011751 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4111752 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2911753 int rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
11754 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3011755
11756 // Complete the SSL handshake, which should abort due to requiring a
11757 // client certificate.
11758 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911759 ASSERT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
[email protected]bd0b6772011-01-11 19:59:3011760
11761 // Indicate that no certificate should be supplied. From the perspective
11762 // of SSLClientCertCache, NULL is just as meaningful as a real
11763 // certificate, so this is the same as supply a
11764 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4111765 rv = trans->RestartWithCertificate(NULL, callback.callback());
ttuttle859dc7a2015-04-23 19:42:2911766 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3011767
11768 // Ensure the certificate was added to the client auth cache before
11769 // allowing the connection to continue restarting.
11770 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4111771 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
11772 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3011773 ASSERT_EQ(NULL, client_cert.get());
11774
[email protected]bd0b6772011-01-11 19:59:3011775 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1711776 // then consume ssl_data3 and ssl_data4, both of which should also fail.
11777 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3011778 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911779 ASSERT_EQ(ERR_SSL_PROTOCOL_ERROR, rv);
[email protected]bd0b6772011-01-11 19:59:3011780
11781 // Ensure that the client certificate is removed from the cache on a
11782 // handshake failure.
[email protected]791879c2013-12-17 07:22:4111783 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11784 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3011785}
11786
[email protected]8c405132011-01-11 22:03:1811787// Ensure that a client certificate is removed from the SSL client auth
11788// cache when:
11789// 1) An HTTPS proxy is involved.
11790// 3) The HTTPS proxy requests a client certificate.
11791// 4) The client supplies an invalid/unacceptable certificate for the
11792// proxy.
11793// The test is repeated twice, first for connecting to an HTTPS endpoint,
11794// then for connecting to an HTTP endpoint.
[email protected]23e482282013-06-14 16:08:0211795TEST_P(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
rdsmith82957ad2015-09-16 19:42:0311796 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:5111797 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0711798 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1811799
11800 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4111801 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1811802
11803 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
11804 // [ssl_]data[1-3]. Rather than represending the endpoint
11805 // (www.example.com:443), they represent failures with the HTTPS proxy
11806 // (proxy:70).
ttuttle859dc7a2015-04-23 19:42:2911807 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1811808 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711809 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2911810 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711811 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1811812
ttuttle859dc7a2015-04-23 19:42:2911813 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1811814 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711815 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2911816 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711817 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1811818
[email protected]80c75f682012-05-26 16:22:1711819 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
11820#if 0
ttuttle859dc7a2015-04-23 19:42:2911821 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1811822 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711823 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2911824 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711825 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1711826#endif
[email protected]8c405132011-01-11 22:03:1811827
ttuttle859dc7a2015-04-23 19:42:2911828 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1811829 requests[0].url = GURL("https://www.example.com/");
11830 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2911831 requests[0].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1811832
11833 requests[1].url = GURL("http://www.example.com/");
11834 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2911835 requests[1].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1811836
11837 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0711838 session_deps_.socket_factory->ResetNextMockIndexes();
mmenke6b3af6e2015-09-12 02:06:0611839 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c405132011-01-11 22:03:1811840 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5011841 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c405132011-01-11 22:03:1811842
11843 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4111844 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2911845 int rv = trans->Start(&requests[i], callback.callback(), BoundNetLog());
11846 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]8c405132011-01-11 22:03:1811847
11848 // Complete the SSL handshake, which should abort due to requiring a
11849 // client certificate.
11850 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911851 ASSERT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
[email protected]8c405132011-01-11 22:03:1811852
11853 // Indicate that no certificate should be supplied. From the perspective
11854 // of SSLClientCertCache, NULL is just as meaningful as a real
11855 // certificate, so this is the same as supply a
11856 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4111857 rv = trans->RestartWithCertificate(NULL, callback.callback());
ttuttle859dc7a2015-04-23 19:42:2911858 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]8c405132011-01-11 22:03:1811859
11860 // Ensure the certificate was added to the client auth cache before
11861 // allowing the connection to continue restarting.
11862 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4111863 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
11864 HostPortPair("proxy", 70), &client_cert));
[email protected]8c405132011-01-11 22:03:1811865 ASSERT_EQ(NULL, client_cert.get());
11866 // Ensure the certificate was NOT cached for the endpoint. This only
11867 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4111868 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11869 HostPortPair("www.example.com", 443), &client_cert));
[email protected]8c405132011-01-11 22:03:1811870
11871 // Restart the handshake. This will consume ssl_data2, which fails, and
11872 // then consume ssl_data3, which should also fail. The result code is
11873 // checked against what ssl_data3 should return.
11874 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911875 ASSERT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
[email protected]8c405132011-01-11 22:03:1811876
11877 // Now that the new handshake has failed, ensure that the client
11878 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4111879 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11880 HostPortPair("proxy", 70), &client_cert));
11881 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11882 HostPortPair("www.example.com", 443), &client_cert));
[email protected]8c405132011-01-11 22:03:1811883 }
11884}
11885
mmenke5c642132015-06-02 16:05:1311886TEST_P(HttpNetworkTransactionTest, UseIPConnectionPooling) {
bnc55ff9da2015-08-19 18:42:3511887 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2311888 session_deps_.next_protos = SpdyNextProtos();
[email protected]e3ceb682011-06-28 23:55:4611889
11890 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0711891 session_deps_.host_resolver.reset(new MockCachingHostResolver());
mmenke6b3af6e2015-09-12 02:06:0611892 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2611893 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
11894 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4611895
[email protected]8ddf8322012-02-23 18:08:0611896 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211897 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711898 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4611899
[email protected]cdf8f7e72013-05-23 10:56:4611900 scoped_ptr<SpdyFrame> host1_req(
bncce36dca22015-04-21 22:11:2311901 spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
[email protected]cdf8f7e72013-05-23 10:56:4611902 scoped_ptr<SpdyFrame> host2_req(
11903 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4611904 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1311905 CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4611906 };
[email protected]23e482282013-06-14 16:08:0211907 scoped_ptr<SpdyFrame> host1_resp(
11908 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11909 scoped_ptr<SpdyFrame> host1_resp_body(
11910 spdy_util_.ConstructSpdyBodyFrame(1, true));
11911 scoped_ptr<SpdyFrame> host2_resp(
11912 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11913 scoped_ptr<SpdyFrame> host2_resp_body(
11914 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4611915 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1311916 CreateMockRead(*host1_resp, 1),
11917 CreateMockRead(*host1_resp_body, 2),
11918 CreateMockRead(*host2_resp, 4),
11919 CreateMockRead(*host2_resp_body, 5),
11920 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4611921 };
11922
[email protected]d2b5f092012-06-08 23:55:0211923 IPAddressNumber ip;
11924 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
11925 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11926 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1311927 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
11928 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711929 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4611930
[email protected]aa22b242011-11-16 18:58:2911931 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4611932 HttpRequestInfo request1;
11933 request1.method = "GET";
bncce36dca22015-04-21 22:11:2311934 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4611935 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011936 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611937
[email protected]49639fa2011-12-20 23:22:4111938 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611939 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111940 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611941
11942 const HttpResponseInfo* response = trans1.GetResponseInfo();
11943 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011944 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611945 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11946
11947 std::string response_data;
11948 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
11949 EXPECT_EQ("hello!", response_data);
11950
11951 // Preload www.gmail.com into HostCache.
11952 HostPortPair host_port("www.gmail.com", 443);
[email protected]5109c1952013-08-20 18:44:1011953 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4611954 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1011955 rv = session_deps_.host_resolver->Resolve(resolve_info,
11956 DEFAULT_PRIORITY,
11957 &ignored,
11958 callback.callback(),
11959 NULL,
11960 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4711961 EXPECT_EQ(ERR_IO_PENDING, rv);
11962 rv = callback.WaitForResult();
11963 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4611964
11965 HttpRequestInfo request2;
11966 request2.method = "GET";
11967 request2.url = GURL("https://www.gmail.com/");
11968 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011969 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611970
[email protected]49639fa2011-12-20 23:22:4111971 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611972 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111973 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611974
11975 response = trans2.GetResponseInfo();
11976 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011977 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611978 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11979 EXPECT_TRUE(response->was_fetched_via_spdy);
11980 EXPECT_TRUE(response->was_npn_negotiated);
11981 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
11982 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4611983}
11984
[email protected]23e482282013-06-14 16:08:0211985TEST_P(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
bnc55ff9da2015-08-19 18:42:3511986 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2311987 session_deps_.next_protos = SpdyNextProtos();
[email protected]d2b5f092012-06-08 23:55:0211988
11989 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0711990 session_deps_.host_resolver.reset(new MockCachingHostResolver());
mmenke6b3af6e2015-09-12 02:06:0611991 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0211992 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
11993 pool_peer.DisableDomainAuthenticationVerification();
11994
11995 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211996 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711997 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]d2b5f092012-06-08 23:55:0211998
[email protected]cdf8f7e72013-05-23 10:56:4611999 scoped_ptr<SpdyFrame> host1_req(
bncce36dca22015-04-21 22:11:2312000 spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
[email protected]cdf8f7e72013-05-23 10:56:4612001 scoped_ptr<SpdyFrame> host2_req(
12002 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0212003 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1312004 CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0212005 };
[email protected]23e482282013-06-14 16:08:0212006 scoped_ptr<SpdyFrame> host1_resp(
12007 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12008 scoped_ptr<SpdyFrame> host1_resp_body(
12009 spdy_util_.ConstructSpdyBodyFrame(1, true));
12010 scoped_ptr<SpdyFrame> host2_resp(
12011 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
12012 scoped_ptr<SpdyFrame> host2_resp_body(
12013 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0212014 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1312015 CreateMockRead(*host1_resp, 1),
12016 CreateMockRead(*host1_resp_body, 2),
12017 CreateMockRead(*host2_resp, 4),
12018 CreateMockRead(*host2_resp_body, 5),
12019 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0212020 };
12021
12022 IPAddressNumber ip;
12023 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
12024 IPEndPoint peer_addr = IPEndPoint(ip, 443);
12025 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1312026 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
12027 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712028 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0212029
12030 TestCompletionCallback callback;
12031 HttpRequestInfo request1;
12032 request1.method = "GET";
bncce36dca22015-04-21 22:11:2312033 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0212034 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012035 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0212036
12037 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
12038 EXPECT_EQ(ERR_IO_PENDING, rv);
12039 EXPECT_EQ(OK, callback.WaitForResult());
12040
12041 const HttpResponseInfo* response = trans1.GetResponseInfo();
12042 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5012043 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d2b5f092012-06-08 23:55:0212044 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12045
12046 std::string response_data;
12047 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
12048 EXPECT_EQ("hello!", response_data);
12049
12050 HttpRequestInfo request2;
12051 request2.method = "GET";
12052 request2.url = GURL("https://www.gmail.com/");
12053 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012054 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0212055
12056 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
12057 EXPECT_EQ(ERR_IO_PENDING, rv);
12058 EXPECT_EQ(OK, callback.WaitForResult());
12059
12060 response = trans2.GetResponseInfo();
12061 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5012062 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d2b5f092012-06-08 23:55:0212063 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12064 EXPECT_TRUE(response->was_fetched_via_spdy);
12065 EXPECT_TRUE(response->was_npn_negotiated);
12066 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
12067 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0212068}
12069
ttuttle859dc7a2015-04-23 19:42:2912070class OneTimeCachingHostResolver : public HostResolver {
[email protected]e3ceb682011-06-28 23:55:4612071 public:
12072 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
12073 : host_port_(host_port) {}
dchengb03027d2014-10-21 12:00:2012074 ~OneTimeCachingHostResolver() override {}
[email protected]e3ceb682011-06-28 23:55:4612075
12076 RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); }
12077
12078 // HostResolver methods:
dchengb03027d2014-10-21 12:00:2012079 int Resolve(const RequestInfo& info,
12080 RequestPriority priority,
12081 AddressList* addresses,
12082 const CompletionCallback& callback,
12083 RequestHandle* out_req,
12084 const BoundNetLog& net_log) override {
[email protected]95a214c2011-08-04 21:50:4012085 return host_resolver_.Resolve(
[email protected]5109c1952013-08-20 18:44:1012086 info, priority, addresses, callback, out_req, net_log);
[email protected]95a214c2011-08-04 21:50:4012087 }
12088
dchengb03027d2014-10-21 12:00:2012089 int ResolveFromCache(const RequestInfo& info,
12090 AddressList* addresses,
12091 const BoundNetLog& net_log) override {
[email protected]95a214c2011-08-04 21:50:4012092 int rv = host_resolver_.ResolveFromCache(info, addresses, net_log);
12093 if (rv == OK && info.host_port_pair().Equals(host_port_))
[email protected]98e1cd012011-11-08 15:33:0912094 host_resolver_.GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4612095 return rv;
12096 }
12097
dchengb03027d2014-10-21 12:00:2012098 void CancelRequest(RequestHandle req) override {
[email protected]e3ceb682011-06-28 23:55:4612099 host_resolver_.CancelRequest(req);
12100 }
12101
[email protected]46da33be2011-07-19 21:58:0412102 MockCachingHostResolver* GetMockHostResolver() {
12103 return &host_resolver_;
12104 }
12105
[email protected]e3ceb682011-06-28 23:55:4612106 private:
12107 MockCachingHostResolver host_resolver_;
12108 const HostPortPair host_port_;
12109};
12110
mmenke5c642132015-06-02 16:05:1312111TEST_P(HttpNetworkTransactionTest,
12112 UseIPConnectionPoolingWithHostCacheExpiration) {
bnc55ff9da2015-08-19 18:42:3512113 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2312114 session_deps_.next_protos = SpdyNextProtos();
[email protected]e3ceb682011-06-28 23:55:4612115
12116 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
[email protected]e3ceb682011-06-28 23:55:4612117 OneTimeCachingHostResolver host_resolver(HostPortPair("www.gmail.com", 443));
[email protected]c6bf8152012-12-02 07:43:3412118 HttpNetworkSession::Params params =
[email protected]bb88e1d32013-05-03 23:11:0712119 SpdySessionDependencies::CreateSessionParams(&session_deps_);
[email protected]e3ceb682011-06-28 23:55:4612120 params.host_resolver = &host_resolver;
mmenke6b3af6e2015-09-12 02:06:0612121 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2612122 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
12123 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4612124
[email protected]8ddf8322012-02-23 18:08:0612125 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212126 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0712127 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4612128
[email protected]cdf8f7e72013-05-23 10:56:4612129 scoped_ptr<SpdyFrame> host1_req(
bncce36dca22015-04-21 22:11:2312130 spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
[email protected]cdf8f7e72013-05-23 10:56:4612131 scoped_ptr<SpdyFrame> host2_req(
12132 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4612133 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1312134 CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4612135 };
[email protected]23e482282013-06-14 16:08:0212136 scoped_ptr<SpdyFrame> host1_resp(
12137 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12138 scoped_ptr<SpdyFrame> host1_resp_body(
12139 spdy_util_.ConstructSpdyBodyFrame(1, true));
12140 scoped_ptr<SpdyFrame> host2_resp(
12141 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
12142 scoped_ptr<SpdyFrame> host2_resp_body(
12143 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4612144 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1312145 CreateMockRead(*host1_resp, 1),
12146 CreateMockRead(*host1_resp_body, 2),
12147 CreateMockRead(*host2_resp, 4),
12148 CreateMockRead(*host2_resp_body, 5),
12149 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4612150 };
12151
[email protected]d2b5f092012-06-08 23:55:0212152 IPAddressNumber ip;
12153 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
12154 IPEndPoint peer_addr = IPEndPoint(ip, 443);
12155 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1312156 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
12157 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712158 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4612159
[email protected]aa22b242011-11-16 18:58:2912160 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4612161 HttpRequestInfo request1;
12162 request1.method = "GET";
bncce36dca22015-04-21 22:11:2312163 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4612164 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012165 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4612166
[email protected]49639fa2011-12-20 23:22:4112167 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4612168 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4112169 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4612170
12171 const HttpResponseInfo* response = trans1.GetResponseInfo();
12172 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5012173 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4612174 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12175
12176 std::string response_data;
12177 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
12178 EXPECT_EQ("hello!", response_data);
12179
12180 // Preload cache entries into HostCache.
[email protected]5109c1952013-08-20 18:44:1012181 HostResolver::RequestInfo resolve_info(HostPortPair("www.gmail.com", 443));
[email protected]e3ceb682011-06-28 23:55:4612182 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1012183 rv = host_resolver.Resolve(resolve_info,
12184 DEFAULT_PRIORITY,
12185 &ignored,
12186 callback.callback(),
12187 NULL,
12188 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4712189 EXPECT_EQ(ERR_IO_PENDING, rv);
12190 rv = callback.WaitForResult();
12191 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4612192
12193 HttpRequestInfo request2;
12194 request2.method = "GET";
12195 request2.url = GURL("https://www.gmail.com/");
12196 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012197 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4612198
[email protected]49639fa2011-12-20 23:22:4112199 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4612200 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4112201 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4612202
12203 response = trans2.GetResponseInfo();
12204 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5012205 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4612206 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12207 EXPECT_TRUE(response->was_fetched_via_spdy);
12208 EXPECT_TRUE(response->was_npn_negotiated);
12209 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
12210 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4612211}
12212
[email protected]23e482282013-06-14 16:08:0212213TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2312214 const std::string https_url = "https://www.example.org:8080/";
12215 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0412216
12217 // SPDY GET for HTTPS URL
[email protected]cdf8f7e72013-05-23 10:56:4612218 scoped_ptr<SpdyFrame> req1(
12219 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0412220
12221 MockWrite writes1[] = {
12222 CreateMockWrite(*req1, 0),
12223 };
12224
[email protected]23e482282013-06-14 16:08:0212225 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12226 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8450d722012-07-02 19:14:0412227 MockRead reads1[] = {
12228 CreateMockRead(*resp1, 1),
12229 CreateMockRead(*body1, 2),
12230 MockRead(ASYNC, ERR_IO_PENDING, 3)
12231 };
12232
rch8e6c6c42015-05-01 14:05:1312233 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
12234 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0412235 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5712236 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0412237
12238 // HTTP GET for the HTTP URL
12239 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1312240 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3412241 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2312242 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3412243 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0412244 };
12245
12246 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1312247 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
12248 MockRead(ASYNC, 2, "hello"),
12249 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0412250 };
12251
rch8e6c6c42015-05-01 14:05:1312252 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
12253 arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0412254
[email protected]8450d722012-07-02 19:14:0412255 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212256 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0712257 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12258 session_deps_.socket_factory->AddSocketDataProvider(&data1);
12259 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0412260
mmenke6b3af6e2015-09-12 02:06:0612261 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0412262
12263 // Start the first transaction to set up the SpdySession
12264 HttpRequestInfo request1;
12265 request1.method = "GET";
12266 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0412267 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012268 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0412269 TestCompletionCallback callback1;
12270 EXPECT_EQ(ERR_IO_PENDING,
12271 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412272 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0412273
12274 EXPECT_EQ(OK, callback1.WaitForResult());
12275 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
12276
12277 // Now, start the HTTP request
12278 HttpRequestInfo request2;
12279 request2.method = "GET";
12280 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0412281 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012282 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0412283 TestCompletionCallback callback2;
12284 EXPECT_EQ(ERR_IO_PENDING,
12285 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412286 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0412287
12288 EXPECT_EQ(OK, callback2.WaitForResult());
12289 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
12290}
12291
bnc1b0e36852015-04-28 15:32:5912292class AltSvcCertificateVerificationTest : public HttpNetworkTransactionTest {
12293 public:
12294 void Run(bool pooling, bool valid) {
12295 HostPortPair origin(valid ? "mail.example.org" : "invalid.example.org",
12296 443);
12297 HostPortPair alternative("www.example.org", 443);
12298
12299 base::FilePath certs_dir = GetTestCertsDirectory();
12300 scoped_refptr<X509Certificate> cert(
12301 ImportCertFromFile(certs_dir, "spdy_pooling.pem"));
12302 ASSERT_TRUE(cert.get());
12303 bool common_name_fallback_used;
12304 EXPECT_EQ(valid,
12305 cert->VerifyNameMatch(origin.host(), &common_name_fallback_used));
12306 EXPECT_TRUE(
12307 cert->VerifyNameMatch(alternative.host(), &common_name_fallback_used));
12308 SSLSocketDataProvider ssl(ASYNC, OK);
12309 ssl.SetNextProto(GetParam());
12310 ssl.cert = cert;
12311 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12312
12313 // If pooling, then start a request to alternative first to create a
12314 // SpdySession.
12315 std::string url0 = "https://www.example.org:443";
12316 // Second request to origin, which has an alternative service, and could
12317 // open a connection to the alternative host or pool to the existing one.
12318 std::string url1("https://");
12319 url1.append(origin.host());
12320 url1.append(":443");
12321
12322 scoped_ptr<SpdyFrame> req0;
12323 scoped_ptr<SpdyFrame> req1;
12324 scoped_ptr<SpdyFrame> resp0;
12325 scoped_ptr<SpdyFrame> body0;
12326 scoped_ptr<SpdyFrame> resp1;
12327 scoped_ptr<SpdyFrame> body1;
12328 std::vector<MockWrite> writes;
12329 std::vector<MockRead> reads;
12330
12331 if (pooling) {
12332 req0.reset(spdy_util_.ConstructSpdyGet(url0.c_str(), false, 1, LOWEST));
12333 req1.reset(spdy_util_.ConstructSpdyGet(url1.c_str(), false, 3, LOWEST));
12334
12335 writes.push_back(CreateMockWrite(*req0, 0));
12336 writes.push_back(CreateMockWrite(*req1, 3));
12337
12338 resp0.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12339 body0.reset(spdy_util_.ConstructSpdyBodyFrame(1, true));
12340 resp1.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
12341 body1.reset(spdy_util_.ConstructSpdyBodyFrame(3, true));
12342
12343 reads.push_back(CreateMockRead(*resp0, 1));
12344 reads.push_back(CreateMockRead(*body0, 2));
12345 reads.push_back(MockRead(ASYNC, ERR_IO_PENDING, 4));
12346 reads.push_back(CreateMockRead(*resp1, 5));
12347 reads.push_back(CreateMockRead(*body1, 6));
12348 reads.push_back(MockRead(ASYNC, OK, 7));
12349 } else {
12350 req1.reset(spdy_util_.ConstructSpdyGet(url1.c_str(), false, 1, LOWEST));
12351
12352 writes.push_back(CreateMockWrite(*req1, 0));
12353
12354 resp1.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12355 body1.reset(spdy_util_.ConstructSpdyBodyFrame(1, true));
12356
12357 reads.push_back(CreateMockRead(*resp1, 1));
12358 reads.push_back(CreateMockRead(*body1, 2));
12359 reads.push_back(MockRead(ASYNC, OK, 3));
12360 }
12361
rch32320842015-05-16 15:57:0912362 SequencedSocketData data(vector_as_array(&reads), reads.size(),
12363 vector_as_array(&writes), writes.size());
bnc1b0e36852015-04-28 15:32:5912364 session_deps_.socket_factory->AddSocketDataProvider(&data);
12365
12366 // Connection to the origin fails.
12367 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
12368 StaticSocketDataProvider data_refused;
12369 data_refused.set_connect_data(mock_connect);
12370 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
12371
bnc55ff9da2015-08-19 18:42:3512372 session_deps_.use_alternative_services = true;
mmenke6b3af6e2015-09-12 02:06:0612373 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc1b0e36852015-04-28 15:32:5912374 base::WeakPtr<HttpServerProperties> http_server_properties =
12375 session->http_server_properties();
12376 AlternativeService alternative_service(
12377 AlternateProtocolFromNextProto(GetParam()), alternative);
bnc7dc7e1b42015-07-28 14:43:1212378 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnc1b0e36852015-04-28 15:32:5912379 http_server_properties->SetAlternativeService(origin, alternative_service,
bnc7dc7e1b42015-07-28 14:43:1212380 1.0, expiration);
bnc1b0e36852015-04-28 15:32:5912381
12382 // First request to alternative.
12383 if (pooling) {
12384 scoped_ptr<HttpTransaction> trans0(
12385 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12386 HttpRequestInfo request0;
12387 request0.method = "GET";
12388 request0.url = GURL(url0);
12389 request0.load_flags = 0;
12390 TestCompletionCallback callback0;
12391
12392 int rv = trans0->Start(&request0, callback0.callback(), BoundNetLog());
12393 EXPECT_EQ(ERR_IO_PENDING, rv);
12394 rv = callback0.WaitForResult();
12395 EXPECT_EQ(OK, rv);
12396 }
12397
12398 // Second request to origin.
12399 scoped_ptr<HttpTransaction> trans1(
12400 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12401 HttpRequestInfo request1;
12402 request1.method = "GET";
12403 request1.url = GURL(url1);
12404 request1.load_flags = 0;
12405 TestCompletionCallback callback1;
12406
12407 int rv = trans1->Start(&request1, callback1.callback(), BoundNetLog());
12408 EXPECT_EQ(ERR_IO_PENDING, rv);
rch32320842015-05-16 15:57:0912409 base::MessageLoop::current()->RunUntilIdle();
12410 if (data.IsReadPaused()) {
12411 data.CompleteRead();
12412 }
bnc1b0e36852015-04-28 15:32:5912413 rv = callback1.WaitForResult();
12414 if (valid) {
12415 EXPECT_EQ(OK, rv);
12416 } else {
12417 if (pooling) {
12418 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
12419 } else {
12420 EXPECT_EQ(ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN, rv);
12421 }
12422 }
12423 }
12424};
12425
12426INSTANTIATE_TEST_CASE_P(NextProto,
12427 AltSvcCertificateVerificationTest,
12428 testing::Values(kProtoSPDY31,
bnc06d22432015-06-29 12:39:4312429 kProtoHTTP2));
bnc1b0e36852015-04-28 15:32:5912430
12431// The alternative service host must exhibit a certificate that is valid for the
12432// origin host. Test that this is enforced when pooling to an existing
12433// connection.
12434TEST_P(AltSvcCertificateVerificationTest, PoolingValid) {
12435 Run(true, true);
12436}
12437
12438TEST_P(AltSvcCertificateVerificationTest, PoolingInvalid) {
12439 Run(true, false);
12440}
12441
12442// The alternative service host must exhibit a certificate that is valid for the
12443// origin host. Test that this is enforced when opening a new connection.
12444TEST_P(AltSvcCertificateVerificationTest, NewConnectionValid) {
12445 Run(false, true);
12446}
12447
12448TEST_P(AltSvcCertificateVerificationTest, NewConnectionInvalid) {
12449 Run(false, false);
12450}
12451
bnc5452e2a2015-05-08 16:27:4212452// Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
12453// with the alternative server. That connection should not be used.
12454TEST_P(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
12455 HostPortPair origin("origin.example.org", 443);
12456 HostPortPair alternative("alternative.example.org", 443);
12457
12458 // Negotiate HTTP/1.1 with alternative.example.org.
12459 SSLSocketDataProvider ssl(ASYNC, OK);
12460 ssl.SetNextProto(kProtoHTTP11);
12461 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12462
12463 // No data should be read from the alternative, because HTTP/1.1 is
12464 // negotiated.
12465 StaticSocketDataProvider data;
12466 session_deps_.socket_factory->AddSocketDataProvider(&data);
12467
12468 // This test documents that an alternate Job should not be used if HTTP/1.1 is
12469 // negotiated. In order to test this, a failed connection to the origin is
12470 // mocked. This way the request relies on the alternate Job.
12471 StaticSocketDataProvider data_refused;
12472 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
12473 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
12474
12475 // Set up alternative service for origin.
bnc55ff9da2015-08-19 18:42:3512476 session_deps_.use_alternative_services = true;
mmenke6b3af6e2015-09-12 02:06:0612477 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc5452e2a2015-05-08 16:27:4212478 base::WeakPtr<HttpServerProperties> http_server_properties =
12479 session->http_server_properties();
12480 AlternativeService alternative_service(
12481 AlternateProtocolFromNextProto(GetParam()), alternative);
bnc7dc7e1b42015-07-28 14:43:1212482 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnc5452e2a2015-05-08 16:27:4212483 http_server_properties->SetAlternativeService(origin, alternative_service,
bnc7dc7e1b42015-07-28 14:43:1212484 1.0, expiration);
bnc5452e2a2015-05-08 16:27:4212485
12486 scoped_ptr<HttpTransaction> trans(
12487 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12488 HttpRequestInfo request;
12489 request.method = "GET";
12490 request.url = GURL("https://origin.example.org:443");
12491 request.load_flags = 0;
12492 TestCompletionCallback callback;
12493
12494 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
12495 // negotiated, the alternate Job should fail with ERR_NPN_NEGOTIATION_FAILED.
12496 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12497 EXPECT_EQ(ERR_NPN_NEGOTIATION_FAILED, callback.GetResult(rv));
12498}
12499
bnc40448a532015-05-11 19:13:1412500// A request to a server with an alternative service fires two Jobs: one to the
12501// origin, and an alternate one to the alternative server. If the former
12502// succeeds, the request should succeed, even if the latter fails because
12503// HTTP/1.1 is negotiated which is insufficient for alternative service.
12504TEST_P(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
12505 HostPortPair origin("origin.example.org", 443);
12506 HostPortPair alternative("alternative.example.org", 443);
12507
12508 // Negotiate HTTP/1.1 with alternative.
12509 SSLSocketDataProvider alternative_ssl(ASYNC, OK);
12510 alternative_ssl.SetNextProto(kProtoHTTP11);
12511 session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
12512
12513 // No data should be read from the alternative, because HTTP/1.1 is
12514 // negotiated.
12515 StaticSocketDataProvider data;
12516 session_deps_.socket_factory->AddSocketDataProvider(&data);
12517
12518 // Negotiate HTTP/1.1 with origin.
12519 SSLSocketDataProvider origin_ssl(ASYNC, OK);
12520 origin_ssl.SetNextProto(kProtoHTTP11);
12521 session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
12522
12523 MockWrite http_writes[] = {
12524 MockWrite(
12525 "GET / HTTP/1.1\r\n"
12526 "Host: origin.example.org\r\n"
12527 "Connection: keep-alive\r\n\r\n"),
12528 MockWrite(
12529 "GET /second HTTP/1.1\r\n"
12530 "Host: origin.example.org\r\n"
12531 "Connection: keep-alive\r\n\r\n"),
12532 };
12533
12534 MockRead http_reads[] = {
12535 MockRead("HTTP/1.1 200 OK\r\n"),
12536 MockRead("Content-Type: text/html\r\n"),
12537 MockRead("Content-Length: 6\r\n\r\n"),
12538 MockRead("foobar"),
12539 MockRead("HTTP/1.1 200 OK\r\n"),
12540 MockRead("Content-Type: text/html\r\n"),
12541 MockRead("Content-Length: 7\r\n\r\n"),
12542 MockRead("another"),
12543 };
12544 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
12545 http_writes, arraysize(http_writes));
12546 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12547
12548 // Set up alternative service for origin.
bnc55ff9da2015-08-19 18:42:3512549 session_deps_.use_alternative_services = true;
mmenke6b3af6e2015-09-12 02:06:0612550 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc40448a532015-05-11 19:13:1412551 base::WeakPtr<HttpServerProperties> http_server_properties =
12552 session->http_server_properties();
12553 AlternativeService alternative_service(
12554 AlternateProtocolFromNextProto(GetParam()), alternative);
bnc7dc7e1b42015-07-28 14:43:1212555 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnc40448a532015-05-11 19:13:1412556 http_server_properties->SetAlternativeService(origin, alternative_service,
bnc7dc7e1b42015-07-28 14:43:1212557 1.0, expiration);
bnc40448a532015-05-11 19:13:1412558
12559 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
12560 HttpRequestInfo request1;
12561 request1.method = "GET";
12562 request1.url = GURL("https://origin.example.org:443");
12563 request1.load_flags = 0;
12564 TestCompletionCallback callback1;
12565
12566 int rv = trans1.Start(&request1, callback1.callback(), BoundNetLog());
12567 rv = callback1.GetResult(rv);
12568 EXPECT_EQ(OK, rv);
12569
12570 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
12571 ASSERT_TRUE(response1 != nullptr);
12572 ASSERT_TRUE(response1->headers.get() != nullptr);
12573 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
12574
12575 std::string response_data1;
12576 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data1));
12577 EXPECT_EQ("foobar", response_data1);
12578
12579 // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
12580 // for alternative service.
12581 EXPECT_TRUE(
12582 http_server_properties->IsAlternativeServiceBroken(alternative_service));
12583
12584 // Since |alternative_service| is broken, a second transaction to origin
12585 // should not start an alternate Job. It should pool to existing connection
12586 // to origin.
12587 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
12588 HttpRequestInfo request2;
12589 request2.method = "GET";
12590 request2.url = GURL("https://origin.example.org:443/second");
12591 request2.load_flags = 0;
12592 TestCompletionCallback callback2;
12593
12594 rv = trans2.Start(&request2, callback2.callback(), BoundNetLog());
12595 rv = callback2.GetResult(rv);
12596 EXPECT_EQ(OK, rv);
12597
12598 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
12599 ASSERT_TRUE(response2 != nullptr);
12600 ASSERT_TRUE(response2->headers.get() != nullptr);
12601 EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
12602
12603 std::string response_data2;
12604 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data2));
12605 EXPECT_EQ("another", response_data2);
12606}
12607
bnc5452e2a2015-05-08 16:27:4212608// Alternative service requires HTTP/2 (or SPDY), but there is already a
12609// HTTP/1.1 socket open to the alternative server. That socket should not be
12610// used.
12611TEST_P(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
12612 HostPortPair origin("origin.example.org", 443);
12613 HostPortPair alternative("alternative.example.org", 443);
12614 std::string origin_url = "https://origin.example.org:443";
12615 std::string alternative_url = "https://alternative.example.org:443";
12616
12617 // Negotiate HTTP/1.1 with alternative.example.org.
12618 SSLSocketDataProvider ssl(ASYNC, OK);
12619 ssl.SetNextProto(kProtoHTTP11);
12620 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12621
12622 // HTTP/1.1 data for |request1| and |request2|.
12623 MockWrite http_writes[] = {
12624 MockWrite(
12625 "GET / HTTP/1.1\r\n"
12626 "Host: alternative.example.org\r\n"
12627 "Connection: keep-alive\r\n\r\n"),
12628 MockWrite(
12629 "GET / HTTP/1.1\r\n"
12630 "Host: alternative.example.org\r\n"
12631 "Connection: keep-alive\r\n\r\n"),
12632 };
12633
12634 MockRead http_reads[] = {
12635 MockRead(
12636 "HTTP/1.1 200 OK\r\n"
12637 "Content-Type: text/html; charset=iso-8859-1\r\n"
12638 "Content-Length: 40\r\n\r\n"
12639 "first HTTP/1.1 response from alternative"),
12640 MockRead(
12641 "HTTP/1.1 200 OK\r\n"
12642 "Content-Type: text/html; charset=iso-8859-1\r\n"
12643 "Content-Length: 41\r\n\r\n"
12644 "second HTTP/1.1 response from alternative"),
12645 };
12646 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
12647 http_writes, arraysize(http_writes));
12648 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12649
12650 // This test documents that an alternate Job should not pool to an already
12651 // existing HTTP/1.1 connection. In order to test this, a failed connection
12652 // to the origin is mocked. This way |request2| relies on the alternate Job.
12653 StaticSocketDataProvider data_refused;
12654 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
12655 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
12656
12657 // Set up alternative service for origin.
bnc55ff9da2015-08-19 18:42:3512658 session_deps_.use_alternative_services = true;
mmenke6b3af6e2015-09-12 02:06:0612659 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc5452e2a2015-05-08 16:27:4212660 base::WeakPtr<HttpServerProperties> http_server_properties =
12661 session->http_server_properties();
12662 AlternativeService alternative_service(
12663 AlternateProtocolFromNextProto(GetParam()), alternative);
bnc7dc7e1b42015-07-28 14:43:1212664 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnc5452e2a2015-05-08 16:27:4212665 http_server_properties->SetAlternativeService(origin, alternative_service,
bnc7dc7e1b42015-07-28 14:43:1212666 1.0, expiration);
bnc5452e2a2015-05-08 16:27:4212667
12668 // First transaction to alternative to open an HTTP/1.1 socket.
12669 scoped_ptr<HttpTransaction> trans1(
12670 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12671 HttpRequestInfo request1;
12672 request1.method = "GET";
12673 request1.url = GURL(alternative_url);
12674 request1.load_flags = 0;
12675 TestCompletionCallback callback1;
12676
12677 int rv = trans1->Start(&request1, callback1.callback(), BoundNetLog());
12678 EXPECT_EQ(OK, callback1.GetResult(rv));
12679 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
12680 ASSERT_TRUE(response1);
12681 ASSERT_TRUE(response1->headers.get());
12682 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
12683 EXPECT_TRUE(response1->was_npn_negotiated);
12684 EXPECT_FALSE(response1->was_fetched_via_spdy);
12685 std::string response_data1;
12686 ASSERT_EQ(OK, ReadTransaction(trans1.get(), &response_data1));
12687 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
12688
12689 // Request for origin.example.org, which has an alternative service. This
12690 // will start two Jobs: the alternative looks for connections to pool to,
12691 // finds one which is HTTP/1.1, and should ignore it, and should not try to
12692 // open other connections to alternative server. The Job to origin fails, so
12693 // this request fails.
12694 scoped_ptr<HttpTransaction> trans2(
12695 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12696 HttpRequestInfo request2;
12697 request2.method = "GET";
12698 request2.url = GURL(origin_url);
12699 request2.load_flags = 0;
12700 TestCompletionCallback callback2;
12701
12702 rv = trans2->Start(&request2, callback2.callback(), BoundNetLog());
12703 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback2.GetResult(rv));
12704
12705 // Another transaction to alternative. This is to test that the HTTP/1.1
12706 // socket is still open and in the pool.
12707 scoped_ptr<HttpTransaction> trans3(
12708 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12709 HttpRequestInfo request3;
12710 request3.method = "GET";
12711 request3.url = GURL(alternative_url);
12712 request3.load_flags = 0;
12713 TestCompletionCallback callback3;
12714
12715 rv = trans3->Start(&request3, callback3.callback(), BoundNetLog());
12716 EXPECT_EQ(OK, callback3.GetResult(rv));
12717 const HttpResponseInfo* response3 = trans3->GetResponseInfo();
12718 ASSERT_TRUE(response3);
12719 ASSERT_TRUE(response3->headers.get());
12720 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
12721 EXPECT_TRUE(response3->was_npn_negotiated);
12722 EXPECT_FALSE(response3->was_fetched_via_spdy);
12723 std::string response_data3;
12724 ASSERT_EQ(OK, ReadTransaction(trans3.get(), &response_data3));
12725 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
12726}
12727
[email protected]23e482282013-06-14 16:08:0212728TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2312729 const std::string https_url = "https://www.example.org:8080/";
12730 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0412731
12732 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2312733 const HostPortPair host_port_pair("www.example.org", 8080);
lgarrona91df87f2014-12-05 00:51:3412734 scoped_ptr<SpdyFrame> connect(
12735 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
[email protected]cdf8f7e72013-05-23 10:56:4612736 scoped_ptr<SpdyFrame> req1(
12737 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]23e482282013-06-14 16:08:0212738 scoped_ptr<SpdyFrame> wrapped_req1(
12739 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3912740
12741 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
[email protected]745aa9c2014-06-27 02:21:2912742 SpdyHeaderBlock req2_block;
bnc7ecc1122015-09-28 13:22:4912743 spdy_util_.MaybeAddVersionHeader(&req2_block);
[email protected]745aa9c2014-06-27 02:21:2912744 req2_block[spdy_util_.GetMethodKey()] = "GET";
bncce36dca22015-04-21 22:11:2312745 req2_block[spdy_util_.GetHostKey()] = "www.example.org:8080";
[email protected]745aa9c2014-06-27 02:21:2912746 req2_block[spdy_util_.GetSchemeKey()] = "http";
bnc7ecc1122015-09-28 13:22:4912747 req2_block[spdy_util_.GetPathKey()] = "/";
[email protected]601e03f12014-04-06 16:26:3912748 scoped_ptr<SpdyFrame> req2(
[email protected]745aa9c2014-06-27 02:21:2912749 spdy_util_.ConstructSpdySyn(3, req2_block, MEDIUM, false, true));
[email protected]8450d722012-07-02 19:14:0412750
12751 MockWrite writes1[] = {
12752 CreateMockWrite(*connect, 0),
12753 CreateMockWrite(*wrapped_req1, 2),
12754 CreateMockWrite(*req2, 5),
12755 };
12756
[email protected]23e482282013-06-14 16:08:0212757 scoped_ptr<SpdyFrame> conn_resp(
12758 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12759 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12760 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
12761 scoped_ptr<SpdyFrame> wrapped_resp1(
12762 spdy_util_.ConstructWrappedSpdyFrame(resp1, 1));
12763 scoped_ptr<SpdyFrame> wrapped_body1(
12764 spdy_util_.ConstructWrappedSpdyFrame(body1, 1));
12765 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
12766 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]8450d722012-07-02 19:14:0412767 MockRead reads1[] = {
12768 CreateMockRead(*conn_resp, 1),
12769 CreateMockRead(*wrapped_resp1, 3),
12770 CreateMockRead(*wrapped_body1, 4),
12771 CreateMockRead(*resp2, 6),
12772 CreateMockRead(*body2, 7),
12773 MockRead(ASYNC, ERR_IO_PENDING, 8)
12774 };
12775
[email protected]dd54bd82012-07-19 23:44:5712776 DeterministicSocketData data1(reads1, arraysize(reads1),
12777 writes1, arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0412778 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5712779 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0412780
rdsmith82957ad2015-09-16 19:42:0312781 session_deps_.proxy_service =
12782 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:5112783 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712784 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0412785 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
[email protected]23e482282013-06-14 16:08:0212786 ssl1.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0712787 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0412788 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
[email protected]23e482282013-06-14 16:08:0212789 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0712790 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
12791 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0412792
mmenke6b3af6e2015-09-12 02:06:0612793 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0712794 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]8450d722012-07-02 19:14:0412795
12796 // Start the first transaction to set up the SpdySession
12797 HttpRequestInfo request1;
12798 request1.method = "GET";
12799 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0412800 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012801 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0412802 TestCompletionCallback callback1;
12803 EXPECT_EQ(ERR_IO_PENDING,
12804 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412805 base::MessageLoop::current()->RunUntilIdle();
[email protected]dd54bd82012-07-19 23:44:5712806 data1.RunFor(4);
[email protected]8450d722012-07-02 19:14:0412807
12808 EXPECT_EQ(OK, callback1.WaitForResult());
12809 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
12810
[email protected]f6c63db52013-02-02 00:35:2212811 LoadTimingInfo load_timing_info1;
12812 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
12813 TestLoadTimingNotReusedWithPac(load_timing_info1,
12814 CONNECT_TIMING_HAS_SSL_TIMES);
12815
[email protected]8450d722012-07-02 19:14:0412816 // Now, start the HTTP request
12817 HttpRequestInfo request2;
12818 request2.method = "GET";
12819 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0412820 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012821 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0412822 TestCompletionCallback callback2;
12823 EXPECT_EQ(ERR_IO_PENDING,
12824 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412825 base::MessageLoop::current()->RunUntilIdle();
[email protected]dd54bd82012-07-19 23:44:5712826 data1.RunFor(3);
[email protected]8450d722012-07-02 19:14:0412827
12828 EXPECT_EQ(OK, callback2.WaitForResult());
12829 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2212830
12831 LoadTimingInfo load_timing_info2;
12832 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
12833 // The established SPDY sessions is considered reused by the HTTP request.
12834 TestLoadTimingReusedWithPac(load_timing_info2);
12835 // HTTP requests over a SPDY session should have a different connection
12836 // socket_log_id than requests over a tunnel.
12837 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0412838}
12839
[email protected]2d88e7d2012-07-19 17:55:1712840// Test that in the case where we have a SPDY session to a SPDY proxy
12841// that we do not pool other origins that resolve to the same IP when
12842// the certificate does not match the new origin.
12843// http://crbug.com/134690
[email protected]23e482282013-06-14 16:08:0212844TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2312845 const std::string url1 = "http://www.example.org/";
12846 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1712847 const std::string ip_addr = "1.2.3.4";
12848
12849 // SPDY GET for HTTP URL (through SPDY proxy)
[email protected]23e482282013-06-14 16:08:0212850 scoped_ptr<SpdyHeaderBlock> headers(
bncce36dca22015-04-21 22:11:2312851 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
[email protected]745aa9c2014-06-27 02:21:2912852 scoped_ptr<SpdyFrame> req1(
12853 spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, false, true));
[email protected]2d88e7d2012-07-19 17:55:1712854
12855 MockWrite writes1[] = {
12856 CreateMockWrite(*req1, 0),
12857 };
12858
[email protected]23e482282013-06-14 16:08:0212859 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12860 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1712861 MockRead reads1[] = {
bncb9e20fc62015-08-17 17:19:3712862 CreateMockRead(*resp1, 1),
12863 CreateMockRead(*body1, 2),
12864 MockRead(ASYNC, OK, 3) // EOF
[email protected]2d88e7d2012-07-19 17:55:1712865 };
12866
12867 scoped_ptr<DeterministicSocketData> data1(
12868 new DeterministicSocketData(reads1, arraysize(reads1),
12869 writes1, arraysize(writes1)));
12870 IPAddressNumber ip;
12871 ASSERT_TRUE(ParseIPLiteralToNumber(ip_addr, &ip));
12872 IPEndPoint peer_addr = IPEndPoint(ip, 443);
12873 MockConnect connect_data1(ASYNC, OK, peer_addr);
12874 data1->set_connect_data(connect_data1);
12875
12876 // SPDY GET for HTTPS URL (direct)
[email protected]cdf8f7e72013-05-23 10:56:4612877 scoped_ptr<SpdyFrame> req2(
12878 spdy_util_.ConstructSpdyGet(url2.c_str(), false, 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1712879
12880 MockWrite writes2[] = {
12881 CreateMockWrite(*req2, 0),
12882 };
12883
[email protected]23e482282013-06-14 16:08:0212884 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12885 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1712886 MockRead reads2[] = {
bncb9e20fc62015-08-17 17:19:3712887 CreateMockRead(*resp2, 1),
12888 CreateMockRead(*body2, 2),
12889 MockRead(ASYNC, OK, 3) // EOF
[email protected]2d88e7d2012-07-19 17:55:1712890 };
12891
12892 scoped_ptr<DeterministicSocketData> data2(
12893 new DeterministicSocketData(reads2, arraysize(reads2),
12894 writes2, arraysize(writes2)));
12895 MockConnect connect_data2(ASYNC, OK);
12896 data2->set_connect_data(connect_data2);
12897
12898 // Set up a proxy config that sends HTTP requests to a proxy, and
12899 // all others direct.
12900 ProxyConfig proxy_config;
12901 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
[email protected]bb88e1d32013-05-03 23:11:0712902 session_deps_.proxy_service.reset(new ProxyService(
csharrisonb7e3a082015-09-22 19:13:0412903 make_scoped_ptr(new ProxyConfigServiceFixed(proxy_config)), nullptr,
12904 NULL));
[email protected]2d88e7d2012-07-19 17:55:1712905
bncce36dca22015-04-21 22:11:2312906 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
12907 ssl1.SetNextProto(GetParam());
[email protected]2d88e7d2012-07-19 17:55:1712908 // Load a valid cert. Note, that this does not need to
12909 // be valid for proxy because the MockSSLClientSocket does
12910 // not actually verify it. But SpdySession will use this
12911 // to see if it is valid for the new origin
bncce36dca22015-04-21 22:11:2312912 ssl1.cert = ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
12913 ASSERT_TRUE(ssl1.cert.get());
[email protected]bb88e1d32013-05-03 23:11:0712914 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
12915 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
12916 data1.get());
[email protected]2d88e7d2012-07-19 17:55:1712917
12918 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
[email protected]23e482282013-06-14 16:08:0212919 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0712920 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
12921 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
12922 data2.get());
[email protected]2d88e7d2012-07-19 17:55:1712923
[email protected]bb88e1d32013-05-03 23:11:0712924 session_deps_.host_resolver.reset(new MockCachingHostResolver());
bncce36dca22015-04-21 22:11:2312925 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0712926 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1712927
mmenke6b3af6e2015-09-12 02:06:0612928 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0712929 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]2d88e7d2012-07-19 17:55:1712930
12931 // Start the first transaction to set up the SpdySession
12932 HttpRequestInfo request1;
12933 request1.method = "GET";
12934 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1712935 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012936 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1712937 TestCompletionCallback callback1;
12938 ASSERT_EQ(ERR_IO_PENDING,
12939 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
12940 data1->RunFor(3);
12941
12942 ASSERT_TRUE(callback1.have_result());
12943 EXPECT_EQ(OK, callback1.WaitForResult());
12944 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
12945
12946 // Now, start the HTTP request
12947 HttpRequestInfo request2;
12948 request2.method = "GET";
12949 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1712950 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012951 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1712952 TestCompletionCallback callback2;
12953 EXPECT_EQ(ERR_IO_PENDING,
12954 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412955 base::MessageLoop::current()->RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1712956 data2->RunFor(3);
12957
12958 ASSERT_TRUE(callback2.have_result());
12959 EXPECT_EQ(OK, callback2.WaitForResult());
12960 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
12961}
12962
[email protected]85f97342013-04-17 06:12:2412963// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
12964// error) in SPDY session, removes the socket from pool and closes the SPDY
12965// session. Verify that new url's from the same HttpNetworkSession (and a new
12966// SpdySession) do work. http://crbug.com/224701
[email protected]23e482282013-06-14 16:08:0212967TEST_P(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2312968 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2412969
12970 MockRead reads1[] = {
12971 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
12972 };
12973
mmenke11eb5152015-06-09 14:50:5012974 SequencedSocketData data1(reads1, arraysize(reads1), NULL, 0);
[email protected]85f97342013-04-17 06:12:2412975
[email protected]cdf8f7e72013-05-23 10:56:4612976 scoped_ptr<SpdyFrame> req2(
12977 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2412978 MockWrite writes2[] = {
12979 CreateMockWrite(*req2, 0),
12980 };
12981
[email protected]23e482282013-06-14 16:08:0212982 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12983 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]85f97342013-04-17 06:12:2412984 MockRead reads2[] = {
12985 CreateMockRead(*resp2, 1),
12986 CreateMockRead(*body2, 2),
12987 MockRead(ASYNC, OK, 3) // EOF
12988 };
12989
mmenke11eb5152015-06-09 14:50:5012990 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
12991 arraysize(writes2));
[email protected]85f97342013-04-17 06:12:2412992
[email protected]85f97342013-04-17 06:12:2412993 SSLSocketDataProvider ssl1(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212994 ssl1.SetNextProto(GetParam());
mmenke11eb5152015-06-09 14:50:5012995 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
12996 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]85f97342013-04-17 06:12:2412997
12998 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212999 ssl2.SetNextProto(GetParam());
mmenke11eb5152015-06-09 14:50:5013000 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
13001 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]85f97342013-04-17 06:12:2413002
mmenke6b3af6e2015-09-12 02:06:0613003 scoped_refptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:5013004 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]85f97342013-04-17 06:12:2413005
13006 // Start the first transaction to set up the SpdySession and verify that
13007 // connection was closed.
13008 HttpRequestInfo request1;
13009 request1.method = "GET";
13010 request1.url = GURL(https_url);
13011 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013012 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2413013 TestCompletionCallback callback1;
13014 EXPECT_EQ(ERR_IO_PENDING,
13015 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]85f97342013-04-17 06:12:2413016 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback1.WaitForResult());
13017
13018 // Now, start the second request and make sure it succeeds.
13019 HttpRequestInfo request2;
13020 request2.method = "GET";
13021 request2.url = GURL(https_url);
13022 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013023 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2413024 TestCompletionCallback callback2;
13025 EXPECT_EQ(ERR_IO_PENDING,
13026 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]85f97342013-04-17 06:12:2413027
mmenke11eb5152015-06-09 14:50:5013028 ASSERT_EQ(OK, callback2.WaitForResult());
[email protected]85f97342013-04-17 06:12:2413029 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
13030}
13031
[email protected]23e482282013-06-14 16:08:0213032TEST_P(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]d7599122014-05-24 03:37:2313033 session_deps_.next_protos = SpdyNextProtos();
[email protected]483fa202013-05-14 01:07:0313034 ClientSocketPoolManager::set_max_sockets_per_group(
13035 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13036 ClientSocketPoolManager::set_max_sockets_per_pool(
13037 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13038
13039 // Use two different hosts with different IPs so they don't get pooled.
13040 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
13041 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
mmenke6b3af6e2015-09-12 02:06:0613042 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]483fa202013-05-14 01:07:0313043
13044 SSLSocketDataProvider ssl1(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0213045 ssl1.SetNextProto(GetParam());
[email protected]483fa202013-05-14 01:07:0313046 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0213047 ssl2.SetNextProto(GetParam());
[email protected]483fa202013-05-14 01:07:0313048 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
13049 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
13050
[email protected]cdf8f7e72013-05-23 10:56:4613051 scoped_ptr<SpdyFrame> host1_req(spdy_util_.ConstructSpdyGet(
[email protected]483fa202013-05-14 01:07:0313052 "https://www.a.com", false, 1, DEFAULT_PRIORITY));
13053 MockWrite spdy1_writes[] = {
rch8e6c6c42015-05-01 14:05:1313054 CreateMockWrite(*host1_req, 0),
[email protected]483fa202013-05-14 01:07:0313055 };
[email protected]23e482282013-06-14 16:08:0213056 scoped_ptr<SpdyFrame> host1_resp(
13057 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
13058 scoped_ptr<SpdyFrame> host1_resp_body(
13059 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0313060 MockRead spdy1_reads[] = {
rch8e6c6c42015-05-01 14:05:1313061 CreateMockRead(*host1_resp, 1),
13062 CreateMockRead(*host1_resp_body, 2),
13063 MockRead(ASYNC, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0313064 };
13065
rch8e6c6c42015-05-01 14:05:1313066 scoped_ptr<SequencedSocketData> spdy1_data(
13067 new SequencedSocketData(spdy1_reads, arraysize(spdy1_reads), spdy1_writes,
13068 arraysize(spdy1_writes)));
[email protected]483fa202013-05-14 01:07:0313069 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
13070
[email protected]cdf8f7e72013-05-23 10:56:4613071 scoped_ptr<SpdyFrame> host2_req(spdy_util_.ConstructSpdyGet(
[email protected]483fa202013-05-14 01:07:0313072 "https://www.b.com", false, 1, DEFAULT_PRIORITY));
13073 MockWrite spdy2_writes[] = {
rch8e6c6c42015-05-01 14:05:1313074 CreateMockWrite(*host2_req, 0),
[email protected]483fa202013-05-14 01:07:0313075 };
[email protected]23e482282013-06-14 16:08:0213076 scoped_ptr<SpdyFrame> host2_resp(
13077 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
13078 scoped_ptr<SpdyFrame> host2_resp_body(
13079 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0313080 MockRead spdy2_reads[] = {
rch8e6c6c42015-05-01 14:05:1313081 CreateMockRead(*host2_resp, 1),
13082 CreateMockRead(*host2_resp_body, 2),
13083 MockRead(ASYNC, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0313084 };
13085
rch8e6c6c42015-05-01 14:05:1313086 scoped_ptr<SequencedSocketData> spdy2_data(
13087 new SequencedSocketData(spdy2_reads, arraysize(spdy2_reads), spdy2_writes,
13088 arraysize(spdy2_writes)));
[email protected]483fa202013-05-14 01:07:0313089 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
13090
13091 MockWrite http_write[] = {
13092 MockWrite("GET / HTTP/1.1\r\n"
13093 "Host: www.a.com\r\n"
13094 "Connection: keep-alive\r\n\r\n"),
13095 };
13096
13097 MockRead http_read[] = {
13098 MockRead("HTTP/1.1 200 OK\r\n"),
13099 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
13100 MockRead("Content-Length: 6\r\n\r\n"),
13101 MockRead("hello!"),
13102 };
13103 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
13104 http_write, arraysize(http_write));
13105 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13106
13107 HostPortPair host_port_pair_a("www.a.com", 443);
[email protected]e6d017652013-05-17 18:01:4013108 SpdySessionKey spdy_session_key_a(
[email protected]314b03992014-04-01 01:28:5313109 host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0313110 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2613111 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0313112
13113 TestCompletionCallback callback;
13114 HttpRequestInfo request1;
13115 request1.method = "GET";
13116 request1.url = GURL("https://www.a.com/");
13117 request1.load_flags = 0;
13118 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5013119 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0313120
13121 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
13122 EXPECT_EQ(ERR_IO_PENDING, rv);
13123 EXPECT_EQ(OK, callback.WaitForResult());
13124
13125 const HttpResponseInfo* response = trans->GetResponseInfo();
13126 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5013127 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0313128 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13129 EXPECT_TRUE(response->was_fetched_via_spdy);
13130 EXPECT_TRUE(response->was_npn_negotiated);
13131
13132 std::string response_data;
13133 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
13134 EXPECT_EQ("hello!", response_data);
13135 trans.reset();
13136 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2613137 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0313138
13139 HostPortPair host_port_pair_b("www.b.com", 443);
[email protected]e6d017652013-05-17 18:01:4013140 SpdySessionKey spdy_session_key_b(
[email protected]314b03992014-04-01 01:28:5313141 host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0313142 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2613143 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0313144 HttpRequestInfo request2;
13145 request2.method = "GET";
13146 request2.url = GURL("https://www.b.com/");
13147 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013148 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0313149
13150 rv = trans->Start(&request2, callback.callback(), BoundNetLog());
13151 EXPECT_EQ(ERR_IO_PENDING, rv);
13152 EXPECT_EQ(OK, callback.WaitForResult());
13153
13154 response = trans->GetResponseInfo();
13155 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5013156 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0313157 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13158 EXPECT_TRUE(response->was_fetched_via_spdy);
13159 EXPECT_TRUE(response->was_npn_negotiated);
13160 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
13161 EXPECT_EQ("hello!", response_data);
13162 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2613163 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0313164 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2613165 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0313166
13167 HostPortPair host_port_pair_a1("www.a.com", 80);
[email protected]e6d017652013-05-17 18:01:4013168 SpdySessionKey spdy_session_key_a1(
[email protected]314b03992014-04-01 01:28:5313169 host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0313170 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2613171 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0313172 HttpRequestInfo request3;
13173 request3.method = "GET";
13174 request3.url = GURL("http://www.a.com/");
13175 request3.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013176 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0313177
13178 rv = trans->Start(&request3, callback.callback(), BoundNetLog());
13179 EXPECT_EQ(ERR_IO_PENDING, rv);
13180 EXPECT_EQ(OK, callback.WaitForResult());
13181
13182 response = trans->GetResponseInfo();
13183 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5013184 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0313185 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13186 EXPECT_FALSE(response->was_fetched_via_spdy);
13187 EXPECT_FALSE(response->was_npn_negotiated);
13188 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
13189 EXPECT_EQ("hello!", response_data);
13190 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2613191 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0313192 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2613193 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0313194}
13195
[email protected]79e1fd62013-06-20 06:50:0413196TEST_P(HttpNetworkTransactionTest, HttpSyncConnectError) {
13197 HttpRequestInfo request;
13198 request.method = "GET";
bncce36dca22015-04-21 22:11:2313199 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0413200 request.load_flags = 0;
13201
mmenke6b3af6e2015-09-12 02:06:0613202 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0413203 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113204 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0413205
ttuttled9dbc652015-09-29 20:00:5913206 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0413207 StaticSocketDataProvider data;
13208 data.set_connect_data(mock_connect);
13209 session_deps_.socket_factory->AddSocketDataProvider(&data);
13210
13211 TestCompletionCallback callback;
13212
13213 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13214 EXPECT_EQ(ERR_IO_PENDING, rv);
13215
13216 rv = callback.WaitForResult();
ttuttled9dbc652015-09-29 20:00:5913217 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
[email protected]79e1fd62013-06-20 06:50:0413218
[email protected]79e1fd62013-06-20 06:50:0413219 // We don't care whether this succeeds or fails, but it shouldn't crash.
13220 HttpRequestHeaders request_headers;
13221 trans->GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4713222
13223 ConnectionAttempts attempts;
13224 trans->GetConnectionAttempts(&attempts);
13225 ASSERT_EQ(1u, attempts.size());
ttuttled9dbc652015-09-29 20:00:5913226 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, attempts[0].result);
13227
13228 IPEndPoint endpoint;
13229 EXPECT_FALSE(trans->GetRemoteEndpoint(&endpoint));
13230 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0413231}
13232
13233TEST_P(HttpNetworkTransactionTest, HttpAsyncConnectError) {
13234 HttpRequestInfo request;
13235 request.method = "GET";
bncce36dca22015-04-21 22:11:2313236 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0413237 request.load_flags = 0;
13238
mmenke6b3af6e2015-09-12 02:06:0613239 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0413240 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113241 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0413242
ttuttled9dbc652015-09-29 20:00:5913243 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0413244 StaticSocketDataProvider data;
13245 data.set_connect_data(mock_connect);
13246 session_deps_.socket_factory->AddSocketDataProvider(&data);
13247
13248 TestCompletionCallback callback;
13249
13250 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13251 EXPECT_EQ(ERR_IO_PENDING, rv);
13252
13253 rv = callback.WaitForResult();
ttuttled9dbc652015-09-29 20:00:5913254 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
[email protected]79e1fd62013-06-20 06:50:0413255
[email protected]79e1fd62013-06-20 06:50:0413256 // We don't care whether this succeeds or fails, but it shouldn't crash.
13257 HttpRequestHeaders request_headers;
13258 trans->GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4713259
13260 ConnectionAttempts attempts;
13261 trans->GetConnectionAttempts(&attempts);
13262 ASSERT_EQ(1u, attempts.size());
ttuttled9dbc652015-09-29 20:00:5913263 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, attempts[0].result);
13264
13265 IPEndPoint endpoint;
13266 EXPECT_FALSE(trans->GetRemoteEndpoint(&endpoint));
13267 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0413268}
13269
13270TEST_P(HttpNetworkTransactionTest, HttpSyncWriteError) {
13271 HttpRequestInfo request;
13272 request.method = "GET";
bncce36dca22015-04-21 22:11:2313273 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0413274 request.load_flags = 0;
13275
mmenke6b3af6e2015-09-12 02:06:0613276 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0413277 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113278 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0413279
13280 MockWrite data_writes[] = {
13281 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13282 };
13283 MockRead data_reads[] = {
13284 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
13285 };
13286
13287 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
13288 data_writes, arraysize(data_writes));
13289 session_deps_.socket_factory->AddSocketDataProvider(&data);
13290
13291 TestCompletionCallback callback;
13292
13293 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13294 EXPECT_EQ(ERR_IO_PENDING, rv);
13295
13296 rv = callback.WaitForResult();
13297 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13298
[email protected]79e1fd62013-06-20 06:50:0413299 HttpRequestHeaders request_headers;
13300 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
13301 EXPECT_TRUE(request_headers.HasHeader("Host"));
13302}
13303
13304TEST_P(HttpNetworkTransactionTest, HttpAsyncWriteError) {
13305 HttpRequestInfo request;
13306 request.method = "GET";
bncce36dca22015-04-21 22:11:2313307 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0413308 request.load_flags = 0;
13309
mmenke6b3af6e2015-09-12 02:06:0613310 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0413311 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113312 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0413313
13314 MockWrite data_writes[] = {
13315 MockWrite(ASYNC, ERR_CONNECTION_RESET),
13316 };
13317 MockRead data_reads[] = {
13318 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
13319 };
13320
13321 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
13322 data_writes, arraysize(data_writes));
13323 session_deps_.socket_factory->AddSocketDataProvider(&data);
13324
13325 TestCompletionCallback callback;
13326
13327 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13328 EXPECT_EQ(ERR_IO_PENDING, rv);
13329
13330 rv = callback.WaitForResult();
13331 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13332
[email protected]79e1fd62013-06-20 06:50:0413333 HttpRequestHeaders request_headers;
13334 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
13335 EXPECT_TRUE(request_headers.HasHeader("Host"));
13336}
13337
13338TEST_P(HttpNetworkTransactionTest, HttpSyncReadError) {
13339 HttpRequestInfo request;
13340 request.method = "GET";
bncce36dca22015-04-21 22:11:2313341 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0413342 request.load_flags = 0;
13343
mmenke6b3af6e2015-09-12 02:06:0613344 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0413345 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113346 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0413347
13348 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2313349 MockWrite(
13350 "GET / HTTP/1.1\r\n"
13351 "Host: www.example.org\r\n"
13352 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0413353 };
13354 MockRead data_reads[] = {
13355 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
13356 };
13357
13358 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
13359 data_writes, arraysize(data_writes));
13360 session_deps_.socket_factory->AddSocketDataProvider(&data);
13361
13362 TestCompletionCallback callback;
13363
13364 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13365 EXPECT_EQ(ERR_IO_PENDING, rv);
13366
13367 rv = callback.WaitForResult();
13368 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13369
[email protected]79e1fd62013-06-20 06:50:0413370 HttpRequestHeaders request_headers;
13371 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
13372 EXPECT_TRUE(request_headers.HasHeader("Host"));
13373}
13374
13375TEST_P(HttpNetworkTransactionTest, HttpAsyncReadError) {
13376 HttpRequestInfo request;
13377 request.method = "GET";
bncce36dca22015-04-21 22:11:2313378 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0413379 request.load_flags = 0;
13380
mmenke6b3af6e2015-09-12 02:06:0613381 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0413382 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113383 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0413384
13385 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2313386 MockWrite(
13387 "GET / HTTP/1.1\r\n"
13388 "Host: www.example.org\r\n"
13389 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0413390 };
13391 MockRead data_reads[] = {
13392 MockRead(ASYNC, ERR_CONNECTION_RESET),
13393 };
13394
13395 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
13396 data_writes, arraysize(data_writes));
13397 session_deps_.socket_factory->AddSocketDataProvider(&data);
13398
13399 TestCompletionCallback callback;
13400
13401 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13402 EXPECT_EQ(ERR_IO_PENDING, rv);
13403
13404 rv = callback.WaitForResult();
13405 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13406
[email protected]79e1fd62013-06-20 06:50:0413407 HttpRequestHeaders request_headers;
13408 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
13409 EXPECT_TRUE(request_headers.HasHeader("Host"));
13410}
13411
13412TEST_P(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
13413 HttpRequestInfo request;
13414 request.method = "GET";
bncce36dca22015-04-21 22:11:2313415 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0413416 request.load_flags = 0;
13417 request.extra_headers.SetHeader("X-Foo", "bar");
13418
mmenke6b3af6e2015-09-12 02:06:0613419 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0413420 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113421 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0413422
13423 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2313424 MockWrite(
13425 "GET / HTTP/1.1\r\n"
13426 "Host: www.example.org\r\n"
13427 "Connection: keep-alive\r\n"
13428 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0413429 };
13430 MockRead data_reads[] = {
13431 MockRead("HTTP/1.1 200 OK\r\n"
13432 "Content-Length: 5\r\n\r\n"
13433 "hello"),
13434 MockRead(ASYNC, ERR_UNEXPECTED),
13435 };
13436
13437 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
13438 data_writes, arraysize(data_writes));
13439 session_deps_.socket_factory->AddSocketDataProvider(&data);
13440
13441 TestCompletionCallback callback;
13442
13443 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13444 EXPECT_EQ(ERR_IO_PENDING, rv);
13445
13446 rv = callback.WaitForResult();
13447 EXPECT_EQ(OK, rv);
13448
13449 HttpRequestHeaders request_headers;
13450 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
13451 std::string foo;
13452 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
13453 EXPECT_EQ("bar", foo);
13454}
13455
[email protected]bf828982013-08-14 18:01:4713456namespace {
13457
yhiranoa7e05bb2014-11-06 05:40:3913458// Fake HttpStream that simply records calls to SetPriority().
13459class FakeStream : public HttpStream,
[email protected]e86839fd2013-08-14 18:29:0313460 public base::SupportsWeakPtr<FakeStream> {
13461 public:
13462 explicit FakeStream(RequestPriority priority) : priority_(priority) {}
dchengb03027d2014-10-21 12:00:2013463 ~FakeStream() override {}
[email protected]e86839fd2013-08-14 18:29:0313464
13465 RequestPriority priority() const { return priority_; }
13466
dchengb03027d2014-10-21 12:00:2013467 int InitializeStream(const HttpRequestInfo* request_info,
13468 RequestPriority priority,
13469 const BoundNetLog& net_log,
13470 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0313471 return ERR_IO_PENDING;
13472 }
13473
dchengb03027d2014-10-21 12:00:2013474 int SendRequest(const HttpRequestHeaders& request_headers,
13475 HttpResponseInfo* response,
13476 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0313477 ADD_FAILURE();
13478 return ERR_UNEXPECTED;
13479 }
13480
dchengb03027d2014-10-21 12:00:2013481 int ReadResponseHeaders(const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0313482 ADD_FAILURE();
13483 return ERR_UNEXPECTED;
13484 }
13485
dchengb03027d2014-10-21 12:00:2013486 int ReadResponseBody(IOBuffer* buf,
13487 int buf_len,
13488 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0313489 ADD_FAILURE();
13490 return ERR_UNEXPECTED;
13491 }
13492
dchengb03027d2014-10-21 12:00:2013493 void Close(bool not_reusable) override {}
[email protected]e86839fd2013-08-14 18:29:0313494
dchengb03027d2014-10-21 12:00:2013495 bool IsResponseBodyComplete() const override {
[email protected]e86839fd2013-08-14 18:29:0313496 ADD_FAILURE();
13497 return false;
13498 }
13499
dchengb03027d2014-10-21 12:00:2013500 bool IsConnectionReused() const override {
[email protected]e86839fd2013-08-14 18:29:0313501 ADD_FAILURE();
13502 return false;
13503 }
13504
dchengb03027d2014-10-21 12:00:2013505 void SetConnectionReused() override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0313506
mmenkebd84c392015-09-02 14:12:3413507 bool CanReuseConnection() const override { return false; }
[email protected]e86839fd2013-08-14 18:29:0313508
sclittle4de1bab92015-09-22 21:28:2413509 int64_t GetTotalReceivedBytes() const override {
[email protected]bc92bc972013-12-13 08:32:5913510 ADD_FAILURE();
13511 return 0;
13512 }
13513
sclittlebe1ccf62015-09-02 19:40:3613514 int64_t GetTotalSentBytes() const override {
13515 ADD_FAILURE();
13516 return 0;
13517 }
13518
dchengb03027d2014-10-21 12:00:2013519 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
[email protected]e86839fd2013-08-14 18:29:0313520 ADD_FAILURE();
13521 return false;
13522 }
13523
dchengb03027d2014-10-21 12:00:2013524 void GetSSLInfo(SSLInfo* ssl_info) override { ADD_FAILURE(); }
13525
13526 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
[email protected]e86839fd2013-08-14 18:29:0313527 ADD_FAILURE();
13528 }
13529
ttuttled9dbc652015-09-29 20:00:5913530 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
13531
dchengb03027d2014-10-21 12:00:2013532 void Drain(HttpNetworkSession* session) override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0313533
dchengb03027d2014-10-21 12:00:2013534 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]e86839fd2013-08-14 18:29:0313535
yhiranoa7e05bb2014-11-06 05:40:3913536 UploadProgress GetUploadProgress() const override { return UploadProgress(); }
13537
13538 HttpStream* RenewStreamForAuth() override { return NULL; }
13539
[email protected]e86839fd2013-08-14 18:29:0313540 private:
13541 RequestPriority priority_;
13542
13543 DISALLOW_COPY_AND_ASSIGN(FakeStream);
13544};
13545
13546// Fake HttpStreamRequest that simply records calls to SetPriority()
13547// and vends FakeStreams with its current priority.
[email protected]bf828982013-08-14 18:01:4713548class FakeStreamRequest : public HttpStreamRequest,
13549 public base::SupportsWeakPtr<FakeStreamRequest> {
13550 public:
[email protected]e86839fd2013-08-14 18:29:0313551 FakeStreamRequest(RequestPriority priority,
13552 HttpStreamRequest::Delegate* delegate)
13553 : priority_(priority),
[email protected]831e4a32013-11-14 02:14:4413554 delegate_(delegate),
13555 websocket_stream_create_helper_(NULL) {}
13556
13557 FakeStreamRequest(RequestPriority priority,
13558 HttpStreamRequest::Delegate* delegate,
13559 WebSocketHandshakeStreamBase::CreateHelper* create_helper)
13560 : priority_(priority),
13561 delegate_(delegate),
13562 websocket_stream_create_helper_(create_helper) {}
[email protected]e86839fd2013-08-14 18:29:0313563
dchengb03027d2014-10-21 12:00:2013564 ~FakeStreamRequest() override {}
[email protected]bf828982013-08-14 18:01:4713565
13566 RequestPriority priority() const { return priority_; }
13567
[email protected]831e4a32013-11-14 02:14:4413568 const WebSocketHandshakeStreamBase::CreateHelper*
13569 websocket_stream_create_helper() const {
13570 return websocket_stream_create_helper_;
13571 }
13572
[email protected]e86839fd2013-08-14 18:29:0313573 // Create a new FakeStream and pass it to the request's
13574 // delegate. Returns a weak pointer to the FakeStream.
13575 base::WeakPtr<FakeStream> FinishStreamRequest() {
13576 FakeStream* fake_stream = new FakeStream(priority_);
13577 // Do this before calling OnStreamReady() as OnStreamReady() may
13578 // immediately delete |fake_stream|.
13579 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
13580 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), fake_stream);
13581 return weak_stream;
13582 }
13583
dchengb03027d2014-10-21 12:00:2013584 int RestartTunnelWithProxyAuth(const AuthCredentials& credentials) override {
[email protected]bf828982013-08-14 18:01:4713585 ADD_FAILURE();
13586 return ERR_UNEXPECTED;
13587 }
13588
dchengb03027d2014-10-21 12:00:2013589 LoadState GetLoadState() const override {
[email protected]bf828982013-08-14 18:01:4713590 ADD_FAILURE();
13591 return LoadState();
13592 }
13593
dchengb03027d2014-10-21 12:00:2013594 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]bf828982013-08-14 18:01:4713595
dchengb03027d2014-10-21 12:00:2013596 bool was_npn_negotiated() const override { return false; }
[email protected]bf828982013-08-14 18:01:4713597
dchengb03027d2014-10-21 12:00:2013598 NextProto protocol_negotiated() const override { return kProtoUnknown; }
[email protected]bf828982013-08-14 18:01:4713599
dchengb03027d2014-10-21 12:00:2013600 bool using_spdy() const override { return false; }
[email protected]bf828982013-08-14 18:01:4713601
ttuttle1f2d7e92015-04-28 16:17:4713602 const ConnectionAttempts& connection_attempts() const override {
13603 static ConnectionAttempts no_attempts;
13604 return no_attempts;
13605 }
13606
[email protected]bf828982013-08-14 18:01:4713607 private:
13608 RequestPriority priority_;
[email protected]e86839fd2013-08-14 18:29:0313609 HttpStreamRequest::Delegate* const delegate_;
[email protected]831e4a32013-11-14 02:14:4413610 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
[email protected]bf828982013-08-14 18:01:4713611
13612 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
13613};
13614
13615// Fake HttpStreamFactory that vends FakeStreamRequests.
13616class FakeStreamFactory : public HttpStreamFactory {
13617 public:
13618 FakeStreamFactory() {}
dchengb03027d2014-10-21 12:00:2013619 ~FakeStreamFactory() override {}
[email protected]bf828982013-08-14 18:01:4713620
13621 // Returns a WeakPtr<> to the last HttpStreamRequest returned by
13622 // RequestStream() (which may be NULL if it was destroyed already).
13623 base::WeakPtr<FakeStreamRequest> last_stream_request() {
13624 return last_stream_request_;
13625 }
13626
dchengb03027d2014-10-21 12:00:2013627 HttpStreamRequest* RequestStream(const HttpRequestInfo& info,
13628 RequestPriority priority,
13629 const SSLConfig& server_ssl_config,
13630 const SSLConfig& proxy_ssl_config,
13631 HttpStreamRequest::Delegate* delegate,
13632 const BoundNetLog& net_log) override {
[email protected]e86839fd2013-08-14 18:29:0313633 FakeStreamRequest* fake_request = new FakeStreamRequest(priority, delegate);
[email protected]bf828982013-08-14 18:01:4713634 last_stream_request_ = fake_request->AsWeakPtr();
13635 return fake_request;
13636 }
13637
dchengb03027d2014-10-21 12:00:2013638 HttpStreamRequest* RequestWebSocketHandshakeStream(
[email protected]bf828982013-08-14 18:01:4713639 const HttpRequestInfo& info,
13640 RequestPriority priority,
13641 const SSLConfig& server_ssl_config,
13642 const SSLConfig& proxy_ssl_config,
13643 HttpStreamRequest::Delegate* delegate,
[email protected]467086b2013-11-12 08:19:4613644 WebSocketHandshakeStreamBase::CreateHelper* create_helper,
mostynbba063d6032014-10-09 11:01:1313645 const BoundNetLog& net_log) override {
[email protected]831e4a32013-11-14 02:14:4413646 FakeStreamRequest* fake_request =
13647 new FakeStreamRequest(priority, delegate, create_helper);
13648 last_stream_request_ = fake_request->AsWeakPtr();
13649 return fake_request;
[email protected]bf828982013-08-14 18:01:4713650 }
13651
dchengb03027d2014-10-21 12:00:2013652 void PreconnectStreams(int num_streams,
13653 const HttpRequestInfo& info,
dchengb03027d2014-10-21 12:00:2013654 const SSLConfig& server_ssl_config,
13655 const SSLConfig& proxy_ssl_config) override {
[email protected]bf828982013-08-14 18:01:4713656 ADD_FAILURE();
13657 }
13658
dchengb03027d2014-10-21 12:00:2013659 const HostMappingRules* GetHostMappingRules() const override {
[email protected]bf828982013-08-14 18:01:4713660 ADD_FAILURE();
13661 return NULL;
13662 }
13663
13664 private:
13665 base::WeakPtr<FakeStreamRequest> last_stream_request_;
13666
13667 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
13668};
13669
Adam Rice425cf122015-01-19 06:18:2413670// TODO(ricea): Maybe unify this with the one in
13671// url_request_http_job_unittest.cc ?
13672class FakeWebSocketBasicHandshakeStream : public WebSocketHandshakeStreamBase {
13673 public:
13674 FakeWebSocketBasicHandshakeStream(scoped_ptr<ClientSocketHandle> connection,
13675 bool using_proxy)
13676 : state_(connection.release(), using_proxy) {}
13677
13678 // Fake implementation of HttpStreamBase methods.
13679 // This ends up being quite "real" because this object has to really send data
13680 // on the mock socket. It might be easier to use the real implementation, but
13681 // the fact that the WebSocket code is not compiled on iOS makes that
13682 // difficult.
13683 int InitializeStream(const HttpRequestInfo* request_info,
13684 RequestPriority priority,
13685 const BoundNetLog& net_log,
13686 const CompletionCallback& callback) override {
13687 state_.Initialize(request_info, priority, net_log, callback);
13688 return OK;
13689 }
13690
13691 int SendRequest(const HttpRequestHeaders& request_headers,
13692 HttpResponseInfo* response,
13693 const CompletionCallback& callback) override {
13694 return parser()->SendRequest(state_.GenerateRequestLine(), request_headers,
13695 response, callback);
13696 }
13697
13698 int ReadResponseHeaders(const CompletionCallback& callback) override {
13699 return parser()->ReadResponseHeaders(callback);
13700 }
13701
13702 int ReadResponseBody(IOBuffer* buf,
13703 int buf_len,
13704 const CompletionCallback& callback) override {
13705 NOTREACHED();
13706 return ERR_IO_PENDING;
13707 }
13708
13709 void Close(bool not_reusable) override {
13710 if (parser())
13711 parser()->Close(true);
13712 }
13713
13714 bool IsResponseBodyComplete() const override {
13715 NOTREACHED();
13716 return false;
13717 }
13718
Adam Rice425cf122015-01-19 06:18:2413719 bool IsConnectionReused() const override {
13720 NOTREACHED();
13721 return false;
13722 }
13723 void SetConnectionReused() override { NOTREACHED(); }
13724
mmenkebd84c392015-09-02 14:12:3413725 bool CanReuseConnection() const override { return false; }
Adam Rice425cf122015-01-19 06:18:2413726
sclittle4de1bab92015-09-22 21:28:2413727 int64_t GetTotalReceivedBytes() const override {
Adam Rice425cf122015-01-19 06:18:2413728 NOTREACHED();
13729 return 0;
13730 }
13731
sclittlebe1ccf62015-09-02 19:40:3613732 int64_t GetTotalSentBytes() const override {
13733 NOTREACHED();
13734 return 0;
13735 }
13736
Adam Rice425cf122015-01-19 06:18:2413737 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
13738 NOTREACHED();
13739 return false;
13740 }
13741
Adam Ricecb76ac62015-02-20 05:33:2513742 void GetSSLInfo(SSLInfo* ssl_info) override {}
Adam Rice425cf122015-01-19 06:18:2413743
13744 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
13745 NOTREACHED();
13746 }
13747
ttuttled9dbc652015-09-29 20:00:5913748 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
13749
Adam Rice425cf122015-01-19 06:18:2413750 void Drain(HttpNetworkSession* session) override { NOTREACHED(); }
13751
13752 void SetPriority(RequestPriority priority) override { NOTREACHED(); }
13753
13754 UploadProgress GetUploadProgress() const override {
13755 NOTREACHED();
13756 return UploadProgress();
13757 }
13758
13759 HttpStream* RenewStreamForAuth() override {
13760 NOTREACHED();
13761 return nullptr;
13762 }
13763
13764 // Fake implementation of WebSocketHandshakeStreamBase method(s)
13765 scoped_ptr<WebSocketStream> Upgrade() override {
13766 NOTREACHED();
13767 return scoped_ptr<WebSocketStream>();
13768 }
13769
13770 private:
13771 HttpStreamParser* parser() const { return state_.parser(); }
13772 HttpBasicState state_;
13773
13774 DISALLOW_COPY_AND_ASSIGN(FakeWebSocketBasicHandshakeStream);
13775};
13776
[email protected]831e4a32013-11-14 02:14:4413777// TODO(yhirano): Split this class out into a net/websockets file, if it is
13778// worth doing.
13779class FakeWebSocketStreamCreateHelper :
13780 public WebSocketHandshakeStreamBase::CreateHelper {
13781 public:
dchengb03027d2014-10-21 12:00:2013782 WebSocketHandshakeStreamBase* CreateBasicStream(
[email protected]7e841a52013-11-22 09:04:2113783 scoped_ptr<ClientSocketHandle> connection,
mostynbba063d6032014-10-09 11:01:1313784 bool using_proxy) override {
Adam Rice425cf122015-01-19 06:18:2413785 return new FakeWebSocketBasicHandshakeStream(connection.Pass(),
13786 using_proxy);
[email protected]831e4a32013-11-14 02:14:4413787 }
13788
dchengb03027d2014-10-21 12:00:2013789 WebSocketHandshakeStreamBase* CreateSpdyStream(
[email protected]831e4a32013-11-14 02:14:4413790 const base::WeakPtr<SpdySession>& session,
mostynbba063d6032014-10-09 11:01:1313791 bool use_relative_url) override {
[email protected]831e4a32013-11-14 02:14:4413792 NOTREACHED();
13793 return NULL;
13794 };
13795
dchengb03027d2014-10-21 12:00:2013796 ~FakeWebSocketStreamCreateHelper() override {}
[email protected]831e4a32013-11-14 02:14:4413797
13798 virtual scoped_ptr<WebSocketStream> Upgrade() {
13799 NOTREACHED();
13800 return scoped_ptr<WebSocketStream>();
13801 }
13802};
13803
[email protected]bf828982013-08-14 18:01:4713804} // namespace
13805
13806// Make sure that HttpNetworkTransaction passes on its priority to its
13807// stream request on start.
13808TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
mmenke6b3af6e2015-09-12 02:06:0613809 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13810 HttpNetworkSessionPeer peer(session);
[email protected]bf828982013-08-14 18:01:4713811 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4413812 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4713813
dcheng48459ac22014-08-26 00:46:4113814 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4713815
13816 ASSERT_TRUE(fake_factory->last_stream_request() == NULL);
13817
13818 HttpRequestInfo request;
13819 TestCompletionCallback callback;
13820 EXPECT_EQ(ERR_IO_PENDING,
13821 trans.Start(&request, callback.callback(), BoundNetLog()));
13822
13823 base::WeakPtr<FakeStreamRequest> fake_request =
13824 fake_factory->last_stream_request();
13825 ASSERT_TRUE(fake_request != NULL);
13826 EXPECT_EQ(LOW, fake_request->priority());
13827}
13828
13829// Make sure that HttpNetworkTransaction passes on its priority
13830// updates to its stream request.
13831TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriority) {
mmenke6b3af6e2015-09-12 02:06:0613832 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13833 HttpNetworkSessionPeer peer(session);
[email protected]bf828982013-08-14 18:01:4713834 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4413835 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4713836
dcheng48459ac22014-08-26 00:46:4113837 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4713838
13839 HttpRequestInfo request;
13840 TestCompletionCallback callback;
13841 EXPECT_EQ(ERR_IO_PENDING,
13842 trans.Start(&request, callback.callback(), BoundNetLog()));
13843
13844 base::WeakPtr<FakeStreamRequest> fake_request =
13845 fake_factory->last_stream_request();
13846 ASSERT_TRUE(fake_request != NULL);
13847 EXPECT_EQ(LOW, fake_request->priority());
13848
13849 trans.SetPriority(LOWEST);
13850 ASSERT_TRUE(fake_request != NULL);
13851 EXPECT_EQ(LOWEST, fake_request->priority());
13852}
13853
[email protected]e86839fd2013-08-14 18:29:0313854// Make sure that HttpNetworkTransaction passes on its priority
13855// updates to its stream.
13856TEST_P(HttpNetworkTransactionTest, SetStreamPriority) {
mmenke6b3af6e2015-09-12 02:06:0613857 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13858 HttpNetworkSessionPeer peer(session);
[email protected]e86839fd2013-08-14 18:29:0313859 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4413860 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]e86839fd2013-08-14 18:29:0313861
dcheng48459ac22014-08-26 00:46:4113862 HttpNetworkTransaction trans(LOW, session.get());
[email protected]e86839fd2013-08-14 18:29:0313863
13864 HttpRequestInfo request;
13865 TestCompletionCallback callback;
13866 EXPECT_EQ(ERR_IO_PENDING,
13867 trans.Start(&request, callback.callback(), BoundNetLog()));
13868
13869 base::WeakPtr<FakeStreamRequest> fake_request =
13870 fake_factory->last_stream_request();
13871 ASSERT_TRUE(fake_request != NULL);
13872 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
13873 ASSERT_TRUE(fake_stream != NULL);
13874 EXPECT_EQ(LOW, fake_stream->priority());
13875
13876 trans.SetPriority(LOWEST);
13877 EXPECT_EQ(LOWEST, fake_stream->priority());
13878}
13879
[email protected]831e4a32013-11-14 02:14:4413880TEST_P(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
13881 // The same logic needs to be tested for both ws: and wss: schemes, but this
13882 // test is already parameterised on NextProto, so it uses a loop to verify
13883 // that the different schemes work.
bncce36dca22015-04-21 22:11:2313884 std::string test_cases[] = {"ws://www.example.org/",
13885 "wss://www.example.org/"};
[email protected]831e4a32013-11-14 02:14:4413886 for (size_t i = 0; i < arraysize(test_cases); ++i) {
mmenke6b3af6e2015-09-12 02:06:0613887 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13888 HttpNetworkSessionPeer peer(session);
[email protected]831e4a32013-11-14 02:14:4413889 FakeStreamFactory* fake_factory = new FakeStreamFactory();
13890 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
[email protected]0191b51c2013-11-18 10:55:2313891 peer.SetHttpStreamFactoryForWebSocket(
[email protected]831e4a32013-11-14 02:14:4413892 scoped_ptr<HttpStreamFactory>(fake_factory));
13893
dcheng48459ac22014-08-26 00:46:4113894 HttpNetworkTransaction trans(LOW, session.get());
[email protected]831e4a32013-11-14 02:14:4413895 trans.SetWebSocketHandshakeStreamCreateHelper(
13896 &websocket_stream_create_helper);
13897
13898 HttpRequestInfo request;
13899 TestCompletionCallback callback;
13900 request.method = "GET";
13901 request.url = GURL(test_cases[i]);
13902
13903 EXPECT_EQ(ERR_IO_PENDING,
13904 trans.Start(&request, callback.callback(), BoundNetLog()));
13905
13906 base::WeakPtr<FakeStreamRequest> fake_request =
13907 fake_factory->last_stream_request();
13908 ASSERT_TRUE(fake_request != NULL);
13909 EXPECT_EQ(&websocket_stream_create_helper,
13910 fake_request->websocket_stream_create_helper());
13911 }
13912}
13913
[email protected]043b68c82013-08-22 23:41:5213914// Tests that when a used socket is returned to the SSL socket pool, it's closed
13915// if the transport socket pool is stalled on the global socket limit.
13916TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
13917 ClientSocketPoolManager::set_max_sockets_per_group(
13918 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13919 ClientSocketPoolManager::set_max_sockets_per_pool(
13920 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13921
13922 // Set up SSL request.
13923
13924 HttpRequestInfo ssl_request;
13925 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2313926 ssl_request.url = GURL("https://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5213927
13928 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2313929 MockWrite(
13930 "GET / HTTP/1.1\r\n"
13931 "Host: www.example.org\r\n"
13932 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5213933 };
13934 MockRead ssl_reads[] = {
13935 MockRead("HTTP/1.1 200 OK\r\n"),
13936 MockRead("Content-Length: 11\r\n\r\n"),
13937 MockRead("hello world"),
13938 MockRead(SYNCHRONOUS, OK),
13939 };
13940 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
13941 ssl_writes, arraysize(ssl_writes));
13942 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
13943
13944 SSLSocketDataProvider ssl(ASYNC, OK);
13945 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13946
13947 // Set up HTTP request.
13948
13949 HttpRequestInfo http_request;
13950 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2313951 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5213952
13953 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2313954 MockWrite(
13955 "GET / HTTP/1.1\r\n"
13956 "Host: www.example.org\r\n"
13957 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5213958 };
13959 MockRead http_reads[] = {
13960 MockRead("HTTP/1.1 200 OK\r\n"),
13961 MockRead("Content-Length: 7\r\n\r\n"),
13962 MockRead("falafel"),
13963 MockRead(SYNCHRONOUS, OK),
13964 };
13965 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
13966 http_writes, arraysize(http_writes));
13967 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13968
mmenke6b3af6e2015-09-12 02:06:0613969 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5213970
13971 // Start the SSL request.
13972 TestCompletionCallback ssl_callback;
13973 scoped_ptr<HttpTransaction> ssl_trans(
13974 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13975 ASSERT_EQ(ERR_IO_PENDING,
13976 ssl_trans->Start(&ssl_request, ssl_callback.callback(),
13977 BoundNetLog()));
13978
13979 // Start the HTTP request. Pool should stall.
13980 TestCompletionCallback http_callback;
13981 scoped_ptr<HttpTransaction> http_trans(
13982 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13983 ASSERT_EQ(ERR_IO_PENDING,
13984 http_trans->Start(&http_request, http_callback.callback(),
13985 BoundNetLog()));
dcheng48459ac22014-08-26 00:46:4113986 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5213987
13988 // Wait for response from SSL request.
13989 ASSERT_EQ(OK, ssl_callback.WaitForResult());
13990 std::string response_data;
13991 ASSERT_EQ(OK, ReadTransaction(ssl_trans.get(), &response_data));
13992 EXPECT_EQ("hello world", response_data);
13993
13994 // The SSL socket should automatically be closed, so the HTTP request can
13995 // start.
dcheng48459ac22014-08-26 00:46:4113996 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
13997 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5213998
13999 // The HTTP request can now complete.
14000 ASSERT_EQ(OK, http_callback.WaitForResult());
14001 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
14002 EXPECT_EQ("falafel", response_data);
14003
dcheng48459ac22014-08-26 00:46:4114004 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5214005}
14006
14007// Tests that when a SSL connection is established but there's no corresponding
14008// request that needs it, the new socket is closed if the transport socket pool
14009// is stalled on the global socket limit.
14010TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
14011 ClientSocketPoolManager::set_max_sockets_per_group(
14012 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14013 ClientSocketPoolManager::set_max_sockets_per_pool(
14014 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14015
14016 // Set up an ssl request.
14017
14018 HttpRequestInfo ssl_request;
14019 ssl_request.method = "GET";
14020 ssl_request.url = GURL("https://www.foopy.com/");
14021
14022 // No data will be sent on the SSL socket.
14023 StaticSocketDataProvider ssl_data;
14024 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
14025
14026 SSLSocketDataProvider ssl(ASYNC, OK);
14027 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14028
14029 // Set up HTTP request.
14030
14031 HttpRequestInfo http_request;
14032 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2314033 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5214034
14035 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2314036 MockWrite(
14037 "GET / HTTP/1.1\r\n"
14038 "Host: www.example.org\r\n"
14039 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5214040 };
14041 MockRead http_reads[] = {
14042 MockRead("HTTP/1.1 200 OK\r\n"),
14043 MockRead("Content-Length: 7\r\n\r\n"),
14044 MockRead("falafel"),
14045 MockRead(SYNCHRONOUS, OK),
14046 };
14047 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
14048 http_writes, arraysize(http_writes));
14049 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
14050
mmenke6b3af6e2015-09-12 02:06:0614051 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5214052
14053 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
14054 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2914055 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
14056 SSLConfig ssl_config;
[email protected]043b68c82013-08-22 23:41:5214057 session->ssl_config_service()->GetSSLConfig(&ssl_config);
mmenked1205bd2015-07-15 22:26:3514058 http_stream_factory->PreconnectStreams(1, ssl_request, ssl_config,
14059 ssl_config);
dcheng48459ac22014-08-26 00:46:4114060 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5214061
14062 // Start the HTTP request. Pool should stall.
14063 TestCompletionCallback http_callback;
14064 scoped_ptr<HttpTransaction> http_trans(
14065 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
14066 ASSERT_EQ(ERR_IO_PENDING,
14067 http_trans->Start(&http_request, http_callback.callback(),
14068 BoundNetLog()));
dcheng48459ac22014-08-26 00:46:4114069 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5214070
14071 // The SSL connection will automatically be closed once the connection is
14072 // established, to let the HTTP request start.
14073 ASSERT_EQ(OK, http_callback.WaitForResult());
14074 std::string response_data;
14075 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
14076 EXPECT_EQ("falafel", response_data);
14077
dcheng48459ac22014-08-26 00:46:4114078 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5214079}
14080
[email protected]02d74a02014-04-23 18:10:5414081TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
14082 ScopedVector<UploadElementReader> element_readers;
14083 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714084 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5414085
14086 HttpRequestInfo request;
14087 request.method = "POST";
14088 request.url = GURL("http://www.foo.com/");
14089 request.upload_data_stream = &upload_data_stream;
14090 request.load_flags = 0;
14091
mmenke6b3af6e2015-09-12 02:06:0614092 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5414093 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114094 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414095 // Send headers successfully, but get an error while sending the body.
14096 MockWrite data_writes[] = {
14097 MockWrite("POST / HTTP/1.1\r\n"
14098 "Host: www.foo.com\r\n"
14099 "Connection: keep-alive\r\n"
14100 "Content-Length: 3\r\n\r\n"),
14101 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14102 };
14103
14104 MockRead data_reads[] = {
14105 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
14106 MockRead("hello world"),
14107 MockRead(SYNCHRONOUS, OK),
14108 };
14109 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14110 arraysize(data_writes));
14111 session_deps_.socket_factory->AddSocketDataProvider(&data);
14112
14113 TestCompletionCallback callback;
14114
14115 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14116 EXPECT_EQ(ERR_IO_PENDING, rv);
14117
14118 rv = callback.WaitForResult();
14119 EXPECT_EQ(OK, rv);
14120
14121 const HttpResponseInfo* response = trans->GetResponseInfo();
14122 ASSERT_TRUE(response != NULL);
14123
14124 EXPECT_TRUE(response->headers.get() != NULL);
14125 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
14126
14127 std::string response_data;
14128 rv = ReadTransaction(trans.get(), &response_data);
14129 EXPECT_EQ(OK, rv);
14130 EXPECT_EQ("hello world", response_data);
14131}
14132
14133// This test makes sure the retry logic doesn't trigger when reading an error
14134// response from a server that rejected a POST with a CONNECTION_RESET.
14135TEST_P(HttpNetworkTransactionTest,
14136 PostReadsErrorResponseAfterResetOnReusedSocket) {
mmenke6b3af6e2015-09-12 02:06:0614137 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5414138 MockWrite data_writes[] = {
14139 MockWrite("GET / HTTP/1.1\r\n"
14140 "Host: www.foo.com\r\n"
14141 "Connection: keep-alive\r\n\r\n"),
14142 MockWrite("POST / HTTP/1.1\r\n"
14143 "Host: www.foo.com\r\n"
14144 "Connection: keep-alive\r\n"
14145 "Content-Length: 3\r\n\r\n"),
14146 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14147 };
14148
14149 MockRead data_reads[] = {
14150 MockRead("HTTP/1.1 200 Peachy\r\n"
14151 "Content-Length: 14\r\n\r\n"),
14152 MockRead("first response"),
14153 MockRead("HTTP/1.1 400 Not OK\r\n"
14154 "Content-Length: 15\r\n\r\n"),
14155 MockRead("second response"),
14156 MockRead(SYNCHRONOUS, OK),
14157 };
14158 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14159 arraysize(data_writes));
14160 session_deps_.socket_factory->AddSocketDataProvider(&data);
14161
14162 TestCompletionCallback callback;
14163 HttpRequestInfo request1;
14164 request1.method = "GET";
14165 request1.url = GURL("http://www.foo.com/");
14166 request1.load_flags = 0;
14167
14168 scoped_ptr<HttpTransaction> trans1(
dcheng48459ac22014-08-26 00:46:4114169 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414170 int rv = trans1->Start(&request1, callback.callback(), BoundNetLog());
14171 EXPECT_EQ(ERR_IO_PENDING, rv);
14172
14173 rv = callback.WaitForResult();
14174 EXPECT_EQ(OK, rv);
14175
14176 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
14177 ASSERT_TRUE(response1 != NULL);
14178
14179 EXPECT_TRUE(response1->headers.get() != NULL);
14180 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
14181
14182 std::string response_data1;
14183 rv = ReadTransaction(trans1.get(), &response_data1);
14184 EXPECT_EQ(OK, rv);
14185 EXPECT_EQ("first response", response_data1);
14186 // Delete the transaction to release the socket back into the socket pool.
14187 trans1.reset();
14188
14189 ScopedVector<UploadElementReader> element_readers;
14190 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714191 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5414192
14193 HttpRequestInfo request2;
14194 request2.method = "POST";
14195 request2.url = GURL("http://www.foo.com/");
14196 request2.upload_data_stream = &upload_data_stream;
14197 request2.load_flags = 0;
14198
14199 scoped_ptr<HttpTransaction> trans2(
dcheng48459ac22014-08-26 00:46:4114200 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414201 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
14202 EXPECT_EQ(ERR_IO_PENDING, rv);
14203
14204 rv = callback.WaitForResult();
14205 EXPECT_EQ(OK, rv);
14206
14207 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
14208 ASSERT_TRUE(response2 != NULL);
14209
14210 EXPECT_TRUE(response2->headers.get() != NULL);
14211 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
14212
14213 std::string response_data2;
14214 rv = ReadTransaction(trans2.get(), &response_data2);
14215 EXPECT_EQ(OK, rv);
14216 EXPECT_EQ("second response", response_data2);
14217}
14218
14219TEST_P(HttpNetworkTransactionTest,
14220 PostReadsErrorResponseAfterResetPartialBodySent) {
14221 ScopedVector<UploadElementReader> element_readers;
14222 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714223 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5414224
14225 HttpRequestInfo request;
14226 request.method = "POST";
14227 request.url = GURL("http://www.foo.com/");
14228 request.upload_data_stream = &upload_data_stream;
14229 request.load_flags = 0;
14230
mmenke6b3af6e2015-09-12 02:06:0614231 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5414232 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114233 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414234 // Send headers successfully, but get an error while sending the body.
14235 MockWrite data_writes[] = {
14236 MockWrite("POST / HTTP/1.1\r\n"
14237 "Host: www.foo.com\r\n"
14238 "Connection: keep-alive\r\n"
14239 "Content-Length: 3\r\n\r\n"
14240 "fo"),
14241 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14242 };
14243
14244 MockRead data_reads[] = {
14245 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
14246 MockRead("hello world"),
14247 MockRead(SYNCHRONOUS, OK),
14248 };
14249 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14250 arraysize(data_writes));
14251 session_deps_.socket_factory->AddSocketDataProvider(&data);
14252
14253 TestCompletionCallback callback;
14254
14255 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14256 EXPECT_EQ(ERR_IO_PENDING, rv);
14257
14258 rv = callback.WaitForResult();
14259 EXPECT_EQ(OK, rv);
14260
14261 const HttpResponseInfo* response = trans->GetResponseInfo();
14262 ASSERT_TRUE(response != NULL);
14263
14264 EXPECT_TRUE(response->headers.get() != NULL);
14265 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
14266
14267 std::string response_data;
14268 rv = ReadTransaction(trans.get(), &response_data);
14269 EXPECT_EQ(OK, rv);
14270 EXPECT_EQ("hello world", response_data);
14271}
14272
14273// This tests the more common case than the previous test, where headers and
14274// body are not merged into a single request.
14275TEST_P(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
14276 ScopedVector<UploadElementReader> element_readers;
14277 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714278 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5414279
14280 HttpRequestInfo request;
14281 request.method = "POST";
14282 request.url = GURL("http://www.foo.com/");
14283 request.upload_data_stream = &upload_data_stream;
14284 request.load_flags = 0;
14285
mmenke6b3af6e2015-09-12 02:06:0614286 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5414287 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114288 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414289 // Send headers successfully, but get an error while sending the body.
14290 MockWrite data_writes[] = {
14291 MockWrite("POST / HTTP/1.1\r\n"
14292 "Host: www.foo.com\r\n"
14293 "Connection: keep-alive\r\n"
14294 "Transfer-Encoding: chunked\r\n\r\n"),
14295 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14296 };
14297
14298 MockRead data_reads[] = {
14299 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
14300 MockRead("hello world"),
14301 MockRead(SYNCHRONOUS, OK),
14302 };
14303 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14304 arraysize(data_writes));
14305 session_deps_.socket_factory->AddSocketDataProvider(&data);
14306
14307 TestCompletionCallback callback;
14308
14309 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14310 EXPECT_EQ(ERR_IO_PENDING, rv);
14311 // Make sure the headers are sent before adding a chunk. This ensures that
14312 // they can't be merged with the body in a single send. Not currently
14313 // necessary since a chunked body is never merged with headers, but this makes
14314 // the test more future proof.
14315 base::RunLoop().RunUntilIdle();
14316
mmenkecbc2b712014-10-09 20:29:0714317 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5414318
14319 rv = callback.WaitForResult();
14320 EXPECT_EQ(OK, rv);
14321
14322 const HttpResponseInfo* response = trans->GetResponseInfo();
14323 ASSERT_TRUE(response != NULL);
14324
14325 EXPECT_TRUE(response->headers.get() != NULL);
14326 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
14327
14328 std::string response_data;
14329 rv = ReadTransaction(trans.get(), &response_data);
14330 EXPECT_EQ(OK, rv);
14331 EXPECT_EQ("hello world", response_data);
14332}
14333
14334TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
14335 ScopedVector<UploadElementReader> element_readers;
14336 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714337 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5414338
14339 HttpRequestInfo request;
14340 request.method = "POST";
14341 request.url = GURL("http://www.foo.com/");
14342 request.upload_data_stream = &upload_data_stream;
14343 request.load_flags = 0;
14344
mmenke6b3af6e2015-09-12 02:06:0614345 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5414346 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114347 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414348
14349 MockWrite data_writes[] = {
14350 MockWrite("POST / HTTP/1.1\r\n"
14351 "Host: www.foo.com\r\n"
14352 "Connection: keep-alive\r\n"
14353 "Content-Length: 3\r\n\r\n"),
14354 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14355 };
14356
14357 MockRead data_reads[] = {
14358 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
14359 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
14360 MockRead("hello world"),
14361 MockRead(SYNCHRONOUS, OK),
14362 };
14363 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14364 arraysize(data_writes));
14365 session_deps_.socket_factory->AddSocketDataProvider(&data);
14366
14367 TestCompletionCallback callback;
14368
14369 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14370 EXPECT_EQ(ERR_IO_PENDING, rv);
14371
14372 rv = callback.WaitForResult();
14373 EXPECT_EQ(OK, rv);
14374
14375 const HttpResponseInfo* response = trans->GetResponseInfo();
14376 ASSERT_TRUE(response != NULL);
14377
14378 EXPECT_TRUE(response->headers.get() != NULL);
14379 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
14380
14381 std::string response_data;
14382 rv = ReadTransaction(trans.get(), &response_data);
14383 EXPECT_EQ(OK, rv);
14384 EXPECT_EQ("hello world", response_data);
14385}
14386
14387TEST_P(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
14388 ScopedVector<UploadElementReader> element_readers;
14389 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714390 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5414391
14392 HttpRequestInfo request;
14393 request.method = "POST";
14394 request.url = GURL("http://www.foo.com/");
14395 request.upload_data_stream = &upload_data_stream;
14396 request.load_flags = 0;
14397
mmenke6b3af6e2015-09-12 02:06:0614398 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5414399 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114400 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414401 // Send headers successfully, but get an error while sending the body.
14402 MockWrite data_writes[] = {
14403 MockWrite("POST / HTTP/1.1\r\n"
14404 "Host: www.foo.com\r\n"
14405 "Connection: keep-alive\r\n"
14406 "Content-Length: 3\r\n\r\n"),
14407 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14408 };
14409
14410 MockRead data_reads[] = {
14411 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
14412 MockRead("hello world"),
14413 MockRead(SYNCHRONOUS, OK),
14414 };
14415 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14416 arraysize(data_writes));
14417 session_deps_.socket_factory->AddSocketDataProvider(&data);
14418
14419 TestCompletionCallback callback;
14420
14421 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14422 EXPECT_EQ(ERR_IO_PENDING, rv);
14423
14424 rv = callback.WaitForResult();
14425 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5414426}
14427
14428TEST_P(HttpNetworkTransactionTest,
14429 PostIgnoresNonErrorResponseAfterResetAnd100) {
14430 ScopedVector<UploadElementReader> element_readers;
14431 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714432 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5414433
14434 HttpRequestInfo request;
14435 request.method = "POST";
14436 request.url = GURL("http://www.foo.com/");
14437 request.upload_data_stream = &upload_data_stream;
14438 request.load_flags = 0;
14439
mmenke6b3af6e2015-09-12 02:06:0614440 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5414441 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114442 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414443 // Send headers successfully, but get an error while sending the body.
14444 MockWrite data_writes[] = {
14445 MockWrite("POST / HTTP/1.1\r\n"
14446 "Host: www.foo.com\r\n"
14447 "Connection: keep-alive\r\n"
14448 "Content-Length: 3\r\n\r\n"),
14449 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14450 };
14451
14452 MockRead data_reads[] = {
14453 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
14454 MockRead("HTTP/1.0 302 Redirect\r\n"),
14455 MockRead("Location: http://somewhere-else.com/\r\n"),
14456 MockRead("Content-Length: 0\r\n\r\n"),
14457 MockRead(SYNCHRONOUS, OK),
14458 };
14459 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14460 arraysize(data_writes));
14461 session_deps_.socket_factory->AddSocketDataProvider(&data);
14462
14463 TestCompletionCallback callback;
14464
14465 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14466 EXPECT_EQ(ERR_IO_PENDING, rv);
14467
14468 rv = callback.WaitForResult();
14469 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5414470}
14471
14472TEST_P(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
14473 ScopedVector<UploadElementReader> element_readers;
14474 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714475 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5414476
14477 HttpRequestInfo request;
14478 request.method = "POST";
14479 request.url = GURL("http://www.foo.com/");
14480 request.upload_data_stream = &upload_data_stream;
14481 request.load_flags = 0;
14482
mmenke6b3af6e2015-09-12 02:06:0614483 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5414484 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114485 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414486 // Send headers successfully, but get an error while sending the body.
14487 MockWrite data_writes[] = {
14488 MockWrite("POST / HTTP/1.1\r\n"
14489 "Host: www.foo.com\r\n"
14490 "Connection: keep-alive\r\n"
14491 "Content-Length: 3\r\n\r\n"),
14492 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14493 };
14494
14495 MockRead data_reads[] = {
14496 MockRead("HTTP 0.9 rocks!"),
14497 MockRead(SYNCHRONOUS, OK),
14498 };
14499 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14500 arraysize(data_writes));
14501 session_deps_.socket_factory->AddSocketDataProvider(&data);
14502
14503 TestCompletionCallback callback;
14504
14505 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14506 EXPECT_EQ(ERR_IO_PENDING, rv);
14507
14508 rv = callback.WaitForResult();
14509 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5414510}
14511
14512TEST_P(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
14513 ScopedVector<UploadElementReader> element_readers;
14514 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714515 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5414516
14517 HttpRequestInfo request;
14518 request.method = "POST";
14519 request.url = GURL("http://www.foo.com/");
14520 request.upload_data_stream = &upload_data_stream;
14521 request.load_flags = 0;
14522
mmenke6b3af6e2015-09-12 02:06:0614523 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5414524 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114525 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414526 // Send headers successfully, but get an error while sending the body.
14527 MockWrite data_writes[] = {
14528 MockWrite("POST / HTTP/1.1\r\n"
14529 "Host: www.foo.com\r\n"
14530 "Connection: keep-alive\r\n"
14531 "Content-Length: 3\r\n\r\n"),
14532 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14533 };
14534
14535 MockRead data_reads[] = {
14536 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
14537 MockRead(SYNCHRONOUS, OK),
14538 };
14539 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14540 arraysize(data_writes));
14541 session_deps_.socket_factory->AddSocketDataProvider(&data);
14542
14543 TestCompletionCallback callback;
14544
14545 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14546 EXPECT_EQ(ERR_IO_PENDING, rv);
14547
14548 rv = callback.WaitForResult();
14549 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5414550}
14551
Adam Rice425cf122015-01-19 06:18:2414552// Verify that proxy headers are not sent to the destination server when
14553// establishing a tunnel for a secure WebSocket connection.
14554TEST_P(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
14555 HttpRequestInfo request;
14556 request.method = "GET";
bncce36dca22015-04-21 22:11:2314557 request.url = GURL("wss://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2414558 AddWebSocketHeaders(&request.extra_headers);
14559
14560 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:0314561 session_deps_.proxy_service =
14562 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2414563
mmenke6b3af6e2015-09-12 02:06:0614564 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2414565
14566 // Since a proxy is configured, try to establish a tunnel.
14567 MockWrite data_writes[] = {
14568 MockWrite(
bncce36dca22015-04-21 22:11:2314569 "CONNECT www.example.org:443 HTTP/1.1\r\n"
14570 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414571 "Proxy-Connection: keep-alive\r\n\r\n"),
14572
14573 // After calling trans->RestartWithAuth(), this is the request we should
14574 // be issuing -- the final header line contains the credentials.
14575 MockWrite(
bncce36dca22015-04-21 22:11:2314576 "CONNECT www.example.org:443 HTTP/1.1\r\n"
14577 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414578 "Proxy-Connection: keep-alive\r\n"
14579 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
14580
14581 MockWrite(
14582 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2314583 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414584 "Connection: Upgrade\r\n"
14585 "Upgrade: websocket\r\n"
bncce36dca22015-04-21 22:11:2314586 "Origin: http://www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414587 "Sec-WebSocket-Version: 13\r\n"
14588 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
14589 };
14590
14591 // The proxy responds to the connect with a 407, using a persistent
14592 // connection.
14593 MockRead data_reads[] = {
14594 // No credentials.
14595 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
14596 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
mmenkee0b5c882015-08-26 20:29:1114597 MockRead("Content-Length: 0\r\n"),
14598 MockRead("Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2414599
14600 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
14601
14602 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
14603 MockRead("Upgrade: websocket\r\n"),
14604 MockRead("Connection: Upgrade\r\n"),
14605 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
14606 };
14607
14608 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14609 arraysize(data_writes));
14610 session_deps_.socket_factory->AddSocketDataProvider(&data);
14611 SSLSocketDataProvider ssl(ASYNC, OK);
14612 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14613
14614 scoped_ptr<HttpTransaction> trans(
14615 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
14616 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
14617 trans->SetWebSocketHandshakeStreamCreateHelper(
14618 &websocket_stream_create_helper);
14619
14620 {
14621 TestCompletionCallback callback;
14622
14623 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14624 EXPECT_EQ(ERR_IO_PENDING, rv);
14625
14626 rv = callback.WaitForResult();
14627 EXPECT_EQ(OK, rv);
14628 }
14629
14630 const HttpResponseInfo* response = trans->GetResponseInfo();
14631 ASSERT_TRUE(response);
14632 ASSERT_TRUE(response->headers.get());
14633 EXPECT_EQ(407, response->headers->response_code());
14634
14635 {
14636 TestCompletionCallback callback;
14637
14638 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
14639 callback.callback());
14640 EXPECT_EQ(ERR_IO_PENDING, rv);
14641
14642 rv = callback.WaitForResult();
14643 EXPECT_EQ(OK, rv);
14644 }
14645
14646 response = trans->GetResponseInfo();
14647 ASSERT_TRUE(response);
14648 ASSERT_TRUE(response->headers.get());
14649
14650 EXPECT_EQ(101, response->headers->response_code());
14651
14652 trans.reset();
14653 session->CloseAllConnections();
14654}
14655
14656// Verify that proxy headers are not sent to the destination server when
14657// establishing a tunnel for an insecure WebSocket connection.
14658// This requires the authentication info to be injected into the auth cache
14659// due to crbug.com/395064
14660// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
14661TEST_P(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
14662 HttpRequestInfo request;
14663 request.method = "GET";
bncce36dca22015-04-21 22:11:2314664 request.url = GURL("ws://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2414665 AddWebSocketHeaders(&request.extra_headers);
14666
14667 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:0314668 session_deps_.proxy_service =
14669 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2414670
mmenke6b3af6e2015-09-12 02:06:0614671 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2414672
14673 MockWrite data_writes[] = {
14674 // Try to establish a tunnel for the WebSocket connection, with
14675 // credentials. Because WebSockets have a separate set of socket pools,
14676 // they cannot and will not use the same TCP/IP connection as the
14677 // preflight HTTP request.
14678 MockWrite(
bncce36dca22015-04-21 22:11:2314679 "CONNECT www.example.org:80 HTTP/1.1\r\n"
14680 "Host: www.example.org:80\r\n"
Adam Rice425cf122015-01-19 06:18:2414681 "Proxy-Connection: keep-alive\r\n"
14682 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
14683
14684 MockWrite(
14685 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2314686 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414687 "Connection: Upgrade\r\n"
14688 "Upgrade: websocket\r\n"
bncce36dca22015-04-21 22:11:2314689 "Origin: http://www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414690 "Sec-WebSocket-Version: 13\r\n"
14691 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
14692 };
14693
14694 MockRead data_reads[] = {
14695 // HTTP CONNECT with credentials.
14696 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
14697
14698 // WebSocket connection established inside tunnel.
14699 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
14700 MockRead("Upgrade: websocket\r\n"),
14701 MockRead("Connection: Upgrade\r\n"),
14702 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
14703 };
14704
14705 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14706 arraysize(data_writes));
14707 session_deps_.socket_factory->AddSocketDataProvider(&data);
14708
14709 session->http_auth_cache()->Add(
14710 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
14711 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
14712
14713 scoped_ptr<HttpTransaction> trans(
14714 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
14715 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
14716 trans->SetWebSocketHandshakeStreamCreateHelper(
14717 &websocket_stream_create_helper);
14718
14719 TestCompletionCallback callback;
14720
14721 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14722 EXPECT_EQ(ERR_IO_PENDING, rv);
14723
14724 rv = callback.WaitForResult();
14725 EXPECT_EQ(OK, rv);
14726
14727 const HttpResponseInfo* response = trans->GetResponseInfo();
14728 ASSERT_TRUE(response);
14729 ASSERT_TRUE(response->headers.get());
14730
14731 EXPECT_EQ(101, response->headers->response_code());
14732
14733 trans.reset();
14734 session->CloseAllConnections();
14735}
14736
sclittlefb249892015-09-10 21:33:2214737TEST_P(HttpNetworkTransactionTest, TotalNetworkBytesPost) {
14738 ScopedVector<UploadElementReader> element_readers;
14739 element_readers.push_back(new UploadBytesElementReader("foo", 3));
14740 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
14741
14742 HttpRequestInfo request;
14743 request.method = "POST";
14744 request.url = GURL("http://www.foo.com/");
14745 request.upload_data_stream = &upload_data_stream;
14746
mmenke6b3af6e2015-09-12 02:06:0614747 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
sclittlefb249892015-09-10 21:33:2214748 scoped_ptr<HttpTransaction> trans(
14749 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
14750 MockWrite data_writes[] = {
14751 MockWrite("POST / HTTP/1.1\r\n"
14752 "Host: www.foo.com\r\n"
14753 "Connection: keep-alive\r\n"
14754 "Content-Length: 3\r\n\r\n"),
14755 MockWrite("foo"),
14756 };
14757
14758 MockRead data_reads[] = {
14759 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
14760 MockRead(SYNCHRONOUS, OK),
14761 };
14762 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14763 arraysize(data_writes));
14764 session_deps_.socket_factory->AddSocketDataProvider(&data);
14765
14766 TestCompletionCallback callback;
14767
14768 EXPECT_EQ(ERR_IO_PENDING,
14769 trans->Start(&request, callback.callback(), BoundNetLog()));
14770 EXPECT_EQ(OK, callback.WaitForResult());
14771
14772 std::string response_data;
14773 EXPECT_EQ(OK, ReadTransaction(trans.get(), &response_data));
14774
14775 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
14776 trans->GetTotalSentBytes());
14777 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
14778 trans->GetTotalReceivedBytes());
14779}
14780
14781TEST_P(HttpNetworkTransactionTest, TotalNetworkBytesPost100Continue) {
14782 ScopedVector<UploadElementReader> element_readers;
14783 element_readers.push_back(new UploadBytesElementReader("foo", 3));
14784 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
14785
14786 HttpRequestInfo request;
14787 request.method = "POST";
14788 request.url = GURL("http://www.foo.com/");
14789 request.upload_data_stream = &upload_data_stream;
14790
mmenke6b3af6e2015-09-12 02:06:0614791 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
sclittlefb249892015-09-10 21:33:2214792 scoped_ptr<HttpTransaction> trans(
14793 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
14794 MockWrite data_writes[] = {
14795 MockWrite("POST / HTTP/1.1\r\n"
14796 "Host: www.foo.com\r\n"
14797 "Connection: keep-alive\r\n"
14798 "Content-Length: 3\r\n\r\n"),
14799 MockWrite("foo"),
14800 };
14801
14802 MockRead data_reads[] = {
14803 MockRead("HTTP/1.1 100 Continue\r\n\r\n"),
14804 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
14805 MockRead(SYNCHRONOUS, OK),
14806 };
14807 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14808 arraysize(data_writes));
14809 session_deps_.socket_factory->AddSocketDataProvider(&data);
14810
14811 TestCompletionCallback callback;
14812
14813 EXPECT_EQ(ERR_IO_PENDING,
14814 trans->Start(&request, callback.callback(), BoundNetLog()));
14815 EXPECT_EQ(OK, callback.WaitForResult());
14816
14817 std::string response_data;
14818 EXPECT_EQ(OK, ReadTransaction(trans.get(), &response_data));
14819
14820 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
14821 trans->GetTotalSentBytes());
14822 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
14823 trans->GetTotalReceivedBytes());
14824}
14825
14826TEST_P(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) {
14827 ScopedVector<UploadElementReader> element_readers;
14828 element_readers.push_back(new UploadBytesElementReader("foo", 3));
14829 ChunkedUploadDataStream upload_data_stream(0);
14830
14831 HttpRequestInfo request;
14832 request.method = "POST";
14833 request.url = GURL("http://www.foo.com/");
14834 request.upload_data_stream = &upload_data_stream;
14835
mmenke6b3af6e2015-09-12 02:06:0614836 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
sclittlefb249892015-09-10 21:33:2214837 scoped_ptr<HttpTransaction> trans(
14838 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
14839 // Send headers successfully, but get an error while sending the body.
14840 MockWrite data_writes[] = {
14841 MockWrite("POST / HTTP/1.1\r\n"
14842 "Host: www.foo.com\r\n"
14843 "Connection: keep-alive\r\n"
14844 "Transfer-Encoding: chunked\r\n\r\n"),
14845 MockWrite("1\r\nf\r\n"), MockWrite("2\r\noo\r\n"), MockWrite("0\r\n\r\n"),
14846 };
14847
14848 MockRead data_reads[] = {
14849 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
14850 MockRead(SYNCHRONOUS, OK),
14851 };
14852 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14853 arraysize(data_writes));
14854 session_deps_.socket_factory->AddSocketDataProvider(&data);
14855
14856 TestCompletionCallback callback;
14857
14858 EXPECT_EQ(ERR_IO_PENDING,
14859 trans->Start(&request, callback.callback(), BoundNetLog()));
14860
14861 base::RunLoop().RunUntilIdle();
14862 upload_data_stream.AppendData("f", 1, false);
14863
14864 base::RunLoop().RunUntilIdle();
14865 upload_data_stream.AppendData("oo", 2, true);
14866
14867 EXPECT_EQ(OK, callback.WaitForResult());
14868
14869 std::string response_data;
14870 EXPECT_EQ(OK, ReadTransaction(trans.get(), &response_data));
14871
14872 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
14873 trans->GetTotalSentBytes());
14874 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
14875 trans->GetTotalReceivedBytes());
14876}
14877
[email protected]89ceba9a2009-03-21 03:46:0614878} // namespace net